* Bug 16357 fixed - Xcos context no longer handled exec() 29/21429/6
Clement David [Tue, 3 Mar 2020 10:00:19 +0000 (11:00 +0100)]
  http://bugzilla.scilab.org/16357

Change-Id: Ia43e42c24b187c7e2ad2efb969c3cfd73f78eff8

scilab/CHANGES.md
scilab/modules/scicos/macros/scicos_scicos/script2var.sci
scilab/modules/scicos/tests/nonreg_tests/bug_16357.tst [new file with mode: 0644]

index b6c266f..2f9a160 100644 (file)
@@ -313,6 +313,7 @@ Bug Fixes
 * [#16342](https://bugzilla.scilab.org/16342): `strcat()` was much slower in Scilab 6.0.2.
 * [#16350](https://bugzilla.scilab.org/16350): in if/while conditions, the empty sparse boolean was considered as TRUE.
 * [#16358](https://bugzilla.scilab.org/16358): `isdef([],..)` yielded an error instead of returning [].
+* [#16357](https://bugzilla.scilab.org/16357): `script2var` did get variables generated by `exec()`.
 * [#16362](https://bugzilla.scilab.org/16362): sparse empty matrix could no be concatenated.
 * [#16365](https://bugzilla.scilab.org/16365): `median(m,"r")` and `median(m,"c")` yielded wrong results (6.1.0 regression)
 * [#16366](https://bugzilla.scilab.org/16366): `plot([0 1], ":")` plotted a dash-dotted curve instead of a dotted one.
index 1ea8f06..b6d9e34 100644 (file)
@@ -2,7 +2,7 @@
 //
 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
 //  Copyright (C) 2011 - INRIA - Serge Steer
-//  Copyright (C) 2018 - Samuel GOUGEON
+//  Copyright (C) 2018, 2020 - Samuel GOUGEON
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -23,8 +23,8 @@
 
 function [%ll,%ierr] = script2var(%txt, %ll)
     //** [%scicos_context, ierr] = script2var(context, %scicos_context)
-    //** context is the scs_m.props.context (string array) associated with the current level
-    //** %scicos_context  is a struct containing the values defined by the
+    //** %txt is the scs_m.props.context (string array) associated with the current level
+    //** %ll  is a struct containing the values defined by the
     //    calling contexts
     //**
     //** 10 Jan 2006
@@ -48,7 +48,6 @@ function [%ll,%ierr] = script2var(%txt, %ll)
         end
     end
     [%ll,%ierr] = getvardef(%txt,%ll)
-    if %ierr<>0 then return, end
 endfunction
 
 //**--------------------------------------------------------------------------
@@ -59,11 +58,14 @@ function [%ll,%ierr]=getvardef(%txt,%ll)
     //local variable names are prefixed with a %  to limit conflicts with
     //variables  defined in %txt instructions
 
-    %ierr = 0;  // to make sure %ierr does not enter the difference
     if isempty(%txt) then return,end
 
-    %ierr = execstr(%txt,"errcatch");
-    if %ierr<>0 then
+    global %_old_   // safe location in case of clear() in the context
+    %_ierr_ = 0;    // to make sure %ierr does not enter the difference
+    %_old_ = who("scope")
+    %_old_ = %_old_(isdef(%_old_,"l"))
+    %_ierr_ = execstr(%txt,"errcatch");
+    if %_ierr_<>0 then
         if errInMsgbox
             messagebox(lasterror(), _("Set Xcos context"), "warning", "modal")
         else
@@ -71,33 +73,32 @@ function [%ll,%ierr]=getvardef(%txt,%ll)
         end
         return
     end
-
-    // Use 'macrovar' to extract the variable names present in %txt: listvar(5) contains all the output variables of the context
-    clear("foo"); // Locally reserve the "foo" name to avoid redefinition warning
-    deff("foo()", %txt);
-    listvar = macrovar(foo);
-    %mm = listvar(5);
-    // In case clear() has been used in the context, remove its arguments
-    if %mm <> [] then
-        %mm(~isdef(%mm, "l")) = [];
+    global %_old_
+    %_new_ = who("scope");
+    %_new_ = setdiff(%_new_, %_old_)
+    if %_new_ <> [] then
+        %_new_ = %_new_(isdef(%_new_,"l"))
     end
+    clearglobal %_old_
 
-    msg = []
-    tmp = _("The variable name %s cannot be used as block parameter: ignored\n")
-    msg0 = msprintf(tmp, "scs_m")
-    for %mi=%mm'
-        if %mi=="scs_m" then
-            msg = [msg ; msg0]
+    %_msg = []
+    %_tmp = _("The variable name %s cannot be used as block parameter: ignored\n")
+    %_msg0 = msprintf(%_tmp, "scs_m")
+    %_forbid = ["scs_m"]
+    %_ignore = ["ans"]
+    for %mi = matrix(%_new_, 1, -1)
+        if or(%mi==%_forbid) then
+            %_msg = [%_msg ; %_msg0]
             continue
-        elseif %mi=="ans" then
+        elseif or(%mi==%_ignore) then
             continue
         end
 
         clear %v
-        %v=evstr(%mi);
+        %v = evstr(%mi);
 
         if typeof(%v)=="scs_m" then
-            msg = [msg ; msg0]
+            %_msg = [%_msg ; %_msg0]
             continue
         elseif or(type(%v)==[13 14]) then
             continue
@@ -106,11 +107,11 @@ function [%ll,%ierr]=getvardef(%txt,%ll)
         %ll(%mi)=%v;
         clear %v
     end
-    if msg ~=[] then
+    if %_msg ~=[] then
         if errInMsgbox
-            messagebox(msg, _("Set Xcos context"), "warning", "modal")
+            messagebox(%_msg, _("Set Xcos context"), "warning", "modal")
         else
-            mprintf("%s\n", msg)
+            mprintf("%s\n", %_msg)
         end
     end
 endfunction
diff --git a/scilab/modules/scicos/tests/nonreg_tests/bug_16357.tst b/scilab/modules/scicos/tests/nonreg_tests/bug_16357.tst
new file mode 100644 (file)
index 0000000..c7091e4
--- /dev/null
@@ -0,0 +1,39 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - ESI Group - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 16357 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=16357
+//
+// <-- Short Description -->
+// script2var failed found variables defined by an exec() call
+//
+
+[st, ierr] = script2var("", struct());
+assert_checkequal(st, struct());
+
+[st, ierr] = script2var("a=1", struct());
+assert_checkequal(st.a, 1);
+
+[st, ierr] = script2var("a=1;b=2", struct());
+assert_checkequal(st.a, 1);
+assert_checkequal(st.b, 2);
+
+f=fullfile(TMPDIR, "vars.ini");
+mputl("a=1", f);
+
+[st, ierr] = script2var("exec(f, -1);b=2", struct());
+assert_checkequal(st.a, 1);
+assert_checkequal(st.b, 2);
+
+[st, ierr] = script2var("a=1; clear;b=2", struct());
+assert_checkequal(st.b, 2);
+assert_checkequal(fieldnames(st), "b");