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