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