TOWS_c block rewrite in API_Scilab 20/10820/41
Paul BIGNIER [Thu, 14 Mar 2013 09:27:25 +0000 (10:27 +0100)]
Change-Id: I5864c568c083b08706db1ae5d8e937cbfb0250ca

scilab/modules/scicos/macros/scicos_auto/scicos_simulate.sci
scilab/modules/scicos_blocks/macros/Sinks/TOWS_c.sci
scilab/modules/scicos_blocks/src/c/tows_c.c
scilab/modules/xcos/macros/xcos_simulate.sci
scilab/modules/xcos/tests/unit_tests/tows_c.dia.ref
scilab/modules/xcos/tests/unit_tests/tows_c.tst
scilab/modules/xcos/tests/unit_tests/tows_c.xcos [new file with mode: 0644]

index b8d306e..45c2433 100644 (file)
@@ -1,5 +1,6 @@
 //  Scicos
 //
+//  Copyright (C) Scilab Enterprises - 2013 - Bruno JOFRET
 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
 //  Copyright (C) 2011 - INRIA - Serge Steer
 
@@ -265,7 +266,7 @@ function Info = scicos_simulate(scs_m, Info, updated_vars, flag, Ignb)
 
     if or(%state0_n <> %state0) then //initial state has been changed
         %state0 = %state0_n
