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 <string.h>
20 #include <stdlib.h>
21 
22 #include "gatewaystruct.hxx"
23 #include "double.hxx"
24 #include "context.hxx"
25 
26 extern "C"
27 {
28 #include "doublecomplex.h"
29 #include "api_scilab.h"
30 #include "api_internal_common.h"
31 #include "api_internal_double.h"
32 #include "localization.h"
33 #include "elem_common.h"
34 #include "sci_tools.h"
35     extern int C2F(entier)(int *n, double *d__, int *s);
36     extern int C2F(icopy)(int *, int *, int *, int *, int *);
37 }
38 
39 /*******************************/
40 /*   double matrix functions   */
41 /*******************************/
42 
43 static int getCommonScalarDouble(void* _pvCtx, int* _piAddress, int _iComplex, double* _pdblReal, double* _pdblImg);
44 static int createCommonScalarDouble(void* _pvCtx, int _iVar, int _iComplex, double _dblReal, double _dblImg);
45 static int createCommonNamedScalarDouble(void* _pvCtx, const char* _pstName, int _iComplex, double _dblReal, double _dblImg);
46 static int getCommonNamedScalarDouble(void* _pvCtx, const char* _pstName, int _iComplex, double* _pdblReal, double* _pdblImg);
47 static int createCommonMatrixDoubleFromInteger(void* _pvCtx, int _iVar, int _iComplex, int _iRows, int _iCols, int* _piReal, int* _piImg);
48 static int createCommonScalarDoubleFromInteger(void* _pvCtx, int _iVar, int _iComplex, int _iReal, int _iImg);
49 
getMatrixOfDouble(void * _pvCtx,int * _piAddress,int * _piRows,int * _piCols,double ** _pdblReal)50 SciErr getMatrixOfDouble(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, double** _pdblReal)
51 {
52     return getCommonMatrixOfDouble(_pvCtx, _piAddress, '$', 0, _piRows, _piCols, _pdblReal, NULL);
53 }
54 
getComplexMatrixOfDouble(void * _pvCtx,int * _piAddress,int * _piRows,int * _piCols,double ** _pdblReal,double ** _pdblImg)55 SciErr getComplexMatrixOfDouble(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, double** _pdblReal, double** _pdblImg)
56 {
57     return getCommonMatrixOfDouble(_pvCtx, _piAddress, '$', 1, _piRows, _piCols, _pdblReal, _pdblImg);
58 }
59 
getComplexZMatrixOfDouble(void * _pvCtx,int * _piAddress,int * _piRows,int * _piCols,doublecomplex ** _pdblZ)60 SciErr getComplexZMatrixOfDouble(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, doublecomplex** _pdblZ)
61 {
62     int iSize = 0;
63     double *pdblReal = NULL;
64 
65     SciErr sciErr = getCommonMatrixOfDouble(_pvCtx, _piAddress, 'z', 0, _piRows, _piCols, &pdblReal, NULL);
66     if (sciErr.iErr)
67     {
68         addErrorMessage(&sciErr, API_ERROR_GET_ZDOUBLE, _("%s: Unable to get argument #%d"), "getComplexZMatrixOfDouble", getRhsFromAddress(_pvCtx, _piAddress));
69         return sciErr;
70     }
71 
72     types::Double* pDbl = (types::Double*)_piAddress;
73     pDbl->convertToZComplex();
74     *_pdblZ	= (doublecomplex*)(pDbl->get());
75     return sciErr;
76 }
77 
getMatrixOfDoubleAsInteger(void * _pvCtx,int * _piAddress,int * _piRows,int * _piCols,int ** _piReal)78 SciErr getMatrixOfDoubleAsInteger(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int** _piReal)
79 {
80     double* pdblReal = NULL;
81     int iSize = 0;
82     SciErr sciErr = getCommonMatrixOfDouble(_pvCtx, _piAddress, 'i', 0, _piRows, _piCols, &pdblReal, NULL);
83     if (sciErr.iErr)
84     {
85         return sciErr;
86     }
87 
88     iSize = *_piRows **_piCols;
89     *_piReal = (int*)pdblReal;
90 
91     //Warning we overwrite double by int !!!!
92     C2F(entier)(&iSize, pdblReal, *_piReal);
93 
94     types::Double* pD = (types::Double*)_piAddress;
95     pD->setViewAsInteger();
96 
97     return sciErr;
98 }
99 
getComplexMatrixOfDoubleAsInteger(void * _pvCtx,int * _piAddress,int * _piRows,int * _piCols,int ** _piReal,int ** _piImg)100 SciErr getComplexMatrixOfDoubleAsInteger(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int** _piReal, int** _piImg)
101 {
102     double* pdblReal = NULL;
103     double* pdblImg  = NULL;
104 
105     SciErr sciErr = getCommonMatrixOfDouble(_pvCtx, _piAddress, 'i', 1, _piRows, _piCols, &pdblReal, &pdblImg);
106     if (sciErr.iErr)
107     {
108         return sciErr;
109     }
110 
111     types::Double* pD = (types::Double*)_piAddress;
112     //convert values and view of data to int and int*
113     pD->convertToInteger();
114 
115     *_piReal = (int*)pD->get();
116     *_piImg = (int*)pD->getImg();
117 
118     return sciErr;
119 }
120 
getCommonMatrixOfDouble(void * _pvCtx,int * _piAddress,char _cType,int _iComplex,int * _piRows,int * _piCols,double ** _pdblReal,double ** _pdblImg)121 SciErr getCommonMatrixOfDouble(void* _pvCtx, int* _piAddress, char _cType, int _iComplex, int* _piRows, int* _piCols, double** _pdblReal, double** _pdblImg)
122 {
123     SciErr sciErr = sciErrInit();
124     int iType = 0;
125     if (_piAddress == NULL)
126     {
127         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), _iComplex ? "getComplexMatrixOfDouble" : "getMatrixOfDouble");
128         return sciErr;
129     }
130 
131     sciErr = getVarType(_pvCtx, _piAddress, &iType);
132     if (sciErr.iErr || iType != sci_matrix)
133     {
134         addErrorMessage(&sciErr, API_ERROR_INVALID_TYPE, _("%s: Invalid argument type, %s expected"), _iComplex ? "getComplexMatrixOfDouble" : "getMatrixOfDouble", _("double matrix"));
135         return sciErr;
136     }
137 
138     sciErr = getVarDimension(_pvCtx, _piAddress, _piRows, _piCols);
139     if (sciErr.iErr)
140     {
141         addErrorMessage(&sciErr, API_ERROR_GET_DOUBLE, _("%s: Unable to get argument #%d"), _iComplex ? "getComplexMatrixOfDouble" : "getMatrixOfDouble", getRhsFromAddress(_pvCtx, _piAddress));
142         return sciErr;
143     }
144 
145     if (_pdblReal != NULL)
146     {
147         *_pdblReal = ((types::InternalType*)_piAddress)->getAs<types::Double>()->getReal();
148     }
149 
150     if (_iComplex && _pdblImg != NULL)
151     {
152         *_pdblImg = ((types::InternalType*)_piAddress)->getAs<types::Double>()->getImg();
153     }
154 
155     return sciErr;
156 }
157 
allocMatrixOfDouble(void * _pvCtx,int _iVar,int _iRows,int _iCols,double ** _pdblReal)158 SciErr allocMatrixOfDouble(void* _pvCtx, int _iVar, int _iRows, int _iCols, double** _pdblReal)
159 {
160     double *pdblReal	= NULL;
161 
162     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, '$', 0, _iRows, _iCols, &pdblReal, NULL);
163     if (sciErr.iErr)
164     {
165         addErrorMessage(&sciErr, API_ERROR_ALLOC_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocMatrixOfDouble");
166         return sciErr;
167     }
168 
169     *_pdblReal = pdblReal;
170 
171     return sciErr;
172 }
173 
allocComplexMatrixOfDouble(void * _pvCtx,int _iVar,int _iRows,int _iCols,double ** _pdblReal,double ** _pdblImg)174 SciErr allocComplexMatrixOfDouble(void* _pvCtx, int _iVar, int _iRows, int _iCols, double** _pdblReal, double** _pdblImg)
175 {
176     double *pdblReal	= NULL;
177     double *pdblImg		= NULL;
178 
179     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, '$', 1, _iRows, _iCols, &pdblReal, &pdblImg);
180     if (sciErr.iErr)
181     {
182         addErrorMessage(&sciErr, API_ERROR_ALLOC_COMPLEX_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
183         return sciErr;
184     }
185 
186     *_pdblReal = pdblReal;
187     *_pdblImg  = pdblImg;
188     return sciErr;
189 }
190 
allocMatrixOfDoubleAsInteger(void * _pvCtx,int _iVar,int _iRows,int _iCols,int ** _piReal)191 SciErr allocMatrixOfDoubleAsInteger(void* _pvCtx, int _iVar, int _iRows, int _iCols, int** _piReal)
192 {
193     double *pdblReal	= NULL;
194 
195     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'i', 0, _iRows, _iCols, &pdblReal, NULL);
196     if (sciErr.iErr)
197     {
198         addErrorMessage(&sciErr, API_ERROR_ALLOC_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocMatrixOfDouble");
199         return sciErr;
200     }
201 
202     *_piReal = (int*)pdblReal;
203     return sciErr;
204 }
205 
allocComplexMatrixOfDoubleAsInteger(void * _pvCtx,int _iVar,int _iRows,int _iCols,int ** _piReal,int ** _piImg)206 SciErr allocComplexMatrixOfDoubleAsInteger(void* _pvCtx, int _iVar, int _iRows, int _iCols, int** _piReal, int** _piImg)
207 {
208     double *pdblReal	= NULL;
209     double *pdblImg		= NULL;
210 
211     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'i', 1, _iRows, _iCols, &pdblReal, &pdblImg);
212     if (sciErr.iErr)
213     {
214         addErrorMessage(&sciErr, API_ERROR_ALLOC_COMPLEX_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
215         return sciErr;
216     }
217 
218     *_piReal = (int*)pdblReal;
219     *_piImg  = (int*)pdblImg;
220     return sciErr;
221 }
222 
allocCommonMatrixOfDouble(void * _pvCtx,int _iVar,char _cType,int _iComplex,int _iRows,int _iCols,double ** _pdblReal,double ** _pdblImg)223 SciErr allocCommonMatrixOfDouble(void* _pvCtx, int _iVar, char _cType, int _iComplex, int _iRows, int _iCols, double** _pdblReal, double** _pdblImg)
224 {
225     SciErr sciErr = sciErrInit();
226 
227     if (_pvCtx == NULL)
228     {
229         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), _iComplex ? "allocComplexMatrixOfDouble" : "allocMatrixOfDouble");
230         return sciErr;
231     }
232 
233     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
234     types::InternalType** out = pStr->m_pOut;
235 
236     types::Double* pDbl = NULL;
237     try
238     {
239         if (_cType == 'z')
240         {
241             pDbl = new types::Double(_iRows, _iCols, _iComplex == 1, true);
242         }
243         else
244         {
245             pDbl = new types::Double(_iRows, _iCols, _iComplex == 1);
246             if (_cType == 'i')
247             {
248                 pDbl->setViewAsInteger();
249             }
250         }
251     }
252     catch (const ast::InternalError& ie)
253     {
254         addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: %ls"), _iComplex ? "allocComplexMatrixOfDouble" : "allocMatrixOfDouble", ie.GetErrorMessage().c_str());
255         return sciErr;
256     }
257 
258     if (pDbl == NULL)
259     {
260         addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: No more memory to allocate variable"), _iComplex ? "allocComplexMatrixOfDouble" : "allocMatrixOfDouble");
261         return sciErr;
262     }
263 
264     int rhs = _iVar - *getNbInputArgument(_pvCtx);
265     out[rhs - 1] = pDbl;
266     *_pdblReal = pDbl->getReal();
267     if (*_pdblReal == NULL)
268     {
269         addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: No more memory to allocate variable"), _iComplex ? "allocComplexMatrixOfDouble" : "allocexMatrixOfDouble");
270         delete pDbl;
271         return sciErr;
272     }
273 
274     if (_iComplex && _pdblImg != NULL)
275     {
276         *_pdblImg	= pDbl->getImg();
277         if (*_pdblImg == NULL)
278         {
279             addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: No more memory to allocate variable"), _iComplex ? "allocComplexMatrixOfDouble" : "allocMatrixOfDouble");
280             delete pDbl;
281             return sciErr;
282         }
283     }
284 
285     return sciErr;
286 }
287 
allocComplexZMatrixOfDouble(void * _pvCtx,int _iVar,int _iRows,int _iCols,const doublecomplex ** _pdblData)288 SciErr allocComplexZMatrixOfDouble(void* _pvCtx, int _iVar, int _iRows, int _iCols, const doublecomplex** _pdblData)
289 {
290     SciErr sciErr = sciErrInit();
291     double *pdblReal	= NULL;
292     double *pdblImg		= NULL;
293 
294     sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'z', 1, _iRows, _iCols, &pdblReal, NULL);
295     if (sciErr.iErr)
296     {
297         addErrorMessage(&sciErr, API_ERROR_ALLOC_COMPLEX_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
298         return sciErr;
299     }
300 
301     *_pdblData = (doublecomplex*)pdblReal;
302     return sciErr;
303 }
304 
createMatrixOfDouble(void * _pvCtx,int _iVar,int _iRows,int _iCols,const double * _pdblReal)305 SciErr createMatrixOfDouble(void* _pvCtx, int _iVar, int _iRows, int _iCols, const double* _pdblReal)
306 {
307     double *pdblReal = NULL;
308 
309     int iOne = 1;
310     int iSize = _iRows * _iCols;
311 
312     SciErr sciErr = allocMatrixOfDouble(_pvCtx, _iVar, _iRows, _iCols, &pdblReal);
313     if (sciErr.iErr)
314     {
315         addErrorMessage(&sciErr, API_ERROR_CREATE_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
316         return sciErr;
317     }
318 
319     C2F(dcopy)(&iSize, const_cast<double*>(_pdblReal), &iOne, pdblReal, &iOne);
320     return sciErr;
321 }
322 
createComplexMatrixOfDouble(void * _pvCtx,int _iVar,int _iRows,int _iCols,const double * _pdblReal,const double * _pdblImg)323 SciErr createComplexMatrixOfDouble(void* _pvCtx, int _iVar, int _iRows, int _iCols, const double* _pdblReal, const double* _pdblImg)
324 {
325     double *pdblReal	= NULL;
326     double *pdblImg		= NULL;
327 
328     int iOne = 1;
329     int iSize = _iRows * _iCols;
330 
331     SciErr sciErr = allocComplexMatrixOfDouble(_pvCtx, _iVar, _iRows, _iCols, &pdblReal, &pdblImg);
332     if (sciErr.iErr)
333     {
334         addErrorMessage(&sciErr, API_ERROR_CREATE_COMPLEX_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
335         return sciErr;
336     }
337 
338     C2F(dcopy)(&iSize, const_cast<double*>(_pdblReal), &iOne, pdblReal, &iOne);
339     C2F(dcopy)(&iSize, const_cast<double*>(_pdblImg), &iOne, pdblImg, &iOne);
340     return sciErr;
341 }
342 
createMatrixOfDoubleAsInteger(void * _pvCtx,int _iVar,int _iRows,int _iCols,const int * _piReal)343 SciErr createMatrixOfDoubleAsInteger(void* _pvCtx, int _iVar, int _iRows, int _iCols, const int* _piReal)
344 {
345     double *pdblReal	= NULL;
346 
347     int iOne = 1;
348     int iSize = _iRows * _iCols;
349 
350     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'i', 0, _iRows, _iCols, &pdblReal, NULL);
351     if (sciErr.iErr)
352     {
353         addErrorMessage(&sciErr, API_ERROR_CREATE_COMPLEX_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
354         return sciErr;
355     }
356 
357     C2F(icopy)(&iSize, (int*)_piReal, &iOne, (int*)pdblReal, &iOne);
358     return sciErr;
359 }
360 
createComplexMatrixOfDoubleAsInteger(void * _pvCtx,int _iVar,int _iRows,int _iCols,const int * _piReal,const int * _piImg)361 SciErr createComplexMatrixOfDoubleAsInteger(void* _pvCtx, int _iVar, int _iRows, int _iCols, const int* _piReal, const int* _piImg)
362 {
363     double *pdblReal	= NULL;
364     double *pdblImg		= NULL;
365 
366     int iOne = 1;
367     int iSize = _iRows * _iCols;
368 
369     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'i', 1, _iRows, _iCols, &pdblReal, &pdblImg);
370     if (sciErr.iErr)
371     {
372         addErrorMessage(&sciErr, API_ERROR_CREATE_COMPLEX_DOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
373         return sciErr;
374     }
375 
376     C2F(icopy)(&iSize, (int*)_piReal, &iOne, (int*)pdblReal, &iOne);
377     C2F(icopy)(&iSize, (int*)_piImg, &iOne, (int*)pdblImg, &iOne);
378     return sciErr;
379 }
380 
createComplexZMatrixOfDouble(void * _pvCtx,int _iVar,int _iRows,int _iCols,const doublecomplex * _pdblData)381 SciErr createComplexZMatrixOfDouble(void* _pvCtx, int _iVar, int _iRows, int _iCols, const doublecomplex* _pdblData)
382 {
383     SciErr sciErr = sciErrInit();
384     const doublecomplex *pdblZ = NULL;
385 
386     sciErr = allocComplexZMatrixOfDouble(_pvCtx, _iVar, _iRows, _iCols, &pdblZ);
387     if (sciErr.iErr)
388     {
389         addErrorMessage(&sciErr, API_ERROR_CREATE_ZDOUBLE, _("%s: Unable to create variable in Scilab memory"), "allocComplexMatrixOfDouble");
390         return sciErr;
391     }
392 
393     memcpy((void*)pdblZ, _pdblData, _iRows * _iCols * sizeof(doublecomplex));
394     return sciErr;
395 }
396 
createNamedMatrixOfDouble(void * _pvCtx,const char * _pstName,int _iRows,int _iCols,const double * _pdblReal)397 SciErr createNamedMatrixOfDouble(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, const double* _pdblReal)
398 {
399     return createCommonNamedMatrixOfDouble(_pvCtx, _pstName, 0, _iRows, _iCols, _pdblReal, NULL);
400 }
401 
createNamedComplexMatrixOfDouble(void * _pvCtx,const char * _pstName,int _iRows,int _iCols,const double * _pdblReal,const double * _pdblImg)402 SciErr createNamedComplexMatrixOfDouble(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, const double* _pdblReal, const double* _pdblImg)
403 {
404     return createCommonNamedMatrixOfDouble(_pvCtx, _pstName, 1, _iRows, _iCols, _pdblReal, _pdblImg);
405 }
406 
createNamedComplexZMatrixOfDouble(void * _pvCtx,const char * _pstName,int _iRows,int _iCols,const doublecomplex * _pdblData)407 SciErr createNamedComplexZMatrixOfDouble(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, const doublecomplex* _pdblData)
408 {
409     SciErr sciErr = sciErrInit();
410 
411     int iOne					= 1;
412     int iTwo					= 2;
413     int iSize					= _iRows * _iCols;
414 
415     if (!checkNamedVarFormat(_pvCtx, _pstName))
416     {
417         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createNamedComplexZMatrixOfDouble", _pstName);
418         return sciErr;
419     }
420 
421     types::Double* pDbl = new types::Double(_iRows, _iCols, true);
422 
423     double* pdblReal = pDbl->get();
424     double* pdblImg = pDbl->getImg();
425     C2F(dcopy)(&iSize, const_cast<double*>(&_pdblData->r), &iTwo, pdblReal, &iOne);
426     C2F(dcopy)(&iSize, const_cast<double*>(&_pdblData->i), &iOne, pdblImg, &iOne);
427 
428     wchar_t* pwstName = to_wide_string(_pstName);
429     symbol::Context* ctx = symbol::Context::getInstance();
430     symbol::Symbol sym = symbol::Symbol(pwstName);
431     FREE(pwstName);
432     if (ctx->isprotected(sym) == false)
433     {
434         ctx->put(sym, pDbl);
435     }
436     else
437     {
438         delete pDbl;
439         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
440     }
441 
442     return sciErr;
443 }
444 
createCommonNamedMatrixOfDouble(void * _pvCtx,const char * _pstName,int _iComplex,int _iRows,int _iCols,const double * _pdblReal,const double * _pdblImg)445 SciErr createCommonNamedMatrixOfDouble(void* _pvCtx, const char* _pstName, int _iComplex, int _iRows, int _iCols, const double* _pdblReal, const double* _pdblImg)
446 {
447     SciErr sciErr = sciErrInit();
448     if (!checkNamedVarFormat(_pvCtx, _pstName))
449     {
450         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createCommonNamedMatrixOfDouble", _pstName);
451         return sciErr;
452     }
453 
454     wchar_t* pwstName           = to_wide_string(_pstName);
455     int iOne					= 1;
456     int iSize					= _iRows * _iCols;
457 
458     types::Double* pDbl = new types::Double(_iRows, _iCols, _iComplex == 1);
459 
460     double* pdblReal = pDbl->get();
461     C2F(dcopy)(&iSize, const_cast<double*>(_pdblReal), &iOne, pdblReal, &iOne);
462 
463     if (_iComplex)
464     {
465         double* pdblImg = pDbl->getImg();
466         C2F(dcopy)(&iSize, const_cast<double*>(_pdblImg), &iOne, pdblImg, &iOne);
467     }
468 
469     symbol::Context* ctx = symbol::Context::getInstance();
470     symbol::Symbol sym = symbol::Symbol(pwstName);
471     FREE(pwstName);
472     if (ctx->isprotected(sym) == false)
473     {
474         ctx->put(sym, pDbl);
475     }
476     else
477     {
478         delete pDbl;
479         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
480     }
481     return sciErr;
482 }
483 
readNamedMatrixOfDouble(void * _pvCtx,const char * _pstName,int * _piRows,int * _piCols,double * _pdblReal)484 SciErr readNamedMatrixOfDouble(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, double* _pdblReal)
485 {
486     return readCommonNamedMatrixOfDouble(_pvCtx, _pstName, 0, _piRows, _piCols, _pdblReal, NULL);
487 }
488 
readNamedComplexMatrixOfDouble(void * _pvCtx,const char * _pstName,int * _piRows,int * _piCols,double * _pdblReal,double * _pdblImg)489 SciErr readNamedComplexMatrixOfDouble(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, double* _pdblReal, double* _pdblImg)
490 {
491     return readCommonNamedMatrixOfDouble(_pvCtx, _pstName, 1, _piRows, _piCols, _pdblReal, _pdblImg);
492 }
493 
readCommonNamedMatrixOfDouble(void * _pvCtx,const char * _pstName,int _iComplex,int * _piRows,int * _piCols,double * _pdblReal,double * _pdblImg)494 SciErr readCommonNamedMatrixOfDouble(void* _pvCtx, const char* _pstName, int _iComplex, int* _piRows, int* _piCols, double* _pdblReal, double* _pdblImg)
495 {
496     int* piAddr = NULL;
497     double* pdblReal = NULL;
498     double* pdblImg = NULL;
499     int iSize = 0;
500     int iOne = 1;
501 
502     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
503     if (sciErr.iErr)
504     {
505         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_DOUBLE, _("%s: Unable to get variable \"%s\""), _iComplex ? "readNamedComplexMatrixOfDouble" : "readNamedMatrixOfDouble", _pstName);
506         return sciErr;
507     }
508 
509     sciErr = getCommonMatrixOfDouble(_pvCtx, piAddr, '$', _iComplex, _piRows, _piCols, &pdblReal, &pdblImg);
510     if (sciErr.iErr)
511     {
512         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_DOUBLE, _("%s: Unable to get variable \"%s\""), _iComplex ? "readNamedComplexMatrixOfDouble" : "readNamedMatrixOfDouble", _pstName);
513         return sciErr;
514     }
515 
516     if (_pdblReal == NULL || (_iComplex && _pdblImg == NULL))
517     {
518         return sciErr;
519     }
520 
521     iSize = (*_piRows) * (*_piCols);
522     /* dcopy source to dest */
523     C2F(dcopy)(&iSize, pdblReal, &iOne, _pdblReal, &iOne);
524     if (_iComplex)
525     {
526         C2F(dcopy)(&iSize, pdblImg, &iOne, _pdblImg, &iOne);
527     }
528 
529     return sciErr;
530 }
531 
532 /*shortcut functions*/
533 
isDoubleType(void * _pvCtx,int * _piAddress)534 int isDoubleType(void* _pvCtx, int* _piAddress)
535 {
536     return checkVarType(_pvCtx, _piAddress, sci_matrix);
537 }
538 /*--------------------------------------------------------------------------*/
isNamedDoubleType(void * _pvCtx,const char * _pstName)539 int isNamedDoubleType(void* _pvCtx, const char* _pstName)
540 {
541     return checkNamedVarType(_pvCtx, _pstName, sci_matrix);
542 }
543 /*--------------------------------------------------------------------------*/
getScalarDouble(void * _pvCtx,int * _piAddress,double * _pdblReal)544 int getScalarDouble(void* _pvCtx, int* _piAddress, double* _pdblReal)
545 {
546     return getCommonScalarDouble(_pvCtx, _piAddress, 0, _pdblReal, NULL);
547 }
548 /*--------------------------------------------------------------------------*/
getScalarComplexDouble(void * _pvCtx,int * _piAddress,double * _pdblReal,double * _pdblImg)549 int getScalarComplexDouble(void* _pvCtx, int* _piAddress, double* _pdblReal, double* _pdblImg)
550 {
551     return getCommonScalarDouble(_pvCtx, _piAddress, 1, _pdblReal, _pdblImg);
552 }
553 /*--------------------------------------------------------------------------*/
getCommonScalarDouble(void * _pvCtx,int * _piAddress,int _iComplex,double * _pdblReal,double * _pdblImg)554 static int getCommonScalarDouble(void* _pvCtx, int* _piAddress, int _iComplex, double* _pdblReal, double* _pdblImg)
555 {
556     int iRows = 0;
557     int iCols = 0;
558 
559     double* pdblReal = NULL;
560     double* pdblImg = NULL;
561 
562     SciErr sciErr = getCommonMatrixOfDouble(_pvCtx, _piAddress, '$', _iComplex, &iRows, &iCols, &pdblReal, &pdblImg);
563     if (sciErr.iErr)
564     {
565         addErrorMessage(&sciErr, API_ERROR_GET_SCALAR_DOUBLE, _("%s: Unable to get argument #%d"), _iComplex ? "getScalarComplexDouble" : "getScalarDouble", getRhsFromAddress(_pvCtx, _piAddress));
566         printError(&sciErr, 0);
567         return sciErr.iErr;
568     }
569 
570     if (isScalar(_pvCtx, _piAddress) == 0)
571     {
572         addErrorMessage(&sciErr, API_ERROR_GET_SCALAR_DOUBLE, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), _iComplex ? "getScalarComplexDouble" : "getScalarDouble", getRhsFromAddress(_pvCtx, _piAddress));
573         printError(&sciErr, 0);
574         return sciErr.iErr;
575     }
576 
577     if (_pdblReal != NULL)
578     {
579         *_pdblReal	= pdblReal[0];
580     }
581 
582     if (_iComplex == 1 && _pdblImg != NULL && pdblImg != NULL)
583     {
584         *_pdblImg		= pdblImg[0];
585     }
586     else if (_pdblImg != NULL)
587     {
588         *_pdblImg = 0;
589     }
590 
591     return 0;
592 }
593 /*--------------------------------------------------------------------------*/
getNamedScalarDouble(void * _pvCtx,const char * _pstName,double * _pdblReal)594 int getNamedScalarDouble(void* _pvCtx, const char* _pstName, double* _pdblReal)
595 {
596     return getCommonNamedScalarDouble(_pvCtx, _pstName, 0, _pdblReal, 0);
597 }
598 /*--------------------------------------------------------------------------*/
getNamedScalarComplexDouble(void * _pvCtx,const char * _pstName,double * _pdblReal,double * _pdblImg)599 int getNamedScalarComplexDouble(void* _pvCtx, const char* _pstName, double* _pdblReal, double* _pdblImg)
600 {
601     return getCommonNamedScalarDouble(_pvCtx, _pstName, 1, _pdblReal, _pdblImg);
602 }
603 /*--------------------------------------------------------------------------*/
getCommonNamedScalarDouble(void * _pvCtx,const char * _pstName,int _iComplex,double * _pdblReal,double * _pdblImg)604 static int getCommonNamedScalarDouble(void* _pvCtx, const char* _pstName, int _iComplex, double* _pdblReal, double* _pdblImg)
605 {
606     SciErr sciErr = sciErrInit();
607     int iRows	= 0;
608     int iCols	= 0;
609 
610     double dblReal = 0;
611     double dblImg	 = 0;
612 
613     if (isNamedScalar(_pvCtx, _pstName) == 0)
614     {
615         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_SCALAR_DOUBLE, _("%s: Wrong type for input argument \"%s\": A scalar expected.\n"), _iComplex ? "getNamedScalarComplexDouble" : "getNamedScalarDouble", _pstName);
616         printError(&sciErr, 0);
617         return sciErr.iErr;
618     }
619 
620     sciErr = readCommonNamedMatrixOfDouble(_pvCtx, _pstName, _iComplex, &iRows, &iCols, &dblReal, &dblImg);
621     if (sciErr.iErr)
622     {
623         addErrorMessage(&sciErr, API_ERROR_GET_NAMED_SCALAR_DOUBLE, _("%s: Unable to get argument \"%s\""), _iComplex ? "getNamedScalarComplexDouble" : "getNamedScalarDouble", _pstName);
624         printError(&sciErr, 0);
625         return sciErr.iErr;
626     }
627 
628     if (_pdblReal != NULL)
629     {
630         _pdblReal[0]	= dblReal;
631     }
632 
633     if (_pdblImg != NULL)
634     {
635         _pdblImg[0]		= dblImg;
636     }
637 
638     return 0;
639 }
640 /*--------------------------------------------------------------------------*/
createScalarDouble(void * _pvCtx,int _iVar,double _dblReal)641 int createScalarDouble(void* _pvCtx, int _iVar, double _dblReal)
642 {
643     return createCommonScalarDouble(_pvCtx, _iVar, 0, _dblReal, 0);
644 }
645 /*--------------------------------------------------------------------------*/
createScalarComplexDouble(void * _pvCtx,int _iVar,double _dblReal,double _dblImg)646 int createScalarComplexDouble(void* _pvCtx, int _iVar, double _dblReal, double _dblImg)
647 {
648     return createCommonScalarDouble(_pvCtx, _iVar, 1, _dblReal, _dblImg);
649 }
650 /*--------------------------------------------------------------------------*/
createCommonScalarDouble(void * _pvCtx,int _iVar,int _iComplex,double _dblReal,double _dblImg)651 static int createCommonScalarDouble(void* _pvCtx, int _iVar, int _iComplex, double _dblReal, double _dblImg)
652 {
653     double *pdblReal	= NULL;
654     double *pdblImg		= NULL;
655 
656     SciErr sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, '$', _iComplex, 1, 1, &pdblReal, &pdblImg);
657     if (sciErr.iErr)
658     {
659         addErrorMessage(&sciErr, API_ERROR_CREATE_SCALAR_DOUBLE, _("%s: Unable to create variable in Scilab memory"), _iComplex ? "createScalarComplexDouble" : "createScalarDouble");
660         printError(&sciErr, 0);
661         return sciErr.iErr;
662     }
663 
664     pdblReal[0] = _dblReal;
665     if (_iComplex)
666     {
667         pdblImg[0]	= _dblImg;
668     }
669     return 0;
670 }
671 /*--------------------------------------------------------------------------*/
createNamedScalarDouble(void * _pvCtx,const char * _pstName,double _dblReal)672 int createNamedScalarDouble(void* _pvCtx, const char* _pstName, double _dblReal)
673 {
674     return createCommonNamedScalarDouble(_pvCtx, _pstName, 0, _dblReal, 0);
675 }
676 /*--------------------------------------------------------------------------*/
createNamedScalarComplexDouble(void * _pvCtx,const char * _pstName,double _dblReal,double _dblImg)677 int createNamedScalarComplexDouble(void* _pvCtx, const char* _pstName, double _dblReal, double _dblImg)
678 {
679     return createCommonNamedScalarDouble(_pvCtx, _pstName, 1, _dblReal, _dblImg);
680 }
681 /*--------------------------------------------------------------------------*/
createCommonNamedScalarDouble(void * _pvCtx,const char * _pstName,int _iComplex,double _dblReal,double _dblImg)682 static int createCommonNamedScalarDouble(void* _pvCtx, const char* _pstName, int _iComplex, double _dblReal, double _dblImg)
683 {
684     SciErr sciErr = createCommonNamedMatrixOfDouble(_pvCtx, _pstName, _iComplex, 1, 1, &_dblReal, &_dblImg);
685     if (sciErr.iErr)
686     {
687         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_SCALAR, _("%s: Unable to create variable in Scilab memory"), _iComplex ? "createNamedScalarComplexDouble" : "createNamedScalarDouble");
688         printError(&sciErr, 0);
689         return sciErr.iErr;
690     }
691 
692     return 0;
693 }
694 /*--------------------------------------------------------------------------*/
createScalarDoubleFromInteger(void * _pvCtx,int _iVar,int _iReal)695 int createScalarDoubleFromInteger(void* _pvCtx, int _iVar, int _iReal)
696 {
697     return createCommonScalarDoubleFromInteger(_pvCtx, _iVar, 0, _iReal, 0);
698 }
699 /*--------------------------------------------------------------------------*/
createScalarComplexDoubleFromInteger(void * _pvCtx,int _iVar,int _iReal,int _iImg)700 int createScalarComplexDoubleFromInteger(void* _pvCtx, int _iVar, int _iReal, int _iImg)
701 {
702     return createCommonScalarDoubleFromInteger(_pvCtx, _iVar, 1, _iReal, _iImg);
703 }
704 /*--------------------------------------------------------------------------*/
createCommonScalarDoubleFromInteger(void * _pvCtx,int _iVar,int _iComplex,int _iReal,int _iImg)705 static int createCommonScalarDoubleFromInteger(void* _pvCtx, int _iVar, int _iComplex, int _iReal, int _iImg)
706 {
707     SciErr sciErr;
708     double* pdblReal = NULL;
709     double* pdblImg     = NULL;
710 
711 
712     sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'i', _iComplex, 1, 1, &pdblReal, &pdblImg);
713     if (sciErr.iErr)
714     {
715         addErrorMessage(&sciErr, API_ERROR_CREATE_SCALAR_FROM_INTEGER, _("%s: Unable to create variable in Scilab memory"), _iComplex ? "createScalarComplexDoubleFromInteger" : "createScalarDoubleFromInteger");
716         printError(&sciErr, 0);
717         return sciErr.iErr;
718     }
719 
720     pdblReal[0] = (double)_iReal;
721 
722     if (_iComplex)
723     {
724         pdblImg[0] = (double)_iImg;
725     }
726     return 0;
727 }
728 /*--------------------------------------------------------------------------*/
createMatrixOfDoubleFromInteger(void * _pvCtx,int _iVar,int _iRows,int _iCols,int * _piReal)729 int createMatrixOfDoubleFromInteger(void* _pvCtx, int _iVar, int _iRows, int _iCols, int* _piReal)
730 {
731     return createCommonMatrixDoubleFromInteger(_pvCtx, _iVar, 0, _iRows, _iCols, _piReal, NULL);
732 }
733 /*--------------------------------------------------------------------------*/
createMatrixOfComplexDoubleFromInteger(void * _pvCtx,int _iVar,int _iRows,int _iCols,int * _piReal,int * _piImg)734 int createMatrixOfComplexDoubleFromInteger(void* _pvCtx, int _iVar, int _iRows, int _iCols, int* _piReal, int* _piImg)
735 {
736     return createCommonMatrixDoubleFromInteger(_pvCtx, _iVar, 1, _iRows, _iCols, _piReal, _piImg);
737 }
738 /*--------------------------------------------------------------------------*/
createCommonMatrixDoubleFromInteger(void * _pvCtx,int _iVar,int _iComplex,int _iRows,int _iCols,int * _piReal,int * _piImg)739 static int createCommonMatrixDoubleFromInteger(void* _pvCtx, int _iVar, int _iComplex, int _iRows, int _iCols, int* _piReal, int* _piImg)
740 {
741     SciErr sciErr;
742     double* pdblReal = NULL;
743     double* pdblImg     = NULL;
744 
745 
746     sciErr = allocCommonMatrixOfDouble(_pvCtx, _iVar, 'i', _iComplex, _iRows, _iCols, &pdblReal, &pdblImg);
747     if (sciErr.iErr)
748     {
749         addErrorMessage(&sciErr, API_ERROR_CREATE_MATRIX_FROM_INTEGER, _("%s: Unable to create variable in Scilab memory"), _iComplex ? "createMatrixOfComplexDoubleFromInteger" : "createMatrixOfDoubleFromInteger");
750         printError(&sciErr, 0);
751         return sciErr.iErr;
752     }
753 
754     memcpy(pdblReal, _piReal, _iRows * _iCols * sizeof(int));
755 
756     if (_iComplex)
757     {
758         memcpy(pdblImg, _piImg, _iRows * _iCols * sizeof(int));
759     }
760     return 0;
761 }
762 /*--------------------------------------------------------------------------*/
763