fix mexlib mexEvalString test
[scilab.git] / scilab / modules / mexlib / src / cpp / mexlib.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - Gsoc 2011 - Iuri SILVIO
4  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
5  *  Copyright (C) 2011 - DIGITEO - Antoine ELIAS
6  *
7  *  This file must be used under the terms of the CeCILL.
8  *  This source file is licensed as described in the file COPYING, which
9  *  you should have received as part of this distribution.  The terms
10  *  are also available at
11  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12  *
13  */
14
15 /*------------------------------------------------------------------------
16  *    mexlib  library
17  *
18  *    This library emulates Matlab' API functions. It is not fully tested...
19  *    -Assumes that Scilab string matrices have one column, e.g.
20  *    Str=["qwerty";"123456"]; here this is a 2 x 6 matrix but Scilab
21  *    considers Str as a 2 x 1 matrix. ["123";"1234"] is a valid string
22  *    matrix which cannot be used here.
23  *    -Assumes that sparse matrices have been converted into the Matlab
24  *    format. Scilab sparse matrices are stored in the transposed Matlab
25  *    format. If A is a sparse Scilab matrix, it should be converted
26  *    by the command A=mtlb_sparse(A) in the calling sequence of the
27  *    mex function.
28  *    -Structs and Cells are Scilab mlists:
29  *    Struct=mlist(["st","dims","field1",...,"fieldk"],
30  *                 int32([d1,d2,...,dn]),
31  *                 list(obj1,      objN),
32  *                 .....
33  *                 list(obj1,      objN))     k such lists
34  *           N = d1 x d2    x dn
35  *           obj = Scilab variable or pointer to Scilab variable.
36  *     Cell = Struct with one field called "entries" and "st" <- "ce"
37  *    One dimensional structs or cells are as follows:
38  *    Struct=mlist(["st","dims","field1",...,"fieldk"],
39  *                 int32([1,1]),
40  *                 obj1,...,objk)
41  *
42  *    -Nd dimensional arrays are Scilab mlists (for Nd > 2):
43  *     X = mlist(["hm","dims","entries"],
44  *                 int32([d1,d2,...,dn]),
45  *                 values)
46  *     values = vector of doubles or int8-16-32 or char
47  --------------------------------------------------------------------------*/
48 #include <stdarg.h>
49
50 #include <limits>
51 #include <list>
52
53 #include "scilabWrite.hxx"
54 #include "context.hxx"
55 #include "symbol.hxx"
56 #include "parser.hxx"
57 #include "configvariable.hxx"
58 #include "overload.hxx"
59 #include "execvisitor.hxx"
60 #include "printvisitor.hxx"
61
62 #include "types.hxx"
63 #include "int.hxx"
64 #include "double.hxx"
65 #include "bool.hxx"
66 #include "string.hxx"
67 #include "struct.hxx"
68 #include "container.hxx"
69 #include "cell.hxx"
70 #include "localization.hxx"
71
72 extern "C"
73 {
74 #include "machine.h"
75 #include "mex.h"
76 #include "os_string.h"
77 #include "freeArrayOfString.h"
78 }
79
80 //#ifdef getType
81 //#undef getType
82 //#endif
83 //
84 //#ifdef isComplex
85 //#undef isComplex
86 //#endif
87
88 static void (*exitFcn)(void);
89
90 static int mexCallSCILAB(int nlhs, mxArray **plhs, int nrhs, mxArray **prhs, const char *name)
91 {
92     wchar_t* pwst = to_wide_string(name);
93     symbol::Context *context = symbol::Context::getInstance();
94     symbol::Symbol *symbol = new symbol::Symbol(pwst);
95     FREE(pwst);
96
97     InternalType *value = context->get(*symbol);
98     Function *func = value->getAs<Function>();
99     if (func == NULL)
100     {
101         return 1;
102     }
103
104     typed_list in;
105     typed_list out;
106     optional_list opt;
107     for (int i = 0; i < nrhs; i++)
108     {
109         in.push_back((InternalType*)prhs[i]);
110     }
111
112     func->call(in, opt, nlhs, out, NULL);
113
114     for (int i = 0; i < nlhs; i++)
115     {
116         plhs[i] = (mxArray *) (out[i]);
117     }
118
119     return 0;
120 }
121
122 //Validated
123
124 //Create or Delete Array
125 mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity complexFlag)
126 {
127     Double *ptr = new Double(m, n, complexFlag == mxCOMPLEX);
128     return (mxArray *)ptr;
129 }
130
131 mxArray *mxCreateDoubleScalar(double value)
132 {
133     mxArray *ptr = mxCreateDoubleMatrix(1, 1, mxREAL);
134
135     ((Double *)ptr)->set(0, value);
136     return ptr;
137 }
138
139 mxArray *mxCreateNumericMatrix(int m, int n, mxClassID CLASS, mxComplexity complexFlag)
140 {
141     int dims[2] = {m, n};
142     return mxCreateNumericArray(2, dims, CLASS, complexFlag);
143 }
144
145 mxArray *mxCreateNumericArray(int ndim, const int *dims, mxClassID CLASS, mxComplexity complexFlag)
146 {
147     GenericType *ptr;
148
149     switch (CLASS)
150     {
151         case mxDOUBLE_CLASS:
152             ptr = new Double(ndim, (int *)dims, complexFlag == mxCOMPLEX);
153             break;
154         case mxINT8_CLASS:
155             ptr = new Int8(ndim, (int *)dims);
156             break;
157         case mxUINT8_CLASS:
158             ptr = new UInt8(ndim, (int *)dims);
159             break;
160         case mxINT16_CLASS:
161             ptr = new Int16(ndim, (int *)dims);
162             break;
163         case mxUINT16_CLASS:
164             ptr = new UInt16(ndim, (int *)dims);
165             break;
166         case mxINT32_CLASS:
167             ptr = new Int32(ndim, (int *)dims);
168             break;
169         case mxUINT32_CLASS:
170             ptr = new UInt32(ndim, (int *)dims);
171             break;
172         case mxINT64_CLASS:
173             ptr = new Int64(ndim, (int *)dims);
174             break;
175         case mxUINT64_CLASS:
176             ptr = new UInt64(ndim, (int *)dims);
177             break;
178         default:
179             ptr = NULL;
180     }
181     return (mxArray *)ptr;
182 }
183
184 mxArray *mxCreateUninitNumericMatrix(size_t m, size_t n, mxClassID classid, mxComplexity ComplexFlag)
185 {
186     //TODO
187     return NULL;
188 }
189
190 mxArray *mxCreateUninitNumericArray(size_t ndim, size_t *dims, mxClassID classid, mxComplexity ComplexFlag)
191 {
192     //TODO
193     return NULL;
194 }
195
196 mxArray *mxCreateString(const char *string)
197 {
198     String *ptr = new String(string);
199     return (mxArray *)ptr;
200 }
201
202 mxArray *mxCreateCharMatrixFromStrings(int m, const char **str)
203 {
204     int n = 1;
205     wchar_t** strings = NULL;
206     strings = (wchar_t**)MALLOC(sizeof(wchar_t*) * m);
207     for (int k = 0; k < m; k++)
208     {
209         strings[k] = to_wide_string(str[k]);
210     }
211     String *ptr = new String(m, n, strings);
212     freeArrayOfWideString(strings, m);
213     return (mxArray *)ptr;
214 }
215
216 mxArray *mxCreateCharArray(int ndim, const int *dims)
217 {
218     if (ndim == 0 || ndim == 1)
219     {
220         ndim = 2;
221     }
222     String *ptr = new String(ndim, (int *)dims);
223
224     int size = ptr->getSize();
225     for (int i = 0; i < size; ++i)
226     {
227         ptr->set(i, L"");
228     }
229     return (mxArray *)ptr;
230 }
231
232 mxArray *mxCreateLogicalScalar(mxLogical value)
233 {
234     mxArray *ptr = mxCreateLogicalMatrix(1, 1);
235
236     ((Bool *)ptr)->set(0, value);
237     return ptr;
238 }
239
240 mxArray *mxCreateLogicalMatrix(int m, int n)
241 {
242     Bool *ptr = new Bool(m, n);
243     return (mxArray *)ptr;
244 }
245
246 mxArray *mxCreateLogicalArray(int ndim, const int *dims)
247 {
248     Bool *ptr = new Bool(ndim, (int *)dims);
249     return (mxArray *)ptr;
250 }
251
252 mxArray *mxCreateSparseLogicalMatrix(mwSize m, mwSize n, mwSize nzmax)
253 {
254     //TODO
255     return NULL;
256 }
257
258 mxArray *mxCreateSparse(int m, int n, int nzmax, mxComplexity cmplx)
259 {
260     //TODO
261     return NULL;
262 }
263
264 mxArray *mxCreateStructMatrix(int m, int n, int nfields, const char **field_names)
265 {
266     int dims[2] = {m, n};
267     return mxCreateStructArray(2, dims, nfields, field_names);
268 }
269
270 mxArray *mxCreateStructArray(int ndim, const int *dims, int nfields, const char **field_names)
271 {
272     Struct *ptr = new Struct(ndim, (int *)dims);
273     for (int i = 0; i < nfields; i++)
274     {
275         wchar_t *name = to_wide_string(field_names[i]);
276         ptr->addField(name);
277         FREE(name);
278     }
279     return (mxArray *)ptr;
280 }
281
282 mxArray *mxCreateCellArray(int ndim, const int *dims)
283 {
284     Cell *ptr = new Cell(ndim, (int *)dims);
285     return (mxArray *)ptr;
286 }
287
288 mxArray *mxCreateCellMatrix(int m, int n)
289 {
290     int dims[2] = {m, n};
291     return mxCreateCellArray(2, dims);
292 }
293
294 void mxDestroyArray(mxArray *ptr)
295 {
296     if (mxGetClassID(ptr) != mxUNKNOWN_CLASS)
297     {
298         delete (InternalType*)ptr;
299         *ptr = NULL;
300     }
301 }
302
303 mxArray *mxDuplicateArray(const mxArray *ptr)
304 {
305     InternalType *pIT = (InternalType *)ptr;
306     if (pIT == NULL)
307     {
308         return 0;
309     }
310
311     return (mxArray *)pIT->clone();
312 }
313
314 void *mxCalloc(size_t n, size_t size)
315 {
316     //TODO
317     return CALLOC(n, size);
318 }
319
320 void *mxMalloc(size_t nsize)
321 {
322     //TODO
323     return MALLOC(nsize);
324 }
325
326 void *mxRealloc(void *ptr, size_t nsize)
327 {
328     //TODO
329     return REALLOC(ptr, nsize);
330 }
331
332 void mxFree(void *ptr)
333 {
334     //TODO
335 }
336
337 //Validate Data
338 int mxIsDouble(const mxArray *ptr)
339 {
340     return mxGetClassID(ptr) == mxDOUBLE_CLASS;
341 }
342
343 int mxIsSingle(const mxArray *ptr)
344 {
345     return mxGetClassID(ptr) == mxSINGLE_CLASS;
346 }
347
348 int mxIsComplex(const mxArray *ptr)
349 {
350     InternalType *pIT = (InternalType *)ptr;
351     if (pIT == NULL)
352     {
353         return 0;
354     }
355
356     GenericType *pGT = pIT->getAs<GenericType>();
357     if (pGT == NULL)
358     {
359         return 0;
360     }
361
362     return pGT->isComplex() ? 1 : 0;
363 }
364
365 int mxIsNumeric(const mxArray *ptr)
366 {
367     return mxIsDouble(ptr) || mxIsSingle(ptr) ||
368            mxIsInt8(ptr) || mxIsUint8(ptr) ||
369            mxIsInt16(ptr) || mxIsUint16(ptr) || mxIsInt32(ptr) || mxIsUint32(ptr) || mxIsInt64(ptr) || mxIsUint64(ptr);
370 }
371
372 int mxIsInt64(const mxArray *ptr)
373 {
374     return mxGetClassID(ptr) == mxINT64_CLASS;
375 }
376
377 int mxIsUint64(const mxArray *ptr)
378 {
379     return mxGetClassID(ptr) == mxUINT64_CLASS;
380 }
381
382 int mxIsInt32(const mxArray *ptr)
383 {
384     return mxGetClassID(ptr) == mxINT32_CLASS;
385 }
386
387 int mxIsUint32(const mxArray *ptr)
388 {
389     return mxGetClassID(ptr) == mxUINT32_CLASS;
390 }
391
392 int mxIsInt16(const mxArray *ptr)
393 {
394     return mxGetClassID(ptr) == mxINT16_CLASS;
395 }
396
397 int mxIsUint16(const mxArray *ptr)
398 {
399     return mxGetClassID(ptr) == mxUINT16_CLASS;
400 }
401
402 int mxIsInt8(const mxArray *ptr)
403 {
404     return mxGetClassID(ptr) == mxINT8_CLASS;
405 }
406
407 int mxIsUint8(const mxArray *ptr)
408 {
409     return mxGetClassID(ptr) == mxUINT8_CLASS;
410 }
411
412 int mxIsScalar(const mxArray *array_ptr)
413 {
414     //TODO
415     return 0;
416 }
417
418 int mxIsChar(const mxArray *ptr)
419 {
420     return mxGetClassID(ptr) == mxCHAR_CLASS;
421 }
422
423 int mxIsLogical(const mxArray *ptr)
424 {
425     return mxGetClassID(ptr) == mxLOGICAL_CLASS;
426 }
427
428 int mxIsLogicalScalar(const mxArray *ptr)
429 {
430     return mxIsLogical(ptr) && mxGetNumberOfElements(ptr) == 1;
431 }
432
433 int mxIsLogicalScalarTrue(const mxArray *ptr)
434 {
435     if (mxIsLogicalScalar(ptr) == false)
436     {
437         return 0;
438     }
439
440     if (*mxGetLogicals(ptr) == 0)
441     {
442         return 0;
443     }
444
445     return 1;
446 }
447
448 int mxIsStruct(const mxArray *ptr)
449 {
450     return mxGetClassID(ptr) == mxSTRUCT_CLASS;
451 }
452
453 int mxIsCell(const mxArray *ptr)
454 {
455     return mxGetClassID(ptr) == mxCELL_CLASS;
456 }
457
458 int mxIsClass(const mxArray *ptr, const char *name)
459 {
460     if (strcmp(name, "cell") == 0)
461     {
462         return mxIsCell(ptr);
463     }
464     if (strcmp(name, "char") == 0)
465     {
466         return mxIsChar(ptr);
467     }
468     if (strcmp(name, "double") == 0)
469     {
470         return mxIsDouble(ptr);
471     }
472     if (strcmp(name, "int8") == 0)
473     {
474         return mxIsInt8(ptr);
475     }
476     if (strcmp(name, "int16") == 0)
477     {
478         return mxIsInt16(ptr);
479     }
480     if (strcmp(name, "int32") == 0)
481     {
482         return mxIsInt32(ptr);
483     }
484     if (strcmp(name, "int64") == 0)
485     {
486         return mxIsInt64(ptr);
487     }
488     if (strcmp(name, "logical") == 0)
489     {
490         return mxIsLogical(ptr);
491     }
492     if (strcmp(name, "single") == 0)
493     {
494         return mxIsSingle(ptr);
495     }
496     if (strcmp(name, "struct") == 0)
497     {
498         return mxIsStruct(ptr);
499     }
500     if (strcmp(name, "uint8") == 0)
501     {
502         return mxIsUint8(ptr);
503     }
504     if (strcmp(name, "uint16") == 0)
505     {
506         return mxIsUint16(ptr);
507     }
508     if (strcmp(name, "uint32") == 0)
509     {
510         return mxIsUint32(ptr);
511     }
512     if (strcmp(name, "uint64") == 0)
513     {
514         return mxIsUint64(ptr);
515     }
516     // TODO: how to handle <class_name> and <class_id>?
517     return 0;
518 }
519
520 int mxIsInf(double x)
521 {
522     if (x == x + 1)
523     {
524         return 1;
525     }
526     else
527     {
528         return 0;
529     }
530 }
531
532 int mxIsFinite(double x)
533 {
534     if (x < x + 1)
535     {
536         return 1;
537     }
538     else
539     {
540         return 0;
541     }
542 }
543
544 int mxIsNaN(double x)
545 {
546     if (x != x)
547     {
548         return 1;
549     }
550     else
551     {
552         return 0;
553     }
554 }
555
556 int mxIsEmpty(const mxArray *ptr)
557 {
558     InternalType * pIT = (InternalType *)ptr;
559     if (pIT == NULL)
560     {
561         //true or false, whatever ;)
562         return 1;
563     }
564
565     switch (pIT->getType())
566     {
567         case InternalType::ScilabDouble:
568         {
569             Double *pD = pIT->getAs<Double>();
570             return pD->getSize() == 0;
571         }
572         case InternalType::ScilabCell:
573         {
574             Cell *pC = pIT->getAs<Cell>();
575             return pC->getSize() == 0;
576         }
577         case InternalType::ScilabContainer:
578         case InternalType::ScilabList:
579         case InternalType::ScilabMList:
580         case InternalType::ScilabTList:
581         {
582             Container *pC = pIT->getAs<Container>();
583             return pC->getSize() == 0;
584         }
585         default:
586         {
587             //other type can not be empty
588             return 0;
589         }
590     }
591 }
592
593 int mxIsSparse(const mxArray *ptr)
594 {
595     //TODO
596     return 0;
597 }
598
599 int mxIsFromGlobalWS(const mxArray *pm)
600 {
601     //TODO
602     return 0;
603 }
604
605 //Convert Data Types
606 char *mxArrayToString(const mxArray *ptr)
607 {
608     if (!mxIsChar(ptr))
609     {
610         return (char *)0;
611     }
612
613     String *pa = (String *)ptr;
614     int items = mxGetM(ptr);
615     int index = 0;
616     int length = 1; // one extra char to \0
617     wchar_t **wstrings = pa->get();
618     for (int k = 0; k < items; k++)
619     {
620         length += (int)wcslen(wstrings[k]);
621     }
622
623     char *str = (char *)malloc(sizeof(char *) * length);
624     for (int k = 0; k < items; k++)
625     {
626         char *dest = wide_string_to_UTF8(wstrings[k]);
627         int dest_length = strlen(dest);
628         memcpy(str + index, dest, dest_length);
629         index += dest_length;
630     }
631
632     str[index] = '\0';
633     return str;
634 }
635
636 char *mxArrayToUTF8String(const mxArray *array_ptr)
637 {
638     //TODO
639     return NULL;
640 }
641
642 int mxGetString(const mxArray *ptr, char *str, int strl)
643 {
644     if (!mxIsChar(ptr))
645     {
646         return 1;
647     }
648
649     String *pa = (String *)ptr;
650     int items = mxGetM(ptr);
651     int index = 0;
652     int free_space = strl - 1;
653     for (int k = 0; k < items; k++)
654     {
655         wchar_t *to_copy = pa->get(k);
656         char *dest = wide_string_to_UTF8(to_copy);
657         int length = (int)strlen(dest);
658         memcpy(str + index, dest, free_space);
659         index += std::min(length, free_space);
660         free_space -= length;
661         FREE(dest);
662         if (free_space <= 0)
663         {
664             break;
665         }
666     }
667
668     str[index] = '\0';
669     return free_space >= 0 ? 0 : 1;
670 }
671
672 int mxSetClassName(mxArray *array_ptr, const char *classname)
673 {
674     //TODO
675     return 0;
676 }
677
678 int mxGetNumberOfDimensions(const mxArray *ptr)
679 {
680     InternalType *pIT = (InternalType *)ptr;
681     if (pIT == NULL)
682     {
683         return 0;
684     }
685
686     GenericType *pGT = pIT->getAs<GenericType>();
687     if (pGT == NULL)
688     {
689         //InternalType but not GenericType, so mono dimension type.
690         return 1;
691     }
692
693     return pGT->getDims();
694 }
695
696 int mxGetElementSize(const mxArray *ptr)
697 {
698     if (mxIsChar(ptr))
699     {
700         return sizeof(wchar_t*);
701     }
702     else if (mxIsLogical(ptr))
703     {
704         return sizeof(int);
705     }
706     else if (mxIsDouble(ptr))
707     {
708         return sizeof(double);
709     }
710     else if (mxIsSparse(ptr))
711     {
712         return sizeof(double);
713     }
714     else if (mxIsInt8(ptr))
715     {
716         return sizeof(char);
717     }
718     else if (mxIsInt16(ptr))
719     {
720         return sizeof(short);
721     }
722     else if (mxIsInt32(ptr))
723     {
724         return sizeof(int);
725     }
726     else if (mxIsInt64(ptr))
727     {
728         return sizeof(long long);
729     }
730     else if (mxIsUint8(ptr))
731     {
732         return sizeof(unsigned char);
733     }
734     else if (mxIsUint16(ptr))
735     {
736         return sizeof(unsigned short);
737     }
738     else if (mxIsUint32(ptr))
739     {
740         return sizeof(unsigned int);
741     }
742     else if (mxIsUint64(ptr))
743     {
744         return sizeof(unsigned long long);
745     }
746     else if (mxIsCell(ptr))
747     {
748         return sizeof(InternalType*);
749     }
750     else if (mxIsStruct(ptr))
751     {
752         return sizeof(SingleStruct*);
753     }
754     return 0;
755 }
756
757 mwSize *mxGetDimensions(const mxArray *ptr)
758 {
759     InternalType *pIT = (InternalType *)ptr;
760     if (pIT == NULL)
761     {
762         return NULL;
763     }
764
765     switch (pIT->getType())
766     {
767         case InternalType::ScilabList:
768         case InternalType::ScilabMList:
769         case InternalType::ScilabTList:
770         {
771             int *piDims = (int *)MALLOC(sizeof(int));
772
773             piDims[0] = pIT->getAs<Container>()->getSize();
774             return piDims;
775         }
776         default:
777         {
778             GenericType *pGT = pIT->getAs<GenericType>();
779             if (pGT == NULL)
780             {
781                 return NULL;
782             }
783             return pGT->getDimsArray();
784         }
785     }
786     return NULL;
787 }
788
789 int mxSetDimensions(mxArray *array_ptr, const int *dims, int ndim)
790 {
791     if (mxIsCell(array_ptr))
792     {
793         ((Cell *)array_ptr)->resize((int *)dims, ndim);
794     }
795     else if (mxIsChar(array_ptr))
796     {
797         ((String *)array_ptr)->resize((int *)dims, ndim);
798     }
799     else if (mxIsDouble(array_ptr))
800     {
801         ((Double *)array_ptr)->resize((int *)dims, ndim);
802     }
803     else if (mxIsSparse(array_ptr))
804     {
805         //TODO
806     }
807     else if (mxIsInt8(array_ptr))
808     {
809         ((Int8 *)array_ptr)->resize((int *)dims, ndim);
810     }
811     else if (mxIsInt16(array_ptr))
812     {
813         ((Int16 *)array_ptr)->resize((int *)dims, ndim);
814     }
815     else if (mxIsInt32(array_ptr))
816     {
817         ((Int32 *)array_ptr)->resize((int *)dims, ndim);
818     }
819     else if (mxIsInt64(array_ptr))
820     {
821         ((Int64 *)array_ptr)->resize((int *)dims, ndim);
822     }
823     else if (mxIsLogical(array_ptr))
824     {
825         ((Bool *)array_ptr)->resize((int *)dims, ndim);
826     }
827     else if (mxIsStruct(array_ptr))
828     {
829         ((Struct *)array_ptr)->resize((int *)dims, ndim);
830     }
831     else if (mxIsUint8(array_ptr))
832     {
833         ((UInt8 *)array_ptr)->resize((int *)dims, ndim);
834     }
835     else if (mxIsUint16(array_ptr))
836     {
837         ((UInt16 *)array_ptr)->resize((int *)dims, ndim);
838     }
839     else if (mxIsUint32(array_ptr))
840     {
841         ((UInt32 *)array_ptr)->resize((int *)dims, ndim);
842     }
843     else if (mxIsUint64(array_ptr))
844     {
845         ((UInt64 *)array_ptr)->resize((int *)dims, ndim);
846     }
847
848     return 0;
849 }
850
851 int mxGetNumberOfElements(const mxArray *ptr)
852 {
853     InternalType *pIT = (InternalType *)ptr;
854     if (pIT == NULL)
855     {
856         return 0;
857     }
858
859     GenericType *pGT = dynamic_cast<GenericType *>(pIT);
860     if (pGT == NULL)
861     {
862         return 0;
863     }
864
865     return pGT->getSize();
866 }
867
868 int mxCalcSingleSubscript(const mxArray *ptr, int nsubs, const int *subs)
869 {
870     int index = 0;
871     int iMult = 1;
872     mwSize *dims = mxGetDimensions(ptr);
873     for (int i = 0; i < nsubs; i++)
874     {
875         index += subs[i] * iMult;
876         iMult *= dims[i];
877     }
878     return index;
879 }
880
881 int mxGetM(const mxArray *ptr)
882 {
883     InternalType *pIT = (InternalType *)ptr;
884     if (pIT == NULL)
885     {
886         return 0;
887     }
888
889     GenericType *pGT = pIT->getAs<GenericType>();
890     if (pGT == NULL)
891     {
892         return 0;
893     }
894     return pGT->getRows();
895 }
896
897 void mxSetM(mxArray *ptr, int M)
898 {
899     InternalType *pIT = (InternalType *)ptr;
900     if (pIT == NULL)
901     {
902         return;
903     }
904
905     GenericType *pGT = pIT->getAs<GenericType>();
906     if (pGT == NULL)
907     {
908         return;
909     }
910
911     pGT->resize(M, pGT->getCols());
912 }
913
914 int mxGetN(const mxArray *ptr)
915 {
916     InternalType * pIT = (InternalType *)ptr;
917     if (pIT == NULL)
918     {
919         return 0;
920     }
921
922     GenericType * pGT = pIT->getAs<GenericType>();
923     if (pGT == 0)
924     {
925         return 0;
926     }
927     return pGT->getCols();
928 }
929
930 void mxSetN(mxArray *ptr, int N)
931 {
932     InternalType * pIT = (InternalType *)ptr;
933     if (pIT == NULL)
934     {
935         return;
936     }
937
938     GenericType * pGT = pIT->getAs<GenericType>();
939     if (pGT == NULL)
940     {
941         return;
942     }
943
944     pGT->resize(pGT->getRows(), N);
945 }
946
947 double mxGetScalar(const mxArray *ptr)
948 {
949     // TODO: review spec
950     InternalType *pIT = (InternalType *)ptr;
951     if (pIT == NULL)
952     {
953         return 0;
954     }
955
956     switch (pIT->getType())
957     {
958         case InternalType::ScilabDouble:
959         {
960             Double *pD = pIT->getAs<Double>();
961             return pD->get(0);
962         }
963         case InternalType::ScilabBool:
964         {
965             Bool *pB = pIT->getAs<Bool>();
966             return (double)pB->get(0);
967         }
968         case InternalType::ScilabInt8:
969         {
970             Int8 *pI = pIT->getAs<Int8>();
971             return (double)pI->get(0);
972         }
973         case InternalType::ScilabUInt8:
974         {
975             UInt8 *pI = pIT->getAs<UInt8>();
976             return (double)pI->get(0);
977         }
978         case InternalType::ScilabInt16:
979         {
980             Int16 *pI = pIT->getAs<Int16>();
981             return (double)pI->get(0);
982         }
983         case InternalType::ScilabUInt16:
984         {
985             UInt16 *pI = pIT->getAs<UInt16>();
986             return (double)pI->get(0);
987         }
988         case InternalType::ScilabInt32:
989         {
990             Int32 *pI = pIT->getAs<Int32>();
991             return (double)pI->get(0);
992         }
993         case InternalType::ScilabUInt32:
994         {
995             UInt32 *pI = pIT->getAs<UInt32>();
996             return (double)pI->get(0);
997         }
998         case InternalType::ScilabInt64:
999         {
1000             Int64 *pI = pIT->getAs<Int64>();
1001             return (double)pI->get(0);
1002         }
1003         case InternalType::ScilabUInt64:
1004         {
1005             UInt64 *pI = pIT->getAs<UInt64>();
1006             return (double)pI->get(0);
1007         }
1008         default:
1009             return 0;
1010     }
1011 }
1012
1013 double *mxGetPr(const mxArray *ptr)
1014 {
1015     InternalType *pIT = (InternalType *)ptr;
1016     if (pIT == NULL)
1017     {
1018         return NULL;
1019     }
1020
1021     Double *pD = dynamic_cast<Double *>(pIT);
1022     if (pD == NULL)
1023     {
1024         return NULL;
1025     }
1026
1027     return pD->get();
1028 }
1029
1030 void mxSetPr(mxArray *ptr, double *pr)
1031 {
1032     ((Double *)ptr)->set(pr);
1033 }
1034
1035 double *mxGetPi(const mxArray *ptr)
1036 {
1037     return ((Double *)ptr)->getImg();
1038 }
1039
1040 void mxSetPi(mxArray *ptr, double *pi)
1041 {
1042     ((Double *)ptr)->setImg(pi);
1043 }
1044
1045 void *mxGetData(const mxArray *ptr)
1046 {
1047     InternalType *pIT = (InternalType *)ptr;
1048     if (pIT == NULL)
1049     {
1050         return NULL;
1051     }
1052
1053     switch (pIT->getType())
1054     {
1055         case InternalType::ScilabDouble:
1056         {
1057             Double *pD = pIT->getAs<Double>();
1058             return pD->get();
1059         }
1060         case InternalType::ScilabBool:
1061         {
1062             Bool *pB = pIT->getAs<Bool>();
1063             return pB->get();
1064         }
1065         case InternalType::ScilabInt8:
1066         {
1067             Int8 *pI = pIT->getAs<Int8>();
1068             return pI->get();
1069         }
1070         case InternalType::ScilabUInt8:
1071         {
1072             UInt8 *pI = pIT->getAs<UInt8>();
1073             return pI->get();
1074         }
1075         case InternalType::ScilabInt16:
1076         {
1077             Int16 *pI = pIT->getAs<Int16>();
1078             return pI->get();
1079         }
1080         case InternalType::ScilabUInt16:
1081         {
1082             UInt16 *pI = pIT->getAs<UInt16>();
1083             return pI->get();
1084         }
1085         case InternalType::ScilabInt32:
1086         {
1087             Int32 *pI = pIT->getAs<Int32>();
1088             return pI->get();
1089         }
1090         case InternalType::ScilabUInt32:
1091         {
1092             UInt32 *pI = pIT->getAs<UInt32>();
1093             return pI->get();
1094         }
1095         case InternalType::ScilabInt64:
1096         {
1097             Int64 *pI = pIT->getAs<Int64>();
1098             return pI->get();
1099         }
1100         case InternalType::ScilabUInt64:
1101         {
1102             UInt64 *pI = pIT->getAs<UInt64>();
1103             return pI->get();
1104         }
1105         default:
1106             return NULL;
1107     }
1108 }
1109
1110 void mxSetData(mxArray *array_ptr, void *data_ptr)
1111 {
1112     if (mxIsChar(array_ptr))
1113     {
1114         ((String *)array_ptr)->set((wchar_t **)data_ptr);
1115     }
1116     else if (mxIsDouble(array_ptr))
1117     {
1118         ((Double *)array_ptr)->set((double *)data_ptr);
1119     }
1120     else if (mxIsInt8(array_ptr))
1121     {
1122         ((Int8 *)array_ptr)->set((char *)data_ptr);
1123     }
1124     else if (mxIsInt16(array_ptr))
1125     {
1126         ((Int16 *)array_ptr)->set((short *)data_ptr);
1127     }
1128     else if (mxIsInt32(array_ptr))
1129     {
1130         ((Int32 *)array_ptr)->set((int *)data_ptr);
1131     }
1132     else if (mxIsInt64(array_ptr))
1133     {
1134         ((Int64 *)array_ptr)->set((long long *)data_ptr);
1135     }
1136     else if (mxIsLogical(array_ptr))
1137     {
1138         ((Bool *)array_ptr)->set((int *)data_ptr);
1139     }
1140     // else if (mxIsSingle(array_ptr)) {
1141     //   ((Float *) array_ptr)->set((float *) data_ptr);
1142     // }
1143     else if (mxIsUint8(array_ptr))
1144     {
1145         ((UInt8 *)array_ptr)->set((unsigned char *)data_ptr);
1146     }
1147     else if (mxIsUint16(array_ptr))
1148     {
1149         ((UInt16 *)array_ptr)->set((unsigned short *)data_ptr);
1150     }
1151     else if (mxIsUint32(array_ptr))
1152     {
1153         ((UInt32 *)array_ptr)->set((unsigned int *)data_ptr);
1154     }
1155     else if (mxIsUint64(array_ptr))
1156     {
1157         ((UInt64 *)array_ptr)->set((unsigned long long *) data_ptr);
1158     }
1159 }
1160
1161 void *mxGetImagData(const mxArray *ptr)
1162 {
1163     InternalType *pIT = (InternalType *)ptr;
1164     if (pIT == NULL)
1165     {
1166         return NULL;
1167     }
1168
1169     switch (pIT->getType())
1170     {
1171         case InternalType::ScilabDouble:
1172         {
1173             Double *pD = pIT->getAs<Double>();
1174             return pD->getImg();
1175         }
1176         case InternalType::ScilabBool:
1177         {
1178             Bool *pB = pIT->getAs<Bool>();
1179             return pB->getImg();
1180         }
1181         case InternalType::ScilabInt8:
1182         {
1183             Int8 *pI = pIT->getAs<Int8>();
1184             return pI->getImg();
1185         }
1186         case InternalType::ScilabUInt8:
1187         {
1188             UInt8 *pI = pIT->getAs<UInt8>();
1189             return pI->getImg();
1190         }
1191         case InternalType::ScilabInt16:
1192         {
1193             Int16 *pI = pIT->getAs<Int16>();
1194             return pI->getImg();
1195         }
1196         case InternalType::ScilabUInt16:
1197         {
1198             UInt16 *pI = pIT->getAs<UInt16>();
1199             return pI->getImg();
1200         }
1201         case InternalType::ScilabInt32:
1202         {
1203             Int32 *pI = pIT->getAs<Int32>();
1204             return pI->getImg();
1205         }
1206         case InternalType::ScilabUInt32:
1207         {
1208             UInt32 *pI = pIT->getAs<UInt32>();
1209             return pI->getImg();
1210         }
1211         case InternalType::ScilabInt64:
1212         {
1213             Int64 *pI = pIT->getAs<Int64>();
1214             return pI->getImg();
1215         }
1216         case InternalType::ScilabUInt64:
1217         {
1218             UInt64 *pI = pIT->getAs<UInt64>();
1219             return pI->getImg();
1220         }
1221         default:
1222             return NULL;
1223     }
1224 }
1225
1226 void mxSetImagData(mxArray *array_ptr, void *data_ptr)
1227 {
1228     if (mxIsChar(array_ptr))
1229     {
1230         ((String *)array_ptr)->setImg((wchar_t **)data_ptr);
1231     }
1232     else if (mxIsDouble(array_ptr))
1233     {
1234         ((Double *)array_ptr)->setImg((double *)data_ptr);
1235     }
1236     else if (mxIsInt8(array_ptr))
1237     {
1238         ((Int8 *)array_ptr)->setImg((char *)data_ptr);
1239     }
1240     else if (mxIsInt16(array_ptr))
1241     {
1242         ((Int16 *)array_ptr)->setImg((short *)data_ptr);
1243     }
1244     else if (mxIsInt32(array_ptr))
1245     {
1246         ((Int32 *)array_ptr)->setImg((int *)data_ptr);
1247     }
1248     else if (mxIsInt64(array_ptr))
1249     {
1250         ((Int64 *)array_ptr)->setImg((long long *)data_ptr);
1251     }
1252     else if (mxIsLogical(array_ptr))
1253     {
1254         ((Bool *)array_ptr)->setImg((int *)data_ptr);
1255     }
1256     // else if (mxIsSingle(array_ptr)) {
1257     //   ((Float *) array_ptr)->setImg((float *) data_ptr);
1258     // }
1259     else if (mxIsUint8(array_ptr))
1260     {
1261         ((UInt8 *)array_ptr)->setImg((unsigned char *)data_ptr);
1262     }
1263     else if (mxIsUint16(array_ptr))
1264     {
1265         ((UInt16 *)array_ptr)->setImg((unsigned short *)data_ptr);
1266     }
1267     else if (mxIsUint32(array_ptr))
1268     {
1269         ((UInt32 *)array_ptr)->setImg((unsigned int *)data_ptr);
1270     }
1271     else if (mxIsUint64(array_ptr))
1272     {
1273         ((UInt64 *)array_ptr)->setImg((unsigned long long *) data_ptr);
1274     }
1275 }
1276
1277 mxChar *mxGetChars(mxArray *array_ptr)
1278 {
1279     if (!mxIsChar(array_ptr))
1280     {
1281         return NULL;
1282     }
1283     wchar_t *chars = ((String *)array_ptr)->get(0);
1284     return (mxChar *)wide_string_to_UTF8(chars);
1285 }
1286
1287 mxLogical *mxGetLogicals(const mxArray *ptr)
1288 {
1289     InternalType *pIT = (InternalType *)ptr;
1290     if (pIT == NULL)
1291     {
1292         return NULL;
1293     }
1294
1295     Bool *pB = pIT->getAs<Bool>();
1296     if (pB == NULL)
1297     {
1298         return NULL;
1299     }
1300
1301     return (mxLogical *)pB->get();
1302 }
1303
1304 mxClassID mxGetClassID(const mxArray *ptr)
1305 {
1306     InternalType *pIT = dynamic_cast<InternalType*>((InternalType*)ptr);
1307     if (pIT == NULL)
1308     {
1309         return mxUNKNOWN_CLASS;
1310     }
1311
1312     switch (pIT->getType())
1313     {
1314         case InternalType::ScilabInt8:
1315             return mxINT8_CLASS;
1316         case InternalType::ScilabUInt8:
1317             return mxUINT8_CLASS;
1318         case InternalType::ScilabInt16:
1319             return mxINT16_CLASS;
1320         case InternalType::ScilabUInt16:
1321             return mxUINT16_CLASS;
1322         case InternalType::ScilabInt32:
1323             return mxINT32_CLASS;
1324         case InternalType::ScilabUInt32:
1325             return mxUINT32_CLASS;
1326         case InternalType::ScilabInt64:
1327             return mxINT64_CLASS;
1328         case InternalType::ScilabUInt64:
1329             return mxUINT64_CLASS;
1330         case InternalType::ScilabString:
1331             return mxCHAR_CLASS;
1332         case InternalType::ScilabDouble:
1333             return mxDOUBLE_CLASS;
1334         case InternalType::ScilabBool:
1335             return mxLOGICAL_CLASS;
1336         case InternalType::ScilabFloat:
1337             return mxSINGLE_CLASS;
1338         case InternalType::ScilabStruct:
1339             return mxSTRUCT_CLASS;
1340         case InternalType::ScilabCell:
1341             return mxCELL_CLASS;
1342         case InternalType::ScilabFunction:
1343             return mxFUNCTION_CLASS;
1344         default:
1345             return mxUNKNOWN_CLASS;
1346     }
1347 }
1348
1349 const char *mxGetClassName(const mxArray *ptr)
1350 {
1351     if (mxIsDouble(ptr))
1352     {
1353         return "double";
1354     }
1355     if (mxIsChar(ptr))
1356     {
1357         return "char";
1358     }
1359     if (mxIsLogical(ptr))
1360     {
1361         return "bool";
1362     }
1363     if (mxIsSparse(ptr))
1364     {
1365         return "sparse";
1366     }
1367     if (mxIsInt8(ptr))
1368     {
1369         return "int8";
1370     }
1371     if (mxIsInt16(ptr))
1372     {
1373         return "int16";
1374     }
1375     if (mxIsInt32(ptr))
1376     {
1377         return "int32";
1378     }
1379     if (mxIsInt64(ptr))
1380     {
1381         return "int64";
1382     }
1383     if (mxIsUint8(ptr))
1384     {
1385         return "uint8";
1386     }
1387     if (mxIsUint16(ptr))
1388     {
1389         return "uint16";
1390     }
1391     if (mxIsUint32(ptr))
1392     {
1393         return "uint32";
1394     }
1395     if (mxIsUint64(ptr))
1396     {
1397         return "uint64";
1398     }
1399     if (mxIsCell(ptr))
1400     {
1401         return "cell";
1402     }
1403     if (mxIsStruct(ptr))
1404     {
1405         return "struct";
1406     }
1407     return "unknown";
1408 }
1409
1410 mxArray *mxGetProperty(const mxArray *pa, mwIndex index, const char *propname)
1411 {
1412     //TODO
1413     return NULL;
1414 }
1415
1416 void mxSetProperty(mxArray *pa, mwIndex index, const char *propname, const mxArray *value)
1417 {
1418     //TODO
1419 }
1420
1421 mxArray *mxGetField(const mxArray *ptr, int lindex, const char *string)
1422 {
1423     int field_num = mxGetFieldNumber(ptr, string);
1424     if (field_num < 0)
1425     {
1426         return NULL;
1427     }
1428     return mxGetFieldByNumber(ptr, lindex, field_num);
1429 }
1430
1431 void mxSetField(mxArray *array_ptr, int lindex, const char *field_name, mxArray *value)
1432 {
1433     int field_num = mxGetFieldNumber(array_ptr, field_name);
1434     if (field_num >= 0)
1435     {
1436         mxSetFieldByNumber(array_ptr, lindex, field_num, value);
1437     }
1438 }
1439
1440 int mxGetNumberOfFields(const mxArray *ptr)
1441 {
1442     if (!mxIsStruct(ptr))
1443     {
1444         return 0;
1445     }
1446     Struct * pa = (Struct *)ptr;
1447     return pa->getFieldNames()->getSize();
1448 }
1449
1450 const char *mxGetFieldNameByNumber(const mxArray *array_ptr, int field_number)
1451 {
1452     if (!mxIsStruct(array_ptr))
1453     {
1454         return NULL;
1455     }
1456     if (field_number < 0 || field_number >= mxGetNumberOfFields(array_ptr))
1457     {
1458         return NULL;
1459     }
1460     String *names = ((Struct *)array_ptr)->getFieldNames();
1461     wchar_t *name = names->get(field_number);
1462     return (const char *)wide_string_to_UTF8(name);
1463 }
1464
1465 int mxGetFieldNumber(const mxArray *ptr, const char *string)
1466 {
1467     if (!mxIsStruct(ptr))
1468     {
1469         return -1;
1470     }
1471     Struct *pa = (Struct *)ptr;
1472     String *names = pa->getFieldNames();
1473     wchar_t *field_name = to_wide_string(string);
1474
1475     for (int i = 0; i < names->getSize(); i++)
1476     {
1477         if (wcscmp(names->get(i), field_name) == 0)
1478         {
1479             FREE(field_name);
1480             return i;
1481         }
1482     }
1483     FREE(field_name);
1484     return -1;
1485 }
1486
1487 mxArray *mxGetFieldByNumber(const mxArray *ptr, int lindex, int field_number)
1488 {
1489     if (!mxIsStruct(ptr))
1490     {
1491         return NULL;
1492     }
1493     if (lindex >= mxGetNumberOfElements(ptr) || lindex < 0)
1494     {
1495         return NULL;
1496     }
1497     if (field_number >= mxGetNumberOfFields(ptr) || field_number < 0)
1498     {
1499         return NULL;
1500     }
1501     Struct *pa = (Struct *)ptr;
1502     String *names = pa->getFieldNames();
1503     SingleStruct *s = pa->get(lindex);
1504     return (mxArray *)s->get(names->get(field_number));
1505 }
1506
1507 void mxSetFieldByNumber(mxArray *array_ptr, int lindex, int field_number, mxArray *value)
1508 {
1509     if (mxIsStruct(array_ptr) && lindex < mxGetNumberOfElements(array_ptr))
1510     {
1511         SingleStruct *ptr = ((Struct *)array_ptr)->get(lindex);
1512         String *names = ptr->getFieldNames();
1513         ptr->set(names->get(field_number), (InternalType *)value);
1514     }
1515 }
1516
1517 int mxAddField(mxArray *ptr, const char *fieldname)
1518 {
1519     if (!mxIsStruct(ptr))
1520     {
1521         return -1;
1522     }
1523     Struct *pa = (Struct *)ptr;
1524     wchar_t *wfieldname = to_wide_string(fieldname);
1525     pa->addField(wfieldname);
1526     return mxGetFieldNumber(ptr, fieldname);
1527 }
1528
1529 void mxRemoveField(mxArray *pm, int fieldnumber)
1530 {
1531     //TODO
1532 }
1533
1534 mxArray *mxGetCell(const mxArray *ptr, int lindex)
1535 {
1536     Cell * pa = (Cell *)ptr;
1537     return (mxArray *)pa->get(lindex);
1538 }
1539
1540 void mxSetCell(mxArray *array_ptr, int lindex, mxArray *value)
1541 {
1542     ((Cell *)array_ptr)->set(lindex, (InternalType *)value);
1543 }
1544
1545 int mxGetNzmax(const mxArray *ptr)
1546 {
1547     // TODO
1548     return 0;
1549 }
1550
1551 void mxSetNzmax(mxArray *array_ptr, int nzmax)
1552 {
1553     // TODO
1554 }
1555
1556 int *mxGetIr(const mxArray *ptr)
1557 {
1558     // TODO
1559     return NULL;
1560 }
1561
1562 void mxSetIr(mxArray *array_ptr, int *ir_data)
1563 {
1564     // TODO
1565 }
1566
1567 int *mxGetJc(const mxArray *ptr)
1568 {
1569     // TODO
1570     return NULL;
1571 }
1572
1573 void mxSetJc(mxArray *array_ptr, int *jc_data)
1574 {
1575     // TODO
1576 }
1577
1578 void setmexFunctionName(const char* name)
1579 {
1580     ConfigVariable::setMexFunctionName(name);
1581 }
1582
1583 const char *mexFunctionName(void)
1584 {
1585     return ConfigVariable::getMexFunctionName().c_str();
1586 }
1587
1588 int mexAtExit(void(*func)(void))
1589 {
1590     exitFcn = func;
1591     return 0;
1592 }
1593
1594 int mexCallMATLAB(int nlhs, mxArray **plhs, int nrhs, mxArray **prhs, const char *name)
1595 {
1596     return mexCallSCILAB(nlhs, plhs, nrhs, prhs, name);;
1597 }
1598
1599 mxArray *mexCallMATLABWithTrap(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], const char *functionName)
1600 {
1601     //TODO
1602     return NULL;
1603 }
1604
1605 int mexEvalString(const char *name)
1606 {
1607     types::typed_list in;
1608     types::typed_list out;
1609     in.push_back(new types::String(name));
1610     ast::ExecVisitor execMe;
1611     types::Callable::ReturnValue ret = Overload::call(L"execstr", in, 1, out, &execMe);
1612     in.back()->killMe();
1613     if (ret != types::Callable::OK)
1614     {
1615         return 1;
1616     }
1617
1618     return 0;
1619 }
1620
1621 mxArray *mexEvalStringWithTrap(const char *command)
1622 {
1623     //TODO
1624     return NULL;
1625 }
1626
1627 const mxArray *mexGet(double handle, const char *property)
1628 {
1629     //TODO
1630     return NULL;
1631 }
1632
1633 int mexSet(double handle, const char *property, mxArray *value)
1634 {
1635     //TODO
1636     return 0;
1637 }
1638
1639 mxArray *mexGetVariable(const char *workspace, const char *name)
1640 {
1641     mxArray* ret = NULL;
1642     const mxArray* ptr = mexGetVariablePtr(workspace, name);
1643
1644     if (ptr)
1645     {
1646         ret = (mxArray*)((InternalType*)ptr)->clone();
1647     }
1648     return ret;
1649 }
1650
1651 const mxArray *mexGetVariablePtr(const char *workspace, const char *name)
1652 {
1653     symbol::Context *context = symbol::Context::getInstance();
1654     wchar_t *key = to_wide_string(name);
1655     InternalType *value = NULL;
1656     symbol::Symbol sym = symbol::Symbol(key);
1657     if (strcmp(workspace, "base") == 0)
1658     {
1659         value = context->get(sym);
1660     }
1661     else if (strcmp(workspace, "caller") == 0)
1662     {
1663         if (context->isGlobalVisible(sym) == false)
1664         {
1665             value = context->get(sym);
1666         }
1667     }
1668     else if (strcmp(workspace, "global") == 0)
1669     {
1670         if (context->isGlobalVisible(sym))
1671         {
1672             value = context->getGlobalValue(sym);
1673         }
1674     }
1675     FREE(key);
1676     return (mxArray *)value;
1677 }
1678
1679 int mexPutVariable(const char *workspace, const char *varname, const mxArray *pm)
1680 {
1681     symbol::Context *context = symbol::Context::getInstance();
1682     wchar_t *dest = to_wide_string(varname);
1683     if (strcmp(workspace, "base") == 0)
1684     {
1685         context->putInPreviousScope(context->getOrCreate(symbol::Symbol(dest)), (InternalType *)pm);
1686     }
1687     else if (strcmp(workspace, "caller") == 0)
1688     {
1689         context->put(symbol::Symbol(dest), (InternalType *)pm);
1690     }
1691     else if (strcmp(workspace, "global") == 0)
1692     {
1693         context->setGlobalVisible(symbol::Symbol(dest), true);
1694         context->put(symbol::Symbol(dest), (InternalType *)pm);
1695     }
1696     else
1697     {
1698         return 1;
1699     }
1700     return 0;
1701 }
1702
1703 int mexIsGlobal(const mxArray *ptr)
1704 {
1705     symbol::Context *context = symbol::Context::getInstance();
1706     std::list<std::wstring> lst;
1707     int size = context->getGlobalNameForWho(lst, false);
1708
1709     for (auto it : lst)
1710     {
1711         symbol::Symbol s = symbol::Symbol(it);
1712         const mxArray *value = (const mxArray *)context->getGlobalValue(s);
1713         if (value == ptr)
1714         {
1715             return 1;
1716         }
1717     }
1718     return 0;
1719 }
1720
1721 int mexPrintf(const char *format, ...)
1722 {
1723     // TODO: define this size limit
1724     char string[1024];
1725     va_list arg_ptr;
1726     va_start(arg_ptr, format);
1727     vsnprintf(string, 1024, format, arg_ptr);
1728     va_end(arg_ptr);
1729     scilabWrite(string);
1730     return 0;
1731 }
1732
1733 void mexSetTrapFlag(int trapflag)
1734 {
1735     //TODO
1736 }
1737
1738 void mexErrMsgIdAndTxt(const char *errorid, const char *errormsg, ...)
1739 {
1740     //TODO
1741 }
1742
1743 void mexWarnMsgIdAndTxt(const char *warningid, const char *warningmsg, ...)
1744 {
1745     //TODO
1746 }
1747
1748 void mexErrMsgTxt(const char *error_msg)
1749 {
1750     throw ast::InternalError(error_msg);
1751 }
1752
1753 void mexWarnMsgTxt(const char *error_msg)
1754 {
1755     scilabError(_("Warning: "));
1756     scilabError(error_msg);
1757     scilabError("\n\n");
1758 }
1759
1760 int mexIsLocked(void)
1761 {
1762     //TODO
1763     return 0;
1764 }
1765
1766 void mexLock(void)
1767 {
1768     //TODO
1769 }
1770
1771 void mexUnlock(void)
1772 {
1773     //TODO
1774 }
1775
1776 void mexMakeArrayPersistent(void *ptr)
1777 {
1778     //TODO
1779 }
1780
1781 void mexMakeMemoryPersistent(void *ptr)
1782 {
1783     //TODO
1784 }
1785
1786 double mxGetInf(void)
1787 {
1788     InternalType *pITInf = symbol::Context::getInstance()->get(symbol::Symbol(L"%inf"));
1789     if (pITInf && pITInf->isDouble())
1790     {
1791         return pITInf->getAs<Double>()->get(0);
1792     }
1793
1794     return -1;
1795 }
1796
1797 double mxGetNaN(void)
1798 {
1799     InternalType *pITInf = symbol::Context::getInstance()->get(symbol::Symbol(L"%nan"));
1800     if (pITInf)
1801     {
1802         return pITInf->getAs<Double>()->get(0);
1803     }
1804
1805     return -1;
1806 }
1807
1808 double mxGetEps(void)
1809 {
1810     InternalType *pITEps = symbol::Context::getInstance()->get(symbol::Symbol(L"%eps"));
1811     if (pITEps && pITEps->isDouble())
1812     {
1813         return pITEps->getAs<Double>()->get(0);
1814     }
1815
1816     return -1;
1817 }
1818