[hdf5] save(file, vector_of_names) allowed 52/20552/10
St├ęphane Mottelet [Mon, 15 Oct 2018 11:34:09 +0000 (13:34 +0200)]
http://bugzilla.scilab.org/show_bug.cgi?id=11605

Change-Id: Ia6cf1368885eb5faca5b0d6bd9d854f93dc51a67

scilab/CHANGES.md
scilab/modules/hdf5/sci_gateway/cpp/sci_hdf5_save.cpp
scilab/modules/hdf5/tests/unit_tests/saveloadHdf5.tst
scilab/modules/io/help/en_US/save.xml

index 3dcff3b..d3e3794 100644 (file)
@@ -440,6 +440,7 @@ Known issues
 * [#11240](http://bugzilla.scilab.org/show_bug.cgi?id=11240): `A=[]; clear B; [A($+1),B]=1;` crashed Scilab.
 * [#11435](http://bugzilla.scilab.org/show_bug.cgi?id=11435): The demo `Simulation => Flow => Blackhole` reliability had to be checked. Its displayed speed value was truncated.
 * [#11583](http://bugzilla.scilab.org/show_bug.cgi?id=11583): When in Scinotes preferences the default header is erased, the available variables were no longer documented.
+* [#11605](http://bugzilla.scilab.org/show_bug.cgi?id=11605): `save(filename, ["a","b","c"..]` was not allowed.
 * [#11765](http://bugzilla.scilab.org/show_bug.cgi?id=11765): `eigs` was not documented among Matlab-Scilab equivalences.
 * [#11916](http://bugzilla.scilab.org/show_bug.cgi?id=11916): Loading a graphic file containing several figures restored them by superimposing them in the same window.
 * [#12109](http://bugzilla.scilab.org/show_bug.cgi?id=12109): `execstr(.,"errcatch")` calling a macro returning before setting the argout crashed Scilab.
index 11a8a90..6790d4c 100644 (file)
@@ -163,32 +163,36 @@ types::Function::ReturnValue sci_hdf5_save(types::typed_list &in, int _iRetCount
     {
         for (int i = 1; i < rhs; ++i)
         {
-            if (in[i]->getId() != types::InternalType::IdScalarString)
+            if (!in[i]->isString())
             {
                 Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), fname.data(), i + 1);
                 return types::Function::Error;
             }
 
-            wchar_t* wvar = in[i]->getAs<types::String>()->get()[0];
-            if (wcscmp(wvar, L"-append") == 0)
-            {
-                bAppendMode = true;
-                continue;
+            types::String *pS = in[i]->getAs<types::String>(); 
+            wchar_t* wvar = pS->get(0);
+            if (wcscmp(wvar, L"-append") == 0) {
+              bAppendMode = true;
+              continue;
             }
 
-            types::InternalType* pIT = ctx->get(symbol::Symbol(wvar));
-            if (pIT == NULL)
+            for (int j = 0; j < pS->getSize(); j++)
             {
-                Scierror(999, _("%s: Wrong value for input argument #%d: Defined variable expected.\n"), fname.data(), i + 1);
-                return types::Function::Error;
-            }
+                wvar = pS->get(j);
+                types::InternalType* pIT = ctx->get(symbol::Symbol(wvar));
+                if (pIT == NULL)
+                {
+                    Scierror(999, _("%s: Wrong value for input argument #%d: Defined variable expected.\n"), fname.data(), i + 1);
+                    return types::Function::Error;
+                }
 
-            char* cvar = wide_string_to_UTF8(wvar);
-            std::string var(cvar);
-            FREE(cvar);
+                char* cvar = wide_string_to_UTF8(wvar);
+                std::string var(cvar);
+                FREE(cvar);
 
-            //check var exists
-            vars[var] = pIT;
+                //check var exists
+                vars[var] = pIT;                
+            }
         }
     }
     //check append option
index 6c35273..5280293 100644 (file)
-//<-- CLI SHELL MODE -->
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2014 - Scilab Enterprises - Vladislav TRUBKIN
+// Copyright (C) 2018 - St├ęphane MOTTELET
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
 //
-
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
 // check function
-function checkValue(value)
-    clear "varName";
-    varName = value;
-    fileName = TMPDIR + "/saveloadHdf5.sod";
+function varNames=checkSaveLoad(varargin)
+    varNames=list();
+    oldVarNames=list();
+    for i=1:length(varargin)
+      varNames(i) = msprintf("%s%d",strsubst(typeof(varargin(i))," ","_"),i);
+      execstr(msprintf("clear %s; %s = varargin(%d)",varNames(i),varNames(i),i));
+      oldVarNames(i) = "old"+varNames(i);
+    end
+    for i=1:length(varargin)
+      execstr(oldVarNames(i) + '=' + varNames(i));
+    end
+    fileNamea = TMPDIR + "/saveloadHdf5a.sod";
+    fileNameb = TMPDIR + "/saveloadHdf5b.sod";
     // export to hdf5
-    oldVarName = varName;
-    save(fileName, "varName");
+    for i=1:length(varargin)
+      execstr(oldVarNames(i) + '=' + varNames(i));
+    end
+    save(fileNamea, varNames(:));
+    save(fileNameb, list2vec(varNames));
     // check that the "varName" has not been modified by export
-    assert_checkequal(oldVarName, varName);
+    for i=1:length(varargin)
+      execstr(msprintf("assert_checkequal(%s,%s)",varNames(i),oldVarNames(i)));
+    end
     // reset ref value
-    clear "varName" "oldVarName";
-    assert_checkequal(exists("varName"), 0);
+    clear(list2vec(varNames))
+    clear(list2vec(oldVarNames))
+    for i=1:length(varargin)
+      assert_checkequal(exists(varNames(i)), 0);
+    end
     // import from hdf5
-    load(fileName);
-    assert_checkequal(varName, value);
+    load(fileNamea);
+    for i=1:length(varargin)
+      execstr(msprintf("assert_checkequal(%s,varargin(%d))",varNames(i),i));
+    end
+    clear(list2vec(varNames))
+    load(fileNameb);
+    for i=1:length(varargin)
+      execstr(msprintf("assert_checkequal(%s,varargin(%d))",varNames(i),i));
+    end
 endfunction
 
+mat1 = 1;
+mat2 = 1:27;
+mat3 = mat2';
+mat4 = matrix(mat2,[9 3]);
+mat5 = matrix(mat2,[3 1 3 3]);
 //// Empty matrix
-checkValue([]);
-
+checkSaveLoad([]);
 //// Double
-// scalar
-checkValue(77);
-// vector
-checkValue([1, 2, 3, 4, 5]);
-checkValue([1; 2; 3; 4; 5]);
-// matrix
-checkValue([1, 2, 3; 4, 5, 6]);
+checkSaveLoad(mat1); // scalar
+checkSaveLoad(mat2); // vector
+checkSaveLoad(mat3); // vector
+checkSaveLoad(mat4); // matrix
+checkSaveLoad(mat5); // hypermatrix
+checkSaveLoad([],mat1,mat2,mat3,mat4,mat5); // all together
 
 //// Double complex
-// scalar
-checkValue(1 + %i*2);
-// vector
-checkValue([1 + %i, 2 + %i, 3 + %i*2, 4 + %i*3, 5 + %i*4]);
-checkValue([1 + %i; 2 + %i; 3 + %i*2; 4 + %i*3; 5 + %i*4]);
-// matrix
-checkValue([1 + %i, 2 + %i, 3 + %i*2; 4 + %i*3, 5 + %i*4, 6 + %i]);
+checkSaveLoad(mat1+%i); // scalar
+checkSaveLoad(mat2+%i); // vector
+checkSaveLoad(mat3+%i); // vector
+checkSaveLoad(mat4+%i); // matrix
+checkSaveLoad(mat5+%i); // hypermatrix
+checkSaveLoad(mat1+%i,mat2+%i,mat3+%i,mat4+%i,mat5+%i); // all together
 
 //// String
-// single
-checkValue("Single String");
-// vector
-checkValue(["a", "b", "c"]);
-checkValue(["a"; "b"; "c"]);
-// matrix
-checkValue(["a", "b", "c"; "d", "e", "f"]);
+checkSaveLoad(string(mat1)); // scalar
+checkSaveLoad(string(mat2)); //vector
+checkSaveLoad(string(mat3)); // vector
+checkSaveLoad(string(mat4)); // matrix
+checkSaveLoad(string(mat5)); // hypermatrix
+checkSaveLoad(string(mat1),string(mat2),string(mat3),string(mat4),string(mat5)); // all together
 
 //// Polynomials
-s = poly(0, "s");
-// single
-checkValue(poly([1, 2], "s", "c"));
-// vector
-checkValue([s, s^2, 1 + 3*s^2, 1 + 2*s + 4*s^3]);
-checkValue([s; s^2; 1 + 3*s^2; 1 + 2*s + 4*s^3]);
-// matrix
-checkValue([s, s^2; 1 + 3*s^2, 1 + 2*s + 4*s^3]);
+p1 = poly(1:3, "s","coeff");
+p2 = repmat(p1,8,1);
+p3 = repmat(p1,1,8);
+p4 = repmat(p1,2,4);
+p5 = repmat(p1,2,2,2);
+checkSaveLoad(p1); // single
+checkSaveLoad(p2); // vector
+checkSaveLoad(p3); // vector
+checkSaveLoad(p4); // matrix
+checkSaveLoad(p5); // hypermatrix
+checkSaveLoad(p1,p2,p3,p4,p5); // all together
 
 //// Boolean
-// single
-checkValue(%t);
-// vector
-checkValue([%t, %t, %f, %t, %t]);
-checkValue([%t; %t; %f; %t; %t]);
-// matrix
-checkValue([%t, %t; %f, %f]);
+bool1 = %t;
+bool2 = modulo(1:27,2)>0;
+bool3 = bool2';
+bool4 = matrix(bool2,[9 3]);
+bool5 = matrix(bool2,[3 1 3 3]);
+checkSaveLoad(bool1); // scalar
+checkSaveLoad(bool2); // vector
+checkSaveLoad(bool3); // vector
+checkSaveLoad(bool4); // boolrix
+checkSaveLoad(bool5); // hyperboolrix
+checkSaveLoad(bool1,bool2,bool3,bool4,bool5); // all together
 
 //// Integer
 clear "createIntValues";
@@ -101,37 +135,38 @@ endfunction
 
 clear "checkIntValue";
 function checkIntValue(refValue, flag)
+    values=list();
     for i = 1:6
-        checkValue(createIntValues(refValue, flag(i)));
+     values(i)=createIntValues(refValue, flag(i));
+     checkSaveLoad(values) // individual int types
     end
+    checkSaveLoad(values(:)); // all together
 endfunction
 
 // all flags for createIntValues
 flag = [8, -8, 16, -16, 32, -32];
 // scalar
-checkIntValue(5, flag);
-// vector
-checkIntValue([1, 2, 3, 4, 5], flag);
-checkIntValue([1, 2, 3, 4, 5]', flag);
-// matrix
-checkIntValue([1, 2, 3; 4, 5, 6], flag);
+checkIntValue(mat1, flag); // vector
+checkIntValue(mat2, flag); //vector
+checkIntValue(mat3, flag); // matrix
+checkIntValue(mat4, flag); // hypermatrix
 
 //// Sparse
-checkValue(sparse([1, 2; 4, 5; 3, 10], [1, 2, 3]));
-checkValue(sparse([1, 2; 4, 5; 3, 10], [1 + %i, 2 + 2*%i, 3 + 3*%i]));
+checkSaveLoad(sparse([1, 2; 4, 5; 3, 10], [1, 2, 3]));
+checkSaveLoad(sparse([1, 2; 4, 5; 3, 10], [1 + %i, 2 + 2*%i, 3 + 3*%i]));
 
 //// Boolean sparse
 valueRef = [%F, %F, %T, %F, %F
 %T, %F, %F, %F, %F
 %F, %F, %F, %F, %F
 %F, %F, %F, %F, %T];
-checkValue(sparse(valueRef));
-checkValue(sparse([1, 1; 2, 2; 3, 3; 4, 4], [%t, %t, %t, %t]));
+checkSaveLoad(sparse(valueRef));
+checkSaveLoad(sparse([1, 1; 2, 2; 3, 3; 4, 4], [%t, %t, %t, %t]));
 
 //// List
 listNew = list();
 // empty list
-checkValue(listNew);
+checkSaveLoad(listNew);
 // double in list
 listNew(1) = 111;
 listNew(2) = [1, 2, 3];
@@ -148,10 +183,10 @@ for i = 7:12
     listNew(i) = createIntValues(valueRef, flag(i - 6));
 end
 // polynom in list
-listNew(13) = [s, s^2; 1 + 3*s^2, 1 + 2*s + 4*s^3];
+listNew(13) = [%s, %s^2; 1 + 3*%s^2, 1 + 2*%s + 4*%s^3];
 // empty matrix in list
 listNew(14) = [];
-checkValue(listNew);
+checkSaveLoad(listNew);
 // list in list
 listNew = list();
 listNew(1) = 111;
@@ -162,19 +197,19 @@ for i = 3:8
 end
 listNew(9) = list(string([1, 2, 3; 4, 5, 6]));
 listNew(10) = list([%f, %f; %t, %t]);
-checkValue(listNew);
+checkSaveLoad(listNew);
 // nested list
 listNew2 = list(listNew, listNew, list("Scilab", 7, %t));
-checkValue(listNew2);
+checkSaveLoad(listNew2);
 // tlist and mlist in the list
 tlstRef = tlist(["random numbers"; "Name"; "Example"; "Example_2"], "Uniform", [%f, %t; %f, %t], [1, 2; 3, 4]);
 mlstRef = mlist(["V", "name", "value"], ["a", "b"; "c", "d"], [1, 2; 3, 4]);
 listNew = list("only one mlist", mlstRef);
-checkValue(listNew);
+checkSaveLoad(listNew);
 listNew = list("only one tlist", tlstRef);
-checkValue(listNew);
+checkSaveLoad(listNew);
 listNew = list(["mlist", "and", "tlist"], mlstRef, tlstRef);
-checkValue(listNew);
+checkSaveLoad(listNew);
 // sparse in the list
 listNew = list(sparse([1, 2; 4, 5; 3, 10], [1, 2, 3]), ...
 sparse([1, 1; 2, 2; 3, 3; 4, 4], [%t, %t, %t, %t]), ...
@@ -189,24 +224,24 @@ lstRef = tlist(["TLIST";
 "Bool"], ["A", "B"; "C", "D"], valueRef, ...
 complex(valueRef, 2), createIntValues(valueRef, 16), ...
 [%f, %t; %f, %t]);
-checkValue(lstRef);
+checkSaveLoad(lstRef);
 // hypermatrix in tlist
 lstRef = tlist(["hmInTlist";
 "Name";
 "Example_1"
 "Example_2"], "List", ones(1, 2, 3), matrix((1:8) == 0, [2 2 1 2]));
-checkValue(lstRef);
+checkSaveLoad(lstRef);
 // tlist in tlist
 lstRef = tlist(["tlistInTlist";
 "Name";
 "Tlist";
 "Poly";
 "List"], "List", lstRef, poly([1, 2], "s", "c"), list(1, %t));
-checkValue(lstRef);
+checkSaveLoad(lstRef);
 
 //// Mlist
 lstRef = mlist(["MLIST", "Name", "Value"], ["a", "b"; "c", "d"], [1, 2; 3, 4]);
-checkValue(lstRef);
+checkSaveLoad(lstRef);
 lstRef = mlist(["MLIST";
 "String";
 "Double";
@@ -215,31 +250,19 @@ lstRef = mlist(["MLIST";
 "Bool"], ["A", "B"; "C", "D"], valueRef, ...
 complex(valueRef, 2), createIntValues(valueRef, 8), ...
 [%f, %t; %f, %t]);
-checkValue(lstRef);
+checkSaveLoad(lstRef);
 // hypermatrix in mlist
 lstRef = mlist(["hmInMlist";
 "Name";
 "Example_1"
 "Example_2"], "List", ones(1, 2, 3), matrix((1:8) == 0, [2 2 1 2]));
-checkValue(lstRef);
-
-//// Hypermatrix
-// double
-checkValue(ones(1, 2, 3, 4));
-checkValue(complex(ones(1, 2, 3, 4), 2));
-checkValue(rand(3, 3));
-// integer
-for i = flag
-    checkValue(createIntValues(ones(1, 2, 3, 4), i));
-end
-// boolean
-checkValue(matrix((1:8) == 0, [2 2 1 2]));
+checkSaveLoad(lstRef);
 
 //// Undefined
 valueRef = list(1, "two", "three");
 valueRef(5) = "five";
 valueRef(7) = 7;
-checkValue(valueRef);
+checkSaveLoad(valueRef);
 
 //// Void
 l = list(1, , 3);
@@ -263,18 +286,18 @@ assert_checkequal(l == list(1, , 3), [%t %f %t]);
 data.data.data = 0;
 data.data.string = "Scilab";
 data.list = list(1,["S" "E"]);
-checkValue(data);
+checkSaveLoad(data);
 
 data2.data.data = 42;
 data2.data.string = "Test";
 data2.list = list(1,["a" "b"]);
-checkValue(data2);
+checkSaveLoad(data2);
 
 struct_ = [data, data, data2; data2, data2, data];
-checkValue(struct_);
+checkSaveLoad(struct_);
 
 emptyStruct = struct();
-checkValue(emptyStruct);
+checkSaveLoad(emptyStruct);
 
 // Cell
 Cell_ = cell(2,2,2);
@@ -286,7 +309,11 @@ Cell_{5} = 5;
 Cell_{6} = 6;
 Cell_{7} = poly(1:3,"s");
 Cell_{8} = "Scilab 6";
-checkValue(Cell_);
+checkSaveLoad(Cell_);
 
 emptyCell = cell();
-checkValue(emptyCell);
+checkSaveLoad(emptyCell);
+
+// Heterogenous save
+checkSaveLoad(mat3, %i+mat3, p3, bool3, listNew, struct_, Cell_);
+
index 61cc11e..ae60987 100644 (file)
@@ -27,7 +27,9 @@
         <synopsis>
             save(filename)
             save(filename, x1, x2,...,xn)
-            save(filename, x1, x2,...,xn, "-append")
+            save(filename, variables)
+            save(filename, "-append", ..)
+            save(.., "-append")
         </synopsis>
     </refsynopsisdiv>
     <refsection>
                     </para>
                 </listitem>
             </varlistentry>
+            <varlistentry>
+                <term>variables</term>
+                <listitem>
+                    <para>
+                        A matrix of strings containing the names of Scilab variables to be saved,
+                      e.g. <literal>["x1", "x2", ..., "xn"]</literal>
+                    </para>
+                </listitem>
+            </varlistentry>
         </variablelist>
     </refsection>
     <refsection>
@@ -440,6 +451,12 @@ Undefined variable: myPi
                     </itemizedlist>
                 </revremark>
             </revision>
+            <revision>
+                <revnumber>6.0.2</revnumber>
+                <revremark>
+                   The names of variables to be saved can now be provided in a vector.
+                </revremark>
+            </revision>
         </revhistory>
     </refsection>
 </refentry>