License Header change: Removed the LICENSE_END before beta
[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         // File totally read : register the latest toolbox
124         if i == (size(lines_in,"*")+1) then
125
126             if and(isfield(current_toolbox,["Toolbox";"Version"])) then
127
128                 if  ~ isfield(packages,current_toolbox("Toolbox")) then
129                     // This is the first version of the package
130                     this_toolbox = struct();
131                 else
132                     // Get the version list of this package
133                     this_toolbox = packages(current_toolbox("Toolbox"));
134                 end
135
136                 // Register the current toolbox : Check the mandatory fields
137                 missingfield = atomsCheckFields( current_toolbox );
138                 if ~ isempty(missingfield) then
139                     atomsCloseProgressBar(winId);
140                     error(msprintf(gettext("%s: The file ""%s"" is not well formated, the toolbox ""%s - %s"" does not contain the %s field\n"), ..
141                     "atomsDESCRIPTIONread",..
142                     file_in,current_toolbox("Toolbox"),..
143                     current_toolbox("Version"),..
144                     missingfield));
145                 end
146
147                 // Register the current toolbox : Check the scilab version
148                 // comptability
149                 if atomsIsCompatible(current_toolbox("ScilabVersion")) then
150                     if isfield(current_toolbox,"PackagingVersion") then
151                         current_toolbox("Version") = current_toolbox("Version") + "-" + current_toolbox("PackagingVersion");
152                         this_toolbox(current_toolbox("Version")) = current_toolbox;
153                     else
154                         this_toolbox(current_toolbox("Version")) = current_toolbox;
155                     end
156                 end
157
158                 // Register the current toolbox : Fill the packages struct
159                 packages(current_toolbox("Toolbox")) = this_toolbox;
160             end
161
162             break;
163         end
164
165         // First case : new field
166         if regexp(lines_in(i),"/^[a-zA-Z0-9]*:\s/","o") == 1 then
167
168             // Start new version of toolbox
169             if regexp(lines_in(i),"/^Toolbox:\s/","o") == 1 then
170
171                 if and(isfield(current_toolbox,["Toolbox";"Version"])) then
172
173                     if  ~ isfield(packages,current_toolbox("Toolbox")) then
174                         // This is the first version of the package
175                         this_toolbox = struct();
176                     else
177                         // Get the version list of this package
178                         this_toolbox = packages(current_toolbox("Toolbox"));
179                     end
180
181                     // Register the current toolbox : Check the mandatory fields
182                     missingfield = atomsCheckFields( current_toolbox );
183                     if ~ isempty(missingfield) then
184                         atomsCloseProgressBar(winId);
185                         error(msprintf(gettext("%s: The file ""%s"" is not well formated, the toolbox ""%s - %s"" does not contain the %s field\n"), ..
186                         "atomsDESCRIPTIONread",..
187                         file_in,current_toolbox("Toolbox"),..
188                         current_toolbox("Version"),..
189                         missingfield));
190                     end
191
192                     // Register the current toolbox : Check the scilab version
193                     // comptability
194                     if atomsIsCompatible(current_toolbox("ScilabVersion")) then
195                         if isfield(current_toolbox,"PackagingVersion") then
196                             current_toolbox("Version") = current_toolbox("Version") + "-" + current_toolbox("PackagingVersion");
197                             this_toolbox(current_toolbox("Version")) = current_toolbox;
198                         else
199                             this_toolbox(current_toolbox("Version")) = current_toolbox;
200                         end
201                     end
202
203                     // Register the current toolbox : Fill the packages struct
204                     packages(current_toolbox("Toolbox")) = this_toolbox;
205                 end
206
207                 // Reset the current_toolbox struct
208                 current_toolbox  = struct();
209             end
210
211             // process field
212             current_field_length           = regexp(lines_in(i),"/:\s/","o")
213             current_field                  = part(lines_in(i),1:current_field_length-1);
214             current_value                  = part(lines_in(i),current_field_length+2:length(lines_in(i)));
215
216             // process binary files
217             if regexp(current_field,"/^(windows|linux|macosx|solaris|bsd)(32|64)?(Url|Name|Md5|Sha1|Id)$/","o")<>[] then
218                 // This field doesn't concern this platform => Next line
219                 if regexp(current_field,"/^"+OSNAME+ARCH+"/","o")==[] then
220                     continue;
221                 else
222                     current_field = "binary"+part(current_field,length(OSNAME+ARCH)+1:length(current_field));
223                 end
224             end
225
226             // process URLs
227             if isfield(additional,"repository") & ..
228                 ( regexp(current_field,"/^(source|binary|windows|linux|macosx|solaris|bsd)(32|64)?Url$/","o")<>[] | current_field=="URL" ) & ..
229                 regexp(current_value,"/^(https?|ftps?|file):\/\//","o")==[] then
230                 current_value = additional("repository") + current_value;
231             end
232
233             current_toolbox(current_field) = current_value;
234
235             // Category management
236             if current_field == "Category" then
237                 if ~ isfield(categories_flat,current_value) then
238                     [categories,categories_flat] = atomsCreateCategory(categories,categories_flat,current_value)
239                 end
240                 if and(isfield(current_toolbox,["Toolbox";"Version"])) then
241                     categories_flat = atomsAddPackage2Cat( categories_flat , [current_toolbox("Toolbox") current_toolbox("Version")],current_value);
242                 else
243                     atomsCloseProgressBar(winId);
244                     error(msprintf(gettext("%s: name and version are not both defined\n"),"atomsDESCRIPTIONread"));
245                 end
246             end
247
248             continue;
249         end
250
251         // Second case : Current field continuation
252         if regexp(lines_in(i),"/^\s/","o") == 1 then
253             current_value = part(lines_in(i),2:length(lines_in(i)));
254             current_toolbox(current_field)($+1) =  current_value;
255
256             // Category management
257             if current_field == "Category" then
258                 if ~ isfield(categories_flat,current_value) then
259                     [categories,categories_flat] = atomsCreateCategory(categories,categories_flat,current_value)
260                 end
261                 if and(isfield(current_toolbox,["Toolbox";"Version"])) then
262                     categories_flat = atomsAddPackage2Cat( categories_flat , [current_toolbox("Toolbox") current_toolbox("Version")],current_value);
263                 else
264                     atomsCloseProgressBar(winId);
265                     error(msprintf(gettext("%s: name and version are not both defined\n"),"atomsDESCRIPTIONread"));
266                 end
267             end
268
269             continue;
270         end
271
272         // Third case : Blank line
273         if length(lines_in(i)) == 0 then
274             continue;
275         end
276
277         // Fourth case : Delimiter
278         if regexp(lines_in(i),"/^\/\//","o") == 1 then
279             continue;
280         end
281
282         // Else Error
283         atomsCloseProgressBar(winId);
284         error(msprintf(gettext("%s: The file ''%s'' is not well formated at line %d\n"),"atomsDESCRIPTIONread",file_in,i));
285
286     end
287
288     description_out("packages")        = packages;
289     description_out("categories")      = categories;
290     description_out("categories_flat") = categories_flat;
291     atomsCloseProgressBar(winId);
292
293 endfunction
294
295 // =============================================================================
296 // atomsCreateCategory
297 // =============================================================================
298
299 function [cat_out , cat_flat_out ] = atomsCreateCategory(cat_in,cat_flat_in,cat_id)
300
301     category_main = "";
302     category_sub  = "";
303     cat_flat_out  = cat_flat_in;
304     cat_out       = cat_in;
305
306     // Build the skeleton of the category
307     cat_struct             = struct();
308     cat_struct("label")    = [];
309     cat_struct("packages") = [];
310     cat_struct("is_main")  = %T;
311
312     // Is this category a main category or a sub category
313
314     pattern_index = regexp(cat_id,"/\s-\s/","o");
315
316     if pattern_index <> [] then
317
318         // Sub category
319         category_main         = part(cat_id,1:pattern_index-1);
320         category_sub          = part(cat_id,pattern_index+3:length(cat_id) );
321         cat_struct("label")   = [ category_main  category_sub ];
322         cat_struct("is_main") = %F;
323
324     else
325         // Main category
326         category_main = cat_id;
327         cat_struct("label")   = [ category_main ];
328         cat_struct("is_main") = %T;
329
330     end
331
332     cat_flat_out(cat_id)  = cat_struct;
333
334     if isfield(categories,category_main) then
335         if category_sub <> "" then
336             subcategories          = cat_out(category_main);
337             subcategories          = [ subcategories ; category_sub ];
338             cat_out(category_main) = subcategories;
339         end
340     else
341         if category_sub == "" then
342             cat_out(category_main) = [];
343         else
344             cat_out(category_main) = category_sub;
345         end
346     end
347
348     if ~cat_struct("is_main") & ~isfield(cat_flat_out,category_main) then
349         [cat_out , cat_flat_out ] = atomsCreateCategory(cat_out,cat_flat_out,category_main)
350     end
351
352 endfunction
353
354 // =============================================================================
355 // atomsAddPackage2Cat
356 // =============================================================================
357
358 function cat_flat_out = atomsAddPackage2Cat( cat_flat_in , package , category)
359
360     cat_flat_out  = cat_flat_in;
361
362     if ~ isfield( cat_flat_out , category ) then
363         error(msprintf(gettext("%s: Wrong value for input argument #%d: ''%s'' is not a registered category"),"atomsAddPackage2Cat",2,category));
364     end
365
366     cat_struct             = cat_flat_out(category);
367     package_mat            = [ cat_struct("packages") ; package ];
368     cat_struct("packages") = package_mat;
369     cat_flat_out(category) = cat_struct;
370
371     if ~ cat_struct("is_main") then
372         label_mat    = cat_struct("label");
373         cat_flat_out = atomsAddPackage2Cat( cat_flat_out , package , label_mat(1))
374     end
375
376 endfunction
377
378 // =============================================================================
379 // atomsCheckFields
380 // =============================================================================
381
382 function field = atomsCheckFields( module )
383
384     field = "";
385
386     mandatory = [             ..
387     "Toolbox"           ; ..
388     "Title"             ; ..
389     "Summary"           ; ..
390     "Version"           ; ..
391     "Author"            ; ..
392     "Maintainer"        ; ..
393     "Category"          ; ..
394     "Entity"            ; ..
395     "License"           ; ..
396     "ScilabVersion"     ; ..
397     "Depends"           ; ..
398     "Date"              ];
399
400     for i=1:size(mandatory,"*")
401         if ~ isfield(module,mandatory(i)) then
402             field = mandatory(i);
403             return;
404         end
405     end
406
407 endfunction