Replace Min, Max and Abs by std::min, std::max and std::abs
[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
52 #include "scilabWrite.hxx"
53 #include "context.hxx"
54 #include "symbol.hxx"
55 #include "parser.hxx"
56 #include "configvariable.hxx"
57 #include "overload.hxx"
58 #include "execvisitor.hxx"
59 #include "printvisitor.hxx"
60
61 #include "types.hxx"
62 #include "int.hxx"
63 #include "double.hxx"
64 #include "bool.hxx"
65 #include "string.hxx"
66 #include "struct.hxx"
67 #include "container.hxx"
68 #include "cell.hxx"
69 #include "localization.hxx"
70
71 extern "C"
72 {
73 #include "machine.h"
74 #include "mex.h"
75 #include "freeArrayOfString.h"
76 #include "os_swprintf.h"
77 }
78
79 #ifdef getType
80 #undef getType
81 #endif
82
83 #ifdef isComplex
84 #undef isComplex
85 #endif
86
87 using namespace ast;
88 static char *the_current_mex_name;
89 static void (*exitFcn)(void);
90
91 mxClassID mxGetClassID(const mxArray *ptr)
92 {
93     types::InternalType *pIT = (types::InternalType *) ptr;
94     if (pIT == NULL)
95     {
96         return mxUNKNOWN_CLASS;
97     }
98     types::InternalType::ScilabType type = pIT->getType();
99
100     switch (type)
101     {
102         case types::InternalType::ScilabInt8:
103             return mxINT8_CLASS;
104         case types::InternalType::ScilabUInt8:
105             return mxUINT8_CLASS;
106         case types::InternalType::ScilabInt16:
107             return mxINT16_CLASS;
108         case types::InternalType::ScilabUInt16:
109             return mxUINT16_CLASS;
110         case types::InternalType::ScilabInt32:
111             return mxINT32_CLASS;
112         case types::InternalType::ScilabUInt32:
113             return mxUINT32_CLASS;
114         case types::InternalType::ScilabInt64:
115             return mxINT64_CLASS;
116         case types::InternalType::ScilabUInt64:
117             return mxUINT64_CLASS;
118         case types::InternalType::ScilabString:
119             return mxCHAR_CLASS;
120         case types::InternalType::ScilabDouble:
121             return mxDOUBLE_CLASS;
122         case types::InternalType::ScilabBool:
123             return mxLOGICAL_CLASS;
124         case types::InternalType::ScilabFloat:
125             return mxSINGLE_CLASS;
126         case types::InternalType::ScilabStruct:
127             return mxSTRUCT_CLASS;
128         case types::InternalType::ScilabCell:
129             return mxCELL_CLASS;
130         case types::InternalType::ScilabFunction:
131             return mxFUNCTION_CLASS;
132         default:
133             return mxUNKNOWN_CLASS;
134     }
135 }
136
137 bool mxIsInt8(const mxArray *ptr)
138 {
139     return mxGetClassID(ptr) == mxINT8_CLASS;
140 }
141
142 bool mxIsInt16(const mxArray *ptr)
143 {
144     return mxGetClassID(ptr) == mxINT16_CLASS;
145 }
146
147 bool mxIsInt32(const mxArray *ptr)
148 {
149     return mxGetClassID(ptr) == mxINT32_CLASS;
150 }
151
152 bool mxIsInt64(const mxArray *ptr)
153 {
154     return mxGetClassID(ptr) == mxINT64_CLASS;
155 }
156
157 bool mxIsUint8(const mxArray *ptr)
158 {
159     return mxGetClassID(ptr) == mxUINT8_CLASS;
160 }
161
162 bool mxIsUint16(const mxArray *ptr)
163 {
164     return mxGetClassID(ptr) == mxUINT16_CLASS;
165 }
166
167 bool mxIsUint32(const mxArray *ptr)
168 {
169     return mxGetClassID(ptr) == mxUINT32_CLASS;
170 }
171
172 bool mxIsUint64(const mxArray *ptr)
173 {
174     return mxGetClassID(ptr) == mxUINT64_CLASS;
175 }
176
177 bool mxIsFunction(const mxArray *ptr)
178 {
179     return mxGetClassID(ptr) == mxFUNCTION_CLASS;
180 }
181
182 double mxGetEps(void)
183 {
184     types::InternalType *pITEps = symbol::Context::getInstance()->get(symbol::Symbol(L"%eps"));
185     if (pITEps && pITEps->isDouble())
186     {
187         return pITEps->getAs<types::Double>()->get(0);
188     }
189
190     return -1;
191 }
192
193 double mxGetInf(void)
194 {
195     types::InternalType *pITInf = symbol::Context::getInstance()->get(symbol::Symbol(L"%inf"));
196     if (pITInf && pITInf->isDouble())
197     {
198         return pITInf->getAs<types::Double>()->get(0);
199     }
200
201     return -1;
202 }
203
204 double mxGetNaN(void)
205 {
206     types::InternalType *pITInf = symbol::Context::getInstance()->get(symbol::Symbol(L"%nan"));
207     if (pITInf)
208     {
209         return pITInf->getAs<types::Double>()->get(0);
210     }
211
212     return -1;
213 }
214
215 bool mxIsInf(double x)
216 {
217     if (x == x + 1)
218     {
219         return 1;
220     }
221     else
222     {
223         return 0;
224     }
225 }
226
227 bool mxIsFinite(double x)
228 {
229     if (x < x + 1)
230     {
231         return 1;
232     }
233     else
234     {
235         return 0;
236     }
237 }
238
239 bool mxIsNaN(double x)
240 {
241     if (x != x)
242     {
243         return 1;
244     }
245     else
246     {
247         return 0;
248     }
249 }
250
251 int mxGetNumberOfElements(const mxArray *ptr)
252 {
253     types::InternalType *pIT = (types::InternalType *) ptr;
254     if (pIT == NULL)
255     {
256         return 0;
257     }
258
259     types::GenericType *pGT = dynamic_cast<types::GenericType *>(pIT);
260     if (pGT == NULL)
261     {
262         return 0;
263     }
264
265     return pGT->getSize();
266 }
267
268 double *mxGetPr(const mxArray *ptr)
269 {
270     types::InternalType *pIT = (types::InternalType *) ptr;
271     if (pIT == NULL)
272     {
273         return NULL;
274     }
275
276     types::Double *pD = dynamic_cast<types::Double *>(pIT);
277     if (pD == NULL)
278     {
279         return NULL;
280     }
281
282     return pD->get();
283 }
284
285 double *mxGetPi(const mxArray *ptr)
286 {
287     return ((types::Double *) ptr)->getImg();
288 }
289
290 int mxGetNumberOfDimensions(const mxArray *ptr)
291 {
292     types::InternalType *pIT = (types::InternalType *) ptr;
293     if (pIT == NULL)
294     {
295         return 0;
296     }
297
298     types::GenericType *pGT = pIT->getAs<types::GenericType>();
299     if (pGT == NULL)
300     {
301         //InternalType but not GenericType, so mono dimension type.
302         return 1;
303     }
304
305     return pGT->getDims();
306 }
307
308 int *mxGetDimensions(const mxArray *ptr)
309 {
310     types::InternalType *pIT = (types::InternalType *) ptr;
311     if (pIT == NULL)
312     {
313         return NULL;
314     }
315
316     switch (pIT->getType())
317     {
318         case types::InternalType::ScilabList:
319         case types::InternalType::ScilabMList:
320         case types::InternalType::ScilabTList:
321         {
322             int *piDims = (int *) MALLOC(sizeof(int));
323
324             piDims[0] = pIT->getAs<types::Container>()->getSize();
325             return piDims;
326         }
327         default:
328         {
329             types::GenericType *pGT = pIT->getAs<types::GenericType>();
330             if (pGT == NULL)
331             {
332                 return NULL;
333             }
334             return pGT->getDimsArray();
335         }
336     }
337     return NULL;
338 }
339
340 int mxGetM(const mxArray *ptr)
341 {
342     types::InternalType *pIT = (types::InternalType *) ptr;
343     if (pIT == NULL)
344     {
345         return 0;
346     }
347
348     types::GenericType *pGT = pIT->getAs<types::GenericType>();
349     if (pGT == NULL)
350     {
351         return 0;
352     }
353     return pGT->getRows();
354 }
355
356 void mxSetM(mxArray *ptr, int M)
357 {
358     types::InternalType *pIT = (types::InternalType *) ptr;
359     if (pIT == NULL)
360     {
361         return;
362     }
363
364     types::GenericType *pGT = pIT->getAs<types::GenericType>();
365     if (pGT == NULL)
366     {
367         return;
368     }
369
370     pGT->resize(M, pGT->getCols());
371 }
372
373 int *mxGetJc(const mxArray *ptr)
374 {
375     // TODO: sparse
376     return NULL;
377 }
378
379 int *mxGetIr(const mxArray *ptr)
380 {
381     // TODO: sparse
382     return NULL;
383 }
384
385 void mxSetJc(mxArray *array_ptr, int *jc_data)
386 {
387     // TODO: sparse
388 }
389
390 void mxSetIr(mxArray *array_ptr, int *ir_data)
391 {
392     // TODO: sparse
393 }
394
395 void mxSetNzmax(mxArray *array_ptr, int nzmax)
396 {
397     // TODO: sparse
398 }
399
400 int mxGetN(const mxArray *ptr)
401 {
402     types::InternalType * pIT = (types::InternalType *) ptr;
403     if (pIT == NULL)
404     {
405         return 0;
406     }
407
408     types::GenericType * pGT = pIT->getAs<types::GenericType>();
409     if (pGT == 0)
410     {
411         return 0;
412     }
413     return pGT->getCols();
414 }
415
416 void mxSetN(mxArray *ptr, int N)
417 {
418     types::InternalType * pIT = (types::InternalType *) ptr;
419     if (pIT == NULL)
420     {
421         return;
422     }
423
424     types::GenericType * pGT = pIT->getAs<types::GenericType>();
425     if (pGT == NULL)
426     {
427         return;
428     }
429
430     pGT->resize(pGT->getRows(), N);
431 }
432
433 bool mxIsString(const mxArray *ptr)
434 {
435     /* mxIsString is obsolete. */
436     return mxIsChar(ptr);
437 }
438
439 bool mxIsChar(const mxArray *ptr)
440 {
441     return mxGetClassID(ptr) == mxCHAR_CLASS;
442 }
443
444 bool mxIsNumeric(const mxArray *ptr)
445 {
446     return mxIsDouble(ptr) || mxIsSingle(ptr) ||
447            mxIsInt8(ptr) || mxIsUint8(ptr) ||
448            mxIsInt16(ptr) || mxIsUint16(ptr) || mxIsInt32(ptr) || mxIsUint32(ptr) || mxIsInt64(ptr) || mxIsUint64(ptr);
449 }
450
451 bool mxIsDouble(const mxArray *ptr)
452 {
453     return mxGetClassID(ptr) == mxDOUBLE_CLASS;
454 }
455
456 bool mxIsSingle(const mxArray *ptr)
457 {
458     return mxGetClassID(ptr) == mxSINGLE_CLASS;
459 }
460
461 bool mxIsEmpty(const mxArray *ptr)
462 {
463     types::InternalType * pIT = (types::InternalType *) ptr;
464     if (pIT == NULL)
465     {
466         //true or false, whatever ;)
467         return true;
468     }
469
470     switch (pIT->getType())
471     {
472         case types::InternalType::ScilabDouble:
473         {
474             types::Double *pD = pIT->getAs<types::Double>();
475             return pD->getSize() == 0;
476         }
477         case types::InternalType::ScilabCell:
478         {
479             types::Cell *pC = pIT->getAs<types::Cell>();
480             return pC->getSize() == 0;
481         }
482         case types::InternalType::ScilabContainer:
483         case types::InternalType::ScilabList:
484         case types::InternalType::ScilabMList:
485         case types::InternalType::ScilabTList:
486         {
487             types::Container *pC = pIT->getAs<types::Container>();
488             return pC->getSize() == 0;
489         }
490         default:
491         {
492             //other type can not be empty
493             return false;
494         }
495     }
496 }
497
498 bool mxIsFull(const mxArray *ptr)
499 {
500     /* mxIsFull is obsolete. */
501     return !mxIsSparse(ptr);
502 }
503
504 bool mxIsSparse(const mxArray *ptr)
505 {
506     // TODO: sparse
507     return false;
508 }
509
510 bool mxIsLogical(const mxArray *ptr)
511 {
512     return mxGetClassID(ptr) == mxLOGICAL_CLASS;
513 }
514
515 void mxSetLogical(mxArray *ptr)
516 {
517     /* obsolete */
518     if (!mxIsNumeric(ptr))
519     {
520         return;
521     }
522     int *data = (int *) mxGetData(ptr);
523     mxArray *newPtr = (mxArray *) new types::Bool(mxGetNumberOfDimensions(ptr), mxGetDimensions(ptr));
524     mxSetData(newPtr, data);
525     *ptr = *newPtr;
526 }
527
528 void mxClearLogical(mxArray *ptr)
529 {
530     /* obsolete */
531     if (!mxIsLogical(ptr))
532     {
533         return;
534     }
535     int *data = (int *) mxGetData(ptr);
536     mxArray *newPtr = (mxArray *) new types::Int32(mxGetNumberOfDimensions(ptr), mxGetDimensions(ptr));
537     mxSetData(newPtr, data);
538     *ptr = *newPtr;
539 }
540
541 bool mxIsComplex(const mxArray *ptr)
542 {
543     types::InternalType *pIT = (types::InternalType *) ptr;
544     if (pIT == NULL)
545     {
546         return false;
547     }
548
549     types::GenericType *pGT = pIT->getAs<types::GenericType>();
550     if (pGT == NULL)
551     {
552         return false;
553     }
554
555     return pGT->isComplex();
556 }
557
558 double mxGetScalar(const mxArray *ptr)
559 {
560     // TODO: review spec
561     types::InternalType *pIT = (types::InternalType *) ptr;
562     if (pIT == NULL)
563     {
564         return 0;
565     }
566
567     switch (pIT->getType())
568     {
569         case types::InternalType::ScilabDouble:
570         {
571             types::Double *pD = pIT->getAs<types::Double>();
572             return pD->get(0);
573         }
574         case types::InternalType::ScilabBool:
575         {
576             types::Bool *pB = pIT->getAs<types::Bool>();
577             return (double) pB->get(0);
578         }
579         case types::InternalType::ScilabInt8:
580         {
581             types::Int8 *pI = pIT->getAs<types::Int8>();
582             return (double) pI->get(0);
583         }
584         case types::InternalType::ScilabUInt8:
585         {
586             types::UInt8 *pI = pIT->getAs<types::UInt8>();
587             return (double) pI->get(0);
588         }
589         case types::InternalType::ScilabInt16:
590         {
591             types::Int16 *pI = pIT->getAs<types::Int16>();
592             return (double) pI->get(0);
593         }
594         case types::InternalType::ScilabUInt16:
595         {
596             types::UInt16 *pI = pIT->getAs<types::UInt16>();
597             return (double) pI->get(0);
598         }
599         case types::InternalType::ScilabInt32:
600         {
601             types::Int32 *pI = pIT->getAs<types::Int32>();
602             return (double) pI->get(0);
603         }
604         case types::InternalType::ScilabUInt32:
605         {
606             types::UInt32 *pI = pIT->getAs<types::UInt32>();
607             return (double) pI->get(0);
608         }
609         case types::InternalType::ScilabInt64:
610         {
611             types::Int64 *pI = pIT->getAs<types::Int64>();
612             return (double) pI->get(0);
613         }
614         case types::InternalType::ScilabUInt64:
615         {
616             types::UInt64 *pI = pIT->getAs<types::UInt64>();
617             return (double) pI->get(0);
618         }
619         default:
620             return 0;
621     }
622 }
623
624 void *mxGetData(const mxArray *ptr)
625 {
626     types::InternalType *pIT = (types::InternalType *) ptr;
627     if (pIT == NULL)
628     {
629         return NULL;
630     }
631
632     switch (pIT->getType())
633     {
634         case types::InternalType::ScilabDouble:
635         {
636             types::Double *pD = pIT->getAs<types::Double>();
637             return pD->get();
638         }
639         case types::InternalType::ScilabBool:
640         {
641             types::Bool *pB = pIT->getAs<types::Bool>();
642             return pB->get();
643         }
644         case types::InternalType::ScilabInt8:
645         {
646             types::Int8 *pI = pIT->getAs<types::Int8>();
647             return pI->get();
648         }
649         case types::InternalType::ScilabUInt8:
650         {
651             types::UInt8 *pI = pIT->getAs<types::UInt8>();
652             return pI->get();
653         }
654         case types::InternalType::ScilabInt16:
655         {
656             types::Int16 *pI = pIT->getAs<types::Int16>();
657             return pI->get();
658         }
659         case types::InternalType::ScilabUInt16:
660         {
661             types::UInt16 *pI = pIT->getAs<types::UInt16>();
662             return pI->get();
663         }
664         case types::InternalType::ScilabInt32:
665         {
666             types::Int32 *pI = pIT->getAs<types::Int32>();
667             return pI->get();
668         }
669         case types::InternalType::ScilabUInt32:
670         {
671             types::UInt32 *pI = pIT->getAs<types::UInt32>();
672             return pI->get();
673         }
674         case types::InternalType::ScilabInt64:
675         {
676             types::Int64 *pI = pIT->getAs<types::Int64>();
677             return pI->get();
678         }
679         case types::InternalType::ScilabUInt64:
680         {
681             types::UInt64 *pI = pIT->getAs<types::UInt64>();
682             return pI->get();
683         }
684         default:
685             return NULL;
686     }
687 }
688
689 void *mxGetImagData(const mxArray *ptr)
690 {
691     types::InternalType *pIT = (types::InternalType *) ptr;
692     if (pIT == NULL)
693     {
694         return NULL;
695     }
696
697     switch (pIT->getType())
698     {
699         case types::InternalType::ScilabDouble:
700         {
701             types::Double *pD = pIT->getAs<types::Double>();
702             return pD->getImg();
703         }
704         case types::InternalType::ScilabBool:
705         {
706             types::Bool *pB = pIT->getAs<types::Bool>();
707             return pB->getImg();
708         }
709         case types::InternalType::ScilabInt8:
710         {
711             types::Int8 *pI = pIT->getAs<types::Int8>();
712             return pI->getImg();
713         }
714         case types::InternalType::ScilabUInt8:
715         {
716             types::UInt8 *pI = pIT->getAs<types::UInt8>();
717             return pI->getImg();
718         }
719         case types::InternalType::ScilabInt16:
720         {
721             types::Int16 *pI = pIT->getAs<types::Int16>();
722             return pI->getImg();
723         }
724         case types::InternalType::ScilabUInt16:
725         {
726             types::UInt16 *pI = pIT->getAs<types::UInt16>();
727             return pI->getImg();
728         }
729         case types::InternalType::ScilabInt32:
730         {
731             types::Int32 *pI = pIT->getAs<types::Int32>();
732             return pI->getImg();
733         }
734         case types::InternalType::ScilabUInt32:
735         {
736             types::UInt32 *pI = pIT->getAs<types::UInt32>();
737             return pI->getImg();
738         }
739         case types::InternalType::ScilabInt64:
740         {
741             types::Int64 *pI = pIT->getAs<types::Int64>();
742             return pI->getImg();
743         }
744         case types::InternalType::ScilabUInt64:
745         {
746             types::UInt64 *pI = pIT->getAs<types::UInt64>();
747             return pI->getImg();
748         }
749         default:
750             return NULL;
751     }
752 }
753
754 void mexErrMsgTxt(const char *error_msg)
755 {
756     throw new ScilabException(error_msg);
757 }
758
759 mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity complexFlag)
760 {
761     types::Double *ptr = new types::Double(m, n, complexFlag == mxCOMPLEX);
762     return (mxArray *) ptr;
763 }
764
765 mxArray *mxCreateDoubleScalar(double value)
766 {
767     mxArray *ptr = mxCreateDoubleMatrix(1, 1, mxREAL);
768
769     ((types::Double *) ptr)->set(0, value);
770     return ptr;
771 }
772
773 bool mxIsClass(const mxArray *ptr, const char *name)
774 {
775     if (strcmp(name, "cell") == 0)
776     {
777         return mxIsCell(ptr);
778     }
779     if (strcmp(name, "char") == 0)
780     {
781         return mxIsChar(ptr);
782     }
783     if (strcmp(name, "double") == 0)
784     {
785         return mxIsDouble(ptr);
786     }
787     if (strcmp(name, "function_handle") == 0)
788     {
789         return mxIsFunction(ptr);
790     }
791     if (strcmp(name, "int8") == 0)
792     {
793         return mxIsInt8(ptr);
794     }
795     if (strcmp(name, "int16") == 0)
796     {
797         return mxIsInt16(ptr);
798     }
799     if (strcmp(name, "int32") == 0)
800     {
801         return mxIsInt32(ptr);
802     }
803     if (strcmp(name, "int64") == 0)
804     {
805         return mxIsInt64(ptr);
806     }
807     if (strcmp(name, "logical") == 0)
808     {
809         return mxIsLogical(ptr);
810     }
811     if (strcmp(name, "single") == 0)
812     {
813         return mxIsSingle(ptr);
814     }
815     if (strcmp(name, "struct") == 0)
816     {
817         return mxIsStruct(ptr);
818     }
819     if (strcmp(name, "uint8") == 0)
820     {
821         return mxIsUint8(ptr);
822     }
823     if (strcmp(name, "uint16") == 0)
824     {
825         return mxIsUint16(ptr);
826     }
827     if (strcmp(name, "uint32") == 0)
828     {
829         return mxIsUint32(ptr);
830     }
831     if (strcmp(name, "uint64") == 0)
832     {
833         return mxIsUint64(ptr);
834     }
835     // TODO: how to handle <class_name> and <class_id>?
836     return false;
837 }
838
839 mxArray *mxCreateStructArray(int ndim, const int *dims, int nfields, const char **field_names)
840 {
841     types::Struct *ptr = new types::Struct(ndim, (int *) dims);
842     for (int i = 0; i < nfields; i++)
843     {
844         wchar_t *name = to_wide_string(field_names[i]);
845         ptr->addField(name);
846         FREE(name);
847     }
848     return (mxArray *) ptr;
849 }
850
851 mxArray *mxCreateStructMatrix(int m, int n, int nfields, const char **field_names)
852 {
853     int dims[2] = {m, n};
854     return mxCreateStructArray(2, dims, nfields, field_names);
855 }
856
857 void mxSetFieldByNumber(mxArray *array_ptr, int lindex, int field_number, mxArray *value)
858 {
859     if (mxIsStruct(array_ptr) && lindex < mxGetNumberOfElements(array_ptr))
860     {
861         types::SingleStruct *ptr = ((types::Struct *) array_ptr)->get(lindex);
862         types::String *names = ptr->getFieldNames();
863         ptr->set(names->get(field_number), (types::InternalType *) value);
864     }
865 }
866
867 void mxSetField(mxArray *array_ptr, int lindex, const char *field_name, mxArray *value)
868 {
869     int field_num = mxGetFieldNumber(array_ptr, field_name);
870     if (field_num >= 0)
871     {
872         mxSetFieldByNumber(array_ptr, lindex, field_num, value);
873     }
874 }
875
876 const char *mxGetFieldNameByNumber(const mxArray *array_ptr, int field_number)
877 {
878     if (!mxIsStruct(array_ptr))
879     {
880         return NULL;
881     }
882     if (field_number < 0 || field_number >= mxGetNumberOfFields(array_ptr))
883     {
884         return NULL;
885     }
886     types::String *names = ((types::Struct *) array_ptr)->getFieldNames();
887     wchar_t *name = names->get(field_number);
888     return (const char *) wide_string_to_UTF8(name);
889 }
890
891 int mxAddField(mxArray *ptr, const char *fieldname)
892 {
893     if (!mxIsStruct(ptr))
894     {
895         return -1;
896     }
897     types::Struct *pa = (types::Struct *) ptr;
898     wchar_t *wfieldname = to_wide_string(fieldname);
899     pa->addField(wfieldname);
900     return mxGetFieldNumber(ptr, fieldname);
901 }
902
903 mxChar *mxGetChars(mxArray *array_ptr)
904 {
905     if (!mxIsChar(array_ptr))
906     {
907         return NULL;
908     }
909     wchar_t *chars = ((types::String *) array_ptr)->get(0);
910     return (mxChar *) wide_string_to_UTF8(chars);
911 }
912
913 mxArray *mxCreateNumericArray(int ndim, const int *dims, mxClassID CLASS, mxComplexity complexFlag)
914 {
915     types::GenericType *ptr;
916
917     switch (CLASS)
918     {
919         case mxDOUBLE_CLASS:
920             ptr = new types::Double(ndim, (int *) dims, complexFlag == mxCOMPLEX);
921             break;
922         case mxINT8_CLASS:
923             ptr = new types::Int8(ndim, (int *) dims);
924             break;
925         case mxUINT8_CLASS:
926             ptr = new types::UInt8(ndim, (int *) dims);
927             break;
928         case mxINT16_CLASS:
929             ptr = new types::Int16(ndim, (int *) dims);
930             break;
931         case mxUINT16_CLASS:
932             ptr = new types::UInt16(ndim, (int *) dims);
933             break;
934         case mxINT32_CLASS:
935             ptr = new types::Int32(ndim, (int *) dims);
936             break;
937         case mxUINT32_CLASS:
938             ptr = new types::UInt32(ndim, (int *) dims);
939             break;
940         case mxINT64_CLASS:
941             ptr = new types::Int64(ndim, (int *) dims);
942             break;
943         case mxUINT64_CLASS:
944             ptr = new types::UInt64(ndim, (int *) dims);
945             break;
946         default:
947             ptr = NULL;
948     }
949     return (mxArray *) ptr;
950 }
951
952 mxArray *mxCreateNumericMatrix(int m, int n, mxClassID CLASS, mxComplexity complexFlag)
953 {
954     int dims[2] = {m, n};
955     return mxCreateNumericArray(2, dims, CLASS, complexFlag);
956 }
957
958 mxArray *mxCreateCharArray(int ndim, const int *dims)
959 {
960     if (ndim == 0 || ndim == 1)
961     {
962         ndim = 2;
963     }
964     types::String *ptr = new types::String(ndim, (int *) dims);
965     return (mxArray *) ptr;
966 }
967
968 mxArray *mxCreateCellArray(int ndim, const int *dims)
969 {
970     types::Cell *ptr = new types::Cell(ndim, (int *) dims);
971     return (mxArray *) ptr;
972 }
973
974 mxArray *mxCreateCellMatrix(int m, int n)
975 {
976     int dims[2] = {m, n};
977     return mxCreateCellArray(2, dims);
978 }
979
980 mxArray *mxGetCell(const mxArray *ptr, int lindex)
981 {
982     types::Cell * pa = (types::Cell *) ptr;
983     return (mxArray *) pa->get(lindex);
984 }
985
986 int mxGetFieldNumber(const mxArray *ptr, const char *string)
987 {
988     if (!mxIsStruct(ptr))
989     {
990         return -1;
991     }
992     types::Struct *pa = (types::Struct *) ptr;
993     types::String *names = pa->getFieldNames();
994     wchar_t *field_name = to_wide_string(string);
995
996     for (int i = 0; i < names->getSize(); i++)
997     {
998         if (wcscmp(names->get(i), field_name) == 0)
999         {
1000             FREE(field_name);
1001             return i;
1002         }
1003     }
1004     FREE(field_name);
1005     return -1;
1006 }
1007
1008 mxArray *mxGetField(const mxArray *ptr, int lindex, const char *string)
1009 {
1010     int field_num = mxGetFieldNumber(ptr, string);
1011     if (field_num < 0)
1012     {
1013         return NULL;
1014     }
1015     return mxGetFieldByNumber(ptr, lindex, field_num);
1016 }
1017
1018 mxArray *mxGetFieldByNumber(const mxArray *ptr, int lindex, int field_number)
1019 {
1020     if (!mxIsStruct(ptr))
1021     {
1022         return NULL;
1023     }
1024     if (lindex >= mxGetNumberOfElements(ptr) || lindex < 0)
1025     {
1026         return NULL;
1027     }
1028     if (field_number >= mxGetNumberOfFields(ptr) || field_number < 0)
1029     {
1030         return NULL;
1031     }
1032     types::Struct *pa = (types::Struct *) ptr;
1033     types::String *names = pa->getFieldNames();
1034     types::SingleStruct *s = pa->get(lindex);
1035     return (mxArray *) s->get(names->get(field_number));
1036 }
1037
1038 int mxGetNumberOfFields(const mxArray *ptr)
1039 {
1040     if (!mxIsStruct(ptr))
1041     {
1042         return 0;
1043     }
1044     types::Struct * pa = (types::Struct *) ptr;
1045     return pa->getFieldNames()->getSize();
1046 }
1047
1048 /*----------------------------------------------------
1049 * mxCalloc is supposed to initialize data to 0
1050 * but what does it means since size can be anythink
1051 * we initialize to zero for double and int data types
1052 *----------------------------------------------------*/
1053
1054 void *mxRealloc(void *ptr, size_t nsize)
1055 {
1056     // TODO: manage this memory
1057     return REALLOC(ptr, nsize);
1058 }
1059
1060 void *mxCalloc(size_t n, size_t size)
1061 {
1062     // TODO: manage this memory
1063     return CALLOC(n, size);
1064 }
1065
1066 void *mxMalloc(size_t nsize)
1067 {
1068     // TODO: manage this memory
1069     return MALLOC(nsize);
1070 }
1071
1072 void mexMakeMemoryPersistent(void *ptr)
1073 {
1074     // FIXME
1075 }
1076
1077
1078 void *mxCalloc_m(unsigned int n, unsigned int size)
1079 {
1080     // FIXME
1081     return NULL;
1082 }
1083
1084 void *mxMalloc_m(unsigned int n)
1085 {
1086     // FIXME
1087     return NULL;
1088 }
1089
1090 /* free : explicit free of a mxCalloc_m allocated space
1091 *        except if space is protected
1092 */
1093
1094 void mxFree_m(void *ptr)
1095 {
1096     // FIXME
1097 }
1098
1099 /* free : explicit free of all mxCalloc_m allocated space
1100 *        except if space is protected
1101 */
1102
1103 static void mxFree_m_all()
1104 {
1105     // FIXME
1106 }
1107
1108 bool mxIsCell(const mxArray *ptr)
1109 {
1110     return mxGetClassID(ptr) == mxCELL_CLASS;
1111 }
1112
1113 bool mxIsStruct(const mxArray *ptr)
1114 {
1115     return mxGetClassID(ptr) == mxSTRUCT_CLASS;
1116 }
1117
1118 int mxGetString(const mxArray *ptr, char *str, int strl)
1119 {
1120     if (!mxIsChar(ptr))
1121     {
1122         return 1;
1123     }
1124     types::String *pa = (types::String *) ptr;
1125     int items = mxGetM(ptr);
1126     int index = 0;
1127     int free_space = strl - 1;
1128     for (int k = 0; k < items; k++)
1129     {
1130         wchar_t *to_copy = pa->get(k);
1131         char *dest = wide_string_to_UTF8(to_copy);
1132         int length = (int)strlen(dest);
1133         memcpy(str + index, dest, free_space);
1134         index += std::min(length, free_space);
1135         free_space -= length;
1136         FREE(dest);
1137         if (free_space <= 0)
1138         {
1139             break;
1140         }
1141     }
1142     str[index] = '\0';
1143     return free_space >= 0 ? 0 : 1;
1144 }
1145
1146 char *mxArrayToString(const mxArray *ptr)
1147 {
1148     if (!mxIsChar(ptr))
1149     {
1150         return (char *) 0;
1151     }
1152     types::String *pa = (types::String *) ptr;
1153     int items = mxGetM(ptr);
1154     int index = 0;
1155     int length = 1; // one extra char to \0
1156     wchar_t **wstrings = pa->get();
1157     for (int k = 0; k < items; k++)
1158     {
1159         length += (int)wcslen(wstrings[k]);
1160     }
1161     char *str = (char *) malloc(sizeof(char *) * length);
1162     for (int k = 0; k < items; k++)
1163     {
1164         char *dest = wide_string_to_UTF8(wstrings[k]);
1165         int dest_length = strlen(dest);
1166         memcpy(str + index, dest, dest_length);
1167         index += dest_length;
1168     }
1169     str[index] = '\0';
1170     return str;
1171 }
1172
1173 void mxFreeMatrix(mxArray *ptr)
1174 {
1175     mxDestroyArray(ptr);
1176 }
1177
1178 bool mexIsGlobal(const mxArray *ptr)
1179 {
1180     symbol::Context *context = symbol::Context::getInstance();
1181     int size = symbol::Symbol::map_size();
1182     wchar_t **keys = symbol::Symbol::get_all();
1183
1184     for (int i = 0; i < size; i++)
1185     {
1186         symbol::Symbol *s = new symbol::Symbol(keys[i]);
1187         const mxArray *value = (const mxArray *) context->get(*s);
1188         if (value == ptr)
1189         {
1190             return context->isGlobalVisible(*s);
1191         }
1192     }
1193     return false;
1194 }
1195
1196 mxArray *mxDuplicateArray(const mxArray *ptr)
1197 {
1198     types::InternalType *pIT = (types::InternalType *) ptr;
1199     if (pIT == NULL)
1200     {
1201         return 0;
1202     }
1203
1204     return (mxArray *) pIT->clone();
1205 }
1206
1207 void mxDestroyArray(mxArray *ptr)
1208 {
1209     if (mxIsDouble(ptr))
1210     {
1211         delete (types::Double *) ptr;
1212     }
1213     else if (mxIsChar(ptr))
1214     {
1215         delete (types::String *) ptr;
1216     }
1217     else if (mxIsLogical(ptr))
1218     {
1219         delete (types::Bool *) ptr;
1220     }
1221     else if (mxIsSparse(ptr))
1222     {
1223         // TODO: sparse
1224     }
1225     else if (mxIsInt8(ptr))
1226     {
1227         delete (types::Int8 *) ptr;
1228     }
1229     else if (mxIsInt16(ptr))
1230     {
1231         delete (types::Int16 *) ptr;
1232     }
1233     else if (mxIsInt32(ptr))
1234     {
1235         delete(types::Int32 *) ptr;
1236     }
1237     else if (mxIsInt64(ptr))
1238     {
1239         delete((types::Int64 *) ptr);
1240     }
1241     else if (mxIsUint8(ptr))
1242     {
1243         delete((types::UInt8 *) ptr);
1244     }
1245     else if (mxIsUint16(ptr))
1246     {
1247         delete((types::UInt16 *) ptr);
1248     }
1249     else if (mxIsUint32(ptr))
1250     {
1251         delete((types::UInt32 *) ptr);
1252     }
1253     else if (mxIsUint64(ptr))
1254     {
1255         delete((types::UInt64 *) ptr);
1256     }
1257     else if (mxIsCell(ptr))
1258     {
1259         delete((types::Cell *) ptr);
1260     }
1261     else if (mxIsStruct(ptr))
1262     {
1263         delete((types::Struct *) ptr);
1264     }
1265 }
1266
1267 void mxFree(void *ptr)
1268 {
1269     // TODO: manage this memory
1270     FREE(ptr);
1271 }
1272
1273 int mexAtExit(void (*func)(void))
1274 {
1275     exitFcn = func;
1276     return 0;
1277 }
1278
1279 mxArray *mxCreateSparse(int m, int n, int nzmax, mxComplexity cmplx)
1280 {
1281     // TODO: sparse
1282     return NULL;
1283 }
1284
1285 mxArray *mxCreateString(const char *string)
1286 {
1287     types::String *ptr = new types::String(string);
1288     return (mxArray *) ptr;
1289 }
1290
1291
1292 mxArray *mxCreateLogicalArray(int ndim, const int *dims)
1293 {
1294     types::Bool *ptr = new types::Bool(ndim, (int *) dims);
1295     return (mxArray *) ptr;
1296 }
1297
1298 mxArray *mxCreateLogicalMatrix(int m, int n)
1299 {
1300     types::Bool *ptr = new types::Bool(m, n);
1301     return (mxArray *) ptr;
1302 }
1303
1304 mxArray *mxCreateLogicalScalar(mxLogical value)
1305 {
1306     mxArray *ptr = mxCreateLogicalMatrix(1, 1);
1307
1308     ((types::Bool *) ptr)->set(0, value);
1309     return ptr;
1310 }
1311
1312 bool mxIsLogicalScalarTrue(const mxArray *ptr)
1313 {
1314     if (mxIsLogicalScalar(ptr) == false)
1315     {
1316         return false;
1317     }
1318
1319     if (*mxGetLogicals(ptr) == 0)
1320     {
1321         return false;
1322     }
1323
1324     return true;
1325 }
1326
1327 bool mxIsLogicalScalar(const mxArray *ptr)
1328 {
1329     return mxIsLogical(ptr) && mxGetNumberOfElements(ptr) == 1;
1330 }
1331
1332 int mexPrintf(const char *format, ...)
1333 {
1334     // TODO: define this size limit
1335     char string[1024];
1336     va_list arg_ptr;
1337     va_start(arg_ptr, format);
1338     vsnprintf(string, 1024, format, arg_ptr);
1339     va_end(arg_ptr);
1340     scilabWrite(string);
1341     return 0;
1342 }
1343
1344 void mexWarnMsgTxt(const char *error_msg)
1345 {
1346     scilabError(_("Warning: "));
1347     scilabError(error_msg);
1348     scilabError("\n\n");
1349 }
1350
1351 int mexCallSCILAB(int nlhs, mxArray **plhs, int nrhs, mxArray **prhs, const char *name)
1352 {
1353     wchar_t* pwst = to_wide_string(name);
1354     symbol::Context *context = symbol::Context::getInstance();
1355     symbol::Symbol *symbol = new symbol::Symbol(pwst);
1356     FREE(pwst);
1357
1358     types::InternalType *value = context->get(*symbol);
1359     types::Function *func = value->getAs<types::Function>();
1360     if (func == NULL)
1361     {
1362         return 1;
1363     }
1364
1365     types::typed_list in;
1366     types::typed_list out;
1367     types::optional_list opt;
1368     for (int i = 0; i < nrhs; i++)
1369     {
1370         in.push_back((types::InternalType*)prhs[i]);
1371     }
1372
1373     func->call(in, opt, nlhs, out, NULL);
1374
1375     for (int i = 0; i < nlhs; i++)
1376     {
1377         plhs[i] = (mxArray *) (out[i]);
1378     }
1379
1380     return 0;
1381 }
1382
1383 int mexCallMATLAB(int nlhs, mxArray **plhs, int nrhs, mxArray **prhs, const char *name)
1384 {
1385     return mexCallSCILAB(nlhs, plhs, nrhs, prhs, name);
1386 }
1387
1388 int mxCalcSingleSubscript(const mxArray *ptr, int nsubs, const int *subs)
1389 {
1390     int index = 0;
1391     int iMult = 1;
1392     int *dims = mxGetDimensions(ptr);
1393     for (int i = 0; i < nsubs; i++)
1394     {
1395         index += subs[i] * iMult;
1396         iMult *= dims[i];
1397     }
1398     return index;
1399 }
1400
1401 int C2F(mexcallscilab) (int *nlhs, mxArray **plhs, int *nrhs, mxArray **prhs, char *name, int namelen)
1402 {
1403     return mexCallSCILAB(*nlhs, plhs, *nrhs, prhs, name);
1404 }
1405
1406 /** generic mex interface **/
1407 const char *mexFunctionName(void)
1408 {
1409     return the_current_mex_name;
1410 }
1411
1412 int mxGetElementSize(const mxArray *ptr)
1413 {
1414     if (mxIsChar(ptr))
1415     {
1416         return sizeof(wchar_t *);
1417     }
1418     else if (mxIsLogical(ptr))
1419     {
1420         return sizeof(int);
1421     }
1422     else if (mxIsDouble(ptr))
1423     {
1424         return sizeof(double);
1425     }
1426     else if (mxIsSparse(ptr))
1427     {
1428         // TODO: sparse
1429     }
1430     else if (mxIsInt8(ptr))
1431     {
1432         return sizeof(char);
1433     }
1434     else if (mxIsInt16(ptr))
1435     {
1436         return sizeof(short);
1437     }
1438     else if (mxIsInt32(ptr))
1439     {
1440         return sizeof(int);
1441     }
1442     else if (mxIsInt64(ptr))
1443     {
1444         return sizeof(long long);
1445     }
1446     else if (mxIsUint8(ptr))
1447     {
1448         return sizeof(unsigned char);
1449     }
1450     else if (mxIsUint16(ptr))
1451     {
1452         return sizeof(unsigned short);
1453     }
1454     else if (mxIsUint32(ptr))
1455     {
1456         return sizeof(unsigned int);
1457     }
1458     else if (mxIsUint64(ptr))
1459     {
1460         return sizeof(unsigned long long);
1461     }
1462     else if (mxIsCell(ptr))
1463     {
1464         return sizeof(types::InternalType *);
1465     }
1466     else if (mxIsStruct(ptr))
1467     {
1468         return sizeof(types::SingleStruct *);
1469     }
1470     return 0;
1471 }
1472
1473 mxArray *mxCreateCharMatrixFromStrings(int m, const char **str)
1474 {
1475     int n = 1;
1476     wchar_t** strings = NULL;
1477     strings = (wchar_t**)MALLOC(sizeof(wchar_t*) * m);
1478     for (int k = 0; k < m; k++)
1479     {
1480         strings[k] = to_wide_string(str[k]);
1481     }
1482     types::String *ptr = new types::String(m, n, strings);
1483     freeArrayOfWideString(strings, m);
1484     return (mxArray *) ptr;
1485 }
1486
1487 int mexEvalString(const char *name)
1488 {
1489     // TODO: It is almost copied from sci_execstr.cpp. Refactor needed!
1490     int iErr = 0;
1491     bool bErrCatch = false;
1492     bool bMute = true;
1493     Parser parser;
1494     parser.parse(to_wide_string(name));
1495     if (parser.getExitStatus() !=  Parser::Succeded)
1496     {
1497         //mexPrintf(wide_string_to_UTF8(parser.getErrorMessage()));
1498         return 1;
1499     }
1500
1501     Exp *pExp = parser.getTree();
1502
1503     if (pExp == NULL)
1504     {
1505         //mexPrintf("pExp is NULL");
1506         return 1;
1507     }
1508
1509     //save current prompt mode
1510     int oldVal = ConfigVariable::getPromptMode();
1511     if (bMute)
1512     {
1513         ConfigVariable::setPromptMode(-1);
1514     }
1515     std::list<Exp *>::iterator j;
1516     std::list<Exp *>LExp = ((SeqExp*)pExp)->exps_get();
1517
1518     for (j = LExp.begin() ; j != LExp.end() ; j++)
1519     {
1520         try
1521         {
1522             //excecute script
1523             ExecVisitor execMe;
1524             (*j)->accept(execMe);
1525
1526             //to manage call without ()
1527             if (execMe.result_get() != NULL && execMe.result_get()->getAs<Callable>())
1528             {
1529                 Callable *pCall = execMe.result_get()->getAs<Callable>();
1530                 types::typed_list out;
1531                 types::typed_list in;
1532                 types::optional_list opt;
1533                 try
1534                 {
1535                     ExecVisitor execCall;
1536                     Function::ReturnValue Ret = pCall->call(in, opt, 1, out, &execCall);
1537                     if (Ret == Callable::OK)
1538                     {
1539                         if (out.size() == 0)
1540                         {
1541                             execMe.result_set(NULL);
1542                         }
1543                         else if (out.size() == 1)
1544                         {
1545                             out[0]->DecreaseRef();
1546                             execMe.result_set(out[0]);
1547                         }
1548                         else
1549                         {
1550                             for (int i = 0 ; i < static_cast<int>(out.size()) ; i++)
1551                             {
1552                                 out[i]->DecreaseRef();
1553                                 execMe.result_set(i, out[i]);
1554                             }
1555                         }
1556                     }
1557                     else if (Ret == Callable::Error)
1558                     {
1559                         if (ConfigVariable::getLastErrorFunction() == L"")
1560                         {
1561                             ConfigVariable::setLastErrorFunction(pCall->getName());
1562                         }
1563
1564                         if (pCall->isMacro() || pCall->isMacroFile())
1565                         {
1566                             wchar_t szError[bsiz];
1567                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*j)->location_get().first_line, pCall->getName().c_str());
1568                             throw ast::ScilabMessage(szError);
1569                         }
1570                         else
1571                         {
1572                             throw ast::ScilabMessage();
1573                         }
1574                     }
1575                 }
1576                 catch (ScilabMessage sm)
1577                 {
1578                     wostringstream os;
1579                     PrintVisitor printMe(os);
1580                     (*j)->accept(printMe);
1581                     os << std::endl << std::endl;
1582                     if (ConfigVariable::getLastErrorFunction() == L"")
1583                     {
1584                         ConfigVariable::setLastErrorFunction(pCall->getName());
1585                     }
1586
1587                     if (pCall->isMacro() || pCall->isMacroFile())
1588                     {
1589                         wstring szAllError;
1590                         wchar_t szError[bsiz];
1591                         os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
1592                         szAllError = szError + os.str();
1593                         os_swprintf(szError, bsiz, _W("in  execstr instruction    called by :\n").c_str());
1594                         szAllError += szError;
1595                         throw ast::ScilabMessage(szAllError);
1596                     }
1597                     else
1598                     {
1599                         sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
1600                         throw sm;
1601                     }
1602                 }
1603             }
1604
1605             //update ans variable.
1606             if (execMe.result_get() != NULL && execMe.result_get()->isDeletable())
1607             {
1608                 symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), execMe.result_get());
1609                 if ((*j)->is_verbose() && bErrCatch == false)
1610                 {
1611                     std::wostringstream ostr;
1612                     ostr << L"ans = " << std::endl;
1613                     ostr << std::endl;
1614                     execMe.result_get()->toString(ostr);
1615                     ostr << std::endl;
1616                     scilabWriteW(ostr.str().c_str());
1617                 }
1618             }
1619         }
1620         catch (ScilabMessage sm)
1621         {
1622             if (bErrCatch  == false && bMute == false)
1623             {
1624                 scilabErrorW(sm.GetErrorMessage().c_str());
1625
1626                 CallExp* pCall = dynamic_cast<CallExp*>(*j);
1627                 if (pCall != NULL)
1628                 {
1629                     //to print call expression only of it is a macro
1630                     ExecVisitor execFunc;
1631                     pCall->name_get().accept(execFunc);
1632
1633                     if (execFunc.result_get() != NULL &&
1634                             (execFunc.result_get()->isMacro() || execFunc.result_get()->isMacroFile()))
1635                     {
1636                         wostringstream os;
1637
1638                         //add function failed
1639                         PrintVisitor printMe(os);
1640                         pCall->accept(printMe);
1641                         os << std::endl;
1642
1643                         //add info on file failed
1644                         wchar_t szError[bsiz];
1645                         os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->location_get().first_line);
1646                         os << szError;
1647
1648                         if (ConfigVariable::getLastErrorFunction() == L"")
1649                         {
1650                             ConfigVariable::setLastErrorFunction(execFunc.result_get()->getAs<Callable>()->getName());
1651                         }
1652
1653                         //restore previous prompt mode
1654                         ConfigVariable::setPromptMode(oldVal);
1655                         throw ast::ScilabMessage(os.str(), 0, (*j)->location_get());
1656                     }
1657                 }
1658                 throw ast::ScilabMessage((*j)->location_get());
1659             }
1660             else
1661             {
1662                 iErr = ConfigVariable::getLastErrorNumber();
1663                 break;
1664             }
1665         }
1666         catch (ast::ScilabError se)
1667         {
1668             if (ConfigVariable::getLastErrorMessage() == L"")
1669             {
1670                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
1671                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
1672                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
1673                 ConfigVariable::setLastErrorFunction(wstring(L""));
1674             }
1675
1676             //store message
1677             iErr = ConfigVariable::getLastErrorNumber();
1678             if (bErrCatch == false)
1679             {
1680                 //in case of error, change mode to 2 ( prompt )
1681                 ConfigVariable::setPromptMode(2);
1682                 //write error
1683                 scilabErrorW(ConfigVariable::getLastErrorMessage().c_str());
1684                 scilabErrorW(L"\n");
1685
1686                 //write positino
1687                 wchar_t szError[bsiz];
1688                 os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->location_get().first_line);
1689                 //restore previous prompt mode
1690                 ConfigVariable::setPromptMode(oldVal);
1691                 throw ast::ScilabMessage(szError, 1, (*j)->location_get());
1692             }
1693             break;
1694         }
1695     }
1696
1697     //restore previous prompt mode
1698     ConfigVariable::setPromptMode(oldVal);
1699
1700     delete parser.getTree();
1701     return 0;
1702 }
1703
1704 mxArray *mexGetArray(char *name, char *workspace)
1705 {
1706     return mexGetVariable(workspace, name);
1707 }
1708
1709 const mxArray *mexGetVariablePtr(const char *workspace, const char *var_name)
1710 {
1711     const mxArray *value = mexGetVariable(workspace, var_name);
1712     return value;
1713 }
1714
1715 mxArray *mexGetVariable(const char *workspace, const char *name)
1716 {
1717     symbol::Context *context = symbol::Context::getInstance();
1718     wchar_t *key = to_wide_string(name);
1719     types::InternalType *value = NULL;
1720     if (strcmp(workspace, "base") == 0)
1721     {
1722         value = context->get(*(new symbol::Symbol(key)));
1723     }
1724     else if (strcmp(workspace, "caller") == 0)
1725     {
1726         value = context->getCurrentLevel(*(new symbol::Symbol(key)));
1727     }
1728     else if (strcmp(workspace, "global") == 0)
1729     {
1730         value = context->getGlobalValue(*(new symbol::Symbol(key)));
1731     }
1732     FREE(key);
1733     return (mxArray *) value;
1734 }
1735
1736 int mexPutVariable(const char *workspace, const char *varname, const mxArray *pm)
1737 {
1738     symbol::Context *context = symbol::Context::getInstance();
1739     wchar_t *dest = to_wide_string(varname);
1740     if (strcmp(workspace, "base") == 0)
1741     {
1742         context->putInPreviousScope(context->getOrCreate(symbol::Symbol(dest)), (types::InternalType *) pm);
1743     }
1744     else if (strcmp(workspace, "caller") == 0)
1745     {
1746         context->put(symbol::Symbol(dest), (types::InternalType *) pm);
1747     }
1748     else if (strcmp(workspace, "global") == 0)
1749     {
1750         context->setGlobalVisible(symbol::Symbol(dest), true);
1751         context->put(symbol::Symbol(dest), (types::InternalType *) pm);
1752     }
1753     else
1754     {
1755         return 1;
1756     }
1757     return 0;
1758 }
1759
1760 int mexPutFull(char *name, int m, int n, double *pr, double *pi)
1761 {
1762     /* obsolete */
1763     mxArray *array_ptr = mxCreateDoubleMatrix(m, n, pi == NULL ? mxREAL : mxCOMPLEX);
1764     mxSetPr(array_ptr, pr);
1765     mxSetPi(array_ptr, pi);
1766     mexPutVariable("caller", name, array_ptr);
1767     return 0;
1768 }
1769
1770 void mxSetName(mxArray *array_ptr, const char *name)
1771 {
1772     /* obsolete */
1773     mexErrMsgTxt(_("Routine mxSetName not implemented !\n"));
1774     exit(1);
1775 }
1776
1777 void mxSetData(mxArray *array_ptr, void *data_ptr)
1778 {
1779     if (mxIsChar(array_ptr))
1780     {
1781         ((types::String *) array_ptr)->set((wchar_t **) data_ptr);
1782     }
1783     else if (mxIsDouble(array_ptr))
1784     {
1785         ((types::Double *) array_ptr)->set((double *) data_ptr);
1786     }
1787     else if (mxIsInt8(array_ptr))
1788     {
1789         ((types::Int8 *) array_ptr)->set((char *) data_ptr);
1790     }
1791     else if (mxIsInt16(array_ptr))
1792     {
1793         ((types::Int16 *) array_ptr)->set((short *) data_ptr);
1794     }
1795     else if (mxIsInt32(array_ptr))
1796     {
1797         ((types::Int32 *) array_ptr)->set((int *) data_ptr);
1798     }
1799     else if (mxIsInt64(array_ptr))
1800     {
1801         ((types::Int64 *) array_ptr)->set((long long *) data_ptr);
1802     }
1803     else if (mxIsLogical(array_ptr))
1804     {
1805         ((types::Bool *) array_ptr)->set((int *) data_ptr);
1806     }
1807     // else if (mxIsSingle(array_ptr)) {
1808     //   ((types::Float *) array_ptr)->set((float *) data_ptr);
1809     // }
1810     else if (mxIsUint8(array_ptr))
1811     {
1812         ((types::UInt8 *) array_ptr)->set((unsigned char *) data_ptr);
1813     }
1814     else if (mxIsUint16(array_ptr))
1815     {
1816         ((types::UInt16 *) array_ptr)->set((unsigned short *) data_ptr);
1817     }
1818     else if (mxIsUint32(array_ptr))
1819     {
1820         ((types::UInt32 *) array_ptr)->set((unsigned int *) data_ptr);
1821     }
1822     else if (mxIsUint64(array_ptr))
1823     {
1824         ((types::UInt64 *) array_ptr)->set((unsigned long long *) data_ptr);
1825     }
1826 }
1827
1828 void mxSetImagData(mxArray *array_ptr, void *data_ptr)
1829 {
1830     if (mxIsChar(array_ptr))
1831     {
1832         ((types::String *) array_ptr)->setImg((wchar_t **) data_ptr);
1833     }
1834     else if (mxIsDouble(array_ptr))
1835     {
1836         ((types::Double *) array_ptr)->setImg((double *) data_ptr);
1837     }
1838     else if (mxIsInt8(array_ptr))
1839     {
1840         ((types::Int8 *) array_ptr)->setImg((char *) data_ptr);
1841     }
1842     else if (mxIsInt16(array_ptr))
1843     {
1844         ((types::Int16 *) array_ptr)->setImg((short *) data_ptr);
1845     }
1846     else if (mxIsInt32(array_ptr))
1847     {
1848         ((types::Int32 *) array_ptr)->setImg((int *) data_ptr);
1849     }
1850     else if (mxIsInt64(array_ptr))
1851     {
1852         ((types::Int64 *) array_ptr)->setImg((long long *) data_ptr);
1853     }
1854     else if (mxIsLogical(array_ptr))
1855     {
1856         ((types::Bool *) array_ptr)->setImg((int *) data_ptr);
1857     }
1858     // else if (mxIsSingle(array_ptr)) {
1859     //   ((types::Float *) array_ptr)->setImg((float *) data_ptr);
1860     // }
1861     else if (mxIsUint8(array_ptr))
1862     {
1863         ((types::UInt8 *) array_ptr)->setImg((unsigned char *) data_ptr);
1864     }
1865     else if (mxIsUint16(array_ptr))
1866     {
1867         ((types::UInt16 *) array_ptr)->setImg((unsigned short *) data_ptr);
1868     }
1869     else if (mxIsUint32(array_ptr))
1870     {
1871         ((types::UInt32 *) array_ptr)->setImg((unsigned int *) data_ptr);
1872     }
1873     else if (mxIsUint64(array_ptr))
1874     {
1875         ((types::UInt64 *) array_ptr)->setImg((unsigned long long *) data_ptr);
1876     }
1877 }
1878
1879 void mxSetPr(mxArray *ptr, double *pr)
1880 {
1881     ((types::Double *) ptr)->set(pr);
1882 }
1883
1884 void mxSetPi(mxArray *ptr, double *pi)
1885 {
1886     ((types::Double *) ptr)->setImg(pi);
1887 }
1888
1889 const char *mxGetName(const mxArray *array_ptr)
1890 {
1891     /* obsolete */
1892     mexPrintf(_("Routine mxGetName not implemented.\n"));
1893     exit(1);
1894     return 0;
1895 }
1896
1897 int mxSetDimensions(mxArray *array_ptr, const int *dims, int ndim)
1898 {
1899     if (mxIsCell(array_ptr))
1900     {
1901         ((types::Cell *) array_ptr)->resize((int *) dims, ndim);
1902     }
1903     else if (mxIsChar(array_ptr))
1904     {
1905         ((types::String *) array_ptr)->resize((int *) dims, ndim);
1906     }
1907     else if (mxIsDouble(array_ptr))
1908     {
1909         ((types::Double *) array_ptr)->resize((int *) dims, ndim);
1910     }
1911     else if (mxIsFunction(array_ptr))
1912     {
1913         //((types::Function *) array_ptr)->resize((int *) dims, ndim);
1914     }
1915     // else if (mxIsSparse(array_ptr)) {
1916     //     TODO: we don't have Sparse classes yet
1917     // }
1918     else if (mxIsInt8(array_ptr))
1919     {
1920         ((types::Int8 *) array_ptr)->resize((int *) dims, ndim);
1921     }
1922     else if (mxIsInt16(array_ptr))
1923     {
1924         ((types::Int16 *) array_ptr)->resize((int *) dims, ndim);
1925     }
1926     else if (mxIsInt32(array_ptr))
1927     {
1928         ((types::Int32 *) array_ptr)->resize((int *) dims, ndim);
1929     }
1930     else if (mxIsInt64(array_ptr))
1931     {
1932         ((types::Int64 *) array_ptr)->resize((int *) dims, ndim);
1933     }
1934     else if (mxIsLogical(array_ptr))
1935     {
1936         ((types::Bool *) array_ptr)->resize((int *) dims, ndim);
1937     }
1938     // else if (mxIsSingle(array_ptr)) {
1939     //     ((types::Float *) array_ptr)->resize((int *) dims, ndim);
1940     // }
1941     else if (mxIsStruct(array_ptr))
1942     {
1943         ((types::Struct *) array_ptr)->resize((int *) dims, ndim);
1944     }
1945     else if (mxIsUint8(array_ptr))
1946     {
1947         ((types::UInt8 *) array_ptr)->resize((int *) dims, ndim);
1948     }
1949     else if (mxIsUint16(array_ptr))
1950     {
1951         ((types::UInt16 *) array_ptr)->resize((int *) dims, ndim);
1952     }
1953     else if (mxIsUint32(array_ptr))
1954     {
1955         ((types::UInt32 *) array_ptr)->resize((int *) dims, ndim);
1956     }
1957     else if (mxIsUint64(array_ptr))
1958     {
1959         ((types::UInt64 *) array_ptr)->resize((int *) dims, ndim);
1960     }
1961
1962     return 0;
1963 }
1964
1965 const char *mxGetClassName(const mxArray *ptr)
1966 {
1967     if (mxIsDouble(ptr))
1968     {
1969         return "double";
1970     }
1971     if (mxIsChar(ptr))
1972     {
1973         return "char";
1974     }
1975     if (mxIsSparse(ptr))
1976     {
1977         return "sparse";
1978     }
1979     if (mxIsInt8(ptr))
1980     {
1981         return "int8";
1982     }
1983     if (mxIsInt16(ptr))
1984     {
1985         return "int16";
1986     }
1987     if (mxIsInt32(ptr))
1988     {
1989         return "int32";
1990     }
1991     if (mxIsInt64(ptr))
1992     {
1993         return "int64";
1994     }
1995     if (mxIsUint8(ptr))
1996     {
1997         return "uint8";
1998     }
1999     if (mxIsUint16(ptr))
2000     {
2001         return "uint16";
2002     }
2003     if (mxIsUint32(ptr))
2004     {
2005         return "uint32";
2006     }
2007     if (mxIsUint64(ptr))
2008     {
2009         return "uint64";
2010     }
2011     if (mxIsCell(ptr))
2012     {
2013         return "cell";
2014     }
2015     if (mxIsStruct(ptr))
2016     {
2017         return "struct";
2018     }
2019     if (mxIsFunction(ptr))
2020     {
2021         return "function_handle";
2022     }
2023     return "unknown";
2024 }
2025
2026 void mxSetCell(mxArray *array_ptr, int lindex, mxArray *value)
2027 {
2028     ((types::Cell *) array_ptr)->set(lindex, (types::InternalType *) value);
2029 }
2030
2031 int mxGetNzmax(const mxArray *ptr)
2032 {
2033     // TODO: sparse
2034     return 0;
2035 }
2036
2037 mxLogical *mxGetLogicals(const mxArray *ptr)
2038 {
2039     types::InternalType *pIT = (types::InternalType *) ptr;
2040     if (pIT == NULL)
2041     {
2042         return NULL;
2043     }
2044
2045     types::Bool *pB = pIT->getAs<types::Bool>();
2046     if (pB == NULL)
2047     {
2048         return NULL;
2049     }
2050
2051     return (mxLogical *) pB->get();
2052 }
2053
2054 void mexInfo(char *str)
2055 {
2056     mexPrintf("mexInfo: %s", str);
2057     // FIXME : Use scilabWrite
2058 }
2059
2060 int mexCheck(char *str, int nbvars)
2061 {
2062     // FIXME : Where does Nbvars come from ??
2063     // if ( nbvars != -1 && Nbvars != nbvars)
2064     //     fprintf(stderr,"%s %d %d\n",str,Nbvars,nbvars);
2065     // return Nbvars ;
2066     return 0;
2067 }
2068
2069 /****************************************************
2070 * C functions for Fortran  mexfunctions
2071 ****************************************************/
2072
2073 double *C2F(mxgetpr) (mxArray *ptr)
2074 {
2075     return mxGetPr(ptr);
2076 }
2077
2078 double *C2F(mxgetpi) (mxArray *ptr)
2079 {
2080     return mxGetPi(ptr);
2081 }
2082
2083 int C2F(mxgetm) (mxArray *ptr)
2084 {
2085     return mxGetM(ptr);
2086 }
2087
2088 int C2F(mxgetn) (mxArray *ptr)
2089 {
2090     return mxGetN(ptr);
2091 }
2092
2093 int C2F(mxisstring) (mxArray *ptr)
2094 {
2095     return mxIsString(ptr);
2096 }
2097
2098 int C2F(mxisnumeric) (mxArray *ptr)
2099 {
2100     return mxIsNumeric(ptr);
2101 }
2102
2103 int C2F(mxisfull) (mxArray *ptr)
2104 {
2105     return mxIsFull(ptr);
2106 }
2107
2108 int C2F(mxissparse) (mxArray *ptr)
2109 {
2110     return mxIsSparse(ptr);
2111 }
2112
2113 int C2F(mxiscomplex) (mxArray *ptr)
2114 {
2115     return mxIsComplex(ptr);
2116 }
2117
2118 double C2F(mxgetscalar) (mxArray *ptr)
2119 {
2120     return mxGetScalar(ptr);
2121 }
2122
2123 void C2F(mexprintf) (char *error_msg, int len)
2124 {
2125     error_msg[len] = '\0';
2126     mexPrintf(error_msg);
2127 }
2128
2129 void C2F(mexerrmsgtxt) (char *error_msg, int len)
2130 {
2131     error_msg[len] = '\0';
2132     mexErrMsgTxt(error_msg);
2133 }
2134
2135 mxArray *C2F(mxcreatefull) (int *m, int *n, int *it)
2136 {
2137     /* mxCreateFull is obsolete. Call mxCreateDoubleMatrix instead. */
2138     return (mxArray *) mxCreateDoubleMatrix(*m, *n, (mxComplexity) * it);
2139 }
2140
2141 mxArray *C2F(mxcreatedoublematrix) (int *m, int *n, int *it)
2142 {
2143     return (mxArray *) mxCreateDoubleMatrix(*m, *n, (mxComplexity) * it);
2144 }
2145
2146 unsigned long int C2F(mxcalloc) (unsigned int *n, unsigned int *size)
2147 {
2148     mxCalloc(*n, *size);
2149     return 0;
2150 }
2151
2152 int C2F(mxgetstring) (mxArray *ptr, char *str, int *strl)
2153 {
2154     return mxGetString(ptr, str, *strl);
2155 }
2156
2157 void C2F(mxfreematrix) (mxArray *ptr)
2158 {
2159     mxFreeMatrix(ptr);
2160 }
2161
2162 mxArray *C2F(mxcreatestring) (char *string, long int l)
2163 {
2164     string[l] = '\0';
2165     return mxCreateString(string);
2166 }
2167
2168 int C2F(mxcopyreal8toptr) (double *y, mxArray *ptr, int *n)
2169 {
2170     double *pr = mxGetPr(ptr);
2171     memcpy(y, pr, (*n) * sizeof(double));
2172     return 0;
2173 }
2174
2175 int C2F(mxcopycomplex16toptr) (double *y, mxArray *ptr, mxArray *pti, int *n)
2176 {
2177     // FIXME : Wrap this one to the C one
2178     return 0;
2179 }
2180
2181 int C2F(mxcopyptrtoreal8) (mxArray *ptr, double *y, int *n)
2182 {
2183     double *pr = mxGetPr(ptr);
2184     memcpy(pr, y, (*n) * sizeof(double));
2185     return 0;
2186 }
2187
2188 int C2F(mxcopyptrtocomplex16) (mxArray *ptr, mxArray *pti, double *y, int *n)
2189 {
2190     // FIXME : Wrap this one to the C one
2191     return 0;
2192 }
2193
2194 /* *mxRealloc(void *ptr, size_t size);
2195    mxArray *mxCreateStringFromNChars(const char *str, int n);
2196    int mxSetClassName(mxArray *pa, const char *classname);
2197    void mxRemoveField(mxArray *pa, int field);
2198    void mxSetCopyInCell(mxArray *pa, int i, mxArray *value);  */