* Bug #15046 fixed - Dynamic_link: call() couldn't mix inputs and outputs 90/19190/4
Paul Bignier [Wed, 15 Mar 2017 14:30:09 +0000 (15:30 +0100)]
Change-Id: I59ca8acd5c11d5c9c24ebb3f33ae20ad517457f7

scilab/CHANGES.md
scilab/modules/dynamic_link/sci_gateway/cpp/sci_call.cpp
scilab/modules/dynamic_link/tests/nonreg_tests/bug_15046.tst [new file with mode: 0644]

index c4a3d4f..ff2ceb7 100644 (file)
@@ -357,6 +357,7 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 * [#15019](http://bugzilla.scilab.org/show_bug.cgi?id=15019): Add 'csci6' in the calling of ilib_build in 'Getting started with API_Scilab' help page.
 * [#15023](http://bugzilla.scilab.org/show_bug.cgi?id=15023): `clf()` wrongly reset `figure_id`.
 * [#15039](http://bugzilla.scilab.org/show_bug.cgi?id=15039): Added demos to showcase Xcos' new graphical features
+* [#15046](http://bugzilla.scilab.org/show_bug.cgi?id=15046): `call` couldn't mix inputs and outputs
 * [#15052](http://bugzilla.scilab.org/show_bug.cgi?id=15052): `getpid` wasn't available anymore
 * [#15053](http://bugzilla.scilab.org/show_bug.cgi?id=15053): `_str2code` was removed with no proper equivalence and made `mfile2sci` failing.
 * [#15054](http://bugzilla.scilab.org/show_bug.cgi?id=15054): The callbacks of `wfir_gui()` were not prioritary.
index 18b8b26..4d8ce90 100644 (file)
@@ -268,36 +268,52 @@ int sci_call(scilabEnv env, int nin, scilabVar* in, int nopt, scilabOpt opt, int
                 scilab_getString(env, in[pos + 2], &param_type);
 
                 void* data = NULL;
+                Parameter& p = params[(int)param_pos - 1];
 
-                switch (param_type[0])
+                if (p.data != nullptr) // Reuse the input slot if it is passed as output
                 {
-                    case L'c':
-                    {
-                        data = malloc((size + 1) * sizeof(char));
-                        break;
-                    }
-                    case L'd':
+                    if (p.type != param_type[0])
                     {
-                        data = malloc(size * sizeof(double));
-                        break;
+                        Scierror(999, _("%s: incompatible type between input and output variables.\n"), fname);
+                        return 1;
                     }
-                    case L'r':
+                    if (p.row != dims[0] || p.col != dims[1])
                     {
-                        data = malloc(size * sizeof(float));
-                        break;
+                        Scierror(999, _("%s: incompatible sizes between input and output variables.\n"), fname);
+                        return 1;
                     }
-                    case L'i':
+                }
+                else // Otherwise allocate one
+                {
+                    switch (param_type[0])
                     {
-                        data = malloc(size * sizeof(int));
-                        break;
+                        case L'c':
+                        {
+                            data = malloc((size + 1) * sizeof(char));
+                            break;
+                        }
+                        case L'd':
+                        {
+                            data = malloc(size * sizeof(double));
+                            break;
+                        }
+                        case L'r':
+                        {
+                            data = malloc(size * sizeof(float));
+                            break;
+                        }
+                        case L'i':
+                        {
+                            data = malloc(size * sizeof(int));
+                            break;
+                        }
                     }
+                    p.row = (int)dims[0];
+                    p.col = (int)dims[1];
+                    p.alloc = true;
+                    p.type = param_type[0];
+                    p.data = data;
                 }
-                Parameter& p = params[(int)param_pos - 1];
-                p.row = (int)dims[0];
-                p.col = (int)dims[1];
-                p.alloc = true;
-                p.type = param_type[0];
-                p.data = data;
                 pos += 3;
                 output_order[output_pos] = (int)param_pos - 1;
             }
diff --git a/scilab/modules/dynamic_link/tests/nonreg_tests/bug_15046.tst b/scilab/modules/dynamic_link/tests/nonreg_tests/bug_15046.tst
new file mode 100644 (file)
index 0000000..1787872
--- /dev/null
@@ -0,0 +1,39 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - Scilab Enterprises - Paul Bignier
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- NO CHECK REF -->
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 15046 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=15046
+//
+// <-- Short Description -->
+// call() couldn't mix inputs and outputs
+
+ilib_verbose(0);
+cd TMPDIR;
+sub2 = [ ..
+"      subroutine sub2(n, m)"; ..
+"       implicit none"; ..
+"       integer n, m"; ..
+"       m=n+1"; ..
+"      end"
+];
+mputl(sub2, "sub2.f");
+ilib_for_link("sub2", "sub2.f", [], "f");
+exec loader.sce;
+
+N = 3;
+[M, K] = call("sub2", N, 1, "i", "out", [1, 1], 1, "i", [1, 1], 2, "i"); // M = N = 3, K = N+1 = 4
+
+assert_checkequal([M K], [3 4]);
+
+M = call("sub2", N, 1, "i", "out", [1, 1], 2, "i"); // M = N+1 = 4
+
+assert_checkequal(M, 4);