1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  * Please note that piece of code will be rewrited for the Scilab 6 family
15  * However, the API (profile of the functions in the header files) will be
16  * still available and supported in Scilab 6.
17  */
18 
19 #include "types.hxx"
20 #include "internal.hxx"
21 #include "double.hxx"
22 #include "polynom.hxx"
23 #include "gatewaystruct.hxx"
24 #include "double.hxx"
25 #include "polynom.hxx"
26 #include "list.hxx"
27 #include "overload.hxx"
28 #include "context.hxx"
29 #include "symbol.hxx"
30 
31 extern "C"
32 {
33 #include <string.h>
34 #include <stdlib.h>
35 #include "api_scilab.h"
36 #include "api_internal_common.h"
37 #include "call_scilab.h"
38 #include "Scierror.h"
39 #include "sciprint.h"
40 #include "localization.h"
41 #include "sci_malloc.h"
42 }
43 
44 static int api_fake_int; //only for compatibility with Scilab 5 stack functions
45 /*Global structure for scilab 5.x*/
46 extern "C"
47 {
48     //StrCtx *pvApiCtx = NULL;
49 }
50 
51 /*--------------------------------------------------------------------------*/
52 static SciErr getinternalVarAddress(void* _pvCtx, int _iVar, int** _piAddress);
53 
54 /*--------------------------------------------------------------------------*/
55 /* Replaces Rhs */
getNbInputArgument(void * _pvCtx)56 int* getNbInputArgument(void* _pvCtx)
57 {
58     types::GatewayStruct *pStr = (types::GatewayStruct*)_pvCtx;
59 
60     if (pStr == NULL)
61     {
62         std::cout << "pStr == NULL" << std::endl;
63         return NULL;
64     }
65 
66     if (pStr->m_pIn == NULL)
67     {
68         std::cout << "pStr->m_pin == NULL" << std::endl;
69         return NULL;
70     }
71 
72     return &pStr->m_iIn;;
73 }
74 
75 /* Replaces Lhs */
getNbOutputArgument(void * _pvCtx)76 int* getNbOutputArgument(void* _pvCtx)
77 {
78     types::GatewayStruct *pStr =  (types::GatewayStruct*)_pvCtx;
79 
80     if (pStr == NULL)
81     {
82         return 0;
83     }
84 
85     if (pStr->m_piRetCount == NULL)
86     {
87         return 0;
88     }
89 
90     return &pStr->m_iOut;
91 }
92 
assignOutputVariable(void * _pvCtx,int _iVal)93 int* assignOutputVariable(void* _pvCtx, int _iVal)
94 {
95     //do nothing but don't crash
96     if (_pvCtx == NULL)
97     {
98         return &api_fake_int;
99     }
100 
101     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
102 
103     //do nothing but don't crash
104     if (_iVal > *pStr->m_piRetCount || (_iVal - 1) < 0)
105     {
106         return &api_fake_int;
107     }
108 
109     int* pVal = &(pStr->m_pOutOrder[_iVal - 1]);
110     return pVal;
111 }
112 
returnArguments(void * _pvCtx)113 int returnArguments(void* _pvCtx)
114 {
115     return 1;
116 }
117 
checkInputArgument(void * _pvCtx,int _iMin,int _iMax)118 int checkInputArgument(void* _pvCtx, int _iMin, int _iMax)
119 {
120     types::GatewayStruct *pStr = (types::GatewayStruct*)_pvCtx;
121     int iRhs            = *getNbInputArgument(_pvCtx);
122 
123     if (_iMin <= nbInputArgument(_pvCtx) && _iMax >= nbInputArgument(_pvCtx))
124     {
125         return 1;
126     }
127 
128     if (_iMin == _iMax)
129     {
130         /* No optional argument */
131         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), pStr->m_pstName, _iMax);
132     }
133     else
134     {
135         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), pStr->m_pstName, _iMin, _iMax);
136     }
137     return 0;
138 }
139 
reshapeArray(void * _pvCtx,int * _piAddress,int * _iDimsArray,int _iDims)140 SciErr reshapeArray(void* _pvCtx, int* _piAddress, int* _iDimsArray, int _iDims)
141 {
142     SciErr sciErr = sciErrInit();
143 
144     types::InternalType* pIT = (types::InternalType*)_piAddress;
145     if (pIT->isGenericType() == false)
146     {
147         addErrorMessage(&sciErr, API_ERROR_INVALID_TYPE, _("%s: Invalid argument type, %s expected"), "resizeArray", _("matrix"));
148         return sciErr;
149     }
150 
151     pIT->getAs<types::GenericType>()->reshape(_iDimsArray, _iDims);
152 
153     return sciErr;
154 }
155 
156 /*--------------------------------------------------------------------------*/
checkInputArgumentAtLeast(void * _pvCtx,int _iMin)157 int checkInputArgumentAtLeast(void* _pvCtx, int _iMin)
158 {
159     if (_iMin <= nbInputArgument(_pvCtx))
160     {
161         return 1;
162     }
163 
164     Scierror(77, _("%s: Wrong number of input argument(s): at least %d expected.\n"), ((types::GatewayStruct*)_pvCtx)->m_pstName, _iMin);
165     return 0;
166 }
167 
168 /*--------------------------------------------------------------------------*/
checkInputArgumentAtMost(void * _pvCtx,int _iMax)169 int checkInputArgumentAtMost(void* _pvCtx, int _iMax)
170 {
171     if (_iMax >= nbInputArgument(_pvCtx))
172     {
173         return 1;
174     }
175 
176     Scierror(77, _("%s: Wrong number of input argument(s): at most %d expected.\n"), ((types::GatewayStruct*)_pvCtx)->m_pstName, _iMax);
177     return 0;
178 }
179 
180 /*--------------------------------------------------------------------------*/
checkOutputArgument(void * _pvCtx,int _iMin,int _iMax)181 int checkOutputArgument(void* _pvCtx, int _iMin, int _iMax)
182 {
183     if (_iMin <= nbOutputArgument(_pvCtx) && _iMax >= nbOutputArgument(_pvCtx))
184     {
185         return 1;
186     }
187 
188     if (_iMax == _iMin)
189     {
190         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), ((types::GatewayStruct*)_pvCtx)->m_pstName, _iMax);
191     }
192     else
193     {
194         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), ((types::GatewayStruct*)_pvCtx)->m_pstName, _iMin, _iMax);
195     }
196 
197     return 0;
198 }
199 
200 /*--------------------------------------------------------------------------*/
checkOutputArgumentAtLeast(void * _pvCtx,int _iMin)201 int checkOutputArgumentAtLeast(void* _pvCtx, int _iMin)
202 {
203     if (_iMin <= nbOutputArgument(_pvCtx))
204     {
205         return 1;
206     }
207 
208     Scierror(78, _("%s: Wrong number of output argument(s): at least %d expected.\n"), ((types::GatewayStruct*)_pvCtx)->m_pstName, _iMin);
209     return 0;
210 }
211 
212 /*--------------------------------------------------------------------------*/
checkOutputArgumentAtMost(void * _pvCtx,int _iMax)213 int checkOutputArgumentAtMost(void* _pvCtx, int _iMax)
214 {
215     if (_iMax >= nbOutputArgument(_pvCtx))
216     {
217         return 1;
218     }
219 
220     Scierror(78, _("%s: Wrong number of output argument(s): at most %d expected.\n"), ((types::GatewayStruct*)_pvCtx)->m_pstName, _iMax);
221     return 0;
222 }
223 
224 /*--------------------------------------------------------------------------*/
callScilabFunction(void * _pvCtx,char const * _pstName,int _iStart,int _iLhs,int _iRhs)225 int callScilabFunction(void* _pvCtx, char const* _pstName, int _iStart, int _iLhs, int _iRhs)
226 {
227     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
228     types::Function::ReturnValue callResult;
229 
230     wchar_t* pwstName = to_wide_string(_pstName);
231     std::wstring wsFunName(pwstName);
232 
233     types::typed_list in;
234     types::typed_list out;
235 
236 
237     for (int i = 0 ; i < _iRhs ; i++)
238     {
239         in.push_back((*pStr->m_pIn)[i + (_iStart - 1)]);
240         in[i]->IncreaseRef();
241     }
242 
243     callResult = Overload::call(wsFunName, in, _iLhs, out);
244 
245     //unprotect input arguments
246     for (int i = 0 ; i < _iRhs ; i++)
247     {
248         in[i]->DecreaseRef();
249     }
250 
251     if (callResult == types::Function::OK)
252     {
253         int iCallerRhs = (int)pStr->m_pIn->size();
254         pStr->m_pIn->resize(iCallerRhs + _iRhs + _iLhs, NULL);
255         for (int i = 0 ; i < _iLhs ; i++)
256         {
257             (*pStr->m_pIn)[iCallerRhs + _iRhs + i] = out[i];
258             //pStr->m_pOutOrder[i] = i + 1;
259         }
260     }
261 
262     FREE(pwstName);
263     return 0;
264 }
265 
callOverloadFunction(void * _pvCtx,int _iVar,char * _pstName,unsigned int _iNameLen)266 int callOverloadFunction(void* _pvCtx, int _iVar, char* _pstName, unsigned int _iNameLen)
267 {
268     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
269     types::Function::ReturnValue callResult;
270     types::typed_list tlReturnedValues;
271 
272     wchar_t* pwstName = NULL;
273     if (_pstName == NULL || strlen(_pstName) == 0)
274     {
275         pwstName = to_wide_string(pStr->m_pstName);
276     }
277     else
278     {
279         pwstName = to_wide_string(_pstName);
280     }
281     std::wstring wsFunName;
282 
283     if (_iVar == 0)
284     {
285         wsFunName = std::wstring(L"%_") + std::wstring(pwstName);
286     }
287     else
288     {
289         wsFunName = std::wstring(L"%") + (*pStr->m_pIn)[_iVar - 1]->getShortTypeStr() + L"_" + std::wstring(pwstName);
290     }
291 
292     //protect input arguments
293     for (int i = 0 ; i < pStr->m_pIn->size() ; i++)
294     {
295         (*pStr->m_pIn)[i]->IncreaseRef();
296     }
297 
298     callResult = Overload::call(wsFunName, *(pStr->m_pIn), *(pStr->m_piRetCount), tlReturnedValues);
299 
300     //unprotect input arguments
301     for (int i = 0 ; i < pStr->m_pIn->size() ; i++)
302     {
303         (*pStr->m_pIn)[i]->DecreaseRef();
304     }
305 
306     if (callResult == types::Function::OK)
307     {
308         int i = 0;
309         types::typed_list::iterator it;
310         for (it = tlReturnedValues.begin() ; it != tlReturnedValues.end() ; ++it, ++i)
311         {
312             (pStr->m_pOut)[i] = *it;
313             pStr->m_pOutOrder[i] = (int)pStr->m_pIn->size() + i + 1;
314         }
315     }
316 
317     FREE(pwstName);
318     return 0;
319 }
320 
321 /*--------------------------------------------------------------------------*/
getVarDimension(void * _pvCtx,int * _piAddress,int * _piRows,int * _piCols)322 SciErr getVarDimension(void *_pvCtx, int *_piAddress, int *_piRows, int *_piCols)
323 {
324     SciErr sciErr = sciErrInit();
325 
326     if (_piAddress != NULL && isVarMatrixType(_pvCtx, _piAddress))
327     {
328         *_piRows = ((types::InternalType*)_piAddress)->getAs<types::GenericType>()->getRows();
329         *_piCols = ((types::InternalType*)_piAddress)->getAs<types::GenericType>()->getCols();
330     }
331     else
332     {
333         *_piRows = 0;
334         *_piCols = 0;
335         if (_piAddress == NULL)
336         {
337             addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "getVarDimension");
338         }
339         else
340         {
341             addErrorMessage(&sciErr, API_ERROR_NOT_MATRIX_TYPE, _("%s: matrix argument expected"), "getVarDimension");
342         }
343     }
344     return sciErr;
345 }
346 
347 /*--------------------------------------------------------------------------*/
getNamedVarDimension(void * _pvCtx,const char * _pstName,int * _piRows,int * _piCols)348 SciErr getNamedVarDimension(void *_pvCtx, const char *_pstName, int *_piRows, int *_piCols)
349 {
350     SciErr sciErr = sciErrInit();
351     int *piAddr = NULL;
352 
353     sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
354     if (sciErr.iErr)
355     {
356         addErrorMessage(&sciErr, API_ERROR_NAMED_VARDIM, _("%s: Unable to get dimension of variable \"%s\""), "getNamedVarDimension", _pstName);
357         return sciErr;
358     }
359 
360     sciErr = getVarDimension(_pvCtx, piAddr, _piRows, _piCols);
361     if (sciErr.iErr)
362     {
363         addErrorMessage(&sciErr, API_ERROR_NAMED_VARDIM, _("%s: Unable to get dimension of variable \"%s\""), "getNamedVarDimension", _pstName);
364         return sciErr;
365     }
366 
367     return sciErr;
368 }
369 
370 /*--------------------------------------------------------------------------*/
getVarAddressFromPosition(void * _pvCtx,int _iVar,int ** _piAddress)371 SciErr getVarAddressFromPosition(void *_pvCtx, int _iVar, int **_piAddress)
372 {
373     SciErr sciErr = getinternalVarAddress(_pvCtx, _iVar, _piAddress);
374     return sciErr;
375 }
376 
377 /*--------------------------------------------------------------------------*/
getinternalVarAddress(void * _pvCtx,int _iVar,int ** _piAddress)378 static SciErr getinternalVarAddress(void *_pvCtx, int _iVar, int **_piAddress)
379 {
380     SciErr sciErr = sciErrInit();
381     int iAddr = 0;
382     int iValType = 0;
383 
384     if (_pvCtx == NULL)
385     {
386         addErrorMessage(&sciErr, API_ERROR_INVALID_POSITION, _("%s: bad call to %s! (1rst argument).\n"), "",
387                         "getVarAddressFromPosition");
388         return sciErr;
389     }
390 
391     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
392     types::typed_list in = *pStr->m_pIn;
393     types::optional_list opt = *pStr->m_pOpt;
394     int* piRetCount = pStr->m_piRetCount;
395     int iInputSize = static_cast<int>(in.size()) + static_cast<int>(opt.size());
396 
397     /* we accept a call to getVarAddressFromPosition after a create... call */
398     if (_iVar > *piRetCount + iInputSize)
399     {
400         //manage case where _iVar > in.size(), then look in out to get recent create variable.
401         addErrorMessage(&sciErr, API_ERROR_INVALID_POSITION, _("%s: bad call to %s! (1rst argument).\n"), pStr->m_pstName, "getVarAddressFromPosition");
402         return sciErr;
403     }
404 
405     if (_iVar > iInputSize)
406     {
407         *_piAddress = (int*)pStr->m_pOut[_iVar - iInputSize - 1];
408     }
409     else if (_iVar > in.size())
410     {
411         *_piAddress = NULL; //never happend, I hope !
412     }
413     else
414     {
415         *_piAddress = (int*)in[_iVar - 1];
416     }
417     return sciErr;
418 }
419 /*--------------------------------------------------------------------------*/
getVarNameFromPosition(void * _pvCtx,int _iVar,char * _pstName)420 SciErr getVarNameFromPosition(void *_pvCtx, int _iVar, char *_pstName)
421 {
422     SciErr sciErr = sciErrInit();
423 
424     if (_pvCtx == NULL)
425     {
426         addErrorMessage(&sciErr, API_ERROR_INVALID_POSITION, _("%s: bad call to %s! (1rst argument).\n"), "",
427                         "getVarNameFromPosition");
428         return sciErr;
429     }
430 
431     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
432     types::typed_list in = *pStr->m_pIn;
433 
434     if (in[_iVar - 1]->isCallable())
435     {
436         std::wstring pwstring = in[_iVar - 1]->getAs<types::Callable>()->getName();
437         const wchar_t* pwcName = pwstring.c_str();
438         char* pstNameTempo = wide_string_to_UTF8(pwcName);
439         strcpy(_pstName, pstNameTempo);
440         FREE(pstNameTempo);
441     }
442 
443     return sciErr;
444 }
445 /*--------------------------------------------------------------------------*/
getNewVarAddressFromPosition(void * _pvCtx,int _iVar,int ** _piAddress)446 int getNewVarAddressFromPosition(void *_pvCtx, int _iVar, int **_piAddress)
447 {
448     // FIXME
449     return 0;
450 }
451 
452 /*--------------------------------------------------------------------------*/
getVarAddressFromName(void * _pvCtx,const char * _pstName,int ** _piAddress)453 SciErr getVarAddressFromName(void *_pvCtx, const char *_pstName, int **_piAddress)
454 {
455     SciErr sciErr = sciErrInit();
456 
457     wchar_t* pwstName = to_wide_string(_pstName);
458     symbol::Context* pCtx = symbol::Context::getInstance();
459     types::InternalType* pVar = pCtx->get(symbol::Symbol(pwstName));
460     FREE(pwstName);
461 
462     if (pVar == NULL)
463     {
464         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Unable to get address of variable \"%s\""), "getVarAddressFromName", _pstName);
465     }
466     else
467     {
468         *_piAddress = (int*)pVar;
469     }
470 
471     return sciErr;
472 }
473 
474 /*--------------------------------------------------------------------------*/
getVarType(void * _pvCtx,int * _piAddress,int * _piType)475 SciErr getVarType(void *_pvCtx, int *_piAddress, int *_piType)
476 {
477     SciErr sciErr = sciErrInit();
478 
479     if (_piAddress == NULL)
480     {
481         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "getVarType");
482         return sciErr;
483     }
484 
485     switch (((types::InternalType*)_piAddress)->getType())
486     {
487         case types::InternalType::ScilabDouble :
488             *_piType = sci_matrix;
489             break;
490         case types::InternalType::ScilabPolynom :
491             *_piType = sci_poly;
492             break;
493         case types::InternalType::ScilabBool :
494             *_piType = sci_boolean;
495             break;
496         case types::InternalType::ScilabSparse :
497             *_piType = sci_sparse;
498             break;
499         case types::InternalType::ScilabSparseBool :
500             *_piType = sci_boolean_sparse;
501             break;
502             //case types::InternalType::RealMatlabSparse :
503             //    *_piType = sci_matlab_sparse;
504             //    break;
505         case types::InternalType::ScilabInt8 :
506         case types::InternalType::ScilabUInt8 :
507         case types::InternalType::ScilabInt16 :
508         case types::InternalType::ScilabUInt16 :
509         case types::InternalType::ScilabInt32 :
510         case types::InternalType::ScilabUInt32 :
511         case types::InternalType::ScilabInt64 :
512         case types::InternalType::ScilabUInt64 :
513             *_piType = sci_ints;
514             break;
515         case types::InternalType::ScilabHandle :
516             *_piType = sci_handles;
517             break;
518         case types::InternalType::ScilabString :
519             *_piType = sci_strings;
520             break;
521         case types::InternalType::ScilabMacroFile :
522         case types::InternalType::ScilabMacro :
523             *_piType = sci_c_function;
524             break;
525         case types::InternalType::ScilabList :
526             *_piType = sci_list;
527             break;
528         case types::InternalType::ScilabCell :
529             *_piType = sci_mlist;
530             break;
531         case types::InternalType::ScilabTList :
532             *_piType = sci_tlist;
533             break;
534         case types::InternalType::ScilabMList :
535             *_piType = sci_mlist;
536             break;
537         case types::InternalType::ScilabStruct :
538             // Scilab < 6 compatibility... Struct have type 17;
539             *_piType = sci_mlist;
540             break;
541         case types::InternalType::ScilabUserType :
542             *_piType = sci_pointer;
543             break;
544         case types::InternalType::ScilabColon :
545         case types::InternalType::ScilabImplicitList :
546             *_piType = sci_implicit_poly;
547             break;
548         case types::InternalType::ScilabFunction:
549             *_piType = sci_intrinsic_function;
550             break;
551         case types::InternalType::ScilabLibrary:
552             *_piType = sci_lib;
553             break;
554         default:
555             *_piType = 0;
556     }
557 
558     return sciErr;
559 }
560 
561 /*--------------------------------------------------------------------------*/
562 // _pvCtx will not be used by getVarAddressFromName neither getVarType
563 // it can then be NULL.
getNamedVarType(void * _pvCtx,const char * _pstName,int * _piType)564 SciErr getNamedVarType(void *_pvCtx, const char *_pstName, int *_piType)
565 {
566     int *piAddr = NULL;
567 
568     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
569     if (sciErr.iErr)
570     {
571         addErrorMessage(&sciErr, API_ERROR_NAMED_UNDEFINED_VAR, _("%s: Unable to get variable \"%s\""), "getNamedVarType", _pstName);
572         return sciErr;
573     }
574 
575     sciErr = getVarType(_pvCtx, piAddr, _piType);
576     if (sciErr.iErr)
577     {
578         addErrorMessage(&sciErr, API_ERROR_NAMED_TYPE, _("%s: Unable to get type of variable \"%s\""), "getNamedVarType", _pstName);
579         return sciErr;
580     }
581     return sciErr;
582 }
583 
584 /*--------------------------------------------------------------------------*/
isVarComplex(void * _pvCtx,int * _piAddress)585 int isVarComplex(void *_pvCtx, int *_piAddress)
586 {
587     SciErr sciErr = sciErrInit();
588     int iType = 0;
589     int iComplex = 0;
590 
591     if (_piAddress == NULL)
592     {
593         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "isVarComplex");
594         return 0;
595     }
596 
597     types::InternalType* pIT = (types::InternalType*)_piAddress;
598     types::GenericType* pGT = dynamic_cast<types::GenericType*>(pIT);
599     if (pGT == NULL)
600     {
601         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "isVarComplex");
602         return 0;
603     }
604 
605     return pGT->isComplex();
606 }
607 
608 /*--------------------------------------------------------------------------*/
isNamedVarComplex(void * _pvCtx,const char * _pstName)609 int isNamedVarComplex(void *_pvCtx, const char *_pstName)
610 {
611     int *piAddr = NULL;
612 
613     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
614     if (sciErr.iErr)
615     {
616         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "isNamedVarComplex");
617         return 0;
618     }
619     return isVarComplex(_pvCtx, piAddr);
620 }
621 
622 /*--------------------------------------------------------------------------*/
createNamedVariable(int * _piVarID)623 void createNamedVariable(int *_piVarID)
624 {
625     //deprecated
626 }
627 
628 /*--------------------------------------------------------------------------*/
updateLstk(int _iNewpos,int _iSCIDataAddress,int _iVarSize)629 int updateLstk(int _iNewpos, int _iSCIDataAddress, int _iVarSize)
630 {
631     //deprecated
632     return 0;
633 }
634 
635 /*--------------------------------------------------------------------------*/
isVarMatrixType(void * _pvCtx,int * _piAddress)636 int isVarMatrixType(void *_pvCtx, int *_piAddress)
637 {
638     if (_piAddress != NULL)
639     {
640         int iType = 0;
641         getVarType(_pvCtx, _piAddress, &iType);
642 
643         switch (iType)
644         {
645             case sci_matrix:
646             case sci_poly:
647             case sci_boolean:
648             case sci_sparse:
649             case sci_boolean_sparse:
650             case sci_matlab_sparse:
651             case sci_ints:
652             case sci_handles:
653             case sci_strings:
654                 return 1;
655             default:
656                 return 0;
657         }
658     }
659     else
660     {
661         return 0;
662     }
663     return 1;
664 }
665 
666 /*--------------------------------------------------------------------------*/
isNamedVarMatrixType(void * _pvCtx,const char * _pstName)667 int isNamedVarMatrixType(void *_pvCtx, const char *_pstName)
668 {
669     int *piAddr = NULL;
670 
671     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
672     if (sciErr.iErr)
673     {
674         return 0;
675     }
676     return isVarMatrixType(_pvCtx, piAddr);
677 }
678 
679 /*--------------------------------------------------------------------------*/
getProcessMode(void * _pvCtx,int _iPos,int * _piAddRef,int * _piMode)680 SciErr getProcessMode(void *_pvCtx, int _iPos, int *_piAddRef, int *_piMode)
681 {
682     int iRows1 = 0;
683     int iCols1 = 0;
684     int iRows2 = 0;
685     int iCols2 = 0;
686     int iType2 = 0;
687     int iMode = 0;
688     int *piAddr2 = NULL;
689 
690     SciErr sciErr = getVarDimension(_pvCtx, _piAddRef, &iRows1, &iCols1);
691     if (sciErr.iErr)
692     {
693         addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get argument dimension"), "getProcessMode");
694         return sciErr;
695     }
696 
697     //sciprint("getProcessMode ->");
698     sciErr = getinternalVarAddress(_pvCtx, _iPos, &piAddr2);
699     if (sciErr.iErr)
700     {
701         addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get variable address"), "getProcessMode");
702         return sciErr;
703     }
704 
705     sciErr = getVarType(_pvCtx, piAddr2, &iType2);
706     if (sciErr.iErr)
707     {
708         addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get argument type"), "getProcessMode");
709         return sciErr;
710     }
711 
712     if (iType2 == sci_matrix && !isVarComplex(_pvCtx, piAddr2))
713     {
714         double *pdblReal2 = NULL;
715 
716         sciErr = getMatrixOfDouble(_pvCtx, piAddr2, &iRows2, &iCols2, &pdblReal2);
717         if (sciErr.iErr)
718         {
719             addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get argument data"), "getProcessMode");
720             return sciErr;
721         }
722 
723         if (iRows2 != 1 || iCols2 != 1)
724         {
725             addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Wrong size for argument #%d: (%d,%d) expected.\n"), "getProcessMode", _iPos, 1,
726                             1);
727             return sciErr;
728         }
729 
730         iMode = (int)pdblReal2[0];
731     }
732     else if (iType2 == sci_strings)
733     {
734         int iLen = 0;
735         char initialValue = '\0';
736         char *pstMode[1] = { &initialValue };
737 
738         sciErr = getVarDimension(_pvCtx, piAddr2, &iRows2, &iCols2);
739         if (sciErr.iErr)
740         {
741             addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get argument dimension"), "getProcessMode");
742             return sciErr;
743         }
744 
745         if (iRows2 != 1 || iCols2 != 1)
746         {
747             addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Wrong size for argument #%d: (%d,%d) expected.\n"), "getProcessMode", _iPos, 1,
748                             1);
749             return sciErr;
750         }
751 
752         sciErr = getMatrixOfString(_pvCtx, piAddr2, &iRows2, &iCols2, &iLen, NULL);
753         if (sciErr.iErr)
754         {
755             addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get argument data"), "getProcessMode");
756             return sciErr;
757         }
758 
759         pstMode[0] = (char *)MALLOC(sizeof(char) * (iLen + 1)); //+1 for null termination
760         sciErr = getMatrixOfString(_pvCtx, piAddr2, &iRows2, &iCols2, &iLen, pstMode);
761         if (sciErr.iErr)
762         {
763             addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Unable to get argument data"), "getProcessMode");
764             return sciErr;
765         }
766 
767         iMode = (int)pstMode[0][0];
768         FREE(pstMode[0]);
769     }
770     else
771     {
772         addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Wrong type for input argument #%d: string or scalar expected.\n"),
773                         "getProcessMode", _iPos);
774         return sciErr;
775     }
776 
777     if (iMode == ROW_LETTER || iMode == BY_ROWS)
778     {
779         *_piMode = BY_ROWS;
780     }
781     else if (iMode == COL_LETTER || iMode == BY_COLS)
782     {
783         *_piMode = BY_COLS;
784     }
785     else if (iMode == STAR_LETTER || iMode == BY_ALL)
786     {
787         *_piMode = BY_ALL;
788     }
789     else if (iMode == MTLB_LETTER || iMode == BY_MTLB)
790     {
791         *_piMode = 0;
792         if (iRows1 > 1)
793         {
794             *_piMode = 1;
795         }
796         else if (iCols1 > 1)
797         {
798             *_piMode = 2;
799         }
800     }
801     else
802     {
803         addErrorMessage(&sciErr, API_ERROR_GET_PROCESSMODE, _("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), "getProcessMode",
804                         _iPos, "'*', 'r', 'c', 'm', '0', '1', '2'", "-1");
805         return sciErr;
806     }
807     return sciErr;
808 }
809 
810 /*--------------------------------------------------------------------------*/
getDimFromVar(void * _pvCtx,int * _piAddress,int * _piVal)811 SciErr getDimFromVar(void *_pvCtx, int *_piAddress, int *_piVal)
812 {
813     int iType = 0;
814     int iRows = 0;
815     int iCols = 0;
816     double *pdblReal = NULL;
817 
818     SciErr sciErr = getVarType(_pvCtx, _piAddress, &iType);
819     if (sciErr.iErr)
820     {
821         addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument type"), "getDimFromVar");
822         return sciErr;
823     }
824 
825     if (iType == sci_matrix)
826     {
827         if (isVarComplex(_pvCtx, _piAddress))
828         {
829             addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Wrong type for argument #%d: Real matrix expected.\n"), "getDimFromVar",
830                             getRhsFromAddress(_pvCtx, _piAddress));
831             return sciErr;
832         }
833 
834         sciErr = getMatrixOfDouble(_pvCtx, _piAddress, &iRows, &iCols, &pdblReal);
835         if (sciErr.iErr)
836         {
837             addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
838             return sciErr;
839         }
840 
841         *_piVal = (int)std::max(pdblReal[0], double(0));
842     }
843     else if (iType == sci_ints)
844     {
845         int iPrec = 0;
846 
847         sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
848         if (sciErr.iErr)
849         {
850             addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument dimension"), "getDimFromVar");
851             return sciErr;
852         }
853 
854         if (iRows != 1 || iCols != 1)
855         {
856             addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Wrong size for argument #%d: (%d,%d) expected.\n"), "getProcessMode",
857                             getRhsFromAddress(_pvCtx, _piAddress), 1, 1);
858             return sciErr;
859         }
860 
861         sciErr = getMatrixOfIntegerPrecision(_pvCtx, _piAddress, &iPrec);
862         if (sciErr.iErr)
863         {
864             addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument precision"), "getDimFromVar");
865             return sciErr;
866         }
867 
868         switch (iPrec)
869         {
870             case SCI_INT8:
871             {
872                 char *pcData = NULL;
873 
874                 sciErr = getMatrixOfInteger8(_pvCtx, _piAddress, &iRows, &iCols, &pcData);
875                 if (sciErr.iErr)
876                 {
877                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
878                     return sciErr;
879                 }
880                 *_piVal = pcData[0];
881             }
882             break;
883             case SCI_UINT8:
884             {
885                 unsigned char *pucData = NULL;
886 
887                 sciErr = getMatrixOfUnsignedInteger8(_pvCtx, _piAddress, &iRows, &iCols, &pucData);
888                 if (sciErr.iErr)
889                 {
890                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
891                     return sciErr;
892                 }
893                 *_piVal = pucData[0];
894             }
895             break;
896             case SCI_INT16:
897             {
898                 short *psData = NULL;
899 
900                 sciErr = getMatrixOfInteger16(_pvCtx, _piAddress, &iRows, &iCols, &psData);
901                 if (sciErr.iErr)
902                 {
903                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
904                     return sciErr;
905                 }
906                 *_piVal = psData[0];
907             }
908             break;
909             case SCI_UINT16:
910             {
911                 unsigned short *pusData = NULL;
912 
913                 sciErr = getMatrixOfUnsignedInteger16(_pvCtx, _piAddress, &iRows, &iCols, &pusData);
914                 if (sciErr.iErr)
915                 {
916                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
917                     return sciErr;
918                 }
919                 *_piVal = pusData[0];
920             }
921             break;
922             case SCI_INT32:
923             {
924                 int *piData = NULL;
925 
926                 sciErr = getMatrixOfInteger32(_pvCtx, _piAddress, &iRows, &iCols, &piData);
927                 if (sciErr.iErr)
928                 {
929                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
930                     return sciErr;
931                 }
932                 *_piVal = piData[0];
933             }
934             break;
935             case SCI_UINT32:
936             {
937                 unsigned int *puiData = NULL;
938 
939                 sciErr = getMatrixOfUnsignedInteger32(_pvCtx, _piAddress, &iRows, &iCols, &puiData);
940                 if (sciErr.iErr)
941                 {
942                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
943                     return sciErr;
944                 }
945                 *_piVal = puiData[0];
946             }
947             break;
948 #ifdef __SCILAB_INT64__
949             case SCI_INT64:
950             {
951                 long long *pllData = NULL;
952 
953                 sciErr = getMatrixOfInteger64(_pvCtx, _piAddress, &iRows, &iCols, &pllData);
954                 if (sciErr.iErr)
955                 {
956                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
957                     return sciErr;
958                 }
959                 *_piVal = (int)pllData[0];
960             }
961             break;
962             case SCI_UINT64:
963             {
964                 unsigned long long *pullData = NULL;
965 
966                 sciErr = getMatrixOfUnsignedInteger64(_pvCtx, _piAddress, &iRows, &iCols, &pullData);
967                 if (sciErr.iErr)
968                 {
969                     addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Unable to get argument data"), "getDimFromVar");
970                     return sciErr;
971                 }
972                 *_piVal = (int)pullData[0];
973             }
974             break;
975 #endif
976         }
977     }
978     else
979     {
980         addErrorMessage(&sciErr, API_ERROR_GET_DIMFROMVAR, _("%s: Wrong type for input argument #%d: A real scalar or an integer scalar expected.\n"),
981                         "getDimFromVar", getRhsFromAddress(_pvCtx, _piAddress));
982         return sciErr;
983     }
984     return sciErr;
985 }
986 
987 /*--------------------------------------------------------------------------*/
getDimFromNamedVar(void * _pvCtx,const char * _pstName,int * _piVal)988 SciErr getDimFromNamedVar(void *_pvCtx, const char *_pstName, int *_piVal)
989 {
990     int *piAddr = NULL;
991 
992     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
993     if (sciErr.iErr)
994     {
995         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_DIMFROMVAR, _("%s: Unable to get dimension from variable \"%s\""), "getDimFromNamedVar",
996                         _pstName);
997         return sciErr;
998     }
999 
1000     sciErr = getDimFromVar(_pvCtx, piAddr, _piVal);
1001     if (sciErr.iErr)
1002     {
1003         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_DIMFROMVAR, _("%s: Unable to get dimension from variable \"%s\""), "getDimFromNamedVar",
1004                         _pstName);
1005         return sciErr;
1006     }
1007 
1008     return sciErr;
1009 }
1010 
1011 /*--------------------------------------------------------------------------*/
getRhsFromAddress(void * _pvCtx,int * _piAddress)1012 int getRhsFromAddress(void *_pvCtx, int *_piAddress)
1013 {
1014     int i = 0;
1015     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
1016     types::typed_list in = *pStr->m_pIn;
1017 
1018     for (i = 0 ; i < in.size() ; i++)
1019     {
1020         if (_piAddress == (int*)in[i])
1021         {
1022             return i + 1;
1023         }
1024     }
1025     return -1;
1026 }
1027 
1028 /*short cut functions*/
1029 
1030 /*--------------------------------------------------------------------------*/
isRowVector(void * _pvCtx,int * _piAddress)1031 int isRowVector(void *_pvCtx, int *_piAddress)
1032 {
1033     int iRows = 0;
1034     int iCols = 0;
1035 
1036     if (_piAddress == NULL)
1037     {
1038         return 0;
1039     }
1040 
1041     if (isVarMatrixType(_pvCtx, _piAddress) == 0)
1042     {
1043         return 0;
1044     }
1045 
1046     SciErr sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
1047     if (sciErr.iErr)
1048     {
1049         addErrorMessage(&sciErr, API_ERROR_IS_ROW_VECTOR, _("%s: Unable to get argument dimension"), "isRowVector");
1050         printError(&sciErr, 0);
1051         return sciErr.iErr;
1052     }
1053 
1054     if (iRows == 1 && iCols > 1)
1055     {
1056         return 1;
1057     }
1058 
1059     return 0;
1060 }
1061 
1062 /*--------------------------------------------------------------------------*/
isNamedRowVector(void * _pvCtx,const char * _pstName)1063 int isNamedRowVector(void *_pvCtx, const char *_pstName)
1064 {
1065     int iRows = 0;
1066     int iCols = 0;
1067 
1068     if (isNamedVarMatrixType(_pvCtx, _pstName) == 0)
1069     {
1070         return 0;
1071     }
1072 
1073     SciErr sciErr = getNamedVarDimension(_pvCtx, _pstName, &iRows, &iCols);
1074     if (sciErr.iErr)
1075     {
1076         addErrorMessage(&sciErr, API_ERROR_IS_NAMED_ROW_VECTOR, _("%s: Unable to get argument dimension"), "isNamedRowVector");
1077         printError(&sciErr, 0);
1078         return sciErr.iErr;
1079     }
1080 
1081     if (iRows == 1 && iCols > 1)
1082     {
1083         return 1;
1084     }
1085 
1086     return 0;
1087 }
1088 
1089 /*--------------------------------------------------------------------------*/
isColumnVector(void * _pvCtx,int * _piAddress)1090 int isColumnVector(void *_pvCtx, int *_piAddress)
1091 {
1092     int iRows = 0;
1093     int iCols = 0;
1094 
1095     if (_piAddress == NULL)
1096     {
1097         return 0;
1098     }
1099 
1100     if (isVarMatrixType(_pvCtx, _piAddress) == 0)
1101     {
1102         return 0;
1103     }
1104 
1105     SciErr sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
1106     if (sciErr.iErr)
1107     {
1108         addErrorMessage(&sciErr, API_ERROR_IS_COLUMN_VECTOR, _("%s: Unable to get argument dimension"), "isColumnVector");
1109         printError(&sciErr, 0);
1110         return 0;
1111     }
1112 
1113     if (iCols == 1 && iRows > 1)
1114     {
1115         return 1;
1116     }
1117 
1118     return 0;
1119 }
1120 
1121 /*--------------------------------------------------------------------------*/
isNamedColumnVector(void * _pvCtx,const char * _pstName)1122 int isNamedColumnVector(void *_pvCtx, const char *_pstName)
1123 {
1124     int iRows = 0;
1125     int iCols = 0;
1126 
1127     if (isNamedVarMatrixType(_pvCtx, _pstName) == 0)
1128     {
1129         return 0;
1130     }
1131 
1132     SciErr sciErr = getNamedVarDimension(_pvCtx, _pstName, &iRows, &iCols);
1133     if (sciErr.iErr)
1134     {
1135         addErrorMessage(&sciErr, API_ERROR_IS_NAMED_COLUMN_VECTOR, _("%s: Unable to get argument dimension"), "isNamedColumnVector");
1136         printError(&sciErr, 0);
1137         return 0;
1138     }
1139 
1140     if (iCols == 1 && iRows > 1)
1141     {
1142         return 1;
1143     }
1144 
1145     return 0;
1146 }
1147 
1148 /*--------------------------------------------------------------------------*/
isVector(void * _pvCtx,int * _piAddress)1149 int isVector(void *_pvCtx, int *_piAddress)
1150 {
1151     return isRowVector(_pvCtx, _piAddress) || isColumnVector(_pvCtx, _piAddress);
1152 }
1153 
1154 /*--------------------------------------------------------------------------*/
isNamedVector(void * _pvCtx,const char * _pstName)1155 int isNamedVector(void *_pvCtx, const char *_pstName)
1156 {
1157     return isNamedRowVector(_pvCtx, _pstName) || isNamedColumnVector(_pvCtx, _pstName);
1158 }
1159 
1160 /*--------------------------------------------------------------------------*/
isStruct(void * _pvCtx,int * _piAddress)1161 int isStruct(void *_pvCtx, int *_piAddress)
1162 {
1163     if (((types::InternalType*)_piAddress)->getType() == types::InternalType::ScilabStruct)
1164     {
1165         return 1;
1166     }
1167     return 0;
1168 }
1169 /*--------------------------------------------------------------------------*/
isCell(void * _pvCtx,int * _piAddress)1170 int isCell(void *_pvCtx, int *_piAddress)
1171 {
1172     if (((types::InternalType*)_piAddress)->getType() == types::InternalType::ScilabCell)
1173     {
1174         return 1;
1175     }
1176     return 0;
1177 }
1178 /*--------------------------------------------------------------------------*/
isScalar(void * _pvCtx,int * _piAddress)1179 int isScalar(void *_pvCtx, int *_piAddress)
1180 {
1181     int iRows = 0;
1182     int iCols = 0;
1183 
1184     if (_piAddress == NULL)
1185     {
1186         return 0;
1187     }
1188 
1189     if (isVarMatrixType(_pvCtx, _piAddress) == 0)
1190     {
1191         return 0;
1192     }
1193 
1194     SciErr sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
1195     if (sciErr.iErr)
1196     {
1197         addErrorMessage(&sciErr, API_ERROR_IS_SCALAR, _("%s: Unable to get argument dimension"), "isScalar");
1198         printError(&sciErr, 0);
1199         return 0;
1200     }
1201 
1202     if (iCols == 1 && iRows == 1)
1203     {
1204         return 1;
1205     }
1206 
1207     return 0;
1208 }
1209 
1210 /*--------------------------------------------------------------------------*/
isNamedScalar(void * _pvCtx,const char * _pstName)1211 int isNamedScalar(void *_pvCtx, const char *_pstName)
1212 {
1213     int iRows = 0;
1214     int iCols = 0;
1215 
1216     if (isNamedVarMatrixType(_pvCtx, _pstName) == 0)
1217     {
1218         return 0;
1219     }
1220 
1221     SciErr sciErr = getNamedVarDimension(_pvCtx, _pstName, &iRows, &iCols);
1222     if (sciErr.iErr)
1223     {
1224         addErrorMessage(&sciErr, API_ERROR_IS_NAMED_SCALAR, _("%s: Unable to get argument dimension"), "isNamedScalar");
1225         printError(&sciErr, 0);
1226         return 0;
1227     }
1228 
1229     if (iCols == 1 && iRows == 1)
1230     {
1231         return 1;
1232     }
1233 
1234     return 0;
1235 }
1236 
1237 /*--------------------------------------------------------------------------*/
isSquareMatrix(void * _pvCtx,int * _piAddress)1238 int isSquareMatrix(void *_pvCtx, int *_piAddress)
1239 {
1240     int iRows = 0;
1241     int iCols = 0;
1242 
1243     if (_piAddress == NULL)
1244     {
1245         return 0;
1246     }
1247 
1248     if (isVarMatrixType(_pvCtx, _piAddress) == 0)
1249     {
1250         return 0;
1251     }
1252 
1253     SciErr sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
1254     if (sciErr.iErr)
1255     {
1256         addErrorMessage(&sciErr, API_ERROR_IS_SQUARE, _("%s: Unable to get argument dimension"), "isSquareMatrix");
1257         printError(&sciErr, 0);
1258         return 0;
1259     }
1260 
1261     if (iRows > 1 && iCols == iRows)
1262     {
1263         return 1;
1264     }
1265 
1266     return 0;
1267 }
1268 
1269 /*--------------------------------------------------------------------------*/
isNamedSquareMatrix(void * _pvCtx,const char * _pstName)1270 int isNamedSquareMatrix(void *_pvCtx, const char *_pstName)
1271 {
1272     int iRows = 0;
1273     int iCols = 0;
1274 
1275     if (isNamedVarMatrixType(_pvCtx, _pstName) == 0)
1276     {
1277         return 0;
1278     }
1279 
1280     SciErr sciErr = getNamedVarDimension(_pvCtx, _pstName, &iRows, &iCols);
1281     if (sciErr.iErr)
1282     {
1283         addErrorMessage(&sciErr, API_ERROR_IS_NAMED_SQUARE, _("%s: Unable to get argument dimension"), "isNamedSquareMatrix");
1284         printError(&sciErr, 0);
1285         return 0;
1286     }
1287 
1288     if (iRows > 1 && iCols == iRows)
1289     {
1290         return 1;
1291     }
1292 
1293     return 0;
1294 }
1295 
1296 /*--------------------------------------------------------------------------*/
checkVarDimension(void * _pvCtx,int * _piAddress,int _iRows,int _iCols)1297 int checkVarDimension(void *_pvCtx, int *_piAddress, int _iRows, int _iCols)
1298 {
1299     int iRows = 0;
1300     int iCols = 0;
1301 
1302     if (_piAddress == NULL)
1303     {
1304         return 0;
1305     }
1306 
1307     if (isVarMatrixType(_pvCtx, _piAddress) == 0)
1308     {
1309         return 0;
1310     }
1311 
1312     SciErr sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
1313     if (sciErr.iErr)
1314     {
1315         addErrorMessage(&sciErr, API_ERROR_CHECK_VAR_DIMENSION, _("%s: Unable to get argument dimension"), "checkVarDimension");
1316         printError(&sciErr, 0);
1317         return 0;
1318     }
1319 
1320     if ((_iRows == iRows || _iRows == -1) && (_iCols == iCols || _iCols == -1))
1321     {
1322         return 1;
1323     }
1324 
1325     return 0;
1326 }
1327 
1328 /*--------------------------------------------------------------------------*/
checkNamedVarDimension(void * _pvCtx,const char * _pstName,int _iRows,int _iCols)1329 int checkNamedVarDimension(void *_pvCtx, const char *_pstName, int _iRows, int _iCols)
1330 {
1331     int iRows = 0;
1332     int iCols = 0;
1333 
1334     if (isNamedVarMatrixType(_pvCtx, _pstName) == 0)
1335     {
1336         return 0;
1337     }
1338 
1339     SciErr sciErr = getNamedVarDimension(_pvCtx, _pstName, &iRows, &iCols);
1340     if (sciErr.iErr)
1341     {
1342         addErrorMessage(&sciErr, API_ERROR_CHECK_NAMED_VAR_DIMENSION, _("%s: Unable to get argument dimension"), "checkNamedVarDimension");
1343         printError(&sciErr, 0);
1344         return 0;
1345     }
1346 
1347     if ((_iRows == iRows || _iRows == -1) && (_iCols == iCols || _iCols == -1))
1348     {
1349         return 1;
1350     }
1351 
1352     return 0;
1353 }
1354 
1355 /*--------------------------------------------------------------------------*/
checkVarType(void * _pvCtx,int * _piAddress,int _iType)1356 int checkVarType(void *_pvCtx, int *_piAddress, int _iType)
1357 {
1358     int iType = 0;
1359 
1360     if (_piAddress == NULL)
1361     {
1362         return 0;
1363     }
1364 
1365     SciErr sciErr = getVarType(_pvCtx, _piAddress, &iType);
1366     if (sciErr.iErr)
1367     {
1368         return 0;
1369     }
1370 
1371     if (iType == _iType)
1372     {
1373         return 1;
1374     }
1375 
1376     return 0;
1377 }
1378 
1379 /*--------------------------------------------------------------------------*/
checkNamedVarType(void * _pvCtx,const char * _pstName,int _iType)1380 int checkNamedVarType(void *_pvCtx, const char *_pstName, int _iType)
1381 {
1382     int iType = 0;
1383 
1384     SciErr sciErr = getNamedVarType(_pvCtx, _pstName, &iType);
1385     if (sciErr.iErr)
1386     {
1387         return 0;
1388     }
1389 
1390     if (iType == _iType)
1391     {
1392         return 1;
1393     }
1394 
1395     return 0;
1396 }
1397 
1398 /*--------------------------------------------------------------------------*/
getInputArgumentType(void * _pvCtx,int _iVar)1399 int getInputArgumentType(void* _pvCtx, int _iVar)
1400 {
1401     int* piAddr = NULL;
1402     int iType = 0;
1403 
1404     SciErr sciErr = getinternalVarAddress(_pvCtx, _iVar, &piAddr);
1405     if (sciErr.iErr)
1406     {
1407         return 0;
1408     }
1409 
1410     sciErr = getVarType(_pvCtx, piAddr, &iType);
1411     if (sciErr.iErr)
1412     {
1413         return 0;
1414     }
1415 
1416     return iType;
1417 }
1418 
1419 /*--------------------------------------------------------------------------*/
checkInputArgumentType(void * _pvCtx,int _iVar,int _iType)1420 int checkInputArgumentType(void* _pvCtx, int _iVar, int _iType)
1421 {
1422     return getInputArgumentType(_pvCtx, _iVar) == _iType;
1423 }
1424 
1425 /*--------------------------------------------------------------------------*/
isEmptyMatrix(void * _pvCtx,int * _piAddress)1426 int isEmptyMatrix(void *_pvCtx, int *_piAddress)
1427 {
1428     if (checkVarType(_pvCtx, _piAddress, sci_matrix))
1429     {
1430         return checkVarDimension(_pvCtx, _piAddress, 0, 0);
1431     }
1432     return 0;
1433 }
1434 
1435 /*--------------------------------------------------------------------------*/
isNamedEmptyMatrix(void * _pvCtx,const char * _pstName)1436 int isNamedEmptyMatrix(void *_pvCtx, const char *_pstName)
1437 {
1438     if (checkNamedVarType(_pvCtx, _pstName, sci_matrix))
1439     {
1440         return checkNamedVarDimension(_pvCtx, _pstName, 0, 0);
1441     }
1442     return 0;
1443 }
1444 
1445 /*--------------------------------------------------------------------------*/
createEmptyMatrix(void * _pvCtx,int _iVar)1446 int createEmptyMatrix(void *_pvCtx, int _iVar)
1447 {
1448     double dblReal = 0;
1449 
1450     SciErr sciErr = createMatrixOfDouble(_pvCtx, _iVar, 0, 0, &dblReal);
1451     if (sciErr.iErr)
1452     {
1453         addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
1454         printError(&sciErr, 0);
1455         return sciErr.iErr;
1456     }
1457 
1458     return 0;
1459 }
1460 
1461 /*--------------------------------------------------------------------------*/
createNamedEmptyMatrix(void * _pvCtx,const char * _pstName)1462 int createNamedEmptyMatrix(void *_pvCtx, const char *_pstName)
1463 {
1464     double dblOne = 0;
1465 
1466     SciErr sciErr = createNamedMatrixOfDouble(_pvCtx, _pstName, 0, 0, &dblOne);
1467     if (sciErr.iErr)
1468     {
1469         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createNamedEmptyMatrix");
1470         printError(&sciErr, 0);
1471         return sciErr.iErr;
1472     }
1473 
1474     return 0;
1475 }
1476 
1477 /*--------------------------------------------------------------------------*/
isNamedVarExist(void * _pvCtx,const char * _pstName)1478 int isNamedVarExist(void *_pvCtx, const char *_pstName)
1479 {
1480     SciErr sciErr = sciErrInit();
1481     int *piAddr = NULL;
1482 
1483     sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
1484     if (sciErr.iErr || piAddr == NULL)
1485     {
1486         sciErrClean(&sciErr);
1487         return 0;
1488     }
1489 
1490     return 1;
1491 }
1492 
1493 /*--------------------------------------------------------------------------*/
checkNamedVarFormat(void * _pvCtx,const char * _pstName)1494 int checkNamedVarFormat(void* _pvCtx, const char *_pstName)
1495 {
1496     // check pointer
1497     if (_pstName == NULL)
1498     {
1499         return 0;
1500     }
1501 
1502     // check length _pstName <> 0
1503     if (symbol::Context::getInstance()->isValidVariableName(_pstName) == false)
1504     {
1505         return 0;
1506     }
1507 
1508     return 1;
1509 }
1510 /*--------------------------------------------------------------------------*/
deleteNamedVariable(void * _pvCtx,const char * _pstName)1511 int deleteNamedVariable(void* _pvCtx, const char* _pstName)
1512 {
1513     SciErr sciErr = sciErrInit();
1514 
1515     if (isNamedVarExist(_pvCtx, _pstName) == 0)
1516     {
1517         return 0;
1518     }
1519 
1520     if (!checkNamedVarFormat(_pvCtx, _pstName))
1521     {
1522         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createNamedComplexZMatrixOfDouble", _pstName);
1523         return 0;
1524     }
1525 
1526     wchar_t* pwstName = to_wide_string(_pstName);
1527     symbol::Context* ctx = symbol::Context::getInstance();
1528     symbol::Symbol sym = symbol::Symbol(pwstName);
1529     FREE(pwstName);
1530     bool ret = false;
1531     if (ctx->isprotected(sym) == false)
1532     {
1533         ret = ctx->remove(sym);
1534     }
1535     else
1536     {
1537         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
1538     }
1539 
1540     return ret ? 1 : 0;
1541 }
1542 /*--------------------------------------------------------------------------*/
increaseValRef(void * _pvCtx,int * _piAddress)1543 int increaseValRef(void* _pvCtx, int* _piAddress)
1544 {
1545     if (_piAddress)
1546     {
1547         types::InternalType* pIT = (types::InternalType*)_piAddress;
1548         types::InternalType* pIT2 = dynamic_cast<types::InternalType*>(pIT);
1549         if (pIT2)
1550         {
1551             pIT->IncreaseRef();
1552             return 1;
1553         }
1554         else
1555         {
1556             Scierror(999, _("Invalid type pointer in '%s'\n"), "increaseValRef");
1557             return -1;
1558         }
1559     }
1560     return 0;
1561 }
1562 /*--------------------------------------------------------------------------*/
decreaseValRef(void * _pvCtx,int * _piAddress)1563 int decreaseValRef(void* _pvCtx, int* _piAddress)
1564 {
1565     if (_piAddress)
1566     {
1567         types::InternalType* pIT = (types::InternalType*)_piAddress;
1568         types::InternalType* pIT2 = dynamic_cast<types::InternalType*>(pIT);
1569         if (pIT2)
1570         {
1571             pIT->DecreaseRef();
1572             if (pIT->isDeletable())
1573             {
1574                 delete pIT;
1575             }
1576             return 1;
1577         }
1578         else
1579         {
1580             Scierror(999, _("Invalid type pointer in '%s'\n"), "decreaseValRef");
1581             return -1;
1582         }
1583     }
1584     return 0;
1585 }
1586 /*--------------------------------------------------------------------------*/
1587 static char eostr = '\0';
sciErrInit()1588 SciErr sciErrInit()
1589 {
1590     int i = 0 ;
1591     SciErr sciErr;
1592     sciErr.iErr = 0;
1593     sciErr.iMsgCount = 0;
1594 
1595     for (; i < MESSAGE_STACK_SIZE ; i++)
1596     {
1597         sciErr.pstMsg[i] = &eostr;
1598     }
1599 
1600     return sciErr;
1601 }
1602 
sciErrClean(SciErr * _psciErr)1603 void sciErrClean(SciErr* _psciErr)
1604 {
1605     //reset error
1606     for (int i = _psciErr->iMsgCount - 1; i >= 0; i--)
1607     {
1608         FREE(_psciErr->pstMsg[i]);
1609     }
1610 
1611     _psciErr->iMsgCount = 0;
1612 }
1613