fix Windows compilation after scicos commits
[scilab.git] / scilab / modules / scicos / sci_gateway / cpp / sci_model2blk.cpp
1 /*  Scicos
2 *
3 *  Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
4 *  Copyright (C) INRIA -
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * See the file ./license.txt
21 */
22 /*--------------------------------------------------------------------------*/
23 #include <string>
24 #include <cwchar>
25 #include <cstring>
26
27 #include "gw_scicos.hxx"
28
29 #include "internal.hxx"
30 #include "function.hxx"
31 #include "string.hxx"
32 #include "double.hxx"
33 #include "int.hxx"
34 #include "list.hxx"
35 #include "mlist.hxx"
36 #include "context.hxx"
37 #include "configvariable.hxx"
38
39 extern "C"
40 {
41 #include "machine.h" /* F2C */
42 #include "sci_malloc.h"
43 #include "sciblk4.h"
44 #include "sciblk2.h"
45 #include "MlistGetFieldNumber.h"
46 #include "scicos.h"
47 #include "charEncoding.h"
48 #include "Scierror.h"
49 #include "localization.h"
50
51     extern void F2C(sciblk)();
52 }
53
54 #include "createblklist.hxx"
55
56 /*--------------------------------------------------------------------------*/
57 //extern int *listentry(int *header, int i);
58 //extern int C2F(funnum) (char *fname);
59 //extern int C2F(namstr)();
60 /*--------------------------------------------------------------------------*/
61 //extern int ntabsim;
62 //extern OpTab tabsim[];
63 /*--------------------------------------------------------------------------*/
64 /* model2blk Build a scicos_block structure from
65 * a scicos model
66 *
67 * [Block] = model2blk(objs.model)
68 *
69 * rhs 1 : a scicos model Tlist
70 *        - 1  : model(1)     : !model      sim     in      in2     intyp    out    out2  outtyp
71 *                               evtin      evtout  state   dstate  odstate  rpar   ipar  opar
72 *                               blocktype  firing  dep_ut  label   nzcross  nmode  equations  !
73 *        - 2  : model.sim       :
74 *        - 3  : model.in        :
75 *        - 4  : model.in2       :
76 *        - 5  : model.intyp     :
77 *        - 6  : model.out       :
78 *        - 7  : model.out2      :
79 *        - 8  : model.outtyp    :
80 *        - 9  : model.evtin     :
81 *        - 10 : model.evtout    :
82 *        - 11 : model.state     :
83 *        - 12 : model.dsate     :
84 *        - 13 : model.odsate    :
85 *        - 14 : model.rpar      :
86 *        - 15 : model.ipar      :
87 *        - 16 : model.opar      :
88 *        - 17 : model.blocktype :
89 *        - 18 : model.firing    :
90 *        - 19 : model.dep_ut    :
91 *        - 20 : model.label     :
92 *        - 21 : model.nzcross   :
93 *        - 22 : model.nmode      :
94 *        - 23 : model.equations :
95 *
96 * lhs 1 : a scicos block Tlist
97 *
98 * initial rev 12/11/07, Alan
99 * 05/07/08, Alan : fix for xprop
100 *                  add extra comments
101 *                  check in/out size and type
102 *
103 */
104 static const std::string name = "model2blk";
105
106 static void freeSubBlock(void* _ptr)
107 {
108     if (_ptr)
109     {
110         FREE(_ptr);
111     }
112 }
113
114 static void freeBlock(scicos_block* block)
115 {
116     for (int i = 0; i < block->nin; ++i)
117     {
118         freeSubBlock(block->inptr[i]);
119     }
120
121     freeSubBlock(block->inptr);
122     freeSubBlock(block->insz);
123
124     for (int i = 0; i < block->nout; ++i)
125     {
126         freeSubBlock(block->outptr[i]);
127     }
128     freeSubBlock(block->outptr);
129     freeSubBlock(block->outsz);
130
131     freeSubBlock(block->evout);
132     freeSubBlock(block->x);
133     freeSubBlock(block->xd);
134     freeSubBlock(block->xprop);
135     freeSubBlock(block->res);
136     freeSubBlock(block->z);
137     freeSubBlock(block->ozsz);
138     freeSubBlock(block->oztyp);
139
140     for (int i = 0; i < block->noz; ++i)
141     {
142         freeSubBlock(block->ozptr[i]);
143     }
144     freeSubBlock(block->ozptr);
145
146     freeSubBlock(block->rpar);
147     freeSubBlock(block->ipar);
148     freeSubBlock(block->oparsz);
149     freeSubBlock(block->opartyp);
150
151     for (int i = 0; i < block->nopar; ++i)
152     {
153         freeSubBlock(block->oparptr[i]);
154     }
155     freeSubBlock(block->oparptr);
156     freeSubBlock(block->g);
157     freeSubBlock(block->label);
158     freeSubBlock(block->jroot);
159     freeSubBlock(block->mode);
160     freeSubBlock(block->uid);
161     freeSubBlock(block->work);
162 }
163
164 template<typename T>
165 bool alloc_and_set(T* t, void** v)
166 {
167     const int size = t->getSize();
168     typename T::type* src = t->get();
169     *v = MALLOC(sizeof(typename T::type) * size);
170     if (*v == nullptr)
171     {
172         return false;
173     }
174
175     for (int i = 0; i < size; ++i)
176     {
177         ((typename T::type*)(*v))[i] = src[i];
178     }
179
180     return true;
181 }
182
183 types::Function::ReturnValue sci_model2blk(types::typed_list &in, int _iRetCount, types::typed_list &out)
184 {
185     types::InternalType* pIT = nullptr;
186     types::InternalType* il_sim = nullptr;
187
188     /* misc */
189     types::Double* d = nullptr;
190     types::List * l = nullptr;
191     types::String * s = nullptr;
192
193     scicos_block Block;
194     memset(&Block, 0, sizeof(scicos_block));
195
196     if (in.size() != 1)
197     {
198         Scierror(77, _("%s: Wrong number of input argument: %d expected.\n"), name.data(), 1);
199         return types::Function::Error;
200     }
201
202     if (_iRetCount != 1)
203     {
204         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), name.data(), 1);
205         return types::Function::Error;
206     }
207
208     pIT = in[0];
209     /* check for a tlist */
210     if (pIT->isMList() == false)
211     {
212         Scierror(888, _("%s : First argument must be a Typed list.\n"), name.data());
213         return types::Function::Error;
214     }
215
216     types::MList* m = pIT->getAs<types::MList>();
217
218     /* check for a type "scicos model" */
219     if (wcscmp(m->getTypeStr().data(), L"model"))
220     {
221         Scierror(888, _("%s : First argument must be a Typed list.\n"), name.data());
222         return types::Function::Error;
223     }
224
225     char* c = wide_string_to_UTF8(m->getTypeStr().data());
226     std::string blockname(c);
227     FREE(c);
228
229     /* 2 : model.sim  */
230     pIT = m->getField(L"sim");
231     if (pIT->isList())
232     {
233         l = pIT->getAs<types::List>();
234         il_sim = l->get(0)->getAs<types::Double>();
235         d = l->get(1)->getAs<types::Double>();
236         Block.type = static_cast<int>(d->get()[0]);
237     }
238     else
239     {
240         Block.type = 0;
241         il_sim = pIT;
242     }
243
244     bool isMacro = false;
245     /* check if typfsim is a scilab function */
246     if (il_sim->isMacro() || il_sim->isMacroFile())
247     {
248         isMacro = true;
249     }
250     else if (il_sim->isString())
251     {
252         types::String* funStr = il_sim->getAs<types::String>();
253         wchar_t* w_str = funStr->get(0);
254         char* c_str = wide_string_to_UTF8(w_str);
255         void* f = funnum2(c_str); // Search associated function number of function name
256         // Block is defined by a C or Fortran function
257         if (f != nullptr)
258         {
259             // C interface from "tabsim" defined in blocks.h
260             Block.funpt = (voidg)f;
261         }
262         // Block is defined by a predefined scilab function
263         else
264         {
265             ConfigVariable::EntryPointStr* pEP = ConfigVariable::getEntryPoint(w_str);
266             if (pEP)
267             {
268                 //linked functions
269                 Block.funpt = static_cast<voidg>(pEP->functionPtr);
270             }
271             else
272             {
273                 types::InternalType* pMacro = symbol::Context::getInstance()->get(symbol::Symbol(w_str));
274                 if (pMacro && pMacro->isCallable())
275                 {
276                     //macros
277                     il_sim = pMacro;
278                     isMacro = true;
279                 }
280                 else
281                 {
282                     Scierror(888, _("%s : unknown block : %s\n"), name.data(), blockname.data());
283                     return types::Function::Error;
284                 }
285             }
286         }
287     }
288
289     if (isMacro)
290     {
291         switch (Block.type)
292         {
293             case 0:
294                 Block.funpt = F2C(sciblk);
295                 break;
296             case 1:
297                 Scierror(888, _("%s : type 1 function not allowed for scilab blocks\n"), name.data());
298                 return types::Function::Error;
299             case 2:
300                 Scierror(888, _("%s : type 2 function not allowed for scilab blocks\n"), name.data());
301                 return types::Function::Error;
302             case 3:
303                 Block.funpt = (voidg)sciblk2;
304                 Block.type = 2;
305                 break;
306             case 5:
307                 Block.funpt = (voidg)sciblk4;
308                 Block.type = 4;
309                 break;
310             case 99: /* debugging block */
311                 Block.funpt = (voidg)sciblk4;
312                 Block.type = 4;
313                 break;
314             case 10005:
315                 Block.funpt = (voidg)sciblk4;
316                 Block.type = 10004;
317                 break;
318             default:
319                 Scierror(888, _("%s : Undefined Function type\n"), name.data());
320                 return types::Function::Error;
321         }
322         Block.scsptr = static_cast<void*>(il_sim);
323     }
324
325     /* check input ports */
326     /* 3 : model.in  */
327     pIT = m->getField(L"in");
328     d = pIT->getAs<types::Double>();
329     const int sizeIn = d->getSize();
330     Block.nin = d->getSize();
331     Block.insz = nullptr;
332     Block.inptr = nullptr;
333     if (Block.nin > 0)
334     {
335         const double* const vIn = d->get();
336         for (int i = 0; i < sizeIn; ++i)
337         {
338             /* check value of in */
339             if (vIn[i] <= 0)
340             {
341                 Scierror(888, _("%s : Undetermined Size. in(%d)=%d. Please adjust your model.\n"), \
342                          name.data(), i + 1, static_cast<int>(vIn[i]));
343                 return types::Function::Error;
344             }
345         }
346
347         /* alloc insz */
348         if ((Block.insz = (int *)MALLOC(Block.nin * 3 * sizeof(int))) == nullptr)
349         {
350             Scierror(888, _("%s : Allocation error.\n"), name.data());
351             return types::Function::Error;
352         }
353         /* alloc inptr */
354         if ((Block.inptr = (void **)MALLOC(Block.nin * sizeof(void *))) == nullptr)
355         {
356             freeBlock(&Block);
357             Scierror(888, _("%s : Allocation error.\n"), name.data());
358             return types::Function::Error;
359         }
360
361         /* 4 : model.in2  */
362         pIT = m->getField(L"in2");
363         d = pIT->getAs<types::Double>();
364         const int sizeIn2 = d->getSize();
365         const double* const vIn2 = d->get();
366         for (int i = 0; i < sizeIn2; ++i)
367         {
368             /* check value of in2 */
369             if (vIn2[i] <= 0)
370             {
371                 Scierror(888, _("%s : Undetermined Size. in2(%d)=%d. Please adjust your model.\n"), \
372                          name.data(), i + 1, static_cast<int>(vIn2[i]));
373                 freeBlock(&Block);
374                 return types::Function::Error;
375             }
376         }
377
378         /* 5 : model.intyp  */
379         pIT = m->getField(L"intyp");
380         d = pIT->getAs<types::Double>();
381         const int sizeIntyp = d->getSize();
382         const double* const vIntype = d->get();
383         for (int i = 0; i < sizeIntyp; ++i)
384         {
385             /* check value of intyp */
386             if (vIntype[i] <= 0)
387             {
388                 Scierror(888, _("%s : Undetermined Size. intyp(%d)=%d. Please adjust your model.\n"), \
389                          name.data(), i + 1, static_cast<int>(vIntype[i]));
390                 freeBlock(&Block);
391                 return types::Function::Error;
392             }
393         }
394
395         if (sizeIn == sizeIn2 && sizeIn == sizeIntyp)
396         {
397             for (int i = 0; i < sizeIn; ++i)
398             {
399                 Block.insz[i] = static_cast<int>(vIn[i]);
400                 Block.insz[i + sizeIn] = static_cast<int>(vIn2[i]);
401                 int val = 0;
402                 switch (static_cast<int>(vIntype[i]))
403                 {
404                     case 1:
405                     default:
406                         val = 10;
407                         break;
408                     case 2:
409                         val = 11;
410                         break;
411                     case 3:
412                         val = 84;
413                         break;
414                     case 4:
415                         val = 82;
416                         break;
417                     case 5:
418                         val = 81;
419                         break;
420                     case 6:
421                         val = 814;
422                         break;
423                     case 7:
424                         val = 812;
425                         break;
426                     case 8:
427                         val = 811;
428                         break;
429                 }
430
431                 Block.insz[i + sizeIn * 2] = val;
432             }
433         }
434         else
435         {
436             for (int i = 0; i < Block.nin; i++)
437             {
438                 Block.insz[i] = static_cast<int>(vIn[i]);
439                 Block.insz[i + sizeIn] = 1;
440                 Block.insz[i + sizeIn * 2] = 10;
441             }
442         }
443
444         for (int i = 0; i < sizeIn; i++)
445         {
446             int size = Block.insz[i] * Block.insz[Block.nin + i];
447             switch (Block.insz[2 * sizeIn + i])
448             {
449                 case 10: //double
450                     size *= sizeof(double);
451                     break;
452                 case 11: //complex
453                     size *= 2 * sizeof(double);
454                     break;
455                 case 84: //int32
456                     size *= sizeof(SCSINT32_COP);
457                     break;
458                 case 82: //int16
459                     size *= sizeof(short);
460                     break;
461                 case 81: //int8
462                     size *= sizeof(char);
463                     break;
464                 case 814: //uint32
465                     size *= sizeof(SCSUINT32_COP);
466                     break;
467                 case 812: //uint16
468                     size *= sizeof(unsigned short);
469                     break;
470                 case 811: //uint8
471                     size *= sizeof(unsigned char);
472                     break;
473                 default:
474                     Scierror(888, _("%s : Unknown Data type\n"), name.data());
475                     return types::Function::Error;
476             }
477
478             Block.inptr[i] = MALLOC(size);
479             if (Block.inptr == nullptr)
480             {
481                 freeBlock(&Block);
482                 Scierror(888, _("%s : Allocation error.\n"), name.data());
483                 return types::Function::Error;
484             }
485
486             memset(Block.inptr, 0x00, size);
487         }
488     }
489
490     /* check output ports */
491     /* 6 : model.out  */
492     pIT = m->getField(L"out");
493     d = pIT->getAs<types::Double>();
494     const int sizeOut = d->getSize();
495     Block.nout = d->getSize();
496     Block.outsz  = nullptr;
497     Block.outptr = nullptr;
498     if (sizeOut > 0)
499     {
500         const double* const vOut = d->get();
501         for (int i = 0; i < sizeOut; ++i)
502         {
503             /* check value of out */
504             if (vOut[i] <= 0)
505             {
506                 Scierror(888, _("%s : Undetermined Size. out(%d)=%d. Please adjust your model.\n"), \
507                          name.data(), i + 1, static_cast<int>(vOut[i]));
508                 freeBlock(&Block);
509                 return types::Function::Error;
510             }
511         }
512
513         /* alloc outsz */
514         if ((Block.outsz = (int *)MALLOC(sizeOut * 3 * sizeof(int))) == nullptr)
515         {
516             Scierror(888, _("%s : Allocation error.\n"), name.data());
517             freeBlock(&Block);
518             return types::Function::Error;
519         }
520
521         /* alloc outptr */
522         if ((Block.outptr = (void **)MALLOC(sizeOut * sizeof(void *))) == nullptr)
523         {
524             Scierror(888, _("%s : Allocation error.\n"), name.data());
525             freeBlock(&Block);
526             return types::Function::Error;
527         }
528
529         /* 7 : model.out2  */
530         pIT = m->getField(L"out2");
531         d = pIT->getAs<types::Double>();
532         const int sizeOut2 = d->getSize();
533         const double* const vOut2 = d->get();
534         for (int i = 0; i < sizeOut2; ++i)
535         {
536             /* check value of in2 */
537             if (vOut2[i] <= 0)
538             {
539                 Scierror(888, _("%s : Undetermined Size. out2(%d)=%d. Please adjust your model.\n"), \
540                          name.data(), i + 1, static_cast<int>(vOut2[i]));
541                 freeBlock(&Block);
542                 return types::Function::Error;
543             }
544         }
545
546         /* 5 : model.intyp  */
547         pIT = m->getField(L"intyp");
548         d = pIT->getAs<types::Double>();
549         const int sizeOuttyp = d->getSize();
550         const double* const vOuttype = d->get();
551         for (int i = 0; i < sizeOuttyp; ++i)
552         {
553             /* check value of intyp */
554             if (vOuttype[i] <= 0)
555             {
556                 Scierror(888, _("%s : Undetermined Size. outtyp(%d)=%d. Please adjust your model.\n"), \
557                          name.data(), i + 1, static_cast<int>(vOuttype[i]));
558                 freeBlock(&Block);
559                 return types::Function::Error;
560             }
561         }
562
563         if (sizeOut == sizeOut2 && sizeOut == sizeOuttyp)
564         {
565             for (int i = 0; i < sizeOut; ++i)
566             {
567                 Block.outsz[i] = static_cast<int>(vOut[i]);
568                 Block.outsz[i + sizeOut] = static_cast<int>(vOut2[i]);
569                 int val = 0;
570                 switch (static_cast<int>(vOuttype[i]))
571                 {
572                     case 1:
573                     default:
574                         val = 10;
575                         break;
576                     case 2:
577                         val = 11;
578                         break;
579                     case 3:
580                         val = 84;
581                         break;
582                     case 4:
583                         val = 82;
584                         break;
585                     case 5:
586                         val = 81;
587                         break;
588                     case 6:
589                         val = 814;
590                         break;
591                     case 7:
592                         val = 812;
593                         break;
594                     case 8:
595                         val = 811;
596                         break;
597                 }
598
599                 Block.outsz[i + sizeOut * 2] = val;
600             }
601         }
602         else
603         {
604             for (int i = 0; i < sizeOut; i++)
605             {
606                 Block.outsz[i] = static_cast<int>(vOut[i]);
607                 Block.outsz[i + sizeOut] = 1;
608                 Block.outsz[i + sizeOut * 2] = 10;
609             }
610         }
611
612         for (int i = 0; i < sizeOut; i++)
613         {
614             int size = Block.outsz[i] * Block.outsz[sizeOut + i];
615             switch (Block.outsz[2 * sizeOut + i])
616             {
617                 case 10: //double
618                     size *= sizeof(double);
619                     break;
620                 case 11: //complex
621                     size *= 2 * sizeof(double);
622                     break;
623                 case 84: //int32
624                     size *= sizeof(SCSINT32_COP);
625                     break;
626                 case 82: //int16
627                     size *= sizeof(short);
628                     break;
629                 case 81: //int8
630                     size *= sizeof(char);
631                     break;
632                 case 814: //uint32
633                     size *= sizeof(SCSUINT32_COP);
634                     break;
635                 case 812: //uint16
636                     size *= sizeof(unsigned short);
637                     break;
638                 case 811: //uint8
639                     size *= sizeof(unsigned char);
640                     break;
641                 default:
642                     Scierror(888, _("%s : Unknown Data type\n"), name.data());
643                     return types::Function::Error;
644             }
645
646             Block.outptr[i] = MALLOC(size);
647             if (Block.outptr[i] == nullptr)
648             {
649                 freeBlock(&Block);
650                 Scierror(888, _("%s : Allocation error.\n"), name.data());
651                 return types::Function::Error;
652             }
653
654             memset(Block.outptr[i], 0x00, size);
655         }
656     }
657
658     /* event input port */
659     /* 9 : model.evtin  */
660
661     /* event output port  */
662     /* 10 : model.evtout  */
663     pIT = m->getField(L"evtout");
664     d = pIT->getAs<types::Double>();
665     Block.nevout = d->getSize();
666     if (Block.nevout > 0)
667     {
668         if ((Block.evout = (double *)MALLOC(Block.nevout * sizeof(double))) == nullptr)
669         {
670             freeBlock(&Block);
671             Scierror(888, _("%s : Allocation error.\n"), name.data());
672             return types::Function::Error;
673         }
674
675         pIT = m->getField(L"firing");
676         types::Double* firing = pIT->getAs<types::Double>();
677         if (Block.nevout == firing->getSize())
678         {
679             const double* const f = firing->get();
680             for (int j = 0; j < Block.nevout; j++)
681             {
682                 Block.evout[j] = f[j];
683             }
684         }
685         else
686         {
687             for (int j = 0; j < Block.nevout; j++)
688             {
689                 Block.evout[j] = -1;
690             }
691         }
692     }
693
694     /* continuous state  */
695     /* 11 : model.state  */
696     m->getField(L"state");
697     d = pIT->getAs<types::Double>();
698     Block.nx        = d->getSize();
699     Block.x         = nullptr;
700     Block.xprop     = nullptr;
701     Block.xd        = nullptr;
702     Block.res       = nullptr;
703     if (Block.nx > 0)
704     {
705         /* x */
706         if ((Block.x = (double *) MALLOC(Block.nx * sizeof(double))) == nullptr)
707         {
708             freeBlock(&Block);
709             Scierror(888, _("%s : Allocation error.\n"), name.data());
710             return types::Function::Error;
711         }
712
713         const double* const x = d->get();
714         for (int j = 0; j < Block.nx; j++)
715         {
716             Block.x[j] = x[j];
717         }
718
719         /* xd */
720         if ((Block.xd = (double *) MALLOC(Block.nx * sizeof(double))) == nullptr)
721         {
722             freeBlock(&Block);
723             Scierror(888, _("%s : Allocation error.\n"), name.data());
724             return types::Function::Error;
725         }
726
727         for (int j = 0; j < Block.nx; j++)
728         {
729             Block.xd[j] = 0;
730         }
731
732         /* xprop */
733         if ((Block.xprop = (int *) MALLOC(Block.nx * sizeof(int))) == nullptr)
734         {
735             freeBlock(&Block);
736             Scierror(888, _("%s : Allocation error.\n"), name.data());
737             return types::Function::Error;
738         }
739
740         for (int j = 0; j < Block.nx; j++)
741         {
742             Block.xprop[j] = 1;
743         }
744
745         /* res */
746         /*if (blktyp>10000) {*/
747         if ((Block.res = (double *)MALLOC(Block.nx * sizeof(double))) == nullptr)
748         {
749             freeBlock(&Block);
750             Scierror(888, _("%s : Allocation error.\n"), name.data());
751             return types::Function::Error;
752         }
753
754         for (int j = 0; j < Block.nx; j++)
755         {
756             Block.res[j] = 0;
757         }
758         /*}*/
759     }
760
761     /* discrete state  */
762     /* 12 : model.dstate  */
763     m->getField(L"dstate");
764     d = pIT->getAs<types::Double>();
765     Block.nz = d->getSize();
766     if (Block.nz > 0)
767     {
768         if ((Block.z = (double *)MALLOC(Block.nz * sizeof(double))) == nullptr)
769         {
770             freeBlock(&Block);
771             Scierror(888, _("%s : Allocation error.\n"), name.data());
772             return types::Function::Error;
773         }
774
775         const double* const z = d->get();
776         for (int j = 0; j < Block.nz; j++)
777         {
778             Block.z[j] = z[j];
779         }
780     }
781
782     /* discrete object state  */
783     /* 13 : model.odstate  */
784     pIT = m->getField(L"odstate");
785     l = pIT->getAs<types::List>();
786     Block.noz    = l->getSize();
787     Block.ozsz   = nullptr;
788     Block.oztyp  = nullptr;
789     Block.ozptr  = nullptr;
790     if (Block.noz > 0)
791     {
792         if ((Block.ozsz = (int *)MALLOC(2 * Block.noz * sizeof(int))) == nullptr)
793         {
794             freeBlock(&Block);
795             Scierror(888, _("%s : Allocation error.\n"), name.data());
796             return types::Function::Error;
797         }
798
799         if ((Block.oztyp = (int *)MALLOC(Block.noz * sizeof(int))) == nullptr)
800         {
801             freeBlock(&Block);
802             Scierror(888, _("%s : Allocation error.\n"), name.data());
803             return types::Function::Error;
804         }
805
806         if ((Block.ozptr = (void **)MALLOC(Block.noz * sizeof(void *))) == nullptr)
807         {
808             freeBlock(&Block);
809             Scierror(888, _("%s : Allocation error.\n"), name.data());
810             return types::Function::Error;
811         }
812
813
814         for (int i = 0; i < Block.noz; ++i)
815         {
816             pIT = l->get(i);
817
818             if (pIT->isGenericType())
819             {
820                 types::GenericType* pGT = pIT->getAs<types::GenericType>();
821                 Block.ozsz[i] = pGT->getRows();
822                 Block.ozsz[Block.noz + i] = pGT->getCols();
823             }
824
825             if (pIT->isDouble())
826             {
827                 d = pIT->getAs<types::Double>();
828                 Block.ozsz[i] = d->getRows();
829                 Block.ozsz[Block.noz + i] = d->getCols();
830                 const int size = d->getSize();
831                 const double* const r = d->get();
832                 if (d->isComplex() == false)
833                 {
834                     Block.oztyp[i] = 10;
835                     if ((Block.ozptr[i] = (double *)MALLOC(size * sizeof(double))) == nullptr)
836                     {
837                         freeBlock(&Block);
838                         Scierror(888, _("%s : Allocation error.\n"), name.data());
839                         return types::Function::Error;
840                     }
841
842                     for (int j = 0; j < size; ++j)
843                     {
844                         ((double*)Block.ozptr[i])[j] = r[j];
845                     }
846                 }
847                 else
848                 {
849                     Block.oztyp[i] = 11;
850                     if ((Block.ozptr[i] = (double *)MALLOC(2 * size * sizeof(double))) == nullptr)
851                     {
852                         freeBlock(&Block);
853                         Scierror(888, _("%s : Allocation error.\n"), name.data());
854                         return types::Function::Error;
855                     }
856
857                     const double* const im = d->getImg();
858                     for (int j = 0; j < size; ++j)
859                     {
860                         ((double*)Block.ozptr[i])[j] = r[j];
861                         ((double*)Block.ozptr[i])[size + j] = im[j];
862                     }
863                 }
864             }
865             else if (pIT->isInt())
866             {
867                 bool ret = false;
868                 switch (pIT->getType())
869                 {
870                     case types::InternalType::ScilabInt8:
871                         Block.oztyp[i] = 81;
872                         ret = alloc_and_set(pIT->getAs<types::Int8>(), &Block.ozptr[i]);
873                         break;
874                     case types::InternalType::ScilabInt16:
875                         Block.oztyp[i] = 82;
876                         ret = alloc_and_set(pIT->getAs<types::Int16>(), &Block.ozptr[i]);
877                         break;
878                     case types::InternalType::ScilabInt32:
879                         Block.oztyp[i] = 84;
880                         ret = alloc_and_set(pIT->getAs<types::Int32>(), &Block.ozptr[i]);
881                         break;
882                     case types::InternalType::ScilabUInt8:
883                         Block.oztyp[i] = 811;
884                         ret = alloc_and_set(pIT->getAs<types::UInt8>(), &Block.ozptr[i]);
885                         break;
886                     case types::InternalType::ScilabUInt16:
887                         Block.oztyp[i] = 812;
888                         ret = alloc_and_set(pIT->getAs<types::UInt16>(), &Block.ozptr[i]);
889                         break;
890                     case types::InternalType::ScilabUInt32:
891                         Block.oztyp[i] = 814;
892                         ret = alloc_and_set(pIT->getAs<types::UInt32>(), &Block.ozptr[i]);
893                         break;
894                     default :
895                         ret = false;
896                         break;
897                 }
898
899                 if (ret == false)
900                 {
901                     freeBlock(&Block);
902                     Scierror(888, _("%s : Allocation error.\n"), name.data());
903                     return types::Function::Error;
904                 }
905             }
906         }
907     }
908
909     /* real parameters */
910     /* 14 : model.rpar  */
911     pIT = m->getField(L"rpar");
912     d = pIT->getAs<types::Double>();
913     Block.nrpar = d->getSize();
914     Block.rpar = nullptr;
915     if (Block.nrpar > 0)
916     {
917         if ((Block.rpar = (double *)MALLOC(Block.nrpar * sizeof(double))) == nullptr)
918         {
919             freeBlock(&Block);
920             Scierror(888, _("%s : Allocation error.\n"), name.data());
921             return types::Function::Error;
922         }
923
924         const double* const r = d->get();
925         for (int j = 0; j < Block.nrpar; j++)
926         {
927             Block.rpar[j] = r[j];
928         }
929     }
930
931     /* integer parameters */
932     /* 15 : model.ipar  */
933     pIT = m->getField(L"ipar");
934     d = pIT->getAs<types::Double>();
935     Block.nipar = d->getSize();
936     Block.ipar = nullptr;
937     if (Block.nrpar > 0)
938     {
939         if ((Block.ipar = (int *)MALLOC(Block.nrpar * sizeof(int))) == nullptr)
940         {
941             freeBlock(&Block);
942             Scierror(888, _("%s : Allocation error.\n"), name.data());
943             return types::Function::Error;
944         }
945
946         const double* const r = d->get();
947         for (int j = 0; j < Block.nrpar; j++)
948         {
949             Block.ipar[j] = static_cast<int>(r[j]);
950         }
951     }
952
953     /* object parameters */
954     /* 16 : model.opar  */
955     pIT = m->getField(L"opar");
956     l = pIT->getAs<types::List>();
957     Block.nopar = l->getSize();
958     Block.oparsz = nullptr;
959     Block.opartyp = nullptr;
960     Block.oparptr = nullptr;
961
962     if (Block.nopar > 0)
963     {
964         if ((Block.oparsz = (int *)MALLOC(2 * Block.nopar * sizeof(int))) == nullptr)
965         {
966             freeBlock(&Block);
967             Scierror(888, _("%s : Allocation error.\n"), name.data());
968             return types::Function::Error;
969         }
970
971         if ((Block.opartyp = (int *)MALLOC(Block.nopar * sizeof(int))) == nullptr)
972         {
973             freeBlock(&Block);
974             Scierror(888, _("%s : Allocation error.\n"), name.data());
975             return types::Function::Error;
976         }
977
978         if ((Block.oparptr = (void **)MALLOC(Block.nopar * sizeof(void *))) == nullptr)
979         {
980             freeBlock(&Block);
981             Scierror(888, _("%s : Allocation error.\n"), name.data());
982             return types::Function::Error;
983         }
984
985         for (int i = 0; i < Block.nopar; ++i)
986         {
987             pIT = l->get(i);
988             if (pIT->isDouble())
989             {
990                 d = pIT->getAs<types::Double>();
991                 const int size = d->getSize();
992                 const double* const r = d->get();
993                 if (d->isComplex() == false)
994                 {
995                     Block.opartyp[i] = 10;
996                     if ((Block.oparptr[i] = (double *)MALLOC(size * sizeof(double))) == nullptr)
997                     {
998                         freeBlock(&Block);
999                         Scierror(888, _("%s : Allocation error.\n"), name.data());
1000                         return types::Function::Error;
1001                     }
1002
1003                     for (int j = 0; j < size; ++j)
1004                     {
1005                         ((double*)Block.oparptr[i])[j] = r[j];
1006                     }
1007                 }
1008                 else
1009                 {
1010                     Block.opartyp[i] = 11;
1011                     if ((Block.oparptr[i] = (double *)MALLOC(2 * size * sizeof(double))) == nullptr)
1012                     {
1013                         freeBlock(&Block);
1014                         Scierror(888, _("%s : Allocation error.\n"), name.data());
1015                         return types::Function::Error;
1016                     }
1017
1018                     const double* const im = d->getImg();
1019                     for (int j = 0; j < size; ++j)
1020                     {
1021                         ((double*)Block.oparptr[i])[j] = r[j];
1022                         ((double*)Block.oparptr[i])[size + j] = im[j];
1023                     }
1024                 }
1025             }
1026             else if (pIT->isInt())
1027             {
1028                 bool ret = false;
1029                 switch (pIT->getType())
1030                 {
1031                     case types::InternalType::ScilabInt8:
1032                         Block.opartyp[i] = 81;
1033                         ret = alloc_and_set(pIT->getAs<types::Int8>(), &Block.oparptr[i]);
1034                         break;
1035                     case types::InternalType::ScilabInt16:
1036                         Block.opartyp[i] = 82;
1037                         ret = alloc_and_set(pIT->getAs<types::Int16>(), &Block.oparptr[i]);
1038                         break;
1039                     case types::InternalType::ScilabInt32:
1040                         Block.opartyp[i] = 84;
1041                         ret = alloc_and_set(pIT->getAs<types::Int32>(), &Block.oparptr[i]);
1042                         break;
1043                     case types::InternalType::ScilabUInt8:
1044                         Block.opartyp[i] = 811;
1045                         ret = alloc_and_set(pIT->getAs<types::UInt8>(), &Block.oparptr[i]);
1046                         break;
1047                     case types::InternalType::ScilabUInt16:
1048                         Block.opartyp[i] = 812;
1049                         ret = alloc_and_set(pIT->getAs<types::UInt16>(), &Block.oparptr[i]);
1050                         break;
1051                     case types::InternalType::ScilabUInt32:
1052                         Block.opartyp[i] = 814;
1053                         ret = alloc_and_set(pIT->getAs<types::UInt32>(), &Block.oparptr[i]);
1054                         break;
1055                     default :
1056                         ret = false;
1057                         break;
1058                 }
1059
1060                 if (ret == false)
1061                 {
1062                     freeBlock(&Block);
1063                     Scierror(888, _("%s : Allocation error.\n"), name.data());
1064                     return types::Function::Error;
1065                 }
1066             }
1067         }
1068     }
1069
1070     /* labels */
1071     /* 20 : model.label  */
1072     pIT = m->getField(L"label");
1073     s = pIT->getAs<types::String>();
1074     Block.label = wide_string_to_UTF8(s->get()[0]);
1075
1076     /* zero crossing */
1077     /* 21 : model.nzcross  */
1078     pIT = m->getField(L"nzcross");
1079     d = pIT->getAs<types::Double>();
1080     Block.ng = static_cast<int>(d->get()[0]);
1081     Block.g = nullptr;
1082     Block.jroot = nullptr;
1083     if (Block.ng > 0)
1084     {
1085         if ((Block.g = (double *)MALLOC(Block.ng * sizeof(double))) == nullptr)
1086         {
1087             freeBlock(&Block);
1088             Scierror(888, _("%s : Allocation error.\n"), name.data());
1089             return types::Function::Error;
1090         }
1091
1092         for (int j = 0; j < Block.ng; j++)
1093         {
1094             Block.g[j] = 0;
1095         }
1096
1097         if ((Block.jroot = (int *)MALLOC(Block.ng * sizeof(int))) == nullptr)
1098         {
1099             freeBlock(&Block);
1100             Scierror(888, _("%s : Allocation error.\n"), name.data());
1101             return types::Function::Error;
1102         }
1103
1104         for (int j = 0; j < Block.ng; j++)
1105         {
1106             Block.jroot[j] = 0;
1107         }
1108     }
1109
1110     /* mode */
1111     /* 22 : model.nmode  */
1112     pIT = m->getField(L"nmode");
1113     d = pIT->getAs<types::Double>();
1114     Block.nmode = static_cast<int>(d->get()[0]);
1115     if (Block.nmode > 0)
1116     {
1117         if ((Block.mode = (int *)MALLOC(Block.nmode * sizeof(int))) == nullptr)
1118         {
1119             freeBlock(&Block);
1120             Scierror(888, _("%s : Allocation error.\n"), name.data());
1121             return types::Function::Error;
1122         }
1123
1124         for (int j = 0; j < Block.nmode; j++)
1125         {
1126             Block.mode[j] = 0;
1127         }
1128     }
1129
1130     /* uids */
1131     /* 23 : model.uid  */
1132     pIT = m->getField(L"uid");
1133     s = pIT->getAs<types::String>();
1134     Block.uid = wide_string_to_UTF8(s->get()[0]);
1135
1136     if ((Block.work = (void **)MALLOC(sizeof(void *))) == nullptr)
1137     {
1138         freeBlock(&Block);
1139         Scierror(888, _("%s : Allocation error.\n"), name.data());
1140         return types::Function::Error;
1141     }
1142
1143     *Block.work = nullptr;
1144
1145     out.push_back(createblklist(&Block, -1, Block.type));
1146
1147     freeBlock(&Block);
1148     return types::Function::OK;
1149 }
1150 /*--------------------------------------------------------------------------*/
1151