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