19fbd058819ae1256cf4a303750ba834e41a3324
[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
1608     // TODO : call execstr
1609
1610     //    // TODO: It is almost copied from sci_execstr.cpp. Refactor needed!
1611     //    int iErr = 0;
1612     //    bool bErrCatch = false;
1613     //    bool bMute = true;
1614     //    Parser parser;
1615     //    parser.parse(to_wide_string(name));
1616     //    if (parser.getExitStatus() != Parser::Succeded)
1617     //    {
1618     //        //mexPrintf(wide_string_to_UTF8(parser.getErrorMessage()));
1619     //        return 1;
1620     //    }
1621     //
1622     //    ast::Exp *pExp = parser.getTree();
1623     //
1624     //    if (pExp == NULL)
1625     //    {
1626     //        //mexPrintf("pExp is NULL");
1627     //        return 1;
1628     //    }
1629     //
1630     //    //save current prompt mode
1631     //    int oldVal = ConfigVariable::getPromptMode();
1632     //    if (bMute)
1633     //    {
1634     //        ConfigVariable::setPromptMode(-1);
1635     //    }
1636     //    ast::exps_t LExp = pExp->getAs<ast::SeqExp>()->getExps();
1637     //
1638     //    for (ast::exps_t::iterator j = LExp.begin(), itEnd = LExp.end(); j != itEnd; ++j)
1639     //    {
1640     //        try
1641     //        {
1642     //            //excecute script
1643     //            ast::ExecVisitor execMe;
1644     //            (*j)->accept(execMe);
1645     //
1646     //            //to manage call without ()
1647     //            if (execMe.getResult() != NULL && execMe.getResult()->getAs<Callable>())
1648     //            {
1649     //                Callable *pCall = execMe.getResult()->getAs<Callable>();
1650     //                typed_list out;
1651     //                typed_list in;
1652     //                optional_list opt;
1653     //                try
1654     //                {
1655     //                    ast::ExecVisitor execCall;
1656     //                    Function::ReturnValue Ret = pCall->call(in, opt, 1, out, &execCall);
1657     //                    if (Ret == Callable::OK)
1658     //                    {
1659     //                        if (out.size() == 0)
1660     //                        {
1661     //                            execMe.setResult(NULL);
1662     //                        }
1663     //                        else if (out.size() == 1)
1664     //                        {
1665     //                            out[0]->DecreaseRef();
1666     //                            execMe.setResult(out[0]);
1667     //                        }
1668     //                        else
1669     //                        {
1670     //                            for (int i = 0; i < static_cast<int>(out.size()); i++)
1671     //                            {
1672     //                                out[i]->DecreaseRef();
1673     //                                execMe.setResult(i, out[i]);
1674     //                            }
1675     //                        }
1676     //                    }
1677     //                    else if (Ret == Callable::Error)
1678     //                    {
1679     //                        if (ConfigVariable::getLastErrorFunction() == L"")
1680     //                        {
1681     //                            ConfigVariable::setLastErrorFunction(pCall->getName());
1682     //                        }
1683     //
1684     //                        if (pCall->isMacro() || pCall->isMacroFile())
1685     //                        {
1686     //                            wchar_t szError[bsiz];
1687     //                            os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*j)->getLocation().first_line, pCall->getName().c_str());
1688     //                            throw ast::ScilabMessage(szError);
1689     //                        }
1690     //                        else
1691     //                        {
1692     //                            throw ast::ScilabMessage();
1693     //                        }
1694     //                    }
1695     //                }
1696     //                catch (ast::ScilabMessage sm)
1697     //                {
1698     //                    wostringstream os;
1699     //                    ast::PrintVisitor printMe(os);
1700     //                    (*j)->accept(printMe);
1701     //                    os << std::endl << std::endl;
1702     //                    if (ConfigVariable::getLastErrorFunction() == L"")
1703     //                    {
1704     //                        ConfigVariable::setLastErrorFunction(pCall->getName());
1705     //                    }
1706     //
1707     //                    if (pCall->isMacro() || pCall->isMacroFile())
1708     //                    {
1709     //                        wstring szAllError;
1710     //                        wchar_t szError[bsiz];
1711     //                        os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
1712     //                        szAllError = szError + os.str();
1713     //                        os_swprintf(szError, bsiz, _W("in  execstr instruction    called by :\n").c_str());
1714     //                        szAllError += szError;
1715     //                        throw ast::ScilabMessage(szAllError);
1716     //                    }
1717     //                    else
1718     //                    {
1719     //                        sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
1720     //                        throw sm;
1721     //                    }
1722     //                }
1723     //            }
1724     //
1725     //            //update ans variable.
1726     //            if (execMe.getResult() != NULL && execMe.getResult()->isDeletable())
1727     //            {
1728     //                symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), execMe.getResult());
1729     //                if ((*j)->isVerbose() && bErrCatch == false)
1730     //                {
1731     //                    std::wostringstream ostr;
1732     //                    ostr << L"ans = " << std::endl;
1733     //                    ostr << std::endl;
1734     //                    execMe.getResult()->toString(ostr);
1735     //                    ostr << std::endl;
1736     //                    scilabWriteW(ostr.str().c_str());
1737     //                }
1738     //            }
1739     //        }
1740     //        catch (ast::ScilabMessage sm)
1741     //        {
1742     //            if (bErrCatch == false && bMute == false)
1743     //            {
1744     //                scilabErrorW(sm.GetErrorMessage().c_str());
1745     //
1746     //                ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(*j);
1747     //                if (pCall != NULL)
1748     //                {
1749     //                    //to print call expression only of it is a macro
1750     //                    ast::ExecVisitor execFunc;
1751     //                    pCall->getName().accept(execFunc);
1752     //
1753     //                    if (execFunc.getResult() != NULL &&
1754     //                            (execFunc.getResult()->isMacro() || execFunc.getResult()->isMacroFile()))
1755     //                    {
1756     //                        wostringstream os;
1757     //
1758     //                        //add function failed
1759     //                        ast::PrintVisitor printMe(os);
1760     //                        pCall->accept(printMe);
1761     //                        os << std::endl;
1762     //
1763     //                        //add info on file failed
1764     //                        wchar_t szError[bsiz];
1765     //                        os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->getLocation().first_line);
1766     //                        os << szError;
1767     //
1768     //                        if (ConfigVariable::getLastErrorFunction() == L"")
1769     //                        {
1770     //                            ConfigVariable::setLastErrorFunction(execFunc.getResult()->getAs<Callable>()->getName());
1771     //                        }
1772     //
1773     //                        //restore previous prompt mode
1774     //                        ConfigVariable::setPromptMode(oldVal);
1775     //                        throw ast::ScilabMessage(os.str(), 0, (*j)->getLocation());
1776     //                    }
1777     //                }
1778     //                throw ast::ScilabMessage((*j)->getLocation());
1779     //            }
1780     //            else
1781     //            {
1782     //                iErr = ConfigVariable::getLastErrorNumber();
1783     //                break;
1784     //            }
1785     //        }
1786     //        catch (ast::ScilabError se)
1787     //        {
1788     //            if (ConfigVariable::getLastErrorMessage() == L"")
1789     //            {
1790     //                ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
1791     //                ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
1792     //                ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
1793     //                ConfigVariable::setLastErrorFunction(wstring(L""));
1794     //            }
1795     //
1796     //            //store message
1797     //            iErr = ConfigVariable::getLastErrorNumber();
1798     //            if (bErrCatch == false)
1799     //            {
1800     //                //in case of error, change mode to 2 ( prompt )
1801     //                ConfigVariable::setPromptMode(2);
1802     //                //write error
1803     //                scilabErrorW(ConfigVariable::getLastErrorMessage().c_str());
1804     //                scilabErrorW(L"\n");
1805     //
1806     //                //write positino
1807     //                wchar_t szError[bsiz];
1808     //                os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->getLocation().first_line);
1809     //                //restore previous prompt mode
1810     //                ConfigVariable::setPromptMode(oldVal);
1811     //                throw ast::ScilabMessage(szError, 1, (*j)->getLocation());
1812     //            }
1813     //            break;
1814     //        }
1815     //    }
1816     //
1817     //    //restore previous prompt mode
1818     //    ConfigVariable::setPromptMode(oldVal);
1819     //
1820     //    delete parser.getTree();
1821     return 0;
1822 }
1823
1824 mxArray *mexEvalStringWithTrap(const char *command)
1825 {
1826     //TODO
1827     return NULL;
1828 }
1829
1830 const mxArray *mexGet(double handle, const char *property)
1831 {
1832     //TODO
1833     return NULL;
1834 }
1835
1836 int mexSet(double handle, const char *property, mxArray *value)
1837 {
1838     //TODO
1839     return 0;
1840 }
1841
1842 mxArray *mexGetVariable(const char *workspace, const char *name)
1843 {
1844     mxArray* ret = NULL;
1845     const mxArray* ptr = mexGetVariablePtr(workspace, name);
1846
1847     if (ptr)
1848     {
1849         ret = (mxArray*)((InternalType*)ptr)->clone();
1850     }
1851     return ret;
1852 }
1853
1854 const mxArray *mexGetVariablePtr(const char *workspace, const char *name)
1855 {
1856     symbol::Context *context = symbol::Context::getInstance();
1857     wchar_t *key = to_wide_string(name);
1858     InternalType *value = NULL;
1859     symbol::Symbol sym = symbol::Symbol(key);
1860     if (strcmp(workspace, "base") == 0)
1861     {
1862         value = context->get(sym);
1863     }
1864     else if (strcmp(workspace, "caller") == 0)
1865     {
1866         if (context->isGlobalVisible(sym) == false)
1867         {
1868             value = context->get(sym);
1869         }
1870     }
1871     else if (strcmp(workspace, "global") == 0)
1872     {
1873         if (context->isGlobalVisible(sym))
1874         {
1875             value = context->getGlobalValue(sym);
1876         }
1877     }
1878     FREE(key);
1879     return (mxArray *)value;
1880 }
1881
1882 int mexPutVariable(const char *workspace, const char *varname, const mxArray *pm)
1883 {
1884     symbol::Context *context = symbol::Context::getInstance();
1885     wchar_t *dest = to_wide_string(varname);
1886     if (strcmp(workspace, "base") == 0)
1887     {
1888         context->putInPreviousScope(context->getOrCreate(symbol::Symbol(dest)), (InternalType *)pm);
1889     }
1890     else if (strcmp(workspace, "caller") == 0)
1891     {
1892         context->put(symbol::Symbol(dest), (InternalType *)pm);
1893     }
1894     else if (strcmp(workspace, "global") == 0)
1895     {
1896         context->setGlobalVisible(symbol::Symbol(dest), true);
1897         context->put(symbol::Symbol(dest), (InternalType *)pm);
1898     }
1899     else
1900     {
1901         return 1;
1902     }
1903     return 0;
1904 }
1905
1906 int mexIsGlobal(const mxArray *ptr)
1907 {
1908     symbol::Context *context = symbol::Context::getInstance();
1909     std::list<std::wstring> lst;
1910     int size = context->getGlobalNameForWho(lst, false);
1911
1912     for (auto it : lst)
1913     {
1914         symbol::Symbol s = symbol::Symbol(it);
1915         const mxArray *value = (const mxArray *)context->getGlobalValue(s);
1916         if (value == ptr)
1917         {
1918             return 1;
1919         }
1920     }
1921     return 0;
1922 }
1923
1924 int mexPrintf(const char *format, ...)
1925 {
1926     // TODO: define this size limit
1927     char string[1024];
1928     va_list arg_ptr;
1929     va_start(arg_ptr, format);
1930     vsnprintf(string, 1024, format, arg_ptr);
1931     va_end(arg_ptr);
1932     scilabWrite(string);
1933     return 0;
1934 }
1935
1936 void mexSetTrapFlag(int trapflag)
1937 {
1938     //TODO
1939 }
1940
1941 void mexErrMsgIdAndTxt(const char *errorid, const char *errormsg, ...)
1942 {
1943     //TODO
1944 }
1945
1946 void mexWarnMsgIdAndTxt(const char *warningid, const char *warningmsg, ...)
1947 {
1948     //TODO
1949 }
1950
1951 void mexErrMsgTxt(const char *error_msg)
1952 {
1953     throw ast::InternalError(error_msg);
1954 }
1955
1956 void mexWarnMsgTxt(const char *error_msg)
1957 {
1958     scilabError(_("Warning: "));
1959     scilabError(error_msg);
1960     scilabError("\n\n");
1961 }
1962
1963 int mexIsLocked(void)
1964 {
1965     //TODO
1966     return 0;
1967 }
1968
1969 void mexLock(void)
1970 {
1971     //TODO
1972 }
1973
1974 void mexUnlock(void)
1975 {
1976     //TODO
1977 }
1978
1979 void mexMakeArrayPersistent(void *ptr)
1980 {
1981     //TODO
1982 }
1983
1984 void mexMakeMemoryPersistent(void *ptr)
1985 {
1986     //TODO
1987 }
1988
1989 double mxGetInf(void)
1990 {
1991     InternalType *pITInf = symbol::Context::getInstance()->get(symbol::Symbol(L"%inf"));
1992     if (pITInf && pITInf->isDouble())
1993     {
1994         return pITInf->getAs<Double>()->get(0);
1995     }
1996
1997     return -1;
1998 }
1999
2000 double mxGetNaN(void)
2001 {
2002     InternalType *pITInf = symbol::Context::getInstance()->get(symbol::Symbol(L"%nan"));
2003     if (pITInf)
2004     {
2005         return pITInf->getAs<Double>()->get(0);
2006     }
2007
2008     return -1;
2009 }
2010
2011 double mxGetEps(void)
2012 {
2013     InternalType *pITEps = symbol::Context::getInstance()->get(symbol::Symbol(L"%eps"));
2014     if (pITEps && pITEps->isDouble())
2015     {
2016         return pITEps->getAs<Double>()->get(0);
2017     }
2018
2019     return -1;
2020 }
2021