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