5534aa88feab5cad9b41b68cd7a2a7216f80cad4
[scilab.git] / scilab / modules / external_objects / src / cpp / ScilabObjects.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "ScilabObjects.hxx"
14 #include <cstring>
15
16 #include <cstdio>
17
18 extern "C" {
19     extern int C2F(varfunptr)(int *, int *, int *);
20 }
21
22 namespace org_modules_external_objects
23 {
24     bool ScilabObjects::isInit = false;
25     const char * ScilabObjects::_EOBJ[] = {"_EObj", "_EnvId", "_id"};
26     const char * ScilabObjects::_ECLASS[] = {"_EClass", "_EnvId", "_id"};
27     const char * ScilabObjects::_EVOID[] = {"_EVoid", "_EnvId", "_id"};
28     const char * ScilabObjects::_INVOKE_ = "!!_invoke_";
29
30     void ScilabObjects::initialization(ScilabAbstractEnvironment & env, void * pvApiCtx)
31     {
32         if (!isInit)
33         {
34             isInit = true;
35             //createNamedEnvironmentObject(EXTERNAL_OBJECT, "enull", 0, 0, pvApiCtx);
36         }
37     }
38
39     int ScilabObjects::createNamedEnvironmentObject(int type, const char * name, int id, const int envId, void * pvApiCtx)
40     {
41         const char ** fields;
42         int * mlistaddr = 0;
43         SciErr err;
44
45         if (envId < 0)
46         {
47             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid environment"));
48         }
49
50         switch (type)
51         {
52         case EXTERNAL_OBJECT:
53             fields = static_cast<const char **>(_EOBJ);
54             break;
55         case EXTERNAL_CLASS:
56             fields = static_cast<const char **>(_ECLASS);
57             break;
58         case EXTERNAL_VOID:
59             fields = static_cast<const char **>(_EVOID);
60             break;
61         default :
62             fields = static_cast<const char **>(_EOBJ);
63             break;
64         }
65
66         err = createNamedMList(pvApiCtx, name, FIELDS_LENGTH, &mlistaddr);
67         if (err.iErr)
68         {
69             if (err.iErr == API_ERROR_INVALID_NAME)
70             {
71                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable name: %s"), name);
72             }
73
74             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
75         }
76
77         err = createMatrixOfStringInNamedList(pvApiCtx, name, mlistaddr, 1, 1, FIELDS_LENGTH, fields);
78         if (err.iErr)
79         {
80             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
81         }
82
83         err = createMatrixOfInteger32InNamedList(pvApiCtx, name, mlistaddr, EXTERNAL_ENV_ID_POSITION, 1, 1, &envId);
84         if (err.iErr)
85         {
86             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
87         }
88
89         err = createMatrixOfInteger32InNamedList(pvApiCtx, name, mlistaddr, EXTERNAL_OBJ_ID_POSITION, 1, 1, &id);
90         if (err.iErr)
91         {
92             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
93         }
94
95         return 1;
96     }
97
98     void ScilabObjects::createEnvironmentObjectAtPos(int type, int pos, int id, const int envId, void * pvApiCtx)
99     {
100         const char ** fields = 0;
101         int * mlistaddr = 0;
102         SciErr err;
103
104         if (envId < 0)
105         {
106             throw ScilabAbstractEnvironmentException("Invalid environment");
107         }
108
109         switch (type)
110         {
111         case EXTERNAL_OBJECT:
112             fields = static_cast<const char **>(_EOBJ);
113             break;
114         case EXTERNAL_CLASS:
115             fields = static_cast<const char **>(_ECLASS);
116             break;
117         case EXTERNAL_VOID:
118             fields = static_cast<const char **>(_EVOID);
119             break;
120         default :
121             fields = static_cast<const char **>(_EOBJ);
122             break;
123         }
124
125         err = createMList(pvApiCtx, pos, FIELDS_LENGTH, &mlistaddr);
126         if (err.iErr)
127         {
128             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
129         }
130
131         err = createMatrixOfStringInList(pvApiCtx, pos, mlistaddr, 1, 1, FIELDS_LENGTH, fields);
132         if (err.iErr)
133         {
134             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
135         }
136
137         err = createMatrixOfInteger32InList(pvApiCtx, pos, mlistaddr, EXTERNAL_ENV_ID_POSITION, 1, 1, &envId);
138         if (err.iErr)
139         {
140             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
141         }
142
143         err = createMatrixOfInteger32InList(pvApiCtx, pos, mlistaddr, EXTERNAL_OBJ_ID_POSITION, 1, 1, &id);
144         if (err.iErr)
145         {
146             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Cannot allocate memory"));
147         }
148     }
149
150     void ScilabObjects::copyInvocationMacroToStack(int pos, ScilabAbstractEnvironment & env, void * pvApiCtx)
151     {
152         static bool init = false;
153         static int id[nsiz];
154         static int interf = 0;
155         static int funnumber = 0;
156
157         if (!init)
158         {
159             init = true;
160             C2F(str2name)(const_cast<char *>(_INVOKE_), id, strlen(_INVOKE_));
161             int fins = Fin;
162             int funs = C2F(com).fun;
163             Fin = -1;
164             C2F(funs)(id);
165             funnumber = Fin;
166             interf = C2F(com).fun;
167             C2F(com).fun = funs;
168             Fin = fins;
169         }
170
171         int tops = Top;
172         // Remove 1 since varfunptr will increment Top
173         Top = Top - Rhs + pos - 1;
174
175         // Create a function pointer variable
176         C2F(varfunptr)(id, &interf, &funnumber);
177         C2F(intersci).ntypes[pos - 1] = '$';
178
179         Top = tops;
180
181         OptionsHelper::setCopyOccured(true);
182     }
183
184     void ScilabObjects::removeTemporaryVars(const int envId, int * tmpvar)
185     {
186         if (tmpvar && *tmpvar)
187         {
188             ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
189
190             for (int i = 1; i <= *tmpvar; i++)
191             {
192                 env.removeobject(tmpvar[i]);
193             }
194
195             *tmpvar = 0;
196         }
197     }
198
199     void ScilabObjects::removeVar(int * addr, void * pvApiCtx)
200     {
201         SciErr err;
202         int type, row, col, * id;
203
204         err = getVarType(pvApiCtx, addr, &type);
205         if (err.iErr)
206         {
207             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
208         }
209
210         if (type == sci_mlist && (isExternalObjOrClass(addr, pvApiCtx)))
211         {
212             err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
213             if (err.iErr)
214             {
215                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
216             }
217
218             int envId = getEnvironmentId(addr, pvApiCtx);
219             ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
220
221             env.removeobject(*id);
222         }
223         else if (type == sci_strings)
224         {
225             char * varName = 0;
226             if (getAllocatedSingleString(pvApiCtx, addr, &varName))
227             {
228                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
229             }
230
231             err = getVarAddressFromName(pvApiCtx, varName, &addr);
232             if (err.iErr)
233             {
234                 freeAllocatedSingleString(varName);
235                 return;
236             }
237
238             err = getVarType(pvApiCtx, addr, &type);
239             if (err.iErr)
240             {
241                 freeAllocatedSingleString(varName);
242                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
243             }
244
245             if (type == sci_mlist && isExternalObjOrClass(addr, pvApiCtx))
246             {
247                 err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
248                 if (err.iErr)
249                 {
250                     freeAllocatedSingleString(varName);
251                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
252                 }
253
254                 int envId = getEnvironmentId(addr, pvApiCtx);
255                 ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
256
257                 env.removeobject(*id);
258                 deleteNamedVariable(pvApiCtx, varName);
259                 freeAllocatedSingleString(varName);
260             }
261         }
262     }
263
264     bool ScilabObjects::unwrap(int idObj, int pos, const int envId, void * pvApiCtx)
265     {
266         if (idObj == 0)
267         {
268             if (createEmptyMatrix(pvApiCtx, pos))
269             {
270                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot create data"));
271             }
272             return true;
273         }
274
275         VariableType type = Nothing;
276         ScilabAbstractEnvironment & env = ScilabEnvironments::getEnvironment(envId);
277         const ScilabAbstractEnvironmentWrapper & wrapper = env.getWrapper();
278
279         type = env.isunwrappable(idObj);
280
281         switch (type)
282         {
283         case Nothing:
284             return false;
285         case Null:
286             if (createEmptyMatrix(pvApiCtx, pos))
287             {
288                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot create data"));
289             }
290         case SingleDouble:
291             wrapper.unwrapdouble(idObj, ScilabDoubleStackAllocator(pvApiCtx, pos));
292             break;
293         case RowDouble:
294             wrapper.unwraprowdouble(idObj, ScilabDoubleStackAllocator(pvApiCtx, pos));
295             break;
296         case MatDouble:
297             wrapper.unwrapmatdouble(idObj, ScilabDoubleStackAllocator(pvApiCtx, pos));
298             break;
299         case SingleString:
300             wrapper.unwrapstring(idObj, ScilabStringStackAllocator(pvApiCtx, pos));
301             break;
302         case RowString:
303             wrapper.unwraprowstring(idObj, ScilabStringStackAllocator(pvApiCtx, pos));
304             break;
305         case MatString:
306             wrapper.unwrapmatstring(idObj, ScilabStringStackAllocator(pvApiCtx, pos));
307             break;
308         case SingleBoolean:
309             wrapper.unwrapboolean(idObj, ScilabBooleanStackAllocator(pvApiCtx, pos));
310             break;
311         case RowBoolean:
312             wrapper.unwraprowboolean(idObj, ScilabBooleanStackAllocator(pvApiCtx, pos));
313             break;
314         case MatBoolean:
315             wrapper.unwrapmatboolean(idObj, ScilabBooleanStackAllocator(pvApiCtx, pos));
316             break;
317         case SingleChar:
318             wrapper.unwrapchar(idObj, ScilabCharStackAllocator(pvApiCtx, pos));
319             break;
320         case RowChar:
321             wrapper.unwraprowchar(idObj, ScilabCharStackAllocator(pvApiCtx, pos));
322             break;
323         case MatChar:
324             wrapper.unwrapmatchar(idObj, ScilabCharStackAllocator(pvApiCtx, pos));
325             break;
326         case SingleUChar:
327             wrapper.unwrapuchar(idObj, ScilabUCharStackAllocator(pvApiCtx, pos));
328             break;
329         case RowUChar:
330             wrapper.unwraprowuchar(idObj, ScilabUCharStackAllocator(pvApiCtx, pos));
331             break;
332         case MatUChar:
333             wrapper.unwrapmatuchar(idObj, ScilabUCharStackAllocator(pvApiCtx, pos));
334             break;
335         case SingleShort:
336             wrapper.unwrapshort(idObj, ScilabShortStackAllocator(pvApiCtx, pos));
337             break;
338         case RowShort:
339             wrapper.unwraprowshort(idObj, ScilabShortStackAllocator(pvApiCtx, pos));
340             break;
341         case MatShort:
342             wrapper.unwrapmatshort(idObj, ScilabShortStackAllocator(pvApiCtx, pos));
343             break;
344         case SingleUShort:
345             wrapper.unwrapushort(idObj, ScilabUShortStackAllocator(pvApiCtx, pos));
346             break;
347         case RowUShort:
348             wrapper.unwraprowushort(idObj, ScilabUShortStackAllocator(pvApiCtx, pos));
349             break;
350         case MatUShort:
351             wrapper.unwrapmatushort(idObj, ScilabUShortStackAllocator(pvApiCtx, pos));
352             break;
353         case SingleInt:
354             wrapper.unwrapint(idObj, ScilabIntStackAllocator(pvApiCtx, pos));
355             break;
356         case RowInt:
357             wrapper.unwraprowint(idObj, ScilabIntStackAllocator(pvApiCtx, pos));
358             break;
359         case MatInt:
360             wrapper.unwrapmatint(idObj, ScilabIntStackAllocator(pvApiCtx, pos));
361             break;
362         case SingleUInt:
363             wrapper.unwrapuint(idObj, ScilabUIntStackAllocator(pvApiCtx, pos));
364             break;
365         case RowUInt:
366             wrapper.unwraprowuint(idObj, ScilabUIntStackAllocator(pvApiCtx, pos));
367             break;
368         case MatUInt:
369             wrapper.unwrapmatuint(idObj, ScilabUIntStackAllocator(pvApiCtx, pos));
370             break;
371         case SingleLong:
372             wrapper.unwraplong(idObj, ScilabLongStackAllocator(pvApiCtx, pos));
373             break;
374         case RowLong:
375             wrapper.unwraprowlong(idObj, ScilabLongStackAllocator(pvApiCtx, pos));
376             break;
377         case MatLong:
378             wrapper.unwrapmatlong(idObj, ScilabLongStackAllocator(pvApiCtx, pos));
379             break;
380         case SingleULong:
381             wrapper.unwrapulong(idObj, ScilabULongStackAllocator(pvApiCtx, pos));
382             break;
383         case RowULong:
384             wrapper.unwraprowulong(idObj, ScilabULongStackAllocator(pvApiCtx, pos));
385             break;
386         case MatULong:
387             wrapper.unwrapmatulong(idObj, ScilabULongStackAllocator(pvApiCtx, pos));
388             break;
389         case SingleFloat:
390             wrapper.unwrapfloat(idObj, ScilabFloatStackAllocator(pvApiCtx, pos));
391             break;
392         case RowFloat:
393             wrapper.unwraprowfloat(idObj, ScilabFloatStackAllocator(pvApiCtx, pos));
394             break;
395         case MatFloat:
396             wrapper.unwrapmatfloat(idObj, ScilabFloatStackAllocator(pvApiCtx, pos));
397             break;
398         case SingleComplex:
399             wrapper.unwrapcomplex(idObj, ScilabComplexStackAllocator(pvApiCtx, pos));
400             break;
401         case RowComplex:
402             wrapper.unwraprowcomplex(idObj, ScilabComplexStackAllocator(pvApiCtx, pos));
403             break;
404         case MatComplex:
405             wrapper.unwrapmatcomplex(idObj, ScilabComplexStackAllocator(pvApiCtx, pos));
406             break;
407         default:
408             return false;
409         }
410
411         return true;
412     }
413
414     int ScilabObjects::getEnvironmentId(int * addr, void * pvApiCtx)
415     {
416         SciErr err;
417         int row = 0, col = 0;
418         int * envId = 0;
419
420         err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_ENV_ID_POSITION, &row, &col, &envId);
421         if (err.iErr)
422         {
423             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
424         }
425
426         return *envId;
427     }
428
429     int ScilabObjects::getExternalId(int * addr, void * pvApiCtx)
430     {
431         SciErr err;
432         int row = 0, col = 0;
433         int * id = 0;
434
435         err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
436         if (err.iErr)
437         {
438             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
439         }
440
441         return *id;
442     }
443
444     int ScilabObjects::getArgumentId(int * addr, int * tmpvars, const bool isRef, const bool isClass, const int envId, void * pvApiCtx)
445     {
446         SciErr err;
447         int typ, row = 0, col = 0, returnId;
448         const ScilabAbstractEnvironmentWrapper & wrapper = ScilabEnvironments::getEnvironment(envId).getWrapper();
449
450         err = getVarType(pvApiCtx, addr, &typ);
451         if (err.iErr)
452         {
453             removeTemporaryVars(envId, tmpvars);
454             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
455         }
456
457         if (isClass && typ != sci_mlist)
458         {
459             removeTemporaryVars(envId, tmpvars);
460             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("External Class expected"));
461         }
462
463         switch (typ)
464         {
465         case sci_matrix :
466         {
467             double * mat = 0;
468
469             if (isVarComplex(pvApiCtx, addr))
470             {
471                 double * imag = 0;
472                 err = getComplexMatrixOfDouble(pvApiCtx, addr, &row, &col, &mat, &imag);
473                 if (err.iErr)
474                 {
475                     removeTemporaryVars(envId, tmpvars);
476                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
477                 }
478
479                 returnId = wrap(row, col, mat, imag, wrapper, isRef);
480             }
481             else
482             {
483                 err = getMatrixOfDouble(pvApiCtx, addr, &row, &col, &mat);
484                 if (err.iErr)
485                 {
486                     removeTemporaryVars(envId, tmpvars);
487                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
488                 }
489
490                 returnId = wrap<double>(row, col, mat, wrapper, isRef);
491             }
492
493             tmpvars[++tmpvars[0]] = returnId;
494
495             return returnId;
496         }
497         case sci_ints :
498         {
499             int prec = 0;
500             void * ints = 0;
501
502             err = getMatrixOfIntegerPrecision(pvApiCtx, addr, &prec);
503             if (err.iErr)
504             {
505                 removeTemporaryVars(envId, tmpvars);
506                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
507             }
508
509             switch (prec)
510             {
511             case SCI_INT8 :
512                 err = getMatrixOfInteger8(pvApiCtx, addr, &row, &col, (char**)(&ints));
513                 if (err.iErr)
514                 {
515                     removeTemporaryVars(envId, tmpvars);
516                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
517                 }
518
519                 returnId = wrap<char>(row, col, static_cast<char *>(ints), wrapper, isRef);
520                 tmpvars[++tmpvars[0]] = returnId;
521                 return returnId;
522             case SCI_UINT8 :
523                 err = getMatrixOfUnsignedInteger8(pvApiCtx, addr, &row, &col, (unsigned char**)(&ints));
524                 if (err.iErr)
525                 {
526                     removeTemporaryVars(envId, tmpvars);
527                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
528                 }
529
530                 returnId = wrap<unsigned char>(row, col, static_cast<unsigned char *>(ints), wrapper, isRef);
531                 tmpvars[++tmpvars[0]] = returnId;
532                 return returnId;
533             case SCI_INT16 :
534                 err = getMatrixOfInteger16(pvApiCtx, addr, &row, &col, (short**)(&ints));
535                 if (err.iErr)
536                 {
537                     removeTemporaryVars(envId, tmpvars);
538                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
539                 }
540
541                 returnId = wrap<short>(row, col, static_cast<short *>(ints), wrapper, isRef);
542                 tmpvars[++tmpvars[0]] = returnId;
543                 return returnId;
544             case SCI_UINT16 :
545                 err = getMatrixOfUnsignedInteger16(pvApiCtx, addr, &row, &col, (unsigned short**)(&ints));
546                 if (err.iErr)
547                 {
548                     removeTemporaryVars(envId, tmpvars);
549                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
550                 }
551
552                 returnId = wrap<unsigned short>(row, col, static_cast<unsigned short *>(ints), wrapper, isRef);
553                 tmpvars[++tmpvars[0]] = returnId;
554                 return returnId;
555             case SCI_INT32 :
556                 err = getMatrixOfInteger32(pvApiCtx, addr, &row, &col, (int**)(&ints));
557                 if (err.iErr)
558                 {
559                     removeTemporaryVars(envId, tmpvars);
560                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
561                 }
562
563                 returnId = wrap<int>(row, col, static_cast<int *>(ints), wrapper, isRef);
564                 tmpvars[++tmpvars[0]] = returnId;
565                 return returnId;
566             case SCI_UINT32 :
567                 err = getMatrixOfUnsignedInteger32(pvApiCtx, addr, &row, &col, (unsigned int**)(&ints));
568                 if (err.iErr)
569                 {
570                     removeTemporaryVars(envId, tmpvars);
571                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
572                 }
573
574                 returnId = wrap<unsigned int>(row, col, static_cast<unsigned int *>(ints), wrapper, isRef);
575                 tmpvars[++tmpvars[0]] = returnId;
576                 return returnId;
577
578 #ifdef __SCILAB_INT64__
579             case SCI_INT64 :
580                 err = getMatrixOfInteger64(pvApiCtx, addr, &row, &col, (long long**)(&ints));
581                 if (err.iErr)
582                 {
583                     removeTemporaryVars(envId, tmpvars);
584                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
585                 }
586
587                 returnId = wrap<long long>(row, col, static_cast<long long *>(ints), wrapper, isRef);
588                 tmpvars[++tmpvars[0]] = returnId;
589                 return returnId;
590             case SCI_UINT64 :
591                 err = getMatrixOfUnsignedInteger64(pvApiCtx, addr, &row, &col, (unsigned long long**)(&ints));
592                 if (err.iErr)
593                 {
594                     removeTemporaryVars(envId, tmpvars);
595                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
596                 }
597
598                 returnId = wrap<unsigned long long>(row, col, static_cast<unsigned long long *>(ints), wrapper, isRef);
599                 tmpvars[++tmpvars[0]] = returnId;
600                 return returnId;
601 #endif
602             }
603         }
604         case sci_strings :
605         {
606             char ** matS = NULL;
607             if (getAllocatedMatrixOfString(pvApiCtx, addr, &row, &col, &matS))
608             {
609                 removeTemporaryVars(envId, tmpvars);
610                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
611             }
612
613             returnId = wrap<char *>(row, col, matS, wrapper, isRef);
614             freeAllocatedMatrixOfString(row, col, matS);
615             tmpvars[++tmpvars[0]] = returnId;
616
617             return returnId;
618         }
619         case sci_boolean :
620         {
621             int * matB;
622
623             err = getMatrixOfBoolean(pvApiCtx, addr, &row, &col, &matB);
624             if (err.iErr)
625             {
626                 removeTemporaryVars(envId, tmpvars);
627                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
628             }
629
630             returnId = wrapBool(row, col, matB, wrapper, isRef);
631             tmpvars[++tmpvars[0]] = returnId;
632
633             return returnId;
634         }
635         case sci_mlist :
636         {
637             int * id = 0;
638             int type = getMListType(addr, pvApiCtx);
639             int eId = getEnvironmentId(addr, pvApiCtx);
640
641             if (eId != envId)
642             {
643                 removeTemporaryVars(envId, tmpvars);
644                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Incompatible External Objects"));
645             }
646
647             if (isClass)
648             {
649                 if (type == EXTERNAL_CLASS)
650                 {
651                     err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
652                     if (err.iErr)
653                     {
654                         removeTemporaryVars(envId, tmpvars);
655                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
656                     }
657                     return *id;
658                 }
659                 else
660                 {
661                     removeTemporaryVars(envId, tmpvars);
662                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("External Class expected"));
663                 }
664             }
665
666             if (type == EXTERNAL_OBJECT || type == EXTERNAL_CLASS)
667             {
668                 err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
669                 if (err.iErr)
670                 {
671                     removeTemporaryVars(envId, tmpvars);
672                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
673                 }
674                 return *id;
675             }
676             else
677             {
678                 removeTemporaryVars(envId, tmpvars);
679                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("External object expected"));
680             }
681
682             break;
683         }
684         default :
685         {
686             removeTemporaryVars(envId, tmpvars);
687             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Unable to wrap. Unmanaged datatype ?"));
688         }
689         }
690     }
691
692     int ScilabObjects::getMListType(int * mlist, void * pvApiCtx)
693     {
694         char * mlist_type[3];
695         char * mtype = 0;
696         int lengths[3];
697         int rows, cols;
698         int type;
699
700         SciErr err = getVarType(pvApiCtx, mlist, &type);
701         if (err.iErr || type != sci_mlist)
702         {
703             return EXTERNAL_INVALID;
704         }
705
706         err = getMatrixOfStringInList(pvApiCtx, mlist, 1, &rows, &cols, NULL, NULL);
707         if (err.iErr || rows != 1 || cols != 3)
708         {
709             return EXTERNAL_INVALID;
710         }
711
712         err = getMatrixOfStringInList(pvApiCtx, mlist, 1, &rows, &cols, lengths, NULL);
713         if (err.iErr)
714         {
715             return EXTERNAL_INVALID;
716         }
717
718         for (int i = 0; i < 3; i++)
719         {
720             mlist_type[i] = new char[lengths[i] + 1];
721         }
722
723         err = getMatrixOfStringInList(pvApiCtx, mlist, 1, &rows, &cols, lengths, mlist_type);
724         mtype = mlist_type[0];
725         for (int i = 1; i < 3; i++)
726         {
727             delete[] mlist_type[i];
728         }
729
730         type = EXTERNAL_INVALID;
731
732         if (err.iErr)
733         {
734             return EXTERNAL_INVALID;
735         }
736
737         if (!std::strcmp("_EObj", mtype))
738         {
739             type = EXTERNAL_OBJECT;
740         }
741         else if (!std::strcmp("_EClass", mtype))
742         {
743             type = EXTERNAL_CLASS;
744         }
745         else if (!std::strcmp("_EVoid", mtype))
746         {
747             type = EXTERNAL_VOID;
748         }
749
750         delete[] mtype;
751
752         return type;
753     }
754
755     bool ScilabObjects::isValidExternal(int * mlist, void * pvApiCtx)
756     {
757         int type = getMListType(mlist, pvApiCtx);
758         return type == EXTERNAL_OBJECT || type == EXTERNAL_CLASS || type == EXTERNAL_VOID;
759     }
760
761     bool ScilabObjects::isExternalObj(int * mlist, void * pvApiCtx)
762     {
763         return getMListType(mlist, pvApiCtx) == EXTERNAL_OBJECT;
764     }
765
766     bool ScilabObjects::isExternalClass(int * mlist, void * pvApiCtx)
767     {
768         return getMListType(mlist, pvApiCtx) == EXTERNAL_CLASS;
769     }
770
771     bool ScilabObjects::isExternalObjOrClass(int * mlist, void * pvApiCtx)
772     {
773         int type = getMListType(mlist, pvApiCtx);
774         return type == EXTERNAL_OBJECT || type == EXTERNAL_CLASS;
775     }
776
777     bool ScilabObjects::isExternalVoid(int * mlist, void * pvApiCtx)
778     {
779         return getMListType(mlist, pvApiCtx) == EXTERNAL_VOID;
780     }
781
782     char * ScilabObjects::getSingleString(int pos, void * pvApiCtx)
783     {
784         SciErr err;
785         int * addr = 0;
786         char * str = 0;
787
788         err = getVarAddressFromPosition(pvApiCtx, pos, &addr);
789         if (err.iErr)
790         {
791             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid String"));
792         }
793
794         if (!isStringType(pvApiCtx, addr))
795         {
796             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("A single string expected"));
797         }
798
799         if (!isScalar(pvApiCtx, addr))
800         {
801             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("A single String expected"));
802         }
803
804         if (getAllocatedSingleString(pvApiCtx, addr, &str))
805         {
806             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid String"));
807         }
808
809         return str;
810     }
811
812     int ScilabObjects::isPositiveIntegerAtAddress(int * addr, void * pvApiCtx)
813     {
814         SciErr err;
815         int typ = 0, row, col, prec;
816         int * id = 0;
817
818         err = getVarDimension(pvApiCtx, addr, &row, &col);
819         if (err.iErr)
820         {
821             return -1;
822         }
823
824         if (row != 1 || col != 1)
825         {
826             return -1;
827         }
828
829         err = getVarType(pvApiCtx, addr, &typ);
830         if (err.iErr)
831         {
832             return -1;
833         }
834
835         if (typ == sci_ints)
836         {
837             err = getMatrixOfIntegerPrecision(pvApiCtx, addr, &prec);
838             if (err.iErr)
839             {
840                 return -1;
841             }
842             switch (prec)
843             {
844             case SCI_INT8:
845             {
846                 char * cvalue = 0;
847                 err = getMatrixOfInteger8(pvApiCtx, addr, &row, &col, &cvalue);
848                 if (err.iErr)
849                 {
850                     return -1;
851                 }
852                 return (int)(*cvalue);
853             }
854             break;
855             case SCI_UINT8:
856             {
857                 unsigned char * ucvalue = 0;
858                 err = getMatrixOfUnsignedInteger8(pvApiCtx, addr, &row, &col, &ucvalue);
859                 if (err.iErr)
860                 {
861                     return -1;
862                 }
863                 return (int)(*ucvalue);
864             }
865             break;
866             case SCI_INT16:
867             {
868                 short * svalue = 0;
869                 err = getMatrixOfInteger16(pvApiCtx, addr, &row, &col, &svalue);
870                 if (err.iErr)
871                 {
872                     return -1;
873                 }
874                 return (int)(*svalue);
875             }
876             break;
877             case SCI_UINT16:
878             {
879                 unsigned short * usvalue = 0;
880                 err = getMatrixOfUnsignedInteger16(pvApiCtx, addr, &row, &col, &usvalue);
881                 if (err.iErr)
882                 {
883                     return -1;
884                 }
885                 return (int)(*usvalue);
886             }
887             break;
888             case SCI_INT32:
889             {
890                 int * ivalue = 0;
891                 err = getMatrixOfInteger32(pvApiCtx, addr, &row, &col, &ivalue);
892                 if (err.iErr)
893                 {
894                     return -1;
895                 }
896                 return (int)(*ivalue);
897             }
898             break;
899             case SCI_UINT32:
900             {
901                 unsigned int * uivalue = 0;
902                 err = getMatrixOfUnsignedInteger32(pvApiCtx, addr, &row, &col, &uivalue);
903                 if (err.iErr)
904                 {
905                     return -1;
906                 }
907                 return (int)(*uivalue);
908             }
909             break;
910 #ifdef __SCILAB_INT64__
911             case SCI_INT64:
912             {
913                 long long * llvalue = 0;
914                 err = getMatrixOfInteger64(pvApiCtx, addr, &row, &col, &llvalue);
915                 if (err.iErr)
916                 {
917                     return -1;
918                 }
919                 return (int)(*llvalue);
920             }
921             break;
922             case SCI_UINT64:
923             {
924                 unsigned long long * ullvalue = 0;
925                 err = getMatrixOfUnsignedInteger64(pvApiCtx, addr, &row, &col, &ullvalue);
926                 if (err.iErr)
927                 {
928                     return -1;
929                 }
930                 return (int)(*ullvalue);
931             }
932             break;
933 #endif
934             default:
935                 return -1;
936             }
937         }
938         else if (typ == sci_matrix)
939         {
940             double * dvalue = 0;
941
942             if (isVarComplex(pvApiCtx, addr))
943             {
944                 return -1;
945             }
946
947             err = getMatrixOfDouble(pvApiCtx, addr, &row, &col, &dvalue);
948             if (err.iErr)
949             {
950                 return -1;
951             }
952
953             if (*dvalue - (double)(int)(*dvalue) == 0.0)
954             {
955                 return (int)(*dvalue);
956             }
957         }
958
959         return -1;
960     }
961 }