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