Cosmetic: removed dupllicate code in atoms
[scilab.git] / scilab / modules / atoms / macros / atoms_internals / atomsDESCRIPTIONread.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2009 - DIGITEO - Pierre MARECHAL <pierre.marechal@scilab.org>
3 //
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 //
6 // This file is hereby licensed under the terms of the GNU GPL v2.0,
7 // pursuant to article 5.3.4 of the CeCILL v.2.1.
8 // This file was originally licensed under the terms of the CeCILL v2.1,
9 // and continues to be available under such terms.
10 // For more information, see the COPYING file which you should have received
11 // along with this program.
12
13 // Internal function
14
15 // Return the full description of
16 //  - TOOLBOXES file present in the differents repositories
17 //  - DESCRIPTION file present in one package
18
19 // DESCRIPTION
20 // |
21 // |-- packages                              [1x1 struct]
22 // |   |-- toolbox_1                         [1x1 struct]
23 // |   |   |-- 2.0                           [1x1 struct]
24 // |   |   |   |-- Toolbox: "toolbox_2"
25 // |   |   |   |-- Title: "Toolbox Test 2"
26 // |   |   |   |-- Version: "2.0"
27 // |   |   |   `-- ..
28 // |   |   `-- 1.0                           [1x1 struct]
29 // |   |   |   |-- Toolbox: "toolbox_2"
30 // |   |   |   |-- Title: "Toolbox Test 2"
31 // |   |   |   |-- Version: "1.0"
32 // |   |   |   `-- ..
33 // |   |-- module_lycee
34 // |   `-- ..
35 // |
36 // |-- categories                            [1x1 struct]
37 // |   |-- Optimization                      [1x1 struct]
38 // |   |   |-- Linear
39 // |   |   `-- General
40 // |   `-- ..
41 // |
42 // |-- categories_flat                       [1x1 struct]
43 //     |-- Optimization - Linear
44 //     |   |-- packages
45 //     |   |   `-- ["simplex" "1.0" ; "lolimot" "0.9"]
46 //     |   `-- label
47 //     |       `-- [ "Optimization" "Linear" ]
48 //     |-- Optimization
49 //     |   |-- packages
50 //     |   |   `-- ["simplex" "1.0" ; "lolimot" "0.9"]
51 //     |   `-- label
52 //     |       `-- [ "Optimization" "Linear" ]
53 //     `-- Education
54 //         |-- packages
55 //         |   `-- ["module_lycee" "1.0" ; "module_lycee" "1.1"]
56 //         `-- label
57 //             `-- [ "Education" ]
58
59
60
61 function description_out = atomsDESCRIPTIONread(file_in,additional)
62
63     // Check input parameters
64     // =========================================================================
65
66     rhs  = argn(2);
67
68     if and(rhs <> [1 2])  then
69         error(msprintf(gettext("%s: Wrong number of input argument: %d to %d expected.\n"),"atomsDESCRIPTIONread",1,2));
70     end
71
72     if regexp( file_in,"/(TOOLBOXES|DESCRIPTION)/") == [] then
73         error(msprintf(gettext("%s: Wrong value for input argument #%d: String that contains ''TOOLBOXES'' or ''DESCRIPTION'' expected.\n"),"atomsDESCRIPTIONread",1));
74     end
75
76     if rhs < 2 then
77         additional = struct();
78     else
79         if type(additional) <> 17 then
80             error(msprintf(gettext("%s: Wrong type for input argument #%d: matrix oriented typed list expected.\n"),"atomsDESCRIPTIONread",2));
81         end
82     end
83
84     // Init the output argument
85     // =========================================================================
86
87     packages         = struct();
88     categories_flat  = struct();
89     categories       = struct();
90     description_out  = struct();
91
92     description_out("packages")        = packages;
93     description_out("categories")      = categories;
94     description_out("categories_flat") = categories_flat;
95
96     // Operating system detection + Architecture detection
97     // =========================================================================
98     [OSNAME, ARCH, LINUX, MACOSX, SOLARIS,BSD] = atomsGetPlatform();
99
100     // Start Read the file
101     // =========================================================================
102
103     if ~isfile(file_in) then
104         error(msprintf(gettext("%s: The file ""%s"" does not exist.\n"), ..
105         "atomsDESCRIPTIONread", ..
106         file_in));
107     end
108
109     lines_in         = mgetl(file_in);
110     current_toolbox  = struct();
111     current_field    = "";
112
113     if isempty(lines_in) then
114         error(msprintf(gettext("%s: The file ""%s"" is empty.\n"), ..
115         "atomsDESCRIPTIONread", ..
116         file_in));
117     end
118
119     winId = atomsOpenProgressBar(_("Updating Atoms modules database..."), %t)
120     for i=1:(size(lines_in,"*")+1)
121
122         atomsUpdateProgressBar(winId, i / size(lines_in,"*"));
123
124         // First case : new field, or file all read
125         if ((i == (size(lines_in,"*")+1)) | (regexp(lines_in(i),"/^[a-zA-Z0-9]*:\s/","o") == 1)) then
126
127             // subcase of First case: new toolbox, or file all read: register the latest toolbox
128             if ((i == (size(lines_in,"*")+1)) | (regexp(lines_in(i),"/^Toolbox:\s/","o") == 1)) then
129
130                 if and(isfield(current_toolbox,["Toolbox";"Version"])) then
131
132                     if  ~ isfield(packages,current_toolbox("Toolbox")) then
133                         // This is the first version of the package
134                         this_toolbox = struct();
135                     else
136                         // Get the version list of this package
137                         this_toolbox = packages(current_toolbox("Toolbox"));
138                     end
139
140                     // Register the current toolbox : Check the mandatory fields
141                     missingfield = atomsCheckFields( current_toolbox );
142                     if ~ isempty(missingfield) then
143                         atomsCloseProgressBar(winId);
144                         error(msprintf(gettext("%s: The file ""%s"" is not well formated, the toolbox ""%s - %s"" does not contain the %s field\n"), ..
145                         "atomsDESCRIPTIONread",..
146                         file_in,current_toolbox("Toolbox"),..
147                         current_toolbox("Version"),..
148                         missingfield));
149                     end
150
151                     // Register the current toolbox : Check the scilab version
152                     // comptability
153                     if atomsIsCompatible(current_toolbox("ScilabVersion")) then
154                         if isfield(current_toolbox,"PackagingVersion") then
155                             current_toolbox("Version") = current_toolbox("Version") + "-" + current_toolbox("PackagingVersion");
156                             this_toolbox(current_toolbox("Version")) = current_toolbox;
157                         else
158                             this_toolbox(current_toolbox("Version")) = current_toolbox;
159                         end
160                     end
161
162                     // Register the current toolbox : Fill the packages struct
163                     packages(current_toolbox("Toolbox")) = this_toolbox;
164
165                     if i == (size(lines_in,"*")+1) then
166                         break
167                     end                
168                 end
169
170                 // Reset the current_toolbox struct
171                 current_toolbox  = struct();
172             end
173
174             // process field
175             current_field_length           = regexp(lines_in(i),"/:\s/","o")
176             current_field                  = part(lines_in(i),1:current_field_length-1);
177             current_value                  = part(lines_in(i),current_field_length+2:length(lines_in(i)));
178
179             // process binary files
180             if regexp(current_field,"/^(windows|linux|macosx|solaris|bsd)(32|64)?(Url|Name|Md5|Sha1|Id)$/","o")<>[] then
181                 // This field doesn't concern this platform => Next line
182                 if regexp(current_field,"/^"+OSNAME+ARCH+"/","o")==[] then
183                     continue;
184                 else
185                     current_field = "binary"+part(current_field,length(OSNAME+ARCH)+1:length(current_field));
186                 end
187             end
188
189             // process URLs
190             if isfield(additional,"repository") & ..
191                 ( regexp(current_field,"/^(source|binary|windows|linux|macosx|solaris|bsd)(32|64)?Url$/","o")<>[] | current_field=="URL" ) & ..
192                 regexp(current_value,"/^(https?|ftps?|file):\/\//","o")==[] then
193                 current_value = additional("repository") + current_value;
194             end
195
196             current_toolbox(current_field) = current_value;
197
198             // Category management
199             if current_field == "Category" then
200                 if ~ isfield(categories_flat,current_value) then
201                     [categories,categories_flat] = atomsCreateCategory(categories,categories_flat,current_value)
202                 end
203                 if and(isfield(current_toolbox,["Toolbox";"Version"])) then
204                     categories_flat = atomsAddPackage2Cat( categories_flat , [current_toolbox("Toolbox") current_toolbox("Version")],current_value);
205                 else
206                     atomsCloseProgressBar(winId);
207                     error(msprintf(gettext("%s: name and version are not both defined\n"),"atomsDESCRIPTIONread"));
208                 end
209             end
210
211             continue;
212         end
213
214         // Second case : Current field continuation
215         if regexp(lines_in(i),"/^\s/","o") == 1 then
216             current_value = part(lines_in(i),2:length(lines_in(i)));
217             current_toolbox(current_field)($+1) =  current_value;
218
219             // Category management
220             if current_field == "Category" then
221                 if ~ isfield(categories_flat,current_value) then
222                     [categories,categories_flat] = atomsCreateCategory(categories,categories_flat,current_value)
223                 end
224                 if and(isfield(current_toolbox,["Toolbox";"Version"])) then
225                     categories_flat = atomsAddPackage2Cat( categories_flat , [current_toolbox("Toolbox") current_toolbox("Version")],current_value);
226                 else
227                     atomsCloseProgressBar(winId);
228                     error(msprintf(gettext("%s: name and version are not both defined\n"),"atomsDESCRIPTIONread"));
229                 end
230             end
231
232             continue;
233         end
234
235         // Third case : blank line
236         if length(lines_in(i)) == 0 then
237             continue;
238         end
239
240         // Fourth case: comment
241         if regexp(lines_in(i),"/^\/\//","o") == 1 then
242             continue;
243         end
244
245         // Else Error
246         atomsCloseProgressBar(winId);
247         error(msprintf(gettext("%s: The file ''%s'' is not well formated at line %d\n"),"atomsDESCRIPTIONread",file_in,i));
248
249     end
250
251     description_out("packages")        = packages;
252     description_out("categories")      = categories;
253     description_out("categories_flat") = categories_flat;
254     atomsCloseProgressBar(winId);
255
256 endfunction
257
258 // =============================================================================
259 // atomsCreateCategory
260 // =============================================================================
261
262 function [cat_out , cat_flat_out ] = atomsCreateCategory(cat_in,cat_flat_in,cat_id)
263
264     category_main = "";
265     category_sub  = "";
266     cat_flat_out  = cat_flat_in;
267     cat_out       = cat_in;
268
269     // Build the skeleton of the category
270     cat_struct             = struct();
271     cat_struct("label")    = [];
272     cat_struct("packages") = [];
273     cat_struct("is_main")  = %T;
274
275     // Is this category a main category or a sub category
276
277     pattern_index = regexp(cat_id,"/\s-\s/","o");
278
279     if pattern_index <> [] then
280
281         // Sub category
282         category_main         = part(cat_id,1:pattern_index-1);
283         category_sub          = part(cat_id,pattern_index+3:length(cat_id) );
284         cat_struct("label")   = [ category_main  category_sub ];
285         cat_struct("is_main") = %F;
286
287     else
288         // Main category
289         category_main = cat_id;
290         cat_struct("label")   = [ category_main ];
291         cat_struct("is_main") = %T;
292
293     end
294
295     cat_flat_out(cat_id)  = cat_struct;
296
297     if isfield(categories,category_main) then
298         if category_sub <> "" then
299             subcategories          = cat_out(category_main);
300             subcategories          = [ subcategories ; category_sub ];
301             cat_out(category_main) = subcategories;
302         end
303     else
304         if category_sub == "" then
305             cat_out(category_main) = [];
306         else
307             cat_out(category_main) = category_sub;
308         end
309     end
310
311     if ~cat_struct("is_main") & ~isfield(cat_flat_out,category_main) then
312         [cat_out , cat_flat_out ] = atomsCreateCategory(cat_out,cat_flat_out,category_main)
313     end
314
315 endfunction
316
317 // =============================================================================
318 // atomsAddPackage2Cat
319 // =============================================================================
320
321 function cat_flat_out = atomsAddPackage2Cat( cat_flat_in , package , category)
322
323     cat_flat_out  = cat_flat_in;
324
325     if ~ isfield( cat_flat_out , category ) then
326         error(msprintf(gettext("%s: Wrong value for input argument #%d: ''%s'' is not a registered category"),"atomsAddPackage2Cat",2,category));
327     end
328
329     cat_struct             = cat_flat_out(category);
330     package_mat            = [ cat_struct("packages") ; package ];
331     cat_struct("packages") = package_mat;
332     cat_flat_out(category) = cat_struct;
333
334     if ~ cat_struct("is_main") then
335         label_mat    = cat_struct("label");
336         cat_flat_out = atomsAddPackage2Cat( cat_flat_out , package , label_mat(1))
337     end
338
339 endfunction
340
341 // =============================================================================
342 // atomsCheckFields
343 // =============================================================================
344
345 function field = atomsCheckFields( module )
346
347     field = "";
348
349     mandatory = [             ..
350     "Toolbox"           ; ..
351     "Title"             ; ..
352     "Summary"           ; ..
353     "Version"           ; ..
354     "Author"            ; ..
355     "Maintainer"        ; ..
356     "Category"          ; ..
357     "Entity"            ; ..
358     "License"           ; ..
359     "ScilabVersion"     ; ..
360     "Depends"           ; ..
361     "Date"              ];
362
363     for i=1:size(mandatory,"*")
364         if ~ isfield(module,mandatory(i)) then
365             field = mandatory(i);
366             return;
367         end
368     end
369
370 endfunction