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