summaryrefslogtreecommitdiff
path: root/modules/m2sci/macros/kernel/lst_funcall.sci
blob: c02374d3a48e27941f51f86187a47c1f84a54e5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) ???? - INRIA - Scilab
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution.  The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt

function   funcallname=lst_funcall(fil,fnamvect)
    //  LST_FUNCALL function (used by "translatepaths" function) Creates a list of vectors. The first component of each vector is the name of a M-file (found in the Paths to translate), followed by the called functions by this file
    //  Output
    //  -funcallname : a list of vectors
    //  Input
    //  -fil : vector which contains all M-files names (path+name) found in the Paths
    //  -fnamvect : vector which contains all M-files names (just the name) found in the Paths

    quote="''";
    dquote="""";

    k=strindex(fil,".")
    ke=k($)-1
    // Function name
    ksep=strindex(fil,sep)
    fnam=part(fil,ksep($)+1:ke) // File name without extension
    txt=mgetl(fil);

    kf=grep(txt,["function[","function "])

    if isempty(kf) then
        // Batch file
        bval=%f
    elseif size(kf,"*")==1 then
        // Only one function defined
        bval=%f
    else
        funcdecl=[]
        for kk=kf
            ind=strindex(txt(kk),["function[";"function "])
            if (ind<isacomment(txt(kk)) | isacomment(txt(kk))==0) & ~isinstring(txt(kk),ind) & part(stripblanks(txt(kk),%T),1:8)=="function"  then // function prototype
                funcdecl=[funcdecl kk]
            end
        end
        if isempty(funcdecl) then
            // "function" only exists in comments and strings
            bval=%f
        elseif size(funcdecl,"*")==1 then
            bval=%f
        else
            bval= %t
        end
    end

    // file contains more than one function declaration
    if bval then
        // Verify if the directory exists
        sep = filesep();
        dirnam = ls(pathconvert(TMPDIR));
        if or(fnam==dirnam) then
            rmdir(pathconvert(TMPDIR)+fnam,"s")
        end
        mkdir(pathconvert(TMPDIR),fnam)

        write(%io(2),msprintf(gettext(" -- File %s contains more than one function -- "),fil));
        // First split file into as many files as function declared
        funcdecl=[funcdecl size(txt,"*")+1]
        tmpfiles=[]
        for k=1:size(funcdecl,"*")-1
            if k==1 then
                functxt=txt(funcdecl(k):funcdecl(k+1)-1)
                str=  strindex(txt(funcdecl(k)),"(")-1
                funcname=stripblanks(part(txt(funcdecl(k)),strindex(txt(funcdecl(k)),["function[","function "])+8:str(1)))
                keq=strindex(funcname,"=")
                if ~isempty(keq) then
                    funcname=stripblanks(part(funcname,keq+1:length(funcname)))
                end
                mputl(functxt,pathconvert(TMPDIR)+fnam+".m");
            else
                functxt=txt(funcdecl(k):funcdecl(k+1)-1)
                str=strindex(txt(funcdecl(k)),"(")-1
                if str==-1 then
                    funcname=stripblanks(part(txt(funcdecl(k)),strindex(txt(funcdecl(k)),["function[","function "])+8:length(txt(funcdecl(k)))))
                else
                    funcname=stripblanks(part(txt(funcdecl(k)),strindex(txt(funcdecl(k)),["function[","function "])+8:str(1)))
                end
                keq=strindex(funcname,"=")
                if ~isempty(keq) then
                    funcname=stripblanks(part(funcname,keq+1:length(funcname)))
                end
                tmpfiles=[tmpfiles;funcname]
                mputl(functxt,pathconvert(TMPDIR)+pathconvert(fnam)+tmpfiles($)+".m");
            end
        end
        write(%io(2),msprintf(gettext(" -- Each function converted separately: %s -- "),strcat(tmpfiles," ")));
        write(%io(2),msprintf(gettext(" -- Temporary files put in: %s -- "),pathconvert(TMPDIR)));

        // Conversion of each file
        //for k=1:size(tmpfiles,"*")
        //mfile2sci(pathconvert(TMPDIR)+pathconvert(fnam)+tmpfiles(k)+".m",pathconvert(TMPDIR)+pathconvert(fnam))
        // Delete useless .m files
        //mdelete(pathconvert(TMPDIR)+pathconvert(fnam)+tmpfiles(k)+".m")
        //end

        translatepaths(pathconvert(TMPDIR)+pathconvert(fnam),pathconvert(TMPDIR)+pathconvert(fnam))
        // Catenation of all .sci files to have only one output file
        txt=[]

        for k=1:size(tmpfiles,"*")
            txt=[txt ;" ";mgetl(pathconvert(TMPDIR)+pathconvert(fnam)+tmpfiles(k)+".sci")]
            mdelete(pathconvert(TMPDIR)+pathconvert(fnam)+tmpfiles(k)+".sci")
        end
        mputl(txt,pathconvert(TMPDIR)+"tmp_"+fnam+".sci");
        // End of catenation of all .sci files to have only one output file
        txt=mgetl(pathconvert(TMPDIR)+pathconvert(fnam)+sep+"log")
        mputl(txt,pathconvert(TMPDIR)+"tmp_m2sci_"+fnam+".log");
        //
        txt=mgetl(pathconvert(TMPDIR)+pathconvert(fnam)+sep+"resumelog")
        mputl(txt,pathconvert(TMPDIR)+"tmp_resume_m2sci_"+fnam+".log");

        // Catenation of all .log files to have only one output file
        // txt=[]
        // for k=1:size(tmpfiles,"*")
        // txt=[txt ; mgetl(pathconvert(TMPDIR)+pathconvert(fnam)+"m2sci_"+tmpfiles(k)+".log")]
        // Delete useless .log files
        // mdelete(pathconvert(TMPDIR)+pathconvert(fnam)+"m2sci_"+tmpfiles(k)+".log")
        //end
        //mputl(txt,pathconvert(TMPDIR)+"tmp_m2sci_"+fnam+".log");
        //End of catenation of all .log files to have only one output file

        // Catenation of all resume.log files to have only one output file
        //txt=[]
        //for k=1:size(tmpfiles,"*")
        //txt=[txt ; mgetl(pathconvert(TMPDIR)+pathconvert(fnam)+"resume_m2sci_"+tmpfiles(k)+".log")]
        // Delete useless resume.log files
        // mdelete(pathconvert(TMPDIR)+pathconvert(fnam)+"resume_m2sci_"+tmpfiles(k)+".log")
        //end
        //mputl(txt,pathconvert(TMPDIR)+"tmp_resume_m2sci_"+fnam+".log");
        //End of catenation of all resume.log files to have only one output file

        txt=mgetl(pathconvert(TMPDIR)+fnam+".m")
    end

    txt = strsubst(txt, ascii(9), "")
    [helppart,txt,batch]=m2sci_syntax(txt)
    // save txt vector, helpart and batch after the syntax modification
    if strindex(fil,TMPDIR)==[] then
        save(pathconvert(TMPDIR)+fnam+".tree",txt,helppart,batch)
    end

    funcallname=[]
    if txt~=[] then
        kc=strindex(txt(1),"function");
        kc=kc(1);

        // Define Scilab function
        fprot=funcprot();
        funcprot(0);

        // Blanks in file name are replaced by _ for batch
        // kc+9 because 'function '

        ksc=min(strindex(txt(1),";")) // searching for a comment on first line after function prototype

        if isempty(ksc) then
            ksc=length(txt(1))+1;
            firstline=[]
        else
            firstline=part(txt(1),ksc+1:length(txt(1)));
        end

        func_proto=part(txt(1),kc+9:ksc-1)
        keq=min(strindex(func_proto,"="))
        kpar=min(strindex(func_proto,"("))

        if isempty(keq) then
            keq=0
        end
        if isempty(kpar) then
            kpar=length(func_proto)+1
        end

        mname=strsubst(stripblanks(part(func_proto,keq+1:kpar-1))," ","_")
        func_proto=part(func_proto,1:keq)+..
        strsubst(stripblanks(part(func_proto,keq+1:kpar-1))," ","_")+..
        part(func_proto,kpar:length(func_proto))

        deff(func_proto,[firstline;txt(2:$)],"n")
        w=who("get");
        mname=w(1);

        // Compilation
        execstr("comp("+mname+",1)")

        funcprot(fprot)

        // Get Scilab pseudo code of the function
        macr=evstr(mname)

        mtlbtree=macr2tree(macr);

        if ~batch then
            mtlbtree.name=mname;
        else
            mtlbtree.name="";
        end

        ninstr=1
        // variablevect is a vector which contains all variables (excluded functions)
        variablevect=[]
        for i=1:size(mtlbtree.inputs)
            variablevect=[variablevect;mtlbtree.inputs(i).name]
        end

        // search the declared variables in mtlbtree
        while ninstr<=size(mtlbtree.statements)-3
            [variablevect]=variablesearch(mtlbtree.statements(ninstr),variablevect)
            ninstr=ninstr+1
        end

        ninstr=1
        // search the called functions in the mtlbtree
        // funcallname contains the name of the M-file, followed by the called functions

        while ninstr<=size(mtlbtree.statements)-3
            [funcallname,variablevect]=funcallsearch(mtlbtree.statements(ninstr),funcallname,fnamvect,variablevect)
            ninstr=ninstr+1
        end

    end

    // add the M-file name in funcallname vector (at the first index)
    funcallname=[fnam;funcallname]

endfunction