-        [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
+        [alreadyran, %cpr, Resume_line, TOWS_vals, Names] = do_terminate1(scs_m, %cpr)
         choix = []
     end
     if (%cpr.sim.xptr($) - 1) < size(%cpr.state.x,"*") & solver < 100 then
@@ -294,7 +295,7 @@ function Info = scicos_simulate(scs_m, Info, updated_vars, flag, Ignb)
 
     if needstart then //scicos initialization
         if alreadyran then
-            [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
+            [alreadyran, %cpr, Resume_line, TOWS_vals, Names] = do_terminate1(scs_m, %cpr)
             alreadyran = %f
         end
         %tcur = 0
@@ -306,7 +307,7 @@ function Info = scicos_simulate(scs_m, Info, updated_vars, flag, Ignb)
         ierr = execstr("[state, t] = scicosim(%cpr.state, %tcur, tf, %cpr.sim," + ..
         "''start'', tolerances)","errcatch")
         if ierr <> 0 then
-            error(_("Initialisation problem:"))
+            error(_("Initialization problem:"))
         end
         %cpr.state = state
     end
@@ -318,7 +319,15 @@ function Info = scicos_simulate(scs_m, Info, updated_vars, flag, Ignb)
         alreadyran = %t
         if (tf - t) < tolerances(3) then
             needstart = %t
-            [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
+            [alreadyran, %cpr, Resume_line, TOWS_vals, Names] = do_terminate1(scs_m, %cpr)
+            for i=1:size(Names, "c")
+                ierr = execstr(Names(i)+" = TOWS_vals("+string(i)+");", "errcatch");
+                if ierr <> 0 then
+                    str_err = split_lasterror(lasterror());
+                    message(["Simulation problem" ; "Unable to find To Workspace Variable {"+Names(i)+"}:" ; str_err]);
+                    break;
+                end
+            end
         else
             %tcur = t
         end
@@ -328,18 +337,20 @@ function Info = scicos_simulate(scs_m, Info, updated_vars, flag, Ignb)
 
     Info = list(%tcur, %cpr, alreadyran, needstart, needcompile, %state0)
 
-    [txt, files] = returntoscilab()
-    n = size(files,1)
-    for i = 1:n
-        load(TMPDIR + "/Workspace/" + files(i))
-        execstr(files(i) + " = struct('"values'", x, '"time'", t)")
+    // Executing the resume() function at the end, because it does not return control
+    if ~isempty(Names) then
+        execstr(Resume_line);
     end
-    execstr(txt)
 endfunction
 
-function [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
+function [alreadyran, %cpr, Resume_line, TOWS_vals, Names] = do_terminate1(scs_m, %cpr)
     // Copyright INRIA
 
+    // Default return values
+    Resume_line = "";
+    TOWS_vals = struct("values",[],"time",[]);
+    Names = [];
+
     if prod(size(%cpr)) < 2 then
         alreadyran = %f
         return
@@ -356,5 +367,65 @@ function [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
         if ierr <> 0 then
             error([_("End problem: ");lasterror()])
         end
+
+        // Restore saved variables in Scilab environment ("To workspace" block)
+
+        // First step: Search the %cpr tree for TOWS_c blocks, and extract the variable names.
+        path = %cpr.sim;
+        buff_sizes = [];
+        increment = 1;
+        for i=1:size(path.funs)
+            increment2 = path.ipptr(i+1);
+            if (increment2 - increment <> 0) then   // ipar has at least a few elements
+                space = increment2 - increment;      // The number of elements that the current block pushed into ipar
+                if (path.funs(i) == "tows_c") then  // Found a Tow_workspace block
+                    varNameLen = space - 2;         // Space minus 'buffer_size' and 'var length' ipar elements
+                    varNameCode = path.ipar(increment+2:increment+2+varNameLen-1);  // varName is stored in Scilab code
+                    varName = ascii(varNameCode);
+                    Names = [Names varName];        // Append varName in Names
+                    buff_size  = path.ipar(increment);  // Retrieve buffer size
+                    buff_sizes = [buff_sizes buff_size];
+                end
+                increment = increment2;
+            end
+        end
+        // At the end, Names contains the string names of the variables and buff_sizes the respective buffer sizes
+
+        // Second step: Link the variable names to their values vectors,
+        //and call '[names(1), names(2), ...] = resume(names(1), names(2), ...)' to save the variable into Scilab
+        if ~isempty(Names) then
+            execstr("Names1val  = "+Names(1)+"_val;");
+            execstr("Names1valt = "+Names(1)+"_valt;");
+            // If input is a matrix, use function matrix() to reshape the saved values
+            if (size(Names1val, "r") > buff_sizes(1)) then  // In this case, size(Names(1), 'r') = buff_sizes(1) * nCols2
+                nRows = buff_sizes(1);
+                nCols  = size(Names1val, "c");
+                nCols2 = size(Names1val, "r") / buff_sizes(1);
+                Names1val = matrix(Names1val, nCols, nCols2, nRows);
+            end
+            // Replace default struct with value vector of first element of 'Names'
+            TOWS_vals.values = Names1val;
+            TOWS_vals.time   = Names1valt;
+            Resume_line_args = Names(1);  // Will contain 'names(1), names(2), ...'
+            for i=2:size(Names, "c")
+                execstr("NamesIval = "+Names(i)+"_val;");
+                // If input is a matrix, use function matrix() to reshape the saved values
+                if (size(NamesIval, "r") > buff_sizes(i)) then  // In this case, size(Names(i), 'r') = buff_sizes(i) * nCols2
+                    nRows = buff_sizes(i);
+                    nCols  = size(NamesIval, "c");
+                    nCols2 = size(NamesIval, "r") / buff_sizes(i);
+                    NamesIval = matrix(NamesIval, nCols, nCols2, nRows);
+                end
+                ierr = execstr("TOWS_vals = [TOWS_vals struct(''values'', NamesIval,''time'',"+Names(i)+"_valt)];", "errcatch");
+                if ierr <> 0 then
+                    str_err = split_lasterror(lasterror());
+                    message(["Simulation problem" ; "Unable to find To Workspace Variable {"+Names(i)+"}:" ; str_err]);
+                    break;
+                end
+                Resume_line_args   = Resume_line_args + ", " + Names(i);  // Concatenate the variable names up to the last one
+            end
+            Resume_line = "[" + Resume_line_args + "] = resume(" + Resume_line_args + ");";  // Build the message
+            // Will execute Resume_line at the end of the main function, because it does not return control
+        end
     end
 endfunction
index 37b1ce7..42f6317 100644 (file)
 // See the file ../license.txt
 //
 
-function [x,y,typ]=TOWS_c(job,arg1,arg2)
-    x=[];y=[];typ=[]
+function [x, y, typ] = TOWS_c(job, arg1, arg2)
+    x = []; y = []; typ = [];
     select job
     case "plot" then
-        varnam=string(arg1.graphics.exprs(2))
-        standard_draw(arg1)
+        varnam = string(arg1.graphics.exprs(2));
+        standard_draw(arg1);
     case "getinputs" then
-        [x,y,typ]=standard_inputs(arg1)
+        [x, y, typ] = standard_inputs(arg1);
     case "getoutputs" then
-        [x,y,typ]=standard_outputs(arg1)
+        [x, y, typ] = standard_outputs(arg1);
     case "getorigin" then
-        [x,y]=standard_origin(arg1)
+        [x, y] = standard_origin(arg1);
     case "set" then
-        x=arg1;
-        graphics=arg1.graphics;model=arg1.model;
-        exprs=graphics.exprs;
+        x = arg1;
+        graphics = arg1.graphics; model = arg1.model;
+        exprs = graphics.exprs;
 
         while %t do
-            [ok,nz,varnam,herit,exprs]=scicos_getvalue("Set Xcos buffer block",...
+            [ok, nz, varnam, herit, exprs] = scicos_getvalue("Set Xcos buffer block", ...
             ["Size of buffer";
             "Scilab variable name";
-            "Inherit (no:0, yes:1)"],...
-            list("vec",1,"str",1,"vec",1),exprs);
+            "Inherit (no:0, yes:1)"], ...
+            list("vec", 1, "str", 1, "vec", 1), exprs);
 
-            if ~ok then break,end;
+            if ~ok then break, end;
 
-            if(nz<=0) then
+            if (nz <= 0) then
                 message("Size of buffer must be positive");
-                ok=%f
+                ok = %f;
             end
 
             //check for valid name variable
-            r=%f;
-            ierr=execstr("r=validvar(varnam)","errcatch")
-            if ~r then
-                message(["Invalid variable name.";
-                "Please choose another variable name."]);
-                ok=%f
+            r = %f;
+            ierr = execstr("r = validvar(varnam)", "errcatch");
+            if ~r | ierr <> 0 then
+                message(["Invalid variable name."; "Please choose another variable name."]);
+                ok = %f;
             end
+            // If varnam already exists, then it must be of type struct (17) with fields "values" and "names".
+            // Otherwise, it is considered as a protected variable, an error is raised and user will be asked to enter a new name.
+            execstr("if type("+varnam+") <> 17 | or(fieldnames("+varnam+") <> [""values""; ""time""]) then" + ...
+            " message([""Protected variable name.""; ""Please choose another variable name.""]);" + ...
+            " ok = %f;" + ...
+            " end", "errcatch");
 
             if ok then
-                [model,graphics,ok]=set_io(model,graphics,...
-                list([-1,-2],-1),list(),...
-                ones(1-herit,1),[])
+                [model, graphics, ok] = set_io(model, graphics, ...
+                list([-1, -2], -1), list(), ...
+                ones(1-herit, 1), []);
                 if herit == 1 then
-                    model.blocktype="x"
+                    model.blocktype = "x";
                 else
                     model.blocktype = "d";
                 end
-                model.ipar=[nz;length(varnam);_str2code(varnam)]
-                graphics.exprs=exprs
-                x.graphics=graphics;
-                x.model=model;
+                model.ipar = [nz; length(varnam); ascii(varnam)'];
+                graphics.exprs = exprs;
+                x.graphics = graphics;
+                x.model = model;
                 break
             end
         end
 
     case "define" then
-        nu     = -1
-        nz     = 128
-        varnam = "A"
-        herit  = 0
+        nu     = -1;
+        nz     = 128;
+        varnam = "A";
+        herit  = 0;
 
         model           = scicos_model();
-        model.sim       = list("tows_c",4);
+        model.sim       = list("tows_c", 4);
         model.in        = [nu];
         model.in2       = -2;
         model.intyp     = -1;
@@ -91,22 +96,22 @@ function [x,y,typ]=TOWS_c(job,arg1,arg2)
         model.evtin     = [1];
         model.evtout    = [];
         model.rpar      = [];
-        model.ipar      = [nz;length(varnam);_str2code(varnam)];
+        model.ipar      = [nz; length(varnam); ascii(varnam)'];
         model.blocktype = "d";
         model.firing    = [];
         model.dep_ut    = [%f %f];
-        gr_i=["xstringb(orig(1),orig(2),''To workspace'',sz(1),sz(2),''fill'')"
-        "txt=varnam;"
-        "style=5;"
-        "rectstr=stringbox(txt,orig(1),orig(2),0,style,1);"
-        "if ~exists(''%zoom'') then %zoom=1, end;"
-        "w=(rectstr(1,3)-rectstr(1,2))*%zoom;"
-        "h=(rectstr(2,2)-rectstr(2,4))*%zoom;"
-        "xstringb(orig(1)+sz(1)/2-w/2,orig(2)-h-4,txt,w,h,''fill'');"
-        "e=gce();"
-        "e.font_style=style;"]
-        exprs=[string(nz);string(varnam);string(herit)]
-        x=standard_define([4 2],model,exprs,gr_i)
+        gr_i = ["xstringb(orig(1), orig(2), ''To workspace'', sz(1), sz(2), ''fill'')"
+        "txt = varnam;"
+        "style = 5;"
+        "rectstr = stringbox(txt, orig(1), orig(2), 0, style, 1);"
+        "if ~exists(''%zoom'') then %zoom = 1, end;"
+        "w = (rectstr(1, 3)-rectstr(1, 2))*%zoom;"
+        "h = (rectstr(2, 2)-rectstr(2, 4))*%zoom;"
+        "xstringb(orig(1)+sz(1)/2-w/2, orig(2)-h-4, txt, w, h, ''fill'');"
+        "e = gce();"
+        "e.font_style = style;"];
+        exprs = [string(nz); string(varnam); string(herit)];
+        x = standard_define([4 2], model, exprs, gr_i);
     end
 endfunction
 
index 7527969..b6d53f3 100644 (file)
@@ -1,6 +1,7 @@
 /*  Scicos
 *
 *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
+*  Copyright (C) Scilab Enterprises - 2013 - Paul Bignier
 *
 * 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
@@ -22,6 +23,9 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h> /* getenv */
+#include "api_scilab.h"
+#include "Scierror.h"
+#include "code2str.h"
 #include "stack-c.h"
 #include "MALLOC.h"
 #include "sciprint.h"
@@ -71,14 +75,6 @@ extern int C2F(namstr)();
        ptr_i[39]  = nz;
 /*--------------------------------------------------------------------------*/
 static int id[nsiz];
-static char fmtd[3]  = {'d', 'l', '\000'};
-static char fmti[3]  = {'i', 'l', '\000'};
-static char fmtl[3]  = {'l', 'l', '\000'};
-static char fmts[3]  = {'s', 'l', '\000'};
-static char fmtc[3]  = {'c', 'l', '\000'};
-static char fmtul[3] = {'u', 'l', '\000'};
-static char fmtus[3] = {'u', 's', '\000'};
-static char fmtuc[3] = {'u', 'c', '\000'};
 /*--------------------------------------------------------------------------*/
 static char *str_hmlst[] = {"hm", "dims", "entries"};
 /*--------------------------------------------------------------------------*/
@@ -96,22 +92,15 @@ typedef struct
     void *workt;
 } towork_struct ;
 /*--------------------------------------------------------------------------*/
+SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag);
 SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
 /* Copyright INRIA */
-/* Put a typed vector in a scilab file.
+/* Put a typed vector in a Scilab file.
 * Independant platform.
 *
 * Author A.Layec - initial rev. 18/09/07
 */
 {
-    /* for mopen */
-    int fd;
-    char *status;
-    int swap = 1;
-    double res;
-    char *filename = NULL;
-    /* for name of file */
-    char str[100];
     /* generic pointer */
     SCSREAL_COP *u_d, *u_cd, *ptr_d, *sav_d;
     SCSINT8_COP *u_c, *ptr_c, *sav_c;
@@ -130,25 +119,30 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
     double t, t_old;
     /* local */
     int i, j, k, l;
-    int ierr;
 
-    int  ismat = 0;
-
-    /* for path of TMPDIR/workspace */
-    char env[256];
-    char sep[2];
-#ifdef _MSC_VER
-    sep[0] = '\\';
-#else
-    sep[0] = '/';
-#endif
-    sep[1] = '\0';
+    int ismat = 0;
+
+    SciErr sciErr;
+    int nRows, nCols, nCols2 = 1, varNameLen;
+    char * varName = NULL;
+    /* Matrices to be copies of the work array, to pass to Scilab */
+    double * MatDouble  = NULL;
+    double * MatComplexReal = NULL;
+    double * MatComplexImg  = NULL;
+    char  *  MatInt8  = NULL;
+    short *  MatInt16 = NULL;
+    int   *  MatInt32 = NULL;
+    unsigned char  *  MatUInt8  = NULL;
+    unsigned short *  MatUInt16 = NULL;
+    unsigned int   *  MatUInt32 = NULL;
+    double * Time = NULL;
 
     /* retrieve param of that block */
     nu  = GetInPortRows(block, 1); /* number of rows of inputs*/
     nu2 = GetInPortCols(block, 1); /* number of cols of inputs*/
     ut  = GetInType(block, 1);    /* input type */
     nz  = block->ipar[0];         /* buffer size */
+    varNameLen = block->ipar[1];
 
     /* check if u is a matrix */
     if (nu2 != 1)
@@ -432,7 +426,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                                                             4 * sizeof(int) + \
                                                             (3) * sizeof(int) + \
                                                             4 * sizeof(int) + \
-                                                            nz * nu * nu2 * sizeof(long))) == NULL)
+                                                            nz * nu * nu2 * sizeof(int))) == NULL)
                     {
                         set_block_error(-16);
                         scicos_free(ptr->workt);
@@ -451,7 +445,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                 else
                 {
                     if ((ptr->work = (void *) scicos_malloc(6 * sizeof(int) + 4 * sizeof(int) + \
-                                                            nz * nu * sizeof(long))) == NULL)
+                                                            nz * nu * sizeof(int))) == NULL)
                     {
                         set_block_error(-16);
                         scicos_free(ptr->workt);
@@ -588,7 +582,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                                                             4 * sizeof(int) + \
                                                             (3) * sizeof(int) + \
                                                             4 * sizeof(int) + \
-                                                            nz * nu * nu2 * sizeof(unsigned long))) == NULL)
+                                                            nz * nu * nu2 * sizeof(unsigned int))) == NULL)
                     {
                         set_block_error(-16);
                         scicos_free(ptr->workt);
@@ -607,7 +601,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                 else
                 {
                     if ((ptr->work = (void *) scicos_malloc(6 * sizeof(int) + 4 * sizeof(int) + \
-                                                            nz * nu * sizeof(unsigned long))) == NULL)
+                                                            nz * nu * sizeof(unsigned int))) == NULL)
                     {
                         set_block_error(-16);
                         scicos_free(ptr->workt);
@@ -662,50 +656,14 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
 
         if (ptr != NULL)
         {
-            /* Put file name in str */
-            C2F(cvstr)(&(block->ipar[1]), &(block->ipar[2]), str, (j = 1, &j), \
-                       (unsigned long)strlen(str));
-            str[block->ipar[1]] = '\0';
-
-            /* retrieve path of TMPDIR/workspace */
-            strcpy(env, getenv("TMPDIR"));
-            strcat(env, sep);
-            strcat(env, "Workspace");
-            strcat(env, sep);
-            strcat(env, str);
-
-            /* open tmp file */
-            status = "wb";
-            /* "w" : write */
-            /* "b" : binary (required for Windows) */
-
-            ierr = 1;
-            filename = expandPathVariable(env);
-            if (filename)
-            {
-                C2F(mopen)(&fd, filename, status, &swap, &res, &ierr);
-                FREE(filename);
-                filename = NULL;
-            }
-
-            if (ierr != 0)
-            {
-                Coserror(_("Error when opening file '%s'.\n"), str);
-                scicos_free(ptr->workt);
-                scicos_free(ptr);
-                *(block->work) = NULL;
-                /*set_block_error(-3);*/
-                return;
-            }
-
             /* check loop */
 
-            /* we don't are at the end of the buffer :
+            /* we are not at the end of the buffer :
             * only first records will be saved
             */
             if ((ptr->cnt == 0) && (ptr->loop == 0))
             {
-                /* nothing have been stored */
+                /* nothing has been stored */
                 ptr_i = (int*) ptr->workt;
                 ptr_i[6] = 1;
                 ptr_i[7] = 0;
@@ -721,7 +679,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
             if ((ptr->cnt != 0) && (ptr->cnt != nz) && (ptr->loop == 0))
             {
                 /* something stored */
-                /* but we don't are at the end */
+                /* but we are not at the end */
                 ptr_i    = (int*) ptr->workt;
                 ptr_i[7] = ptr->cnt;
                 ptr_i    = (int*) ptr->work;
@@ -808,8 +766,8 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                                 {
                                     for (j = 0; j < ptr->cnt; j++)
                                     {
-                                        *((long *)(&ptr_i[10]) + (((i + 1)*nz) + j - (i + 1)*k)) = \
-                                                *((long *)(&ptr_i[10]) + (((i + 1) * nz) + j));
+                                        *((int *)(&ptr_i[10]) + (((i + 1)*nz) + j - (i + 1)*k)) = \
+                                                *((int *)(&ptr_i[10]) + (((i + 1) * nz) + j));
                                     }
                                 }
                                 break;
@@ -841,8 +799,8 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                                 {
                                     for (j = 0; j < ptr->cnt; j++)
                                     {
-                                        *((unsigned long *)(&ptr_i[10]) + (((i + 1)*nz) + j - (i + 1)*k)) = \
-                                                *((unsigned long *)(&ptr_i[10]) + (((i + 1) * nz) + j));
+                                        *((unsigned int *)(&ptr_i[10]) + (((i + 1)*nz) + j - (i + 1)*k)) = \
+                                                *((unsigned int *)(&ptr_i[10]) + (((i + 1) * nz) + j));
                                     }
                                 }
                                 break;
@@ -1096,7 +1054,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                         scicos_free(sav_s);
                         break;
                     case SCSINT32_N   :
-                        if ((sav_l = (long *) scicos_malloc(nu * nu2 * sizeof(long))) == NULL)
+                        if ((sav_l = (int *) scicos_malloc(nu * nu2 * sizeof(int))) == NULL)
                         {
                             set_block_error(-16);
                             scicos_free(ptr->workt);
@@ -1111,18 +1069,18 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                             {
                                 for (k = 0; k < nu * nu2; k++)
                                 {
-                                    sav_l[k] = *((long *)(&ptr_i[44]) + k + (nz - 1) * nu * nu2);
+                                    sav_l[k] = *((int *)(&ptr_i[44]) + k + (nz - 1) * nu * nu2);
                                 }
                                 for (j = (nz - 1); j >= 1; j--)
                                 {
                                     for (k = 0; k < nu * nu2; k++)
                                     {
-                                        *((long *)(&ptr_i[44]) + k + j * (nu * nu2)) = *((long *)(&ptr_i[44]) + k + (j - 1) * (nu * nu2));
+                                        *((int *)(&ptr_i[44]) + k + j * (nu * nu2)) = *((int *)(&ptr_i[44]) + k + (j - 1) * (nu * nu2));
                                     }
                                 }
                                 for (k = 0; k < nu * nu2; k++)
                                 {
-                                    *((long *)(&ptr_i[44]) + k)  = sav_l[k];
+                                    *((int *)(&ptr_i[44]) + k)  = sav_l[k];
                                 }
                             }
                         }
@@ -1132,18 +1090,18 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                             {
                                 for (k = 0; k < nu; k++)
                                 {
-                                    sav_l[k] = *((long *)(&ptr_i[10]) + k * nz + (nz - 1));
+                                    sav_l[k] = *((int *)(&ptr_i[10]) + k * nz + (nz - 1));
                                 }
                                 for (j = (nz - 1); j >= 1; j--)
                                 {
                                     for (k = 0; k < nu; k++)
                                     {
-                                        *((long *)(&ptr_i[10]) + k * nz + j) = *((long *)(&ptr_i[10]) + k * nz + j - 1);
+                                        *((int *)(&ptr_i[10]) + k * nz + j) = *((int *)(&ptr_i[10]) + k * nz + j - 1);
                                     }
                                 }
                                 for (k = 0; k < nu; k++)
                                 {
-                                    *((long *)(&ptr_i[10]) + k * nz)  = sav_l[k];
+                                    *((int *)(&ptr_i[10]) + k * nz)  = sav_l[k];
                                 }
                             }
                         }
@@ -1258,7 +1216,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                         scicos_free(sav_us);
                         break;
                     case SCSUINT32_N  :
-                        if ((sav_ul = (unsigned long *) scicos_malloc(nu * nu2 * sizeof(unsigned long))) == NULL)
+                        if ((sav_ul = (unsigned int *) scicos_malloc(nu * nu2 * sizeof(unsigned int))) == NULL)
                         {
                             set_block_error(-16);
                             scicos_free(ptr->workt);
@@ -1273,18 +1231,18 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                             {
                                 for (k = 0; k < nu * nu2; k++)
                                 {
-                                    sav_ul[k] = *((unsigned long *)(&ptr_i[44]) + k + (nz - 1) * nu * nu2);
+                                    sav_ul[k] = *((unsigned int *)(&ptr_i[44]) + k + (nz - 1) * nu * nu2);
                                 }
                                 for (j = (nz - 1); j >= 1; j--)
                                 {
                                     for (k = 0; k < nu * nu2; k++)
                                     {
-                                        *((unsigned long *)(&ptr_i[44]) + k + j * (nu * nu2)) = *((unsigned long *)(&ptr_i[44]) + k + (j - 1) * (nu * nu2));
+                                        *((unsigned int *)(&ptr_i[44]) + k + j * (nu * nu2)) = *((unsigned int *)(&ptr_i[44]) + k + (j - 1) * (nu * nu2));
                                     }
                                 }
                                 for (k = 0; k < nu * nu2; k++)
                                 {
-                                    *((unsigned long *)(&ptr_i[44]) + k)  = sav_ul[k];
+                                    *((unsigned int *)(&ptr_i[44]) + k)  = sav_ul[k];
                                 }
                             }
                         }
@@ -1294,18 +1252,18 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                             {
                                 for (k = 0; k < nu; k++)
                                 {
-                                    sav_ul[k] = *((unsigned long *)(&ptr_i[10]) + k * nz + (nz - 1));
+                                    sav_ul[k] = *((unsigned int *)(&ptr_i[10]) + k * nz + (nz - 1));
                                 }
                                 for (j = (nz - 1); j >= 1; j--)
                                 {
                                     for (k = 0; k < nu; k++)
                                     {
-                                        *((unsigned long *)(&ptr_i[10]) + k * nz + j) = *((unsigned long *)(&ptr_i[10]) + k * nz + j - 1);
+                                        *((unsigned int *)(&ptr_i[10]) + k * nz + j) = *((unsigned int *)(&ptr_i[10]) + k * nz + j - 1);
                                     }
                                 }
                                 for (k = 0; k < nu; k++)
                                 {
-                                    *((unsigned long *)(&ptr_i[10]) + k * nz)  = sav_ul[k];
+                                    *((unsigned int *)(&ptr_i[10]) + k * nz)  = sav_ul[k];
                                 }
                             }
                         }
@@ -1318,198 +1276,279 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
 
             /* write x */
             ptr_i = (int*) ptr->work;
-            C2F(mputnc)(&fd, &ptr_i[0], (j = nsiz, &j), fmti, &ierr); /* write sci id */
-            if (ierr != 0)
+            if ((varName = scicos_malloc((varNameLen + 5) * sizeof(char))) == NULL)
             {
-                Coserror(_("Write error in file '%s'.\n"), str);
+                set_block_error(-16);
                 scicos_free(ptr->workt);
                 scicos_free(ptr);
                 *(block->work) = NULL;
-                /*set_block_error(-3);*/
                 return;
             }
-            C2F(mputnc)(&fd, &ptr_i[6], (j = 1, &j), fmti, &ierr); /* write sci type */
-            if (ierr != 0)
+            memset(varName, 0x0, (varNameLen + 5) * sizeof(char));
+            /* save the Scilab name into varName */
+            for (i = 0; i < varNameLen; ++i)
             {
-                Coserror(_("Write error in file '%s'.\n"), str);
-                scicos_free(ptr->workt);
-                scicos_free(ptr);
-                *(block->work) = NULL;
-                /*set_block_error(-3);*/
-                return;
+                varName[i] = (char) block->ipar[i + 2];
             }
-            if ((ptr->cnt == 0) && (ptr->loop == 0))
+            if (ismat)
             {
-                C2F(mputnc)(&fd, &ptr_i[7], (j = 3, &j), fmti, &ierr); /* write sci header */
+                nRows  = ptr_i[39]; /* nz  */
+                nCols  = ptr_i[37]; /* nu  */
+                nCols2 = ptr_i[38]; /* nu2 */
             }
             else
             {
-                if (ismat)
-                {
-                    C2F(mputnc)(&fd, &ptr_i[7], (j = 37, &j), fmti, &ierr); /* write sci header */
-                }
-                else
-                {
-                    C2F(mputnc)(&fd, &ptr_i[7], (j = 3, &j), fmti, &ierr); /* write sci header */
-                }
-            }
-            if (ierr != 0)
-            {
-                Coserror(_("Write error in file '%s'.\n"), str);
-                scicos_free(ptr->workt);
-                scicos_free(ptr);
-                *(block->work) = NULL;
-                /*set_block_error(-3);*/
-                return;
+                nRows = ptr_i[7]; /* nz */
+                nCols = ptr_i[8]; /* nu */
             }
             if ((ptr->cnt != 0) || (ptr->loop != 0))
             {
-                /* write data */
+                /* The values will be stored in 'variableName'_val */
+                varName = strcat(varName, "_val");
                 switch (ut)
                 {
+                        // By default, nCols = 1, so should the input be a matrix, scalar or vector, perform the same operations
                     case SCSREAL_N    :
-                        if (ismat)
+                        ptr_d = (SCSREAL_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatDouble = (double *) scicos_malloc(nRows * nCols * nCols2 * sizeof(double))) == NULL)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtd, &ierr);
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
                         }
-                        else
+                        memcpy(MatDouble, ptr_d, nRows * nCols * nCols2 * sizeof(double));
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfDouble(NULL, varName, nRows * nCols2, nCols, MatDouble);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmtd, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatDouble);
                         break;
                     case SCSCOMPLEX_N :
