summaryrefslogtreecommitdiff
path: root/modules/functions/macros/genlib.sci
blob: c2911728d5bd2739da9c782760d8d1897cbff8d5 (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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) INRIA
// Copyright (C) ENPC
// Copyright (C) DIGITEO - 2012 - Allan CORNET
//
// 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 [success, funcs, success_files, failed_files] = genlib(nam, path, force, verbose, names)

    // get all .sci files in the specified directory

    if argn(2) < 1 then
        error(sprintf(_("%s: Wrong number of input argument(s): %d to %d expected.\n"), "genlib", 1, 5));
    end

    if type(nam) <> 10 then
        error(999, msprintf(_("%s: Wrong type for input argument #%d: A string expected.\n"), "genlib", 1));
    end

    if size(nam, "*") <> 1 then
        error(999, msprintf(_("%s: Wrong size for input argument #%d: A string expected.\n"), "genlib", 1));
    end

    if exists("force", "local") == 0 then
        force = %f;
    else
        if type(force) <> 4 then
            error(999, msprintf(_("%s: Wrong type for input argument #%d: A boolean expected.\n"), "genlib", 3));
        end

        if size(force, "*") <> 1 then
            error(999, msprintf(_("%s: Wrong size for input argument #%d: A boolean expected.\n"), "genlib", 3));
        end
    end

    if exists("verbose", "local") == 0 then
        verbose = %f;
    else
        if type(verbose) <> 4 then
            error(999, msprintf(_("%s: Wrong type for input argument #%d: A boolean expected.\n"), "genlib", 4));
        end

        if size(verbose, "*") <> 1 then
            error(999, msprintf(_("%s: Wrong size for input argument #%d: A boolean expected.\n"), "genlib", 4));
        end
    end

    W          = who("get");
    np         = predef();
    predefined = or(W($-np+1:$) == nam);

    success       = %t;
    funcs         = [];
    success_files = [];
    failed_files  = [];

    if verbose then
        mprintf(gettext("-- Creation of [%s] (Macros) --\n"), nam);
    end

    updatelib = %f; //true if updating an already defined library

    //check if a library with the same name exists

    oldlib    = [];
    old_path  = [];
    old_names = [];

    if exists(nam)==1 then
        execstr("oldlib="+nam);
        if typeof(oldlib)=="library" then
            //yes, get its path and function list
            old_names = string(oldlib);
            clear oldlib;
            old_path     = old_names(1);
            old_names(1) = [];
        end
    end

    if (exists("path", "local") == 0) then
        if (old_path <> []) then
            path = old_path;
            updatelib = %t;
        else
            path = pwd();
        end
    else
        if type(path) <> 10 then
            error(999, msprintf(_("%s: Wrong type for input argument #%d: A string expected.\n"), "genlib", 2));
        end

        if size(path, "*") <> 1 then
            error(999, msprintf(_("%s: Wrong size for input argument #%d: A string expected.\n"), "genlib", 2));
        end
    end

    // convert path according to getos() == 'Windows' flag
    // without env variable substitution

    path1 = pathconvert(path, %t, %f);
    // with env subsitution
    path = pathconvert(path, %t, %t);

    if exists("names", "local")==0 then
        // list the sci files
        files          = gsort(listfiles(path+"*.sci",%f), "r", "i");
        files_filtered = [];

        for i=1:size(files,"*")
            if( regexp(files(i),"/\.sci$/") <> [] ) then
                files_filtered = [files_filtered;files(i)];
            end
        end

        files = files_filtered;
        clear files_filtered;

        if files==[] | files== "" then
            warning(msprintf(gettext("%s: No files with extension %s found in %s\n"),"genlib",".sci", path));
            return ;
        end

        names = basename(files,%f);

    else
        if type(names) <> 10 then
            error(999, msprintf(_("%s: Wrong type for input argument #%d:  A matrix of string expected.\n"), "genlib", 5));
        end

        files = path + names;
        names = strsubst(names, "/\.sci$/", "", "r");
    end

    names_changed = %t;

    if updatelib then
        if and(gsort(names)==gsort(old_names)) then names_changed=%f,end
    end

    modified = %f;

    if force == %t then
        modified = %t;
        for i=1:size(files,"*")  // loop on .sci files
            scif = files(i);
            if verbose then
                mprintf(gettext("%s: %s file compilation forced\n"),"genlib",names(i)+".sci");
            end
            // getf sci file and save functions it defines as a .bin file
            getsave(scif);
        end
    else
        for i=1:size(files,"*")  // loop on .sci files
            scif      = files(i);
            binf      = strsubst(scif, "/\.sci$/",".bin","r");
            binf_info = fileinfo(binf);
            recompile = %f;

            if binf_info == [] then
                recompile = %t;
            else
                scif_info = fileinfo(scif);
                if newest(scif,binf) == 1 then
                    recompile = %t ;
                end
            end

            if recompile == %t then

                if verbose then
                    mprintf(gettext("%s: Processing file: %s\n"), "genlib", names(i) + ".sci");
                end

                // getf sci file and save functions it defines as a .bin file
                result = getsave(scif);
                modified = %t;
                if result <> [] then
                    success_files($+1) = scif
                    funcs = [funcs result]
                else
                    failed_files($+1) = scif
                    success = %f
                end
            end
        end
    end

    if modified then

        if verbose then
            mprintf(gettext("%s: Regenerate names and lib\n"),"genlib");
        end

        if names_changed
            mputl(names,path+"names"); // write 'names' file in directory
        end

        // create library
        execstr(nam+"=lib(''"+getshortpathname(path1)+"'')")
        //save it

        warnMode = warning("query");
        warning("off");
        if execstr("save(''"+path1+"lib''"+","+nam+")","errcatch")<>0 then
            success = %f;
            warning(warnMode);
            error(msprintf(gettext("%s: %s file cannot be created\n"),"genlib",path+"lib"));
        end
        warning(warnMode);
    else
        execstr(nam+"=lib(''"+path1+"'')")
    end

    if names_changed then
        if ~predefined then
            execstr(nam+"=resume("+nam+")")
        else
            mprintf(gettext("Library file %s has been updated,\nbut cannot be loaded into Scilab because %s is a protected variable.\n"),path1+"lib",nam);
        end
    end

