024e1807c6233c03afca2e2de34f4901afdd63ac
[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_VOID, "evoid", 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::setCopyOccurred(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     switch (type)
281     {
282         case Nothing:
283             return false;
284         case Null:
285             if (createEmptyMatrix(pvApiCtx, pos))
286             {
287                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot create data"));
288             }
289         case SingleDouble:
290             wrapper.unwrapdouble(idObj, ScilabDoubleStackAllocator(pvApiCtx, pos));
291             break;
292         case RowDouble:
293             wrapper.unwraprowdouble(idObj, ScilabDoubleStackAllocator(pvApiCtx, pos));
294             break;
295         case MatDouble:
296             wrapper.unwrapmatdouble(idObj, ScilabDoubleStackAllocator(pvApiCtx, pos));
297             break;
298         case SingleString:
299             wrapper.unwrapstring(idObj, ScilabStringStackAllocator(pvApiCtx, pos));
300             break;
301         case RowString:
302             wrapper.unwraprowstring(idObj, ScilabStringStackAllocator(pvApiCtx, pos));
303             break;
304         case MatString:
305             wrapper.unwrapmatstring(idObj, ScilabStringStackAllocator(pvApiCtx, pos));
306             break;
307         case SingleBoolean:
308             wrapper.unwrapboolean(idObj, ScilabBooleanStackAllocator(pvApiCtx, pos));
309             break;
310         case RowBoolean:
311             wrapper.unwraprowboolean(idObj, ScilabBooleanStackAllocator(pvApiCtx, pos));
312             break;
313         case MatBoolean:
314             wrapper.unwrapmatboolean(idObj, ScilabBooleanStackAllocator(pvApiCtx, pos));
315             break;
316         case SingleChar:
317             wrapper.unwrapchar(idObj, ScilabCharStackAllocator(pvApiCtx, pos));
318             break;
319         case RowChar:
320             wrapper.unwraprowchar(idObj, ScilabCharStackAllocator(pvApiCtx, pos));
321             break;
322         case MatChar:
323             wrapper.unwrapmatchar(idObj, ScilabCharStackAllocator(pvApiCtx, pos));
324             break;
325         case SingleUChar:
326             wrapper.unwrapuchar(idObj, ScilabUCharStackAllocator(pvApiCtx, pos));
327             break;
328         case RowUChar:
329             wrapper.unwraprowuchar(idObj, ScilabUCharStackAllocator(pvApiCtx, pos));
330             break;
331         case MatUChar:
332             wrapper.unwrapmatuchar(idObj, ScilabUCharStackAllocator(pvApiCtx, pos));
333             break;
334         case SingleShort:
335             wrapper.unwrapshort(idObj, ScilabShortStackAllocator(pvApiCtx, pos));
336             break;
337         case RowShort:
338             wrapper.unwraprowshort(idObj, ScilabShortStackAllocator(pvApiCtx, pos));
339             break;
340         case MatShort:
341             wrapper.unwrapmatshort(idObj, ScilabShortStackAllocator(pvApiCtx, pos));
342             break;
343         case SingleUShort:
344             wrapper.unwrapushort(idObj, ScilabUShortStackAllocator(pvApiCtx, pos));
345             break;
346         case RowUShort:
347             wrapper.unwraprowushort(idObj, ScilabUShortStackAllocator(pvApiCtx, pos));
348             break;
349         case MatUShort:
350             wrapper.unwrapmatushort(idObj, ScilabUShortStackAllocator(pvApiCtx, pos));
351             break;
352         case SingleInt:
353             wrapper.unwrapint(idObj, ScilabIntStackAllocator(pvApiCtx, pos));
354             break;
355         case RowInt:
356             wrapper.unwraprowint(idObj, ScilabIntStackAllocator(pvApiCtx, pos));
357             break;
358         case MatInt:
359             wrapper.unwrapmatint(idObj, ScilabIntStackAllocator(pvApiCtx, pos));
360             break;
361         case SingleUInt:
362             wrapper.unwrapuint(idObj, ScilabUIntStackAllocator(pvApiCtx, pos));
363             break;
364         case RowUInt:
365             wrapper.unwraprowuint(idObj, ScilabUIntStackAllocator(pvApiCtx, pos));
366             break;
367         case MatUInt:
368             wrapper.unwrapmatuint(idObj, ScilabUIntStackAllocator(pvApiCtx, pos));
369             break;
370         case SingleLong:
371             wrapper.unwraplong(idObj, ScilabLongStackAllocator(pvApiCtx, pos));
372             break;
373         case RowLong:
374             wrapper.unwraprowlong(idObj, ScilabLongStackAllocator(pvApiCtx, pos));
375             break;
376         case MatLong:
377             wrapper.unwrapmatlong(idObj, ScilabLongStackAllocator(pvApiCtx, pos));
378             break;
379         case SingleULong:
380             wrapper.unwrapulong(idObj, ScilabULongStackAllocator(pvApiCtx, pos));
381             break;
382         case RowULong:
383             wrapper.unwraprowulong(idObj, ScilabULongStackAllocator(pvApiCtx, pos));
384             break;
385         case MatULong:
386             wrapper.unwrapmatulong(idObj, ScilabULongStackAllocator(pvApiCtx, pos));
387             break;
388         case SingleFloat:
389             wrapper.unwrapfloat(idObj, ScilabFloatStackAllocator(pvApiCtx, pos));
390             break;
391         case RowFloat:
392             wrapper.unwraprowfloat(idObj, ScilabFloatStackAllocator(pvApiCtx, pos));
393             break;
394         case MatFloat:
395             wrapper.unwrapmatfloat(idObj, ScilabFloatStackAllocator(pvApiCtx, pos));
396             break;
397         case SingleComplex:
398             wrapper.unwrapcomplex(idObj, ScilabComplexStackAllocator(pvApiCtx, pos));
399             break;
400         case RowComplex:
401             wrapper.unwraprowcomplex(idObj, ScilabComplexStackAllocator(pvApiCtx, pos));
402             break;
403         case MatComplex:
404             wrapper.unwrapmatcomplex(idObj, ScilabComplexStackAllocator(pvApiCtx, pos));
405             break;
406         default:
407             return false;
408     }
409
410     return true;
411 }
412
413 int ScilabObjects::getEnvironmentId(int * addr, void * pvApiCtx)
414 {
415     SciErr err;
416     int row = 0, col = 0;
417     int * envId = 0;
418
419     err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_ENV_ID_POSITION, &row, &col, &envId);
420     if (err.iErr)
421     {
422         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
423     }
424
425     return *envId;
426 }
427
428 int ScilabObjects::getExternalId(int * addr, void * pvApiCtx)
429 {
430     SciErr err;
431     int row = 0, col = 0;
432     int * id = 0;
433
434     err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
435     if (err.iErr)
436     {
437         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
438     }
439
440     return *id;
441 }
442
443 int ScilabObjects::getArgumentId(int * addr, int * tmpvars, const bool isRef, const bool isClass, const int envId, void * pvApiCtx)
444 {
445     SciErr err;
446     int typ, row = 0, col = 0, returnId;
447     const ScilabAbstractEnvironmentWrapper & wrapper = ScilabEnvironments::getEnvironment(envId).getWrapper();
448
449     err = getVarType(pvApiCtx, addr, &typ);
450     if (err.iErr)
451     {
452         removeTemporaryVars(envId, tmpvars);
453         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
454     }
455
456     if (isClass && typ != sci_mlist)
457     {
458         removeTemporaryVars(envId, tmpvars);
459         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("External Class expected"));
460     }
461
462     switch (typ)
463     {
464         case sci_matrix :
465         {
466             double * mat = 0;
467
468             if (isVarComplex(pvApiCtx, addr))
469             {
470                 double * imag = 0;
471                 err = getComplexMatrixOfDouble(pvApiCtx, addr, &row, &col, &mat, &imag);
472                 if (err.iErr)
473                 {
474                     removeTemporaryVars(envId, tmpvars);
475                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
476                 }
477
478                 returnId = wrap(row, col, mat, imag, wrapper, isRef);
479             }
480             else
481             {
482                 err = getMatrixOfDouble(pvApiCtx, addr, &row, &col, &mat);
483                 if (err.iErr)
484                 {
485                     removeTemporaryVars(envId, tmpvars);
486                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
487                 }
488
489                 returnId = wrap<double>(row, col, mat, wrapper, isRef);
490             }
491
492             tmpvars[++tmpvars[0]] = returnId;
493
494             return returnId;
495         }
496         case sci_ints :
497         {
498             int prec = 0;
499             void * ints = 0;
500
501             err = getMatrixOfIntegerPrecision(pvApiCtx, addr, &prec);
502             if (err.iErr)
503             {
504                 removeTemporaryVars(envId, tmpvars);
505                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
506             }
507
508             switch (prec)
509             {
510                 case SCI_INT8 :
511                     err = getMatrixOfInteger8(pvApiCtx, addr, &row, &col, (char**)(&ints));
512                     if (err.iErr)
513                     {
514                         removeTemporaryVars(envId, tmpvars);
515                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
516                     }
517
518                     returnId = wrap<char>(row, col, static_cast<char *>(ints), wrapper, isRef);
519                     tmpvars[++tmpvars[0]] = returnId;
520                     return returnId;
521                 case SCI_UINT8 :
522                     err = getMatrixOfUnsignedInteger8(pvApiCtx, addr, &row, &col, (unsigned char**)(&ints));
523                     if (err.iErr)
524                     {
525                         removeTemporaryVars(envId, tmpvars);
526                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
527                     }
528
529                     returnId = wrap<unsigned char>(row, col, static_cast<unsigned char *>(ints), wrapper, isRef);
530                     tmpvars[++tmpvars[0]] = returnId;
531                     return returnId;
532                 case SCI_INT16 :
533                     err = getMatrixOfInteger16(pvApiCtx, addr, &row, &col, (short**)(&ints));
534                     if (err.iErr)
535                     {
536                         removeTemporaryVars(envId, tmpvars);
537                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
538                     }
539
540                     returnId = wrap<short>(row, col, static_cast<short *>(ints), wrapper, isRef);
541                     tmpvars[++tmpvars[0]] = returnId;
542                     return returnId;
543                 case SCI_UINT16 :
544                     err = getMatrixOfUnsignedInteger16(pvApiCtx, addr, &row, &col, (unsigned short**)(&ints));
545                     if (err.iErr)
546                     {
547                         removeTemporaryVars(envId, tmpvars);
548                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
549                     }
550
551                     returnId = wrap<unsigned short>(row, col, static_cast<unsigned short *>(ints), wrapper, isRef);
552                     tmpvars[++tmpvars[0]] = returnId;
553                     return returnId;
554                 case SCI_INT32 :
555                     err = getMatrixOfInteger32(pvApiCtx, addr, &row, &col, (int**)(&ints));
556                     if (err.iErr)
557                     {
558                         removeTemporaryVars(envId, tmpvars);
559                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
560                     }
561
562                     returnId = wrap<int>(row, col, static_cast<int *>(ints), wrapper, isRef);
563                     tmpvars[++tmpvars[0]] = returnId;
564                     return returnId;
565                 case SCI_UINT32 :
566                     err = getMatrixOfUnsignedInteger32(pvApiCtx, addr, &row, &col, (unsigned int**)(&ints));
567                     if (err.iErr)
568                     {
569                         removeTemporaryVars(envId, tmpvars);
570                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
571                     }
572
573                     returnId = wrap<unsigned int>(row, col, static_cast<unsigned int *>(ints), wrapper, isRef);
574                     tmpvars[++tmpvars[0]] = returnId;
575                     return returnId;
576
577 #ifdef __SCILAB_INT64__
578                 case SCI_INT64 :
579                     err = getMatrixOfInteger64(pvApiCtx, addr, &row, &col, (long long**)(&ints));
580                     if (err.iErr)
581                     {
582                         removeTemporaryVars(envId, tmpvars);
583                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
584                     }
585
586                     returnId = wrap<long long>(row, col, static_cast<long long *>(ints), wrapper, isRef);
587                     tmpvars[++tmpvars[0]] = returnId;
588                     return returnId;
589                 case SCI_UINT64 :
590                     err = getMatrixOfUnsignedInteger64(pvApiCtx, addr, &row, &col, (unsigned long long**)(&ints));
591                     if (err.iErr)
592                     {
593                         removeTemporaryVars(envId, tmpvars);
594                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
595                     }
596
597                     returnId = wrap<unsigned long long>(row, col, static_cast<unsigned long long *>(ints), wrapper, isRef);
598                     tmpvars[++tmpvars[0]] = returnId;
599                     return returnId;
600 #endif
601             }
602         }
603         case sci_strings :
604         {
605             char ** matS = NULL;
606             if (getAllocatedMatrixOfString(pvApiCtx, addr, &row, &col, &matS))
607             {
608                 removeTemporaryVars(envId, tmpvars);
609                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
610             }
611
612             returnId = wrap<char *>(row, col, matS, wrapper, isRef);
613             freeAllocatedMatrixOfString(row, col, matS);
614             tmpvars[++tmpvars[0]] = returnId;
615
616             return returnId;
617         }
618         case sci_boolean :
619         {
620             int * matB;
621
622             err = getMatrixOfBoolean(pvApiCtx, addr, &row, &col, &matB);
623             if (err.iErr)
624             {
625                 removeTemporaryVars(envId, tmpvars);
626                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
627             }
628
629             returnId = wrapBool(row, col, matB, wrapper, isRef);
630             tmpvars[++tmpvars[0]] = returnId;
631
632             return returnId;
633         }
634         case sci_mlist :
635         {
636             int * id = 0;
637             int type = getMListType(addr, pvApiCtx);
638             int eId = getEnvironmentId(addr, pvApiCtx);
639
640             if (eId != envId)
641             {
642                 removeTemporaryVars(envId, tmpvars);
643                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Incompatible External Objects"));
644             }
645
646             if (isClass)
647             {
648                 if (type == EXTERNAL_CLASS)
649                 {
650                     err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
651                     if (err.iErr)
652                     {
653                         removeTemporaryVars(envId, tmpvars);
654                         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
655                     }
656                     return *id;
657                 }
658                 else
659                 {
660                     removeTemporaryVars(envId, tmpvars);
661                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("External Class expected"));
662                 }
663             }
664
665             if (type == EXTERNAL_OBJECT || type == EXTERNAL_CLASS)
666             {
667                 err = getMatrixOfInteger32InList(pvApiCtx, addr, EXTERNAL_OBJ_ID_POSITION, &row, &col, &id);
668                 if (err.iErr)
669                 {
670                     removeTemporaryVars(envId, tmpvars);
671                     throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid variable: cannot retrieve the data"));
672                 }
673                 return *id;
674             }
675             else if (type == EXTERNAL_VOID)
676             {
677                 return -1;
678             }
679             else
680             {
681                 removeTemporaryVars(envId, tmpvars);
682                 throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("External object expected"));
683             }
684
685             break;
686         }
687         default :
688         {
689             removeTemporaryVars(envId, tmpvars);
690             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Unable to wrap. Unmanaged datatype ?"));
691         }
692     }
693 }
694
695 int ScilabObjects::getMListType(int * mlist, void * pvApiCtx)
696 {
697     char * mlist_type[3];
698     char * mtype = 0;
699     int lengths[3];
700     int rows, cols;
701     int type;
702
703     SciErr err = getVarType(pvApiCtx, mlist, &type);
704     if (err.iErr || type != sci_mlist)
705     {
706         return EXTERNAL_INVALID;
707     }
708
709     err = getMatrixOfStringInList(pvApiCtx, mlist, 1, &rows, &cols, NULL, NULL);
710     if (err.iErr || rows != 1 || cols != 3)
711     {
712         return EXTERNAL_INVALID;
713     }
714
715     err = getMatrixOfStringInList(pvApiCtx, mlist, 1, &rows, &cols, lengths, NULL);
716     if (err.iErr)
717     {
718         return EXTERNAL_INVALID;
719     }
720
721     for (int i = 0; i < 3; i++)
722     {
723         mlist_type[i] = new char[lengths[i] + 1];
724     }
725
726     err = getMatrixOfStringInList(pvApiCtx, mlist, 1, &rows, &cols, lengths, mlist_type);
727     mtype = mlist_type[0];
728     for (int i = 1; i < 3; i++)
729     {
730         delete[] mlist_type[i];
731     }
732
733     type = EXTERNAL_INVALID;
734
735     if (err.iErr)
736     {
737         return EXTERNAL_INVALID;
738     }
739
740     if (!std::strcmp("_EObj", mtype))
741     {
742         type = EXTERNAL_OBJECT;
743     }
744     else if (!std::strcmp("_EClass", mtype))
745     {
746         type = EXTERNAL_CLASS;
747     }
748     else if (!std::strcmp("_EVoid", mtype))
749     {
750         type = EXTERNAL_VOID;
751     }
752
753     delete[] mtype;
754
755     return type;
756 }
757
758 bool ScilabObjects::isValidExternal(int * mlist, void * pvApiCtx)
759 {
760     int type = getMListType(mlist, pvApiCtx);
761     return type == EXTERNAL_OBJECT || type == EXTERNAL_CLASS;
762 }
763
764 bool ScilabObjects::isExternalObj(int * mlist, void * pvApiCtx)
765 {
766     return getMListType(mlist, pvApiCtx) == EXTERNAL_OBJECT;
767 }
768
769 bool ScilabObjects::isExternalClass(int * mlist, void * pvApiCtx)
770 {
771     return getMListType(mlist, pvApiCtx) == EXTERNAL_CLASS;
772 }
773
774 bool ScilabObjects::isExternalObjOrClass(int * mlist, void * pvApiCtx)
775 {
776     int type = getMListType(mlist, pvApiCtx);
777     return type == EXTERNAL_OBJECT || type == EXTERNAL_CLASS;
778 }
779
780 bool ScilabObjects::isExternalVoid(int * mlist, void * pvApiCtx)
781 {
782     return getMListType(mlist, pvApiCtx) == EXTERNAL_VOID;
783 }
784
785 char * ScilabObjects::getSingleString(int pos, void * pvApiCtx)
786 {
787     SciErr err;
788     int * addr = 0;
789     char * str = 0;
790
791     err = getVarAddressFromPosition(pvApiCtx, pos, &addr);
792     if (err.iErr)
793     {
794         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid String"));
795     }
796
797     if (!isStringType(pvApiCtx, addr))
798     {
799         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("A single string expected"));
800     }
801
802     if (!isScalar(pvApiCtx, addr))
803     {
804         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("A single String expected"));
805     }
806
807     if (getAllocatedSingleString(pvApiCtx, addr, &str))
808     {
809         throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, gettext("Invalid String"));
810     }
811
812     return str;
813 }
814
815 int ScilabObjects::isPositiveIntegerAtAddress(int * addr, void * pvApiCtx)
816 {
817     SciErr err;
818     int typ = 0, row, col, prec;
819
820     err = getVarDimension(pvApiCtx, addr, &row, &col);
821     if (err.iErr)
822     {
823         return -1;
824     }
825
826     if (row != 1 || col != 1)
827     {
828         return -1;
829     }
830
831     err = getVarType(pvApiCtx, addr, &typ);
832     if (err.iErr)
833     {
834         return -1;
835     }
836
837     if (typ == sci_ints)
838     {
839         err = getMatrixOfIntegerPrecision(pvApiCtx, addr, &prec);
840         if (err.iErr)
841         {
842             return -1;
843         }
844         switch (prec)
845         {
846             case SCI_INT8:
847             {
848                 char * cvalue = 0;
849                 err = getMatrixOfInteger8(pvApiCtx, addr, &row, &col, &cvalue);
850                 if (err.iErr)
851                 {
852                     return -1;
853                 }
854                 return (int)(*cvalue);
855             }
856             break;
857             case SCI_UINT8:
858             {
859                 unsigned char * ucvalue = 0;
860                 err = getMatrixOfUnsignedInteger8(pvApiCtx, addr, &row, &col, &ucvalue);
861                 if (err.iErr)
862                 {
863                     return -1;
864                 }
865                 return (int)(*ucvalue);
866             }
867             break;
868             case SCI_INT16:
869             {
870                 short * svalue = 0;
871                 err = getMatrixOfInteger16(pvApiCtx, addr, &row, &col, &svalue);
872                 if (err.iErr)
873                 {
874                     return -1;
875                 }
876                 return (int)(*svalue);
877             }
878             break;
879             case SCI_UINT16:
880             {
881                 unsigned short * usvalue = 0;
882                 err = getMatrixOfUnsignedInteger16(pvApiCtx, addr, &row, &col, &usvalue);
883                 if (err.iErr)
884                 {
885                     return -1;
886                 }
887                 return (int)(*usvalue);
888             }
889             break;
890             case SCI_INT32:
891             {
892                 int * ivalue = 0;
893                 err = getMatrixOfInteger32(pvApiCtx, addr, &row, &col, &ivalue);
894                 if (err.iErr)
895                 {
896                     return -1;
897                 }
898                 return (int)(*ivalue);
899             }
900             break;
901             case SCI_UINT32:
902             {
903                 unsigned int * uivalue = 0;
904                 err = getMatrixOfUnsignedInteger32(pvApiCtx, addr, &row, &col, &uivalue);
905                 if (err.iErr)
906                 {
907                     return -1;
908                 }
909                 return (int)(*uivalue);
910             }
911             break;
912 #ifdef __SCILAB_INT64__
913             case SCI_INT64:
914             {
915                 long long * llvalue = 0;
916                 err = getMatrixOfInteger64(pvApiCtx, addr, &row, &col, &llvalue);
917                 if (err.iErr)
918                 {
919                     return -1;
920                 }
921                 return (int)(*llvalue);
922             }
923             break;
924             case SCI_UINT64:
925             {
926                 unsigned long long * ullvalue = 0;
927                 err = getMatrixOfUnsignedInteger64(pvApiCtx, addr, &row, &col, &ullvalue);
928                 if (err.iErr)
929                 {
930                     return -1;
931                 }
932                 return (int)(*ullvalue);
933             }
934             break;
935 #endif
936             default:
937                 return -1;
938         }
939     }
940     else if (typ == sci_matrix)
941     {
942         double * dvalue = 0;
943
944         if (isVarComplex(pvApiCtx, addr))
945         {
946             return -1;
947         }
948
949         err = getMatrixOfDouble(pvApiCtx, addr, &row, &col, &dvalue);
950         if (err.iErr)
951         {
952             return -1;
953         }
954
955         if (*dvalue - (double)(int)(*dvalue) == 0.0)
956         {
957             return (int)(*dvalue);
958         }
959     }
960
961     return -1;
962 }
963 }