-                        if (ismat)
+                        ptr_d = (SCSREAL_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if (((MatComplexReal = (double *) scicos_malloc(nRows * nCols * nCols2 * sizeof(double))) == NULL)
+                                || ((MatComplexImg = (double *) scicos_malloc(nRows * nCols * nCols2 * sizeof(double))) == NULL))
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = 2 * ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtd, &ierr);
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
                         }
-                        else
+                        memcpy(MatComplexReal, ptr_d, nRows * nCols * nCols2 * sizeof(double));
+                        memcpy(MatComplexImg, ptr_d + nRows * nCols * nCols2, nRows * nCols * nCols2 * sizeof(double));
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedComplexMatrixOfDouble(NULL, varName, nRows * nCols2, nCols, MatComplexReal, MatComplexImg);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = 2 * ptr_i[7] * ptr_i[8], &j), fmtd, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatComplexReal);
+                        scicos_free(MatComplexImg);
                         break;
                     case SCSINT8_N    :
-                        if (ismat)
+                        ptr_c = (SCSINT8_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatInt8 = (char *) scicos_malloc(nRows * nCols * nCols2 * sizeof(char))) == NULL)
+                        {
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
+                        }
+                        for (i = 0; i <  nRows * nCols * nCols2; ++i)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtc, &ierr);
+                            MatInt8[i] = (char) ptr_c[i];
                         }
