Bug #16106 fixed: Xcos sciblk4 opar failed to simulate 60/21460/2
Clément DAVID [Fri, 24 Apr 2020 13:14:16 +0000 (15:14 +0200)]
The sciblk4 user-defined blocks did not handle opar and odstate/oz in a
compatible way to Scilab 5. On interface function model.opar is a
list() that should be passed to block.opar on simulation function. On
interface function model.odstate is a list() that should be passed to
block.oz on simulation function.

Change-Id: I5835603e754c0a39543cb0e4e859edfb3c929d5a

scilab/CHANGES.md
scilab/modules/scicos/sci_gateway/cpp/sci_scicosim.cpp
scilab/modules/scicos/src/cpp/createblklist.cpp
scilab/modules/scicos/tests/nonreg_tests/bug_16106.tst [new file with mode: 0644]

index 40b1044..58ec4be 100644 (file)
@@ -266,6 +266,7 @@ Bug Fixes
 
 ### Bugs fixed in 6.1.1:
 * [#3188](https://bugzilla.scilab.org/3188): `part()` was slower than in Scilab 4.1.2.
+* [#16106](https://bugzilla.scilab.org/16106): Xcos sciblk4 user-defined blocks did not handle opar and odstate/oz correctly.
 * [#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.
 * [#16365](https://bugzilla.scilab.org/16365): `median(m,"r")` and `median(m,"c")` yielded wrong results (6.1.0 regression)
index d4c94a2..12eaee8 100644 (file)
@@ -1535,8 +1535,7 @@ types::Function::ReturnValue sci_scicosim(types::typed_list &in, int _iRetCount,
         // Set vectors of 'oz'
         for (int j = 0; j < noz; ++j)
         {
-            int subtype = il_state_oz->get(j)->getType();
-
+            types::InternalType::ScilabType subtype = il_state_oz->get(j)->getType();
             switch (subtype) // Store type and address
             {
                 case types::InternalType::ScilabDouble :
@@ -1613,7 +1612,7 @@ types::Function::ReturnValue sci_scicosim(types::typed_list &in, int _iRetCount,
                 default :
                 {
                     oztyp[j] = SCSUNKNOW_N;
-                    oz[j] = il_sim_opar->get(j);
+                    oz[j] = il_state_oz->get(j);
                     ozsz[j] = 0; // rows
                     ozsz[j + nopar] = 0; // cols
                     break;
index e0e45d7..8cdfc23 100644 (file)
@@ -369,13 +369,24 @@ types::InternalType* createblklist(const scicos_block* const Blocks, const int f
     m->append(oztyp);
 
     /* 11 - ozptr */
-    types::List* ozptr = new types::List();
-    for (int k = 0; k < Blocks->noz; k++)
+    types::List* ozptr;
+
+    // special case, some values are embeded into a Scilab list ; unwrap them
+    if (Blocks->noz == 1 && Blocks->oztyp[0] == SCSUNKNOW_N)
+    {
+        ozptr = (types::List*) vartosci(Blocks->ozptr[0], Blocks->ozsz[0], Blocks->ozsz[1], Blocks->oztyp[0]);
+    }
+    else
     {
-        const int rows = Blocks->ozsz[k];               /* retrieve number of rows */
-        const int cols = Blocks->ozsz[Blocks->noz + k]; /* retrieve number of cols */
-        const int type = Blocks->oztyp[k];              /* retrieve type */
-        ozptr->append(vartosci(Blocks->ozptr[k], rows, cols, type));
+        ozptr = new types::List();
+        for (int k = 0; k < Blocks->noz; k++)
+        {
+            const int rows = Blocks->ozsz[k];               /* retrieve number of rows */
+            const int cols = Blocks->ozsz[Blocks->noz + k]; /* retrieve number of cols */
+            const int type = Blocks->oztyp[k];              /* retrieve type */
+
+            ozptr->append(vartosci(Blocks->ozptr[k], rows, cols, type));
+        }
     }
 
     m->append(ozptr);
@@ -504,13 +515,24 @@ types::InternalType* createblklist(const scicos_block* const Blocks, const int f
     m->append(opartyp);
 
     /* 31 - opar */
-    types::List* opar = new types::List();
-    for (int k = 0; k < Blocks->nopar; k++)
+    types::List* opar;
+
+    // special case, some values are embeded into a Scilab list ; unwrap them
+    if (Blocks->nopar == 1 && Blocks->opartyp[0] == SCSUNKNOW_N)
+    {
+        opar = (types::List*) vartosci(Blocks->oparptr[0], Blocks->oparsz[0], Blocks->oparsz[1], Blocks->opartyp[0]);
+    }
+    else
     {
-        const int rows = Blocks->oparsz[k];                 /* retrieve number of rows */
-        const int cols = Blocks->oparsz[Blocks->nopar + k]; /* retrieve number of cols */
-        const int type = Blocks->opartyp[k];                /* retrieve type */
-        opar->append(vartosci(Blocks->oparptr[k], rows, cols, type));
+        opar = new types::List();
+        for (int k = 0; k < Blocks->noz; k++)
+        {
+            const int rows = Blocks->oparsz[k];               /* retrieve number of rows */
+            const int cols = Blocks->oparsz[Blocks->noz + k]; /* retrieve number of cols */
+            const int type = Blocks->opartyp[k];              /* retrieve type */
+
+            opar->append(vartosci(Blocks->oparptr[k], rows, cols, type));
+        }
     }
 
     m->append(opar);
@@ -650,14 +672,23 @@ types::InternalType* refreshblklist(types::InternalType* pIT, const scicos_block
     if (m->get(10)->isList())
     {
         types::List* ozptr = m->get(10)->getAs<types::List>();
-        for (int k = 0; k < Blocks->noz; k++)
+
+        // special case, some values are embeded into a Scilab list ; wrap them
+        if (Blocks->noz == 1 && Blocks->oztyp[0] == SCSUNKNOW_N)
         {
-            const int rows = Blocks->ozsz[k];               /* retrieve number of rows */
-            const int cols = Blocks->ozsz[Blocks->noz + k]; /* retrieve number of cols */
-            const int type = Blocks->oztyp[k];              /* retrieve type */
-            ozptr->set(k, vartosci(ozptr->get(k), Blocks->ozptr[k], rows, cols, type));
+            m->set(10, ozptr);
+        }
+        else
+        {
+            for (int k = 0; k < Blocks->noz; k++)
+            {
+                const int rows = Blocks->ozsz[k];               /* retrieve number of rows */
+                const int cols = Blocks->ozsz[Blocks->noz + k]; /* retrieve number of cols */
+                const int type = Blocks->oztyp[k];              /* retrieve type */
+                ozptr->set(k, vartosci(ozptr->get(k), Blocks->ozptr[k], rows, cols, type));
+            }
+            m->set(10, ozptr);
         }
-        m->set(10, ozptr);
     }
 
     /* 13 - x */
diff --git a/scilab/modules/scicos/tests/nonreg_tests/bug_16106.tst b/scilab/modules/scicos/tests/nonreg_tests/bug_16106.tst
new file mode 100644 (file)
index 0000000..efdbd1b
--- /dev/null
@@ -0,0 +1,80 @@
+// =============================================================================
+// 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 16106 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=16106
+//
+// <-- Short Description -->
+// block.opar and block.oz could not be used for block implemented in Scilab
+// with the scicos api 5.
+//
+
+loadXcosLibs
+
+function [x,y,typ]=DEMO_BLK4(job,arg1,arg2)
+    x=[];
+    y=[];
+    typ=[];
+
+    select job
+    case "set" then
+        x=arg1;
+
+    case "define" then
+        model=scicos_model();
+        model.sim=list("demo_blk4_sim", 5)
+        model.blocktype="d";
+        model.dep_ut=[%f %t];
+        model.in=[1];
+        model.intyp=[1];
+        model.out=[1];
+        model.outtyp=[1];
+
+        r = rand(); // same shared random value for checking
+        model.opar=list("FOO", r)
+        model.odstate=list("BAR", r)
+
+        x=standard_define([2 2],model,[],[]);
+    end
+
+endfunction
+
+function [blk] = demo_blk4_sim(blk, flag)
+    if flag == 4 | flag == 6 // INIT or REINIT
+    elseif flag ==  1 // OUTPUT UPDATE
+        assert_checkequal(blk.opar(1), "FOO");
+        assert_checkequal(floor(blk.opar(2)), 0);
+        assert_checkequal(blk.oz(1), "BAR");
+        assert_checkequal(blk.oz(2) - floor(blk.oz(2)), blk.opar(2));
+    elseif flag ==  2 // STATE UPDATE
+        blk.odstate(2) = blk.odstate(2) + 1;
+        assert_checkequal(floor(blk.oz(2)) - blk.opar(2), 0);
+    end
+endfunction
+
+// For user specific testing
+// pal = xcosPal("demo");
+// pal = xcosPalAddBlock(pal, "DEMO_BLK4");
+// xcosPalAdd(pal);
+
+// Create a diagram with a DEMO_BLK4 linked to itself
+blk = DEMO_BLK4("define");
+blk.graphics.pin = 2;
+blk.graphics.pout = 2;
+
+lnk = scicos_link();
+lnk.from = [1 1 0];
+lnk.to = [1 1 1];
+
+scs_m = scicos_diagram(objs=list(blk, lnk));
+Info = scicos_simulate(scs_m, list());
+