Improve m2sci tool
[scilab.git] / scilab / modules / m2sci / macros / mfile2sci.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2002-2004 - INRIA - Vincent COUVERT
3 // Copyright (C) ???? - INRIA - Serge STEER
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10
11 function res=mfile2sci(fil,res_path,Recmode,only_double,verbose_mode,prettyprintoutput)
12     // This function performs translation of a single M-file
13     // - fil: file name
14     // - res_path: path to write translated file in (default value is fil path)
15     // - Recmode: recursive mode (default value is false)
16
17     // Get default arguments
18     [lhs,rhs]=argn(0)
19     if rhs<6 then prettyprintoutput=%F,end
20     if rhs<5 then verbose_mode=3,end
21     if rhs<4 then only_double=%T,end
22     if rhs<3 then Recmode=%F,end
23     if rhs<2 then res_path="./",end
24     if rhs<1 then m2sci_gui();res=[];return;end
25     if getos() == "Windows" then
26         fil=strsubst(fil,filesep(),"/")
27         res_path=strsubst(res_path,"\","/")
28     end
29     if part(res_path,length(res_path))<>"/" then
30         res_path=res_path+"/"
31     end
32     // Loads libraries related to m2sci
33     if exists("m2scikernellib")==0 then load("SCI/modules/m2sci/macros/kernel/lib"),end
34     if exists("m2scipercentlib")==0 then load("SCI/modules/m2sci/macros/percent/lib"),end
35     if exists("m2scisci_fileslib")==0 then load("SCI/modules/m2sci/macros/sci_files/lib"),end
36
37     if multi_fun_file(fil,res_path,Recmode,only_double,verbose_mode,prettyprintoutput) then
38         res=1
39         return
40     end
41
42     // Get context
43     global("m2sci_infos")
44     global("mtlbref_fun")
45     global("mtlbtool_fun")
46     global("not_mtlb_fun")
47     [l,mac]=where()
48     Reclevel=size(find(mac=="mfile2sci"),"*")
49     tpcallpos=min(find(mac=="translatepaths"));
50     guicallpos=min(find(mac=="m2sci_gui"));
51     if size(find(mac=="m2sci_gui"),"*")==1 & tpcallpos<guicallpos then // Bug 679
52         Reclevel=Reclevel-1
53     end
54     if size(find(mac=="multi_fun_file"),"*")==1 then
55         Reclevel=Reclevel-1
56     end
57
58     if Reclevel==1 then
59         nametbl=[]
60     else
61         m2sci_infos_save=m2sci_infos
62     end
63     m2sci_infos=[%f %f]
64
65     margin=part(" ",ones(1,3*(Reclevel-1)))
66     margin="  "
67     rec=gettext("OFF");
68     dble=gettext("NO");
69     pretty=gettext("NO");
70     if prettyprintoutput then pretty=gettext("YES");end
71     if Recmode then rec=gettext("ON");end
72     if only_double then dble=gettext("YES");end
73
74     res=[]
75
76     // Handle file path
77     // File name
78     k=strindex(fil,".")
79     if k<>[]
80         ke=k($)-1
81         base_name=part(fil,1:ke)
82     else
83         ke=length(fil)
84         base_name=fil
85     end
86     // File path
87     k=strindex(fil,"/")
88     if k==[] then
89         file_path="./"
90     else
91         file_path=part(fil,1:k($))
92     end
93     // Others M-files in directory
94     if exists("Paths")==0 then
95         Paths=file_path,
96         if getos() == "Windows" then
97             Paths=strsubst(Paths,"/","\")
98             mfiles=listfiles(Paths+"*.m")
99             sep=filesep()
100         else
101             mfiles=listfiles(Paths+"*.m")
102             sep=filesep()
103         end
104     end
105
106     // Function name
107     fnam=part(base_name,k($)+1:ke) // File name without extension
108
109     // logfile initialisation
110     if exists("logfile")==0 then
111         [tempfd1,ierr1]=file("open",pathconvert(TMPDIR)+"logfile.dat","old")
112         if ierr1==0 then
113             load(pathconvert(TMPDIR)+"logfile.dat")
114             file("close",tempfd1)
115             file("close",logfile)
116             mdelete(pathconvert(TMPDIR)+"logfile.dat")
117         end
118         logfile=file("open",res_path+"m2sci_"+fnam+".log","unknown")
119         save(pathconvert(TMPDIR)+"logfile.dat", "logfile")
120     end
121
122     // Output beginning message
123     mss=[gettext("****** Beginning of mfile2sci() session ******");
124     gettext("File to convert:")+" "+fil;
125     gettext("Result file path:")+" "+res_path;
126     gettext("Recursive mode:")+" "+rec;
127     gettext("Only double values used in M-file:")+" "+dble;
128     gettext("Verbose mode:")+" "+string(verbose_mode);
129     gettext("Generate formated code:")+" "+pretty]
130     m2sci_info(mss,-1);
131
132     // Read in the file as text
133     m2sci_info(gettext("M-file reading..."),-1);
134     txt=mgetl(fil);
135     m2sci_info(gettext("M-file reading: Done"),-1);
136
137     //Replace TAB by SPACE
138     txt=strsubst(txt, ascii(9), "");
139
140     if txt==[] then
141         m2sci_infos(msprintf(gettext("File %s is an empty file.\n"),fil),-1);
142         return
143     end
144     tmptxt=txt
145
146     // Make minor changes on syntax
147     m2sci_info(gettext("Syntax modification..."),-1);
148     ierr=execstr("load(''"+pathconvert(TMPDIR)+fnam+ ".tree'',''txt'',''helppart'',''batch'')","errcatch","n")
149     if ierr<>0 | exists("txt")==0 | exists("batch")==0 & strindex(res_path,TMPDIR)==[] then
150         [helppart,txt,batch]=m2sci_syntax(txt)
151     elseif ierr==0 & newest(fil,pathconvert(TMPDIR)+fnam+ ".tree")==1 then
152         [helppart,txt,batch]=m2sci_syntax(tmptxt)
153     end
154
155     m2sci_info(gettext("Syntax modification: Done"),-1);
156
157     // Write .cat file and update whatis
158     if helppart<>[] then
159         catfil=res_path+fnam+".cat"
160         whsfil=res_path+"whatis"
161         mputl(helppart,catfil);
162         if exists("whsfil_unit")==1 then
163             write(whsfil_unit,stripblanks(helppart(1))+" |"+fnam,"(a)")
164         end
165     end
166
167     if txt~=[] then
168         quote="''";
169         dquote="""";
170         kc=strindex(txt(1),"function");
171         kc=kc(1);
172
173         // Define Scilab function
174         fprot=funcprot();
175         funcprot(0);
176
177         // Blanks in file name are replaced by _ for batch
178         // kc+9 because 'function '
179         ksc=min(strindex(txt(1),";")) // searching for a comment on first line after function prototype
180         if isempty(ksc) then
181             ksc=length(txt(1))+1;
182             firstline=[]
183         else
184             firstline=part(txt(1),ksc+1:length(txt(1)));
185         end
186
187         func_proto=part(txt(1),kc+9:ksc-1)
188         keq=min(strindex(func_proto,"="))
189         kpar=min(strindex(func_proto,"("))
190         if isempty(keq) then
191             keq=1
192         end
193         if isempty(kpar) then
194             kpar=length(func_proto)+1
195         end
196         func_proto=part(func_proto,1:keq)+..
197         strsubst(stripblanks(part(func_proto,keq+1:kpar-1))," ","_")+..
198         part(func_proto,kpar:length(func_proto))
199
200         deff(func_proto,[firstline;txt(2:$)],"n")
201         w=who("get");
202         mname=w(1);
203         nametbl=[nametbl;mname]
204         if fnam<>mname & ~batch then // warning is not displayed for a batch file
205             mss=msprintf(gettext("Warning: file %s defines function %s instead of %s\n         %s.sci, %s.cat and sci_%s.sci will be generated !"),fil,mname,fnam,mname,mname,mname);
206             m2sci_info(mss,-1);
207         end
208
209         txt($+1) = "endfunction"
210         // Compilation
211         mputl(txt, TMPDIR+"/"+mname+".sci");
212         exec(TMPDIR+"/"+mname+".sci", -1);
213         funcprot(fprot);
214         mdelete(TMPDIR+"/"+mname+".sci");
215
216         // Get Scilab pseudo code of the function
217         m2sci_info(gettext("Macro to tree conversion..."),-1);
218         macr=evstr(mname)
219         mtlbtree=macr2tree(macr);
220         if ~batch then
221             mtlbtree.name=mname;
222         else
223             mtlbtree.name="";
224         end
225
226         //Transfom a equal instructions(if lhs are multi_operation insert and expression is a funcall) in the matlab tree to sup_equal instructions
227         global("tmpvarnb")
228         tmpvarnb=0;
229         level=[0,0];
230         ninstr=1;
231         while ninstr<=size(mtlbtree.statements)-3
232             mtlbtree.statements(ninstr)=transformtree(mtlbtree.statements(ninstr))
233             ninstr=ninstr+1
234         end
235
236         // Perform the translation
237         [scitree,trad,hdr,crp]=m2sci(mtlbtree,w(1),Recmode,prettyprintoutput)
238
239         //Creation of fname_resume.log file
240         // if mtlbref_fun<>[]|not_mtlb_fun<>[]|mtlbtool_fun<>[] then
241         //resume_logfile initialisation
242         if exists("resume_logfile")==0 then
243             [tempfd2,ierr2]=file("open",pathconvert(TMPDIR)+gettext("resumelogfile.dat"),"old")
244             if ierr2==0 then
245                 load(pathconvert(TMPDIR)+gettext("resumelogfile.dat"))
246                 file("close",tempfd2)
247                 file("close",resume_logfile)
248                 mdelete(pathconvert(TMPDIR)+gettext("resumelogfile.dat"))
249             end
250             resume_logfile=file("open",res_path+gettext("resume")+"_m2sci_"+fnam+".log","unknown")
251             save(pathconvert(TMPDIR)+gettext("resumelogfile.dat"), "resume_logfile")
252         end
253
254         //number of matlab reference functions, matlab toolboxes functions, not matlab functions
255         size1=size(mtlbref_fun,1)
256         size2=size(mtlbtool_fun,1)
257         size3=size(not_mtlb_fun,1)
258
259         if size(mtlbref_fun,"*")<>0 then
260             mtlbref_fun(:,1)=""""+mtlbref_fun(:,1)+""""
261         end
262         if size(mtlbtool_fun,"*")<>0 then
263             mtlbtool_fun(:,1)=""""+mtlbtool_fun(:,1)+""""
264         end
265         if size(not_mtlb_fun,"*")<>0 then
266             not_mtlb_fun(:,1)=""""+not_mtlb_fun(:,1)+""""
267         end
268
269         info_resume=[msprintf(gettext("****** %s: Functions of mfile2sci() session ******"),fnam);
270         "*";
271         msprintf(gettext("%d Matlab Function(s) not yet converted, original calling sequence used:"),size1);
272         mtlbref_fun(:,1)+mtlbref_fun(:,2);
273         "*";
274         msprintf(gettext("%d Matlab Toolbox(es) Functions, original calling sequence used :"),size2);
275         mtlbtool_fun(:,1)+mtlbtool_fun(:,2);
276         "*";
277         msprintf(gettext("%d Unknown Function(s), original calling sequence used :"),size3);
278         not_mtlb_fun(:,1)+not_mtlb_fun(:,2);
279         "*"]
280
281         write(resume_logfile,margin+info_resume)
282         file("close",resume_logfile)
283         mdelete(pathconvert(TMPDIR)+gettext("resumelogfile.dat"))
284         //end
285
286         m2sci_info(gettext("Macro to tree conversion: Done"),-1);
287
288         crp(1)=""; // Delete function prototype
289         if isempty(firstline) then
290             res=[hdr;crp]
291         else
292             hdr(1)=hdr(1)+" "+crp(2);
293             crp(2)=[];
294             res=[hdr;crp];
295         end
296
297         // Strip last return and blank lines
298         n=size(res,1)
299         while res(n)==part(" ",1:length(res(n))) then
300             n=n-1
301         end
302         res=res(1:n)
303
304         // Write sci-file
305         ext=".sci"
306         scifil=res_path+fnam+ext
307         mputl(res,scifil);
308
309         // Write sci_<mname>.sci translation file
310         if trad<>[] then
311             sci_fil=res_path+"sci_"+mname+".sci"
312             mputl(trad,sci_fil);
313             res=1
314         else
315             res=0
316         end
317
318         // Output summary information
319         infos=[]
320         if m2sci_infos(1) then
321             infos=gettext("Translation may be improved: see the //! comments and for all mtlb_<funname> function call\n  Type help mtlb_<funname> in Scilab command window to get information about improvements.");
322         end
323         if m2sci_infos(2) then
324             infos=[infos;gettext("Translation may be wrong (see the //!! comments).")]
325         end
326
327         nametbl($)=[]
328
329     else
330         infos=gettext("File contains no instruction, no translation made...");
331     end
332
333     // End of translation messages
334     mss=gettext("****** End of mfile2sci() session ******");
335
336     m2sci_info([infos;mss],-1);
337
338     if Reclevel>1 then
339         m2sci_infos=m2sci_infos_save
340     end
341
342     file("close",logfile)
343     clearglobal m2sci_infos
344     clearglobal mtlbref_fun
345     clearglobal mtlbtool_fun
346     clearglobal not_mtlb_fun
347     // For execution called by translatepaths()
348     //nametbl=resume(nametbl)
349     mdelete(pathconvert(TMPDIR)+fnam+ ".tree")
350     mdelete(pathconvert(TMPDIR)+"logfile.dat")
351
352 endfunction