-                        else
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfInteger8(NULL, varName, nRows * nCols2, nCols, MatInt8);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmtc, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatInt8);
                         break;
                     case SCSINT16_N   :
-                        if (ismat)
+                        ptr_s = (SCSINT16_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatInt16 = (short *) scicos_malloc(nRows * nCols * nCols2 * sizeof(short))) == NULL)
+                        {
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
+                        }
+                        for (i = 0; i <  nRows * nCols * nCols2; ++i)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmts, &ierr);
+                            MatInt16[i] = (short) ptr_s[i];
                         }
-                        else
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfInteger16(NULL, varName, nRows * nCols2, nCols, MatInt16);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmts, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatInt16);
                         break;
                     case SCSINT32_N   :
-                        if (ismat)
+                        ptr_l = (SCSINT32_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatInt32 = (int *) scicos_malloc(nRows * nCols * nCols2 * sizeof(int))) == NULL)
+                        {
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
+                        }
+                        for (i = 0; i <  nRows * nCols * nCols2; ++i)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtl, &ierr);
+                            MatInt32[i] = (int) ptr_l[i];
                         }
-                        else
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfInteger32(NULL, varName, nRows * nCols2, nCols, MatInt32);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmtl, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatInt32);
                         break;
                     case SCSUINT8_N   :