endfunction

function result = getsave(scifile)

    // utility function
    // performs a exec on file scifile

    result = %f;
    prot   = funcprot();
    nold   = size(who("get"),"*");

    funcprot(0);

    ierr=exec(scifile,"errcatch",-1);
    if ierr <> 0 then
        execstr("error(ierr)","errcatch");
        error(msprintf(gettext("%s: Error in file %s : %s.\n"), "genlib", scifile, lasterror()));
        clear ierr;
        result = %f;

    else

        clear ierr;

        // lookfor names of the functions defined in file 'scifile'
        new = who("get")
        new = new(1:(size(new,"*")-nold-1))

        // create output file name (just replace the ".sci" extension by ".bin"
        binfile = strsubst(scifile,"/\.sci$/",".bin","r")

        // save all functions in the output file
        [u,ierr]=mopen(binfile,"wb")
        if ierr<>0 then
            clear ierr;
            nf = length(binfile);
            if nf>40 then
                binfile="..."+part(binfile,nf-40:nf);
            end
            error(msprintf(gettext("%s: Impossible to open file %s for writing\n"),"genlib",binfile));
        end

        clear ierr

        if new<>[] then
            result = new($:-1:1)';
            warnMode = warning("query");
            warning("off");
            execstr("save(u,"+strcat(new($:-1:1),",")+")");
            warning(warnMode);
        else
            msprintf(gettext("%s: File %s does not contain any function.\n"),"genlib",binfile)
            result = %f;
        end

        mclose(u);
    end

    funcprot(prot);

endfunction