add "-append" argument to export_to_hdf5 function, fix some memory leaks in hdf5...
[scilab.git] / scilab / modules / io / macros / load.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2012 - DIGITEO - Antoine ELIAS
3 // Copyright (C) 2012 - DIGITEO - Vincent COUVERT
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10
11 function load(filename, varargin)
12     function [varValues] = %__convertHandles__(varValues)
13         for i = 1:size(varValues)
14             if typeof(varValues(i)) == "ScilabMatrixHandle" then
15                 //convert handle to tlist
16                 varValues(i) = createMatrixHandle(varValues(i));
17             elseif isList(varValues(i)) then
18                 //list container
19                 varValues(i) = parseList(varValues(i));
20             end
21         end
22     endfunction
23
24     function result = isList(var)
25         //15 : list
26         //16 : tlist
27         //17 : mlist
28         if or(type(var) == [15, 16, 17]) then
29             result  = %t;
30         else
31             result = %f;
32         end
33     endfunction
34
35     function varValue = parseList(varValue)
36         if typeof(varValue)=="list" then
37             for i = 1:size(varValue)
38                 if typeof(varValue(i)) == "ScilabMatrixHandle" then
39                     varValue(i) = createMatrixHandle(varValue(i));
40                 elseif isList(varValue(i)) then
41                     varValue(i) = parseList(varValue(i));
42                 else
43                     varValue(i) = varValue(i);
44                 end
45             end
46         else
47             fieldNb = size(getfield(1, varValue), "*");
48             for kField = 2:fieldNb // Do not inspect first field (field names)
49                 fieldValue = getfield(kField, varValue);
50                 if typeof(fieldValue) == "ScilabMatrixHandle" then
51                     fieldValue = createMatrixHandle(fieldValue);
52                 elseif isList(fieldValue) then
53                     fieldValue = parseList(fieldValue);
54                 end
55                 setfield(kField, fieldValue, varValue);
56             end
57         end
58     endfunction
59
60     function h = createMatrixHandle(matrixHandle)
61         h = [];
62         if typeof(matrixHandle) <> "ScilabMatrixHandle" then
63             return;
64         end
65
66         for i = prod(matrixHandle.dims):-1:1
67             h($+1) = createSingleHandle(matrixHandle.values(i));
68             if or(fieldnames(matrixHandle.values(i))=="user_data") then // TODO Remove after graphic branch merge
69                 if isList(matrixHandle.values(i).user_data) then
70                     h($).user_data = parseList(matrixHandle.values(i).user_data)
71                 elseif typeof(matrixHandle.values(i).user_data) == "ScilabMatrixHandle" then
72                     h($).user_data = createMatrixHandle(matrixHandle.values(i).user_data)
73                 end
74             end
75         end
76         h = matrix(h, matrixHandle.dims);
77     endfunction
78
79     function h = createSingleHandle(item)
80         select item.type
81         case "Figure"
82             h = createFigure(item);
83         case "Axes"
84             h = createAxes(item);
85         case "Polyline"
86             h = createPolyline(item);
87         case "Plot3d"
88             h = createPlot3d(item);
89         case "Fac3d"
90             h = createFac3d(item);
91         case "Compound"
92             h = createCompound(item);
93         case "Rectangle"
94             h = createRectangle(item);
95         case "Arc"
96             h = createArc(item);
97         case "Champ"
98             h = createChamp(item);
99         case "Segs"
100             h = createSegs(item);
101         case "Grayplot"
102             h = createGrayplot(item);
103         case "Matplot"
104             h = createMatplot(item);
105         case "Fec"
106             h = createFec(item);
107         case "Legend"
108             h = createLegend(item);
109         case "Text"
110             h = createText(item);
111         case "Axis"
112             h = createAxis(item);
113         case "uimenu"
114             h = createuimenu(item);
115         case "uicontextmenu"
116             h = createuicontextmenu(item);
117         case "uicontrol"
118             h = createuicontrol(item);
119         else
120             error("handle of type " + item.type + " unhandled");
121             h = [];
122         end
123     endfunction
124
125     //
126     // FIGURE
127     //
128     function h = createFigure(figureProperties)
129         fields = fieldnames(figureProperties);
130         fields(1) = [];
131
132         h = scf(figureProperties.figure_id);
133         fields(fields=="figure_id") = [];
134
135         h.figure_position=figureProperties.figure_position;
136         fields(fields=="figure_position") = [];
137         // set auto_resize first otherwise viewport modification may not have any effect.
138         h.auto_resize = figureProperties.auto_resize;
139         fields(fields=="auto_resize") = [];
140         h.figure_size = figureProperties.figure_size;
141         fields(fields=="figure_size") = [];
142         // set axes_size last because it's more important than figure_size
143         h.axes_size = figureProperties.axes_size;
144         fields(fields=="axes_size") = [];
145
146         for i = 1:size(fields, "*")
147             if fields(i) == "children" then
148                 createMatrixHandle(figureProperties(fields(i)));
149             else
150                 h(fields(i)) = figureProperties(fields(i));
151             end
152         end
153     endfunction
154
155     //
156     // LABEL
157     //
158     function h = createLabel(labelProperties, h)
159         fields = fieldnames(labelProperties);
160         fields(1) = [];
161         for i = 1:size(fields, "*")
162             h(fields(i)) = labelProperties(fields(i));
163         end
164     endfunction
165
166     //
167     // TICKS
168     //
169     function h = createTicks(ticksProperties)
170         h = tlist(['ticks','locations','labels'], [], []);
171         fields = fieldnames(ticksProperties);
172         for i = 1:size(fields, "*")
173             h(fields(i)) = ticksProperties(fields(i));
174         end
175     endfunction
176
177     //
178     // AXES
179     //
180     function h = createAxes(axesProperties)
181         // Hack to determine whether %h_load has been called by the %h_copy macro
182         // in which case a new Axes object is created
183         [lnums, fnames] = where();
184         ind = grep(fnames, '%h_copy');
185         if ~isempty(ind) then
186           newaxes();
187         end;
188         
189         h = gca();
190         fields = fieldnames(axesProperties);
191         fields(1) = [];
192
193         // Get log_flags to be sure to set them after data_bounds
194             log_flags = axesProperties.log_flags;
195             fields(fields=="log_flags") = [];
196
197         for i = 1:size(fields, "*")
198             if or(fields(i) == ["title","x_label","y_label","z_label"]) then
199                 createLabel(axesProperties(fields(i)), h(fields(i)));
200             elseif or(fields(i) == ["x_ticks", "y_ticks", "z_ticks"]) then
201                 h(fields(i)) = createTicks(axesProperties(fields(i)));
202             elseif fields(i) == "children" then
203                 createMatrixHandle(axesProperties(fields(i)));
204             elseif fields(i) == "clip_state" then
205                 if axesProperties.clip_state=="on" then
206                     set(h,"clip_box",axesProperties.clip_box);
207                 end
208                 set(h,"clip_state", axesProperties.clip_state);
209             elseif fields(i) == "clip_box" then
210                 // managed with 'clip_state'
211             elseif fields(i) == "data_bounds" then
212                             set(h, "data_bounds", axesProperties.data_bounds);
213                             set(h, "log_flags", log_flags);
214             else
215                 h(fields(i)) = axesProperties(fields(i));
216             end
217         end
218
219         // Legend management
220         global %LEG
221         if ~isempty(%LEG) then
222             // Get handles from paths
223             links=getlinksfrompath(h, %LEG.paths)
224             if ~isempty(links) then
225                 L = captions(links, %LEG.text)
226                 L.visible         = %LEG.visible
227                 L.font_style      = %LEG.font_style
228                 L.font_size       = %LEG.font_size
229                 L.font_color      = %LEG.font_color
230                 L.fractional_font = %LEG.fractional_font
231                 L.mark_mode       = 'off';
232                 L.legend_location = %LEG.legend_location
233                 L.position        = %LEG.position
234                 L.line_mode       = %LEG.line_mode
235                 L.thickness       = %LEG.thickness
236                 L.foreground      = %LEG.foreground
237                 L.fill_mode       = %LEG.fill_mode
238                 L.background      = %LEG.background
239                 if %LEG.clip_state=="on" then
240                     L.clip_box      = %LEG.clip_box
241                 end
242                 L.clip_state      = %LEG.clip_state
243                 L.user_data       = %LEG.user_data
244             else
245                 warning(msprintf(_("%s: Legend does not fit with the current context. Skipped\n"), "load"));
246             end
247         end
248         clearglobal %LEG
249     endfunction
250
251     //
252     // POLYLINE
253     //
254     function h = createPolyline(polylineProperties)
255         fields = fieldnames(polylineProperties);
256         fields(1) = [];
257
258         xpoly(polylineProperties.data(:,1), polylineProperties.data(:,2))
259
260         h = gce();
261
262         if polylineProperties.clip_state=="on" then
263             set(h, "clip_box", polylineProperties.clip_box)
264         end
265         set(h, "clip_state", polylineProperties.clip_state);
266         fields(fields=="clip_box") = [];
267         fields(fields=="clip_state") = [];
268
269         if polylineProperties.interp_color_mode=="on" & ~isempty(polylineProperties.interp_color_vector) then
270             set(h, "interp_color_vector", polylineProperties.interp_color_vector);
271             set(h, "interp_color_mode", polylineProperties.interp_color_mode);
272         else
273             if ~isempty(polylineProperties.interp_color_vector) then
274                 h.interp_color_vector = polylineProperties.interp_color_vector;
275             end
276             h.interp_color_mode = polylineProperties.interp_color_mode;
277         end
278         fields(fields=="interp_color_vector") = [];
279         fields(fields=="interp_color_mode") = [];
280
281         for i = 1:size(fields, "*")
282             h(fields(i)) = polylineProperties(fields(i));
283         end
284     endfunction
285
286     //
287     // PLOT3D
288     //
289     function h = createPlot3d(plot3dProperties)
290         h = createSurface(plot3dProperties);
291     endfunction
292
293     //
294     // FAC3D
295     //
296     function h = createFac3d(fac3dProperties)
297         h = createSurface(fac3dProperties);
298     endfunction
299
300     //
301     // SURFACE
302     //
303     function h = createSurface(surfaceProperties)
304         fields = fieldnames(surfaceProperties);
305         fields(1) = [];
306         // plot3d modify the axes properties
307         //  - Save it
308         // - Draw plot3d
309         // - Restore it
310         a=gca();
311         rotation_angles = a.rotation_angles;
312         axes_visible = a.axes_visible;
313         box = a.box;
314         margins = a.margins;
315         x_label_visible = a.x_label.visible;
316         y_label_visible = a.y_label.visible;
317         z_label_visible = a.z_label.visible;
318         x_label_text = a.x_label.text;
319         y_label_text = a.y_label.text;
320         z_label_text = a.z_label.text;
321         axes_isoview = a.isoview;
322
323         if (or(surfaceProperties.color_flag==[2 5]) & ~or(fields=="cdata_mapping")) | ..
324             ((surfaceProperties.color_flag>=2) & or(fields=="cdata_mapping")) then
325             plot3d1(surfaceProperties.data.x, surfaceProperties.data.y, list(surfaceProperties.data.z, surfaceProperties.data.color))
326         else
327             plot3d(surfaceProperties.data.x,surfaceProperties.data.y,surfaceProperties.data.z)
328         end
329         fields(fields=="data") = [];
330
331         // Restore this properties after plot3d.
332         a.rotation_angles = rotation_angles;
333         a.axes_visible = axes_visible;
334         a.box = box;
335         a.margins = margins;
336         a.x_label.visible = x_label_visible;
337         a.y_label.visible = y_label_visible;
338         a.z_label.visible = z_label_visible;
339         a.x_label.text = x_label_text;
340         a.y_label.text = y_label_text;
341         a.z_label.text = z_label_text;
342         a.isoview = axes_isoview;
343
344         h=gce();
345
346         if or(fields=="cdata_mapping") then // Fac3d specific
347             if surfaceProperties.color_flag >= 2 then
348                 set(h, "cdata_mapping", surfaceProperties.cdata_mapping);
349             end
350             fields(fields=="cdata_mapping") = [];
351         end
352
353         if surfaceProperties.clip_state == "on" then
354             set(h,"clip_box", surfaceProperties.clip_box);
355         end
356         set(h,"clip_state",surfaceProperties.clip_state);
357         fields(fields=="clip_box") = [];
358         fields(fields=="clip_state") = [];
359
360         for i = 1:size(fields, "*")
361             h(fields(i)) = surfaceProperties(fields(i));
362         end
363     endfunction
364
365     //
366     // COMPOUND
367     //
368     function h = createCompound(compoundProperties)
369         fields = fieldnames(compoundProperties);
370         fields(1) = [];
371
372         h = glue(createMatrixHandle(compoundProperties.children));
373         fields(fields=="children") = [];
374
375         for i = 1:size(fields, "*")
376             h(fields(i)) = compoundProperties(fields(i));
377         end
378     endfunction
379
380     //
381     // RECTANGLE
382     //
383     function h = createRectangle(rectangleProperties)
384         fields = fieldnames(rectangleProperties);
385         fields(1) = [];
386
387         xrect(0,1,1,1); // create the rectangle with dummy values
388         h = gce();
389
390         if rectangleProperties.clip_state == "on" then
391             set(h,"clip_box", rectangleProperties.clip_box);
392         end
393         set(h,"clip_state",rectangleProperties.clip_state);
394         fields(fields=="clip_box") = [];
395         fields(fields=="clip_state") = [];
396
397         for i = 1:size(fields, "*")
398             h(fields(i)) = rectangleProperties(fields(i));
399         end
400     endfunction
401
402     //
403     // ARC
404     //
405     function h = createArc(arcProperties)
406         fields = fieldnames(arcProperties);
407         fields(1) = [];
408
409         xarc(0,1,1,1,0,360); // create the arc with dummy values
410         h = gce();
411
412         if arcProperties.clip_state == "on" then
413             set(h,"clip_box", arcProperties.clip_box);
414         end
415         set(h,"clip_state",arcProperties.clip_state);
416         fields(fields=="clip_box") = [];
417         fields(fields=="clip_state") = [];
418
419         for i = 1:size(fields, "*")
420             h(fields(i)) = arcProperties(fields(i));
421         end
422     endfunction
423
424     //
425     // CHAMP
426     //
427     function h = createChamp(champProperties)
428         fields = fieldnames(champProperties);
429         fields(1) = [];
430
431         champ(champProperties.data.x, champProperties.data.y, champProperties.data.fx, champProperties.data.fy);
432         fields(fields=="data") = [];
433
434         h=gce();
435
436         if champProperties.clip_state == "on" then
437             set(h,"clip_box", champProperties.clip_box);
438         end
439         set(h,"clip_state",champProperties.clip_state);
440         fields(fields=="clip_box") = [];
441         fields(fields=="clip_state") = [];
442
443         for i = 1:size(fields, "*")
444             h(fields(i)) = champProperties(fields(i));
445         end
446     endfunction
447
448     //
449     // SEG
450     //
451     function h = createSegs(segsProperties)
452         fields = fieldnames(segsProperties);
453         fields(1) = [];
454
455         xsegs(segsProperties.data(:,1), segsProperties.data(:,2))
456
457         h=gce()
458
459         if segsProperties.clip_state == "on" then
460             set(h,"clip_box", segsProperties.clip_box);
461         end
462         set(h,"clip_state",segsProperties.clip_state);
463         fields(fields=="clip_box") = [];
464         fields(fields=="clip_state") = [];
465
466         for i = 1:size(fields, "*")
467             h(fields(i)) = segsProperties(fields(i));
468         end
469     endfunction
470
471     //
472     // GRAYPLOT
473     //
474     function h = createGrayplot(grayplotProperties)
475         fields = fieldnames(grayplotProperties);
476         fields(1) = [];
477
478         grayplot(grayplotProperties.data.x, grayplotProperties.data.y, grayplotProperties.data.z);
479         fields(fields=="data") = [];
480
481         h = gce();
482
483         if grayplotProperties.clip_state=="on" then
484             set(h, "clip_box", grayplotProperties.clip_box)
485         end
486         set(h, "clip_state", grayplotProperties.clip_state);
487         fields(fields=="clip_box") = [];
488         fields(fields=="clip_state") = [];
489
490         for i = 1:size(fields, "*")
491             h(fields(i)) = grayplotProperties(fields(i));
492         end
493     endfunction
494
495     //
496     // MATPLOT
497     //
498     function h = createMatplot(matplotProperties)
499         fields = fieldnames(matplotProperties);
500         fields(1) = [];
501
502         Matplot(matplotProperties.data);
503         fields(fields=="data") = [];
504
505         h = gce();
506
507         if matplotProperties.clip_state=="on" then
508             set(h, "clip_box", matplotProperties.clip_box)
509         end
510         set(h, "clip_state", matplotProperties.clip_state);
511         fields(fields=="clip_box") = [];
512         fields(fields=="clip_state") = [];
513
514         for i = 1:size(fields, "*")
515             h(fields(i)) = matplotProperties(fields(i));
516         end
517     endfunction
518
519     //
520     // FEC
521     //
522     function h = createFec(fecProperties)
523         fields = fieldnames(fecProperties);
524         fields(1) = [];
525
526         fec(fecProperties.data(:,1), fecProperties.data(:,2), fecProperties.triangles, fecProperties.data(:,3));
527         fields(fields=="data") = [];
528         fields(fields=="triangles") = [];
529
530         h = unglue(gce());
531
532         if fecProperties.clip_state=="on" then
533             set(h, "clip_box", fecProperties.clip_box)
534         end
535         set(h, "clip_state", fecProperties.clip_state);
536         fields(fields=="clip_box") = [];
537         fields(fields=="clip_state") = [];
538
539         for i = 1:size(fields, "*")
540             h(fields(i)) = fecProperties(fields(i));
541         end
542     endfunction
543
544     //
545     // LEGEND
546     //
547     function h = createLegend(legendProperties)
548         global %LEG
549         %LEG = legendProperties;
550         endfunction
551
552         //
553         // TEXT
554         //
555         function h = createText(textProperties)
556         fields = fieldnames(textProperties);
557         fields(1) = [];
558
559         if textProperties.text_box_mode == 'off' then
560             xstring(textProperties.data(1), textProperties.data(2), textProperties.text)
561         else
562             xstringb(textProperties.data(1), textProperties.data(2), textProperties.text, textProperties.text_box(1), textProperties.text_box(2))
563         end
564
565         h = gce();
566
567         if textProperties.clip_state=="on" then
568             set(h, "clip_box", textProperties.clip_box)
569         end
570         set(h, "clip_state", textProperties.clip_state);
571         fields(fields=="clip_box") = [];
572         fields(fields=="clip_state") = [];
573
574         for i = 1:size(fields, "*")
575             h(fields(i)) = textProperties(fields(i));
576         end
577     endfunction
578
579     //
580     // AXIS
581     //
582     function h = createAxis(axisProperties)
583         fields = fieldnames(axisProperties);
584         fields(1) = [];
585
586         if axisProperties.tics_direction == "bottom" then
587             axisdir='d';
588         elseif axisProperties.tics_direction == "top" then
589             axisdir='u';
590         elseif axisProperties.tics_direction == "left" then
591             axisdir='l';
592         elseif axisProperties.tics_direction == "right" then
593             axisdir='r';
594         elseif size(axisProperties.xtics_coord, "*") > 1 then
595             axisdir='u';
596         else
597             axisdir='l';
598         end
599         fields(fields=="tics_direction") = [];
600
601         drawaxis(x=axisProperties.xtics_coord,y=axisProperties.ytics_coord,dir=axisdir);
602         fields(fields=="xtics_coord") = [];
603         fields(fields=="ytics_coord") = [];
604
605         h=gce()
606
607         if axisProperties.clip_state=="on" then
608             set(h, "clip_box", axisProperties.clip_box)
609         end
610         set(h, "clip_state", axisProperties.clip_state);
611         fields(fields=="clip_box") = [];
612         fields(fields=="clip_state") = [];
613
614         for i = 1:size(fields, "*")
615             h(fields(i)) = axisProperties(fields(i));
616         end
617     endfunction
618
619     //
620     // uimenu
621     //
622     function h = createuimenu(uimenuProperties)
623         fields = fieldnames(uimenuProperties);
624         fields(1) = [];
625
626         h = uimenu();
627
628         for i = 1:size(fields, "*")
629             if fields(i) == "children" then
630                 children = createMatrixHandle(uimenuProperties(fields(i)));
631                 for k=1:size(children, "*")
632                     set(children(k), "parent", h);
633                 end
634             else
635                 h(fields(i)) = uimenuProperties(fields(i));
636             end
637         end
638     endfunction
639
640     //
641     // UICONTEXTMENU
642     //
643     function h = createuicontextmenu(uicontextmenuProperties)
644         fields = fieldnames(uicontextmenuProperties);
645         fields(1) = [];
646
647         h = uicontextmenu();
648
649         for i = 1:size(fields, "*")
650             if fields(i) == "children" then
651                 children = createMatrixHandle(uicontextmenuProperties(fields(i)));
652                 for k=1:size(children, "*")
653                     set(children(k), "parent", h);
654                 end
655             else
656                 h(fields(i)) = uicontextmenuProperties(fields(i));
657             end
658         end
659     endfunction
660
661     //
662     // uicontrol
663     //
664     function h = createuicontrol(uicontrolProperties)
665         fields = fieldnames(uicontrolProperties);
666         fields(1) = [];
667
668         h = uicontrol("Style", uicontrolProperties.style);
669         fields(fields=="style") = [];
670
671         for i = 1:size(fields, "*")
672             if fields(i) == "children" then
673                 children = createMatrixHandle(uicontrolProperties(fields(i)));
674                 for k=1:size(children, "*")
675                     set(children(k), "parent", h);
676                 end
677             else
678                 h(fields(i)) = uicontrolProperties(fields(i));
679             end
680         end
681     endfunction
682
683     // Utility function for legends, copy/paste from %h_load
684     function links=getlinksfrompath(ax,paths)
685         //  ax is a  handle on an axes entity
686         //  paths a list or row vector which gives the set of paths relative to
687         //  the axes
688         links=[];
689         ok=%t;
690         for p=paths
691             e=ax;
692             p(1)=p(1)-1// the caption does not exists yet
693             for kp=1:size(p,'*'),
694                 if or(e.type==['Axes','Compound'])&p(kp)<=size(e.children,'*') then
695                     e=e.children(p(kp)),
696                 else
697                     ok=%f
698                     break
699                 end
700             end
701             if ~ok then
702                 break
703             end
704             links=[links,e]
705         end
706         if ~ok then
707             links=[];
708         end
709     endfunction
710
711
712     [lhs, rhs] = argn();
713     resumeList = list();
714     resumeVarlist = [];
715     if rhs < 1 then
716         error(999, msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"), "load", 1));
717     end
718
719     if rhs >= 1 then
720         if typeof(filename) <> "string" | size(filename, "*") <> 1 then
721             error(999, msprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"), "load", 1));
722         end
723     end
724
725     if is_hdf5_file(filename) then
726         loadFunction = import_from_hdf5;
727     else
728         loadFunction = %_load;
729     end
730
731     //multiple output variables to prevent listinfile prints
732     [variableList, __varB__, __varC__, __varD__] = listvarinfile(filename);
733
734     //
735     if size(varargin) <> 0 then
736         for i = 1:size(varargin)
737             variableName = varargin(i);
738             if typeof(variableName) <> "string" | size(variableName, "*") <> 1 then
739                 error(999, msprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"), "load", i));
740             end
741             
742             if or(variableList == variableName) then
743                 loadFunction(filename, variableName);
744                 resumeList($+1) = evstr(variableName);
745                 resumeVarlist($+1) = variableName;
746             else
747                 error(999, msprintf(gettext("%s: variable ''%s'' does not exist in ''%s''.\n"), "load", variableName, filename));
748             end
749         end
750     else
751         for i = 1:size(variableList, "*")
752             variableName = variableList(i);
753             loadFunction(filename, variableName);
754             resumeList($+1) = evstr(variableName);
755             resumeVarlist($+1) = variableName;
756         end
757     end
758
759     resumeList = %__convertHandles__(resumeList);
760
761     execstr("[" + strcat(resumeVarlist, ",") + "] = resume(resumeList(:))");
762 endfunction