-                        if (ismat)
+                        ptr_uc = (SCSUINT8_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatUInt8 = (unsigned char *) scicos_malloc(nRows * nCols * nCols2 * sizeof(unsigned char))) == NULL)
+                        {
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
+                        }
+                        for (i = 0; i <  nRows * nCols * nCols2; ++i)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtuc, &ierr);
+                            MatUInt8[i] = (unsigned char) ptr_uc[i];
                         }
-                        else
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfUnsignedInteger8(NULL, varName, nRows * nCols2, nCols, MatUInt8);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmtuc, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatUInt8);
                         break;
                     case SCSUINT16_N  :
-                        if (ismat)
+                        ptr_us = (SCSUINT16_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatUInt16 = (unsigned short *) scicos_malloc(nRows * nCols * nCols2 * sizeof(unsigned short))) == NULL)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtus, &ierr);
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
                         }
-                        else
+                        for (i = 0; i <  nRows * nCols * nCols2; ++i)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmtus, &ierr);
+                            MatUInt16[i] = (unsigned short) ptr_us[i];
                         }
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfUnsignedInteger16(NULL, varName, nRows * nCols2, nCols, MatUInt16);
+                        if (sciErr.iErr)
+                        {
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
+                        }
+                        scicos_free(MatUInt16);
                         break;
                     case SCSUINT32_N  :
-                        if (ismat)
+                        ptr_ul = (SCSUINT32_COP *) ((ismat) ? &ptr_i[44] : &ptr_i[10]);
+                        if ((MatUInt32 = (unsigned int *) scicos_malloc(nRows * nCols * nCols2 * sizeof(unsigned int))) == NULL)
+                        {
+                            set_block_error(-16);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            return;
+                        }
+                        for (i = 0; i <  nRows * nCols * nCols2; ++i)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[44], (j = ptr_i[37] * ptr_i[38] * ptr_i[39], &j), fmtul, &ierr);
+                            MatUInt32[i] = (unsigned int) ptr_ul[i];
                         }
-                        else
+                        /* pass Matrix to Scilab */
+                        sciErr = createNamedMatrixOfUnsignedInteger32(NULL, varName, nRows * nCols2, nCols, MatUInt32);
+                        if (sciErr.iErr)
                         {
-                            C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7] * ptr_i[8], &j), fmtul, &ierr);
+                            scicos_free(ptr->workt);
+                            scicos_free(ptr);
+                            *(block->work) = NULL;
+                            printError(&sciErr, 0);
+                            return;
                         }
+                        scicos_free(MatUInt32);
                         break;
                     default  : /* Add a message here */
                         break;
                 }
-                if (ierr != 0)
-                {
-                    Coserror(_("Write error in file '%s'.\n"), str);
-                    scicos_free(ptr->workt);
-                    scicos_free(ptr);
-                    *(block->work) = NULL;
-                    /*set_block_error(-3);*/
-                    return;
-                }
             }
 
             /* write t */
             ptr_i = (int*) ptr->workt;
-            C2F(mputnc)(&fd, &ptr_i[0], (j = nsiz, &j), fmti, &ierr);
-            if (ierr != 0)
-            {
-                Coserror(_("Write error in file '%s'.\n"), str);
-                scicos_free(ptr->workt);
-                scicos_free(ptr);
-                *(block->work) = NULL;
-                /*set_block_error(-3);*/
-                return;
-            }
-            C2F(mputnc)(&fd, &ptr_i[6], (j = 1, &j), fmti, &ierr);
-            if (ierr != 0)
-            {
-                Coserror(_("Write error in file '%s'.\n"), str);
-                scicos_free(ptr->workt);
-                scicos_free(ptr);
-                *(block->work) = NULL;
-                /*set_block_error(-3);*/
-                return;
-            }
-            C2F(mputnc)(&fd, &ptr_i[7], (j = 3, &j), fmti, &ierr);
-            if (ierr != 0)
-            {
-                Coserror(_("Write error in file '%s'.\n"), str);
-                scicos_free(ptr->workt);
-                scicos_free(ptr);
-                *(block->work) = NULL;
-                /*set_block_error(-3);*/
-                return;
-            }
             if ((ptr->cnt != 0) || (ptr->loop != 0))
             {
-                C2F(mputnc)(&fd, &ptr_i[10], (j = ptr_i[7], &j), fmtd, &ierr);
-                if (ierr != 0)
+                ptr_d = (SCSREAL_COP *) &ptr_i[10];
+                /* The TIME values will be stored in 'variableName'_valt */
+                varName = strcat(varName, "t");
+                /* Using variable Time to hold time values */
+                if ((Time = (double *) scicos_malloc(nRows * sizeof(double))) == NULL)
+                {
+                    set_block_error(-16);
+                    scicos_free(ptr->workt);
+                    scicos_free(ptr);
+                    *(block->work) = NULL;
+                    return;
+                }
+                memcpy(Time, ptr_d, nRows * sizeof(double));
+                /* pass Matrix to Scilab */
+                sciErr = createNamedMatrixOfDouble(NULL, varName, nRows, 1, Time);
+                if (sciErr.iErr)
                 {
-                    Coserror(_("Write error in file '%s'.\n"), str);
                     scicos_free(ptr->workt);
                     scicos_free(ptr);
                     *(block->work) = NULL;
-                    /*set_block_error(-3);*/
+                    printError(&sciErr, 0);
                     return;
                 }
+                scicos_free(varName);
+                scicos_free(Time);
             }
 
-            /* close tmp file */
-            C2F(mclose)(&fd, &res);
-
             /* free */
             scicos_free(ptr->work);
             scicos_free(ptr->workt);
@@ -1677,7 +1716,7 @@ SCICOS_BLOCKS_IMPEXP void tows_c(scicos_block *block, int flag)
                     ptr_s = (SCSINT16_COP *) & (ptr_i[10]);
                     for (i = 0; i < nu; i++)
                     {
-                        ptr_s[ptr->cnt * nu + i * nz] = u_s[i];
+                        ptr_s[ptr->cnt + i * nz] = u_s[i];
                     }
                 }
                 break;
index 5d75fc7..082ead5 100644 (file)
@@ -1,5 +1,6 @@
 //
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) Scilab Enterprises - 2013 - Bruno JOFRET
 // Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
 //
 // This file must be used under the terms of the CeCILL.
@@ -36,13 +37,13 @@ function %cpr = xcos_simulate(scs_m, needcompile)
         end
         ok=%t;
 
-        // force update on the parent in case of scoped modification
+        // Force update on the parent in case of scoped modification
         scs_m=resume(scs_m);
     endfunction
 
     if isdef("pre_xcos_simulate") then
         if type(pre_xcos_simulate) == 15 then
-            // if has a multiple implementation (on a list)
+            // If has a multiple implementation (on a list)
             for f=pre_xcos_simulate;
                 ok=invoke_pre_simulate(f, scs_m, needcompile);
                 if ~ok then
@@ -51,7 +52,7 @@ function %cpr = xcos_simulate(scs_m, needcompile)
                 end
             end
         else
-            // if has a unique implementation
+            // If has a unique implementation
             ok=invoke_pre_simulate("pre_xcos_simulate", scs_m, needcompile);
             if ~ok then
                 %cpr=[];
@@ -102,7 +103,7 @@ function %cpr = xcos_simulate(scs_m, needcompile)
     //** context eval here
     [%scicos_context, ierr] = script2var(context, %scicos_context);
 
-    //for backward compatibility for scifunc
+    // For backward compatibility for scifunc
     if ierr==0 then
         %mm = getfield(1,%scicos_context)
         for %mi=%mm(3:$)
@@ -112,7 +113,7 @@ function %cpr = xcos_simulate(scs_m, needcompile)
             end
         end
     end
-    //end of for backward compatibility for scifuncpagate context values
+    // End of for backward compatibility for scifuncpagate context values
 
     [scs_m,%cpr,needcompile,ok] = do_eval(scs_m, %cpr, %scicos_context);
     if ~ok then
@@ -296,7 +297,7 @@ function %cpr = xcos_simulate(scs_m, needcompile)
     //** scicos simulation
     tf = scs_m.props.tf
 
-    // inform Xcos the simulator is going to run
+    // Inform Xcos the simulator is going to run
     xcosSimulationStarted();
 
     //** run scicosim via 'start' flag
@@ -361,17 +362,58 @@ function %cpr = xcos_simulate(scs_m, needcompile)
         ok = %f;
     end
 
-    //restore saved variables in Scilab environment ( "To workspace" block )
-    [txt,files]=returntoscilab()
-    n=size(files,1)
-    for i=1:n
-        load(TMPDIR+"/Workspace/"+files(i))
-        ierr = execstr(files(i)+"=struct('"values'",x,'"time'",t)", "errcatch")
-        if ierr <> 0
-            str_err = split_lasterror(lasterror());
-            message(["Simulation problem:";str_err]);
+    // Restore saved variables in Scilab environment ("To workspace" block)
+
+    // First step: Search the %cpr tree for TOWS_c blocks, and extract the variable names.
+    path = %cpr.sim;
+    Names = [];
+    buff_sizes = [];
+    increment = 1;
+    for i=1:size(path.funs)
+        increment2 = path.ipptr(i+1);
+        if (increment2 - increment <> 0) then   // ipar has at least a few elements
+            space = increment2 - increment;     // The number of elements that the current block pushed into ipar
+            if (path.funs(i) == "tows_c") then  // Found a Tow_workspace block
+                varNameLen = space - 2;         // Space minus 'buffer_size' and 'var length' ipar elements
+                varNameCode = path.ipar(increment+2:increment+2+varNameLen-1);  // varName is stored in Scilab code
+                varName = ascii(varNameCode);
+                Names = [Names varName];        // Append varName in Names
+                buff_size  = path.ipar(increment);  // Retrieve buffer size
+                buff_sizes = [buff_sizes buff_size];
+            end
+            increment = increment2;
         end
-
+    end
+    // At the end, Names contains the string names of the variables and buff_sizes the respective buffer sizes
+
+    // Second step: Link the variable names to their values vectors,
+    //and call '[names(1), names(2), ...] = resume(names(1), names(2), ...)' to save the variable into Scilab
+    if ~isempty(Names) then
+        for i=1:size(Names, "c")
+            execstr("NamesIval = "+Names(i)+"_val;");
+            execstr("NamesIvalt = "+Names(i)+"_valt;");
+            // If input is a matrix, use function matrix() to reshape the saved values
+            // Check condition using time vector, if we have more values than time stamps, split it
+            if (size(NamesIval, "r") > size(NamesIvalt, "r")) then
+                nRows =  size(NamesIvalt, "r");
+                nCols  = size(NamesIval, "c");
+                nCols2 = size(NamesIval, "r") / nRows;
+                NamesIval = matrix(NamesIval, nCols, nCols2, nRows);
+            end
+            ierr = execstr(Names(i)+" = struct(''values'', NamesIval,''time'',NamesIvalt)", "errcatch");
+            if ierr <> 0 then
+                str_err = split_lasterror(lasterror());
+                message(["Simulation problem" ; "Unable to resume To Workspace Variable {"+Names(i)+"}:" ; str_err]);
+                break;
+            end
+            if i == 1 then
+                Resume_line_args = Names(1);
+            else
+                Resume_line_args   = Resume_line_args + ", " + Names(i);  // Concatenate the variable names up to the last one
+            end
+        end
+        Resume_line = "[" + Resume_line_args + "] = resume(" + Resume_line_args + ");";  // Build the message
+        // Will execute Resume_line at the end of the function, to run the following Hook instructions
     end
 
     // Hook according to SEP066
@@ -383,13 +425,13 @@ function %cpr = xcos_simulate(scs_m, needcompile)
             return
         end
         ok=%t
-        // force update on the parent in case of scoped modification
+        // Force update on the parent in case of scoped modification
         scs_m=resume(scs_m);
     endfunction
 
     if isdef("post_xcos_simulate") then
         if type(post_xcos_simulate) == 15 then
-            // if has a multiple implementation (on a list)
+            // If has a multiple implementation (on a list)
             for f=post_xcos_simulate;
                 ok=invoke_post_simulate(f, %cpr, scs_m, needcompile);
                 if ~ok then
