2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - Paul Bignier
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
19 #include "gw_scicos.hxx"
20 #include "internal.hxx"
26 #include "function.hxx"
31 #include "scicos-def.h"
32 #include "charEncoding.h"
34 #include "localization.h"
37 /*--------------------------------------------------------------------------*/
38 // Variable defined in sci_scicosim.cpp
39 extern COSIM_struct C2F(cosim);
40 /*--------------------------------------------------------------------------*/
43 #include "il_state.hxx"
45 #include "createblklist.hxx"
47 /*--------------------------------------------------------------------------*/
48 /* getscicosvars interface routine retrieves some information during simulation.
50 * [myvar]=getscicosvars(str)
52 * rhs 1 : str : a character string matrix with choice,
53 * - 'x' to retrieve continuous state
54 * - 'xptr' to retrieve ptr of continuous state
55 * - 'z' to retrieve discrete state
56 * - 'zptr' to retrieve ptr of discrete state
57 * - 'rpar' to retrieve real parameters
58 * - 'rpptr' to retrieve ptr of real parameters
59 * - 'ipar' to retrieve int parameters
60 * - 'ipptr' to retrieve ptr of int parameters
61 * - 'outtb' to retrieve output register (list of scilb object)
62 * - 'inpptr' to retrieve number of input ports
63 * - 'outptr' to retrieve number of output ports
64 * - 'inplnk' to retrieve link number of input ports
65 * - 'outlnk' to retrieve link number of output ports
68 * lhs 1 : myvar : matrix of int32 or double, or list or a Tlist
70 * 31/05/06, Alan : Rewritten from original fortran
71 * source code intgetscicosvars in coselm.f.
73 * 22/06/06, Alan : Allow multiple string in rhs(1).
74 * Create Tlist for Lhs(1).
76 * 23/06/06, Alan : Create blocks list for Lhs(1).
78 * 13/11/06, Alan : Remove il_sim_save global variable (all in sim
79 * come from import struct now)
80 * evtspt & pointi of state come from import struct
82 * 09/02/07, Alan : Update with oz/opar and restore il_sim_save only for opar
84 * 08/12/14, Paul : Rewrote to C++.
87 /*--------------------------------------------------------------------------*/
89 static const std::string funname = "getscicosvars";
91 types::Function::ReturnValue sci_getscicosvars(types::typed_list &in, int _iRetCount, types::typed_list &out)
95 Scierror(77, _("%s: Wrong number of input argument(s): %d or %d expected.\n"), funname.data(), 0, 1);
96 return types::Function::Error;
101 Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), funname.data(), 1);
102 return types::Function::Error;
105 int isrun = C2F(cosim).isrun;
108 Scierror(999, _("%s: scicosim is not running.\n"), funname.data());
109 return types::Function::Error;
113 // Define accepted entries of getscicosvars -please update me-
114 const std::vector<const char*> entry
116 "x" , "nx" , "xptr" , "zcptr" , "z" ,
117 "nz" , "zptr" , "noz" , "oz" , "ozsz" ,
118 "oztyp" , "ozptr" , "rpar" , "rpptr" , "ipar" ,
119 "ipptr" , "opar" , "oparsz" , "opartyp" , "opptr" ,
120 "outtb" , "inpptr" , "outptr" , "inplnk" , "outlnk" ,
121 "subs" , "tevts" , "evtspt" , "pointi" , "iord" ,
122 "oord" , "zord" , "funtyp" , "ztyp" , "cord" ,
123 "ordclk" , "clkptr" , "ordptr" , "critev" , "mod" ,
124 "nmod" , "iz" , "nblk" , "izptr" , "outtbptr" ,
125 "outtbsz" , "outtbtyp" , "nlnk" , "nsubs" , "nevts" ,
126 "niord" , "noord" , "nzord" , "funptr" , "ncord" ,
127 "nordptr" , "iwa" , "blocks" , "ng" , "g" ,
128 "t0" , "tf" , "Atol" , "rtol" , "ttol" ,
129 "deltat" , "hmax" , "nelem" , "outtb_elem"
132 const size_t nentries = entry.size();
134 // Display usage of getscicosvars function if in.size()==0
137 sciprint(_("\ngetscicosvars: utility function to retrieve\n"));
138 sciprint(_(" scicos arrays during simulation.\n\n"));
139 sciprint(_("Usage: [myvar]=getscicosvars([\"str1\";\"str2\";...]);\n\n"));
140 sciprint(_("- myvar: an int32 or double matrix or a Tlist.\n"));
141 sciprint(_("- [\"str1\";\"str2\",...] is a string matrix\n"));
142 sciprint(_(" that must be informed with the following values:\n"));
144 // Display allowed entries
146 for (size_t j = 0; j < nentries; ++j)
148 if (j == nentries - 1)
150 sciprint("\"%s\" ", entry[j]);
154 sciprint("\"%s\", ", entry[j]);
164 return types::Function::OK;
170 if (!in[0]->isString())
172 Scierror(999, _("%s: Wrong type for input argument #%d: A string matrix expected.\n"), funname.data(), 1);
173 return types::Function::Error;
175 types::String* il_str = in[0]->getAs<types::String>();
177 // Retrieve dimension of input string matrix
178 const int m1 = il_str->getRows();
179 const int n1 = il_str->getCols();
181 // Create header of TList
182 types::String* dyn_char = new types::String(1 + m1 * n1, 1);
184 // Type of list is scicosvar
185 const std::string scicosvar("scicosvar");
186 dyn_char->set(0, "scicosvar");
188 // Check string matrix
189 for (int j = 0; j < m1 * n1; ++j)
192 for (size_t i = 0; i < nentries; ++i)
194 char* field = wide_string_to_UTF8(il_str->get(j));
195 if (strcmp(field, entry[i]) == 0)
197 dyn_char->set(j + 1, entry[i]);
206 // If failed then display an error message and exit
209 Scierror(999, _("%s: Undefined field in string matrix position: %d.\n"), funname.data(), j + 1);
211 return types::Function::Error;
215 // Preparing the return
216 types::TList* ret = new types::TList();
217 ret->append(dyn_char); // Header for the returned tlist
219 types::InternalType* element; // Declare 'element' out of the loop to be able to return it alone in case il_str->getSize()==1
220 for (int j = 0; j < m1 * n1; j++)
222 char* field = wide_string_to_UTF8(il_str->get(j));
224 /*****************************************************************
225 * Entries that can be retrieved by 'il_state_save' global variable
226 *****************************************************************/
227 if (strcmp(field, "x") == 0) /* Retrieve continuous state */
229 types::TList* il_state = get_il_state()->getAs<types::TList>();
230 if (il_state->getSize() < 2)
236 element = il_state->get(1);
240 else if (strcmp(field, "z") == 0) /* Retrieve discrete state */
242 types::TList* il_state = get_il_state()->getAs<types::TList>();
243 if (il_state->getSize() < 3)
249 element = il_state->get(2);
253 else if (strcmp(field, "oz") == 0) /* Retrieve object discrete state */
255 types::TList* il_state = get_il_state()->getAs<types::TList>();
256 if (il_state->getSize() < 4)
262 element = il_state->get(3);
266 else if (strcmp(field, "outtb") == 0) /* Retrieve outtb */
268 types::TList* il_state = get_il_state()->getAs<types::TList>();
269 if (il_state->getSize() < 9)
275 element = il_state->get(8);
279 else if (strcmp(field, "tevts") == 0) /* Retrieve tevts */
281 types::TList* il_state = get_il_state()->getAs<types::TList>();
282 if (il_state->getSize() < 6)
288 element = il_state->get(5);
293 /*****************************************************************
294 * Entries that can be retrieved by 'il_sim_save' global variable
295 *****************************************************************/
296 if (strcmp(field, "opar") == 0) /* retrieve object parameters */
298 types::TList* il_sim = get_il_sim()->getAs<types::TList>();
299 if (il_sim->getSize() < 15)
305 element = il_sim->get(14);
310 /*************************************************
311 * int variables coming from import structure
312 *************************************************/
313 else if ((strcmp(field, "mod") == 0) || /* retrieve mode */
314 (strcmp(field, "nmod") == 0) || /* retrieve nmode */
315 (strcmp(field, "iz") == 0) || /* label int code of blocks */
316 (strcmp(field, "nblk") == 0) || /* number of block */
317 (strcmp(field, "izptr") == 0) || /* label int code of blocks ptr*/
318 (strcmp(field, "outtbptr") == 0) || /* outtb ptr */
319 (strcmp(field, "outtbsz") == 0) || /* outtb size */
320 (strcmp(field, "outtbtyp") == 0) || /* outtb type */
321 (strcmp(field, "nlnk") == 0) || /* number of link */
322 (strcmp(field, "nsubs") == 0) || /* length of nsubs */
323 (strcmp(field, "nevts") == 0) || /* length of evtspt & tevts */
324 (strcmp(field, "niord") == 0) || /* length of iord */
325 (strcmp(field, "noord") == 0) || /* length of oord */
326 (strcmp(field, "nzord") == 0) || /* length of zord */
327 (strcmp(field, "funptr") == 0) || /* retrieve function ptr */
328 (strcmp(field, "ncord") == 0) || /* retrieve ncord */
329 (strcmp(field, "nordptr") == 0) || /* retrieve nordptr */
330 (strcmp(field, "iwa") == 0) || /* retrieve iwa */
331 (strcmp(field, "ng") == 0) || /* retrieve ng */
332 (strcmp(field, "nx") == 0) || /* retrieve nx */
333 (strcmp(field, "nz") == 0) || /* retrieve nz */
334 (strcmp(field, "noz") == 0) || /* retrieve noz */
335 (strcmp(field, "ozptr") == 0) || /* retrieve ozptr */
336 (strcmp(field, "ozsz") == 0) || /* retrieve ozsz */
337 (strcmp(field, "oztyp") == 0) || /* retrieve oztyp */
338 (strcmp(field, "nelem") == 0) || /* retrieve nelem */
339 (strcmp(field, "xptr") == 0) || /* retrieve xptr */
340 (strcmp(field, "zcptr") == 0) || /* retrieve zcptr */
341 (strcmp(field, "zptr") == 0) || /* retrieve zptr */
342 (strcmp(field, "rpptr") == 0) || /* retrieve rpptr */
343 (strcmp(field, "ipar") == 0) || /* retrieve ipar */
344 (strcmp(field, "ipptr") == 0) || /* retrieve ipptr */
345 (strcmp(field, "opptr") == 0) || /* retrieve opptr */
346 (strcmp(field, "oparsz") == 0) || /* retrieve oparsz */
347 (strcmp(field, "opartyp") == 0) || /* retrieve opartyp */
348 (strcmp(field, "inpptr") == 0) || /* retrieve inpptr */
349 (strcmp(field, "outptr") == 0) || /* retrieve outptr */
350 (strcmp(field, "inplnk") == 0) || /* retrieve inplnk */
351 (strcmp(field, "outlnk") == 0) || /* retrieve outlnk */
352 (strcmp(field, "subs") == 0) || /* retrieve subs */
353 (strcmp(field, "iord") == 0) || /* retrieve iord */
354 (strcmp(field, "oord") == 0) || /* retrieve iord */
355 (strcmp(field, "zord") == 0) || /* retrieve iord */
356 (strcmp(field, "funtyp") == 0) || /* retrieve funtyp */
357 (strcmp(field, "ztyp") == 0) || /* retrieve ztyp */
358 (strcmp(field, "cord") == 0) || /* retrieve cord */
359 (strcmp(field, "ordclk") == 0) || /* retrieve ordclk */
360 (strcmp(field, "clkcpr") == 0) || /* retrieve clkcpr */
361 (strcmp(field, "ordptr") == 0) || /* retrieve ordptr */
362 (strcmp(field, "critev") == 0) || /* retrieve critev */
364 (strcmp(field, "evtspt") == 0) || /* retrieve evtspt */
365 (strcmp(field, "pointi") == 0) /* retrieve nelem */
368 /* Retrieve dims and 'ptr' of asked array with getscicosvarsfromimport() */
371 ok = getscicosvarsfromimport(field, &ptr, &nv, &mv) != 0;
376 element = new types::Int32(nv, mv, &data);
377 data = static_cast<int*>(ptr);
381 /*************************************************
382 * double variables coming from import structure
383 *************************************************/
384 else if ((strcmp(field, "rpar") == 0) || /* retrieve rpar */
385 (strcmp(field, "g") == 0) || /* retrieve g */
386 (strcmp(field, "t0") == 0) || /* retrieve t0 */
387 (strcmp(field, "tf") == 0) || /* retrieve tf */
388 (strcmp(field, "Atol") == 0) || /* retrieve Atol */
389 (strcmp(field, "rtol") == 0) || /* retrieve rtol */
390 (strcmp(field, "ttol") == 0) || /* retrieve ttol */
391 (strcmp(field, "deltat") == 0) || /* retrieve deltat */
392 (strcmp(field, "hmax") == 0) /* retrieve hmax */
395 /* Retrieve dims and 'ptr' of asked array with getscicosvarsfromimport() */
398 ok = getscicosvarsfromimport(field, &ptr, &nv, &mv) != 0;
403 element = new types::Double(nv, mv, &data);
404 data = static_cast<double*>(ptr);
408 /*************************************************
409 * scicos_block ptr coming from import structure
410 *************************************************/
411 else if (strcmp(field, "blocks") == 0)
413 /* Retrieve scicos_block 'ptr' of asked array with getscicosvarsfromimport() */
416 ok = getscicosvarsfromimport(field, &ptr, &nv, &mv) != 0;
420 /* Store ptr in ptrscs_blk */
421 scicos_block* ptr_scsblk = static_cast<scicos_block*>(ptr);
423 /* Retrieve 'nblk' by import structure */
424 strcpy(field, "nblk");
425 getscicosvarsfromimport(field, &ptr, &nv, &mv);
426 int nblk = ((int*)ptr)[0];
428 /* Retrieve 'ng' by import structure */
430 getscicosvarsfromimport(field, &ptr, &nv, &mv);
431 //int ng = ((int*)ptr)[0];
433 /* Retrieve 'xptr' by import structure */
434 strcpy(field, "xptr");
435 getscicosvarsfromimport(field, &ptr, &nv, &mv);
436 int* xptr = ((int*)ptr);
438 /* Retrieve 'zcptr' by import structure */
439 strcpy(field, "zcptr");
440 getscicosvarsfromimport(field, &ptr, &nv, &mv);
441 int* zcptr = ((int*)ptr);
443 /* Retrieve 'x' and 'xd' by import structure */
445 getscicosvarsfromimport(field, &ptr, &nv, &mv);
446 double* x = ((double*)ptr);
447 //double* xd = &x[xptr[nblk] - 1];
449 /* Retrieve 'g' by import structure */
451 getscicosvarsfromimport(field, &ptr, &nv, &mv);
452 double* g = ((double*)ptr);
454 /* Retrieve 'funtyp' by import structure */
455 strcpy(field, "funtyp");
456 getscicosvarsfromimport(field, &ptr, &nv, &mv);
457 //int* funtyp = ((int*)ptr);
459 for (int k = 0; k < nblk; ++k)
461 /* For each block, call createblklist() */
463 /* Set 'flag_imp' <0 for createblklst() */
466 /* The following test is done in order to know if block k
467 * have been already called with callf in scicos.c
469 if (ptr_scsblk[k].nx != 0)
471 if (ptr_scsblk[k].x != &x[xptr[k] - 1])
473 /*fprintf(stderr,"k=%d,X,xd Non initialise",k);*/
474 /* Set 'flag_imp'=k for createblklst() <0 */
478 if (ptr_scsblk[k].ng != 0)
480 if ((ptr_scsblk[k].g != &g[zcptr[k] - 1]) && (ptr_scsblk[k].g != &x[xptr[k] - 1]))
482 /*fprintf(stderr,"k=%d,g Non initialise",k);*/
483 /* Set 'flag_imp'=k for createblklst() <0 */
487 /* Call createblklist() */
488 element = createblklist(&ptr_scsblk[k], i, k + 1);
493 /*******************************************
494 * outtb_elem coming from import structure
495 *******************************************/
496 else if ((strcmp(field, "outtb_elem") == 0)) /* retrieve outtb_elem */
498 /* Retrieve dims and 'ptr' of asked array with getscicosvarsfromimport */
501 ok = getscicosvarsfromimport(field, &ptr, &nv, &mv) != 0;
503 /* Check 'ok' flag */
507 element = new types::Int32(nv, mv, &data);
508 outtb_el* ptr_elem = static_cast<outtb_el*>(ptr);
509 for (int i = 0; i < nv; ++i) /* Copy returned array in 'element' */
511 data[i] = ptr_elem[i].lnk + 1; /* +1 is for the connection with outtb list */
512 data[nv + i] = ptr_elem[i].pos + 1;
517 // If failed then display an error message.
520 Scierror(999, _("%s: Error with parameter \"%s\".\n"), funname.data(), il_str->get(j));
524 return types::Function::Error;
528 ret->append(element);
531 if (il_str->getSize() == 1)
533 out.push_back(element);
541 return types::Function::OK;