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