@@ -398,7 +440,7 @@ function %cpr = xcos_simulate(scs_m, needcompile)
                 end
             end
         else
-            // if has a unique implementation
+            // If has a unique implementation
             ok=invoke_post_simulate("post_xcos_simulate", %cpr, scs_m, needcompile);
             if ~ok then
                 %cpr=[];
@@ -407,13 +449,10 @@ function %cpr = xcos_simulate(scs_m, needcompile)
         end
     end
 
-    // finally restore the exported variables on the parent context
-    if ~isempty(txt) then
-        ierr = execstr(txt, "errcatch")
-        if ierr <> 0 then
-            str_err = split_lasterror(lasterror());
-            message(["Simulation problem while executing <"+txt+">:";str_err]);
-        end
+    // Executing the resume() function at the end, because it does not return control
+    if ~isempty(Names) then
+        execstr(Resume_line);
     end
+
 endfunction
 
index d063cbf..1ecd496 100644 (file)
@@ -1,14 +1,91 @@
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2012 - Scilab Enterprises - Clément DAVID
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
+// <-- ENGLISH IMPOSED -->
 // <-- XCOS TEST -->
-assert_checktrue(importXcosDiagram(SCI + "/modules/xcos/tests/unit_tests/tows_c.zcos"));
-scicos_simulate(scs_m, list());
-t = (0.2:0.1:12.9)';
-A_ref = struct('values', sin(t), 'time', t);
-assert_checkequal(fieldnames(A), fieldnames(A_ref));
-assert_checkalmostequal(A.time, A_ref.time);
-assert_checkalmostequal(A.values, A_ref.values);
+// Import diagram
+assert_checktrue(importXcosDiagram("SCI/modules/xcos/tests/unit_tests/tows_c.xcos"));
+Info = scicos_simulate(scs_m, 'nw');
+// Reference values
+t = (2.2 : 0.1 : 14.9)';
+A_ref = struct('values', sin(t), 'time', t); // A_ref = (sin(t), t)
+imgM_ref = [1+2*%i 3+4*%i ; 1 2]; // imgM_ref is an element of hypermatrix imgM
+imgV_ref = ones(128, 2);
+imgV_ref = (1+%i)*imgV_ref;
+imgV_ref(:, 2) = 2*imgV_ref(:, 2); // imgV_ref = [1+%i 2+%i] with 128 rows
+intM1_ref = int32([1 2 ; 3 4]);    // intM1_ref is an element of hypermatrix intM1
+intV_ref = int32(ones(128, 2));
+intV_ref = 5*intV_ref;
+intV_ref(:, 2) = intV_ref(:, 2) + 1;     // intV_ref = [5, 6] with 128 rows
+shortV_ref = int16(ones(128, 2));
+shortV_ref = 7*shortV_ref;
+shortV_ref(:, 2) = shortV_ref(:, 2) + 1; // shortV_ref = [7, 8] with 128 rows
+charV_ref = int8(ones(128, 2));
+charV_ref = 9*charV_ref;
+charV_ref(:, 2) = charV_ref(:, 2) + 1;   // charV_ref = [9, 10] with 128 rows
+intM2_ref = int32([11 12 ; 13 14]); // intM2_ref is an element of hypermatrix intM2
+shortM_ref = int16([15 16; 17 18]); // shortM_ref is an element of hypermatrix shortM
+charM_ref = int8([19 20 ; 21 22]);  // charM_ref is an element of hypermatrix charM
+// Run simulation with scicos_simulate() + check results
+try scicos_simulate(scs_m, Info); catch disp(lasterror()); end  // Run simulation
+assert_checkequal(fieldnames(A), fieldnames(A_ref)); // Check A fields
+assert_checkalmostequal(A.values, A_ref.values);     // Check A values
+assert_checkalmostequal(A.time, A_ref.time);         // Check A time values
+assert_checkequal(fieldnames(B), fieldnames(A_ref)); // Check B fields
+assert_checkalmostequal(B.values, A_ref.values);     // Check B values
+assert_checkequal(fieldnames(C), fieldnames(A_ref)); // Check C fields
+assert_checkalmostequal(C.values, A_ref.values);     // Check C values
+assert_checktrue(imgV.values   == imgV_ref);    // Check that imgV contains a complex vector
+assert_checktrue(intV.values   == intV_ref);    // Check that intV contains an int32 vector
+assert_checktrue(shortV.values == shortV_ref);  // Check that shortV contains an int16 vector
+assert_checktrue(charV.values  == charV_ref);   // Check that charV contains an int8 vector
+for i = 1:128
+    // Check that the following are hypermatrices with correct values
+    assert_checktrue(and(imgM.values(:, :, i)   == imgM_ref));
+    assert_checktrue(and(intM1.values(:, :, i)  == intM1_ref));
+    assert_checktrue(and(intM2.values(:, :, i)  == intM2_ref));
+    assert_checktrue(and(shortM.values(:, :, i) == shortM_ref));
+    assert_checktrue(and(charM.values(:, :, i)  == charM_ref));
+end
+// Run simulation with xcos_simulate() + check results
+try xcos_simulate(scs_m, 4); catch disp(lasterror()); end  // Run simulation
+assert_checkequal(fieldnames(A), fieldnames(A_ref)); // Check A fields
+assert_checkalmostequal(A.values, A_ref.values);     // Check A values
+assert_checkalmostequal(A.time, A_ref.time);         // Check A time values
+assert_checkequal(fieldnames(B), fieldnames(A_ref)); // Check B fields
+assert_checkalmostequal(B.values, A_ref.values);     // Check B values
+assert_checkequal(fieldnames(C), fieldnames(A_ref)); // Check C fields
+assert_checkalmostequal(C.values, A_ref.values);     // Check C values
+assert_checktrue(imgV.values   == imgV_ref);    // Check that imgV contains a complex vector
+assert_checktrue(intV.values   == intV_ref);    // Check that intV contains an int32 vector
+assert_checktrue(shortV.values == shortV_ref);  // Check that shortV contains an int16 vector
+assert_checktrue(charV.values  == charV_ref);   // Check that charV contains an int8 vector
+for i = 1:128
+    // Check that the following are hypermatrices with correct values
+    assert_checktrue(and(imgM.values(:, :, i)   == imgM_ref));
+    assert_checktrue(and(intM1.values(:, :, i)  == intM1_ref));
+    assert_checktrue(and(intM2.values(:, :, i)  == intM2_ref));
+    assert_checktrue(and(shortM.values(:, :, i) == shortM_ref));
+    assert_checktrue(and(charM.values(:, :, i)  == charM_ref));
+end
+// Type checks
+assert_checkequal(type(A.values), 1);              // A takes real numbers
+assert_checkequal(type(imgV.values(1)), 1);       // imgV takes complex numbers
+assert_checkequal(type(imgM.values(:, :, 1)), 1); // imgM takes complex numbers
+assert_checkequal(type(intM1.values(1)), 8);
+assert_checkequal(type(intV.values(1)), 8);
+assert_checkequal(type(shortV.values(1)), 8);
+assert_checkequal(type(charV.values(1)), 8);
+assert_checkequal(type(intM2.values(1)), 8);
+assert_checkequal(type(shortM.values(1)), 8);
+assert_checkequal(type(charM.values(1)), 8);
+assert_checkequal(inttype(intM1.values(1)), 4);  // intM1 takes 4-octets coded integers
+assert_checkequal(inttype(intV.values(1)), 4);   // intV takes 4-octets coded integers
+assert_checkequal(inttype(shortV.values(1)), 2); // shortV takes 2-octets coded integers
+assert_checkequal(inttype(charV.values(1)), 1);  // charV takes 1-octets coded integers
+assert_checkequal(inttype(intM2.values(1)), 4);
+assert_checkequal(inttype(shortM.values(1)), 2);
+assert_checkequal(inttype(charM.values(1)), 1);
index d58e0d3..9f18dd6 100644 (file)
@@ -1,19 +1,99 @@
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2012 - Scilab Enterprises - Clément DAVID
+// Copyright (C) 2013 - Scilab Enterprises - Clément DAVID
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
 
