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