+// <-- ENGLISH IMPOSED -->
 // <-- XCOS TEST -->
 
+// Import diagram
+assert_checktrue(importXcosDiagram("SCI/modules/xcos/tests/unit_tests/tows_c.xcos"));
+Info = scicos_simulate(scs_m, 'nw');
 
-assert_checktrue(importXcosDiagram(SCI + "/modules/xcos/tests/unit_tests/tows_c.zcos"));
-scicos_simulate(scs_m, list());
+// Reference values
+t = (2.2 : 0.1 : 14.9)';
+A_ref = struct('values', sin(t), 'time', t); // A_ref = (sin(t), t)
+imgM_ref = [1+2*%i 3+4*%i ; 1 2]; // imgM_ref is an element of hypermatrix imgM
+imgV_ref = ones(128, 2);
+imgV_ref = (1+%i)*imgV_ref;
+imgV_ref(:, 2) = 2*imgV_ref(:, 2); // imgV_ref = [1+%i 2+%i] with 128 rows
+intM1_ref = int32([1 2 ; 3 4]);    // intM1_ref is an element of hypermatrix intM1
+intV_ref = int32(ones(128, 2));
+intV_ref = 5*intV_ref;
+intV_ref(:, 2) = intV_ref(:, 2) + 1;     // intV_ref = [5, 6] with 128 rows
+shortV_ref = int16(ones(128, 2));
+shortV_ref = 7*shortV_ref;
+shortV_ref(:, 2) = shortV_ref(:, 2) + 1; // shortV_ref = [7, 8] with 128 rows
+charV_ref = int8(ones(128, 2));
+charV_ref = 9*charV_ref;
+charV_ref(:, 2) = charV_ref(:, 2) + 1;   // charV_ref = [9, 10] with 128 rows
+intM2_ref = int32([11 12 ; 13 14]); // intM2_ref is an element of hypermatrix intM2
+shortM_ref = int16([15 16; 17 18]); // shortM_ref is an element of hypermatrix shortM
+charM_ref = int8([19 20 ; 21 22]);  // charM_ref is an element of hypermatrix charM
 
-t = (0.2:0.1:12.9)';
-A_ref = struct('values', sin(t), 'time', t);
+// Run simulation with scicos_simulate() + check results
+try scicos_simulate(scs_m, Info); catch disp(lasterror()); end  // Run simulation
+assert_checkequal(fieldnames(A), fieldnames(A_ref)); // Check A fields
+assert_checkalmostequal(A.values, A_ref.values);     // Check A values
+assert_checkalmostequal(A.time, A_ref.time);         // Check A time values
+assert_checkequal(fieldnames(B), fieldnames(A_ref)); // Check B fields
+assert_checkalmostequal(B.values, A_ref.values);     // Check B values
+assert_checkequal(fieldnames(C), fieldnames(A_ref)); // Check C fields
+assert_checkalmostequal(C.values, A_ref.values);     // Check C values
 
-assert_checkequal(fieldnames(A), fieldnames(A_ref));
-assert_checkalmostequal(A.time, A_ref.time);
-assert_checkalmostequal(A.values, A_ref.values);
+assert_checktrue(imgV.values   == imgV_ref);    // Check that imgV contains a complex vector
+assert_checktrue(intV.values   == intV_ref);    // Check that intV contains an int32 vector
+assert_checktrue(shortV.values == shortV_ref);  // Check that shortV contains an int16 vector
+assert_checktrue(charV.values  == charV_ref);   // Check that charV contains an int8 vector
+for i = 1:128
+    // Check that the following are hypermatrices with correct values
+    assert_checktrue(and(imgM.values(:, :, i)   == imgM_ref));
+    assert_checktrue(and(intM1.values(:, :, i)  == intM1_ref));
+    assert_checktrue(and(intM2.values(:, :, i)  == intM2_ref));
+    assert_checktrue(and(shortM.values(:, :, i) == shortM_ref));
+    assert_checktrue(and(charM.values(:, :, i)  == charM_ref));
+end
+
+// Run simulation with xcos_simulate() + check results
+try xcos_simulate(scs_m, 4); catch disp(lasterror()); end  // Run simulation
+assert_checkequal(fieldnames(A), fieldnames(A_ref)); // Check A fields
+assert_checkalmostequal(A.values, A_ref.values);     // Check A values
+assert_checkalmostequal(A.time, A_ref.time);         // Check A time values
+assert_checkequal(fieldnames(B), fieldnames(A_ref)); // Check B fields
+assert_checkalmostequal(B.values, A_ref.values);     // Check B values
+assert_checkequal(fieldnames(C), fieldnames(A_ref)); // Check C fields
+assert_checkalmostequal(C.values, A_ref.values);     // Check C values
+
+assert_checktrue(imgV.values   == imgV_ref);    // Check that imgV contains a complex vector
+assert_checktrue(intV.values   == intV_ref);    // Check that intV contains an int32 vector
+assert_checktrue(shortV.values == shortV_ref);  // Check that shortV contains an int16 vector
+assert_checktrue(charV.values  == charV_ref);   // Check that charV contains an int8 vector
+for i = 1:128
+    // Check that the following are hypermatrices with correct values
+    assert_checktrue(and(imgM.values(:, :, i)   == imgM_ref));
+    assert_checktrue(and(intM1.values(:, :, i)  == intM1_ref));
+    assert_checktrue(and(intM2.values(:, :, i)  == intM2_ref));
+    assert_checktrue(and(shortM.values(:, :, i) == shortM_ref));
+    assert_checktrue(and(charM.values(:, :, i)  == charM_ref));
+end
+
+// Type checks
+assert_checkequal(type(A.values), 1);              // A takes real numbers
+assert_checkequal(type(imgV.values(1)), 1);       // imgV takes complex numbers
+assert_checkequal(type(imgM.values(:, :, 1)), 1); // imgM takes complex numbers
+assert_checkequal(type(intM1.values(1)), 8);
+assert_checkequal(type(intV.values(1)), 8);
+assert_checkequal(type(shortV.values(1)), 8);
+assert_checkequal(type(charV.values(1)), 8);
+assert_checkequal(type(intM2.values(1)), 8);
+assert_checkequal(type(shortM.values(1)), 8);
+assert_checkequal(type(charM.values(1)), 8);
+assert_checkequal(inttype(intM1.values(1)), 4);  // intM1 takes 4-octets coded integers
+assert_checkequal(inttype(intV.values(1)), 4);   // intV takes 4-octets coded integers
+assert_checkequal(inttype(shortV.values(1)), 2); // shortV takes 2-octets coded integers
+assert_checkequal(inttype(charV.values(1)), 1);  // charV takes 1-octets coded integers
+assert_checkequal(inttype(intM2.values(1)), 4);
+assert_checkequal(inttype(shortM.values(1)), 2);
+assert_checkequal(inttype(charM.values(1)), 1);
diff --git a/scilab/modules/xcos/tests/unit_tests/tows_c.xcos b/scilab/modules/xcos/tests/unit_tests/tows_c.xcos
new file mode 100644 (file)
index 0000000..008f6b5
Binary files /dev/null and b/scilab/modules/xcos/tests/unit_tests/tows_c.xcos differ