* Bug 16208 fixed: 3D string matrix may crash old C-api gateways
[scilab.git] / scilab / modules / api_scilab / src / cpp / api_stack_string.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
4  * Copyright (C) 2009-2011 - DIGITEO - Allan CORNET
5  * Copyright (C) 2015 - Scilab Enterprises - Anais AUBERT
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  * Please note that piece of code will be rewrited for the Scilab 6 family
17  * However, the API (profile of the functions in the header files) will be
18  * still available and supported in Scilab 6.
19  */
20
21 /*--------------------------------------------------------------------------*/
22 #include "gatewaystruct.hxx"
23 #include "string.hxx"
24 #include "double.hxx"
25 #include "context.hxx"
26
27 extern "C"
28 {
29 #include <string.h>
30 #include <stdlib.h>
31 #include "machine.h"
32 #include "charEncoding.h"
33 #include "sci_malloc.h"
34 #include "api_scilab.h"
35 #include "api_internal_common.h"
36 #include "call_scilab.h"
37 #include "localization.h"
38 #include "sci_malloc.h"
39 #include "freeArrayOfString.h"
40 #include "os_string.h"
41 }
42
43 /*--------------------------------------------------------------------------*/
44
45 /*******************************/
46 /*   string matrix functions   */
47 /*******************************/
48
49 SciErr getMatrixOfString(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piLength, char** _pstStrings)
50 {
51     SciErr sciErr = sciErrInit();
52     int *piOffset = NULL;
53     int *piData = NULL;
54     int iType = 0;
55
56     if (_piAddress == NULL)
57     {
58         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "getMatrixOfString");
59         return sciErr;
60     }
61
62     sciErr = getVarType(_pvCtx, _piAddress, &iType);
63     if (sciErr.iErr)
64     {
65         addErrorMessage(&sciErr, API_ERROR_GET_STRING, _("%s: Unable to get argument #%d"), "getMatrixOfString", getRhsFromAddress(_pvCtx, _piAddress));
66         return sciErr;
67     }
68
69     if (iType != sci_strings)
70     {
71         addErrorMessage(&sciErr, API_ERROR_INVALID_TYPE, _("%s: Invalid argument type, %s expected"), "getMatrixOfString", _("string matrix"));
72         return sciErr;
73     }
74
75     sciErr = getVarDimension(_pvCtx, _piAddress, _piRows, _piCols);
76     if (sciErr.iErr)
77     {
78         addErrorMessage(&sciErr, API_ERROR_GET_STRING, _("%s: Unable to get argument #%d"), "getMatrixOfString", getRhsFromAddress(_pvCtx, _piAddress));
79         return sciErr;
80     }
81
82     if (_piLength == NULL)
83     {
84         return sciErr;
85     }
86
87     types::String *pS = ((types::InternalType*)_piAddress)->getAs<types::String>();
88
89     //non cummulative length
90     int iSize = (*_piRows)*(*_piCols);
91     if (_pstStrings == NULL || *_pstStrings == NULL)
92     {
93         for (int i = 0 ; i < iSize; i++)
94         {
95             char* pstTemp = wide_string_to_UTF8(pS->get(i));
96             _piLength[i] = (int)strlen(pstTemp);
97             FREE(pstTemp);
98         }
99     }
100     else
101     {
102         for (int i = 0 ; i < iSize; i++)
103         {
104             if (_pstStrings[i] == NULL)
105             {
106                 addErrorMessage(&sciErr, API_ERROR_INVALID_SUBSTRING_POINTER, _("%s: Invalid argument address"), "getMatrixOfString");
107                 return sciErr;
108             }
109
110             char* c = wide_string_to_UTF8(pS->get(i));
111             strcpy(_pstStrings[i], c);
112             FREE(c);
113         }
114     }
115
116     return sciErr;
117 }
118 /*--------------------------------------------------------------------------*/
119 SciErr createMatrixOfString(void* _pvCtx, int _iVar, int _iRows, int _iCols, const char* const * _pstStrings)
120 {
121     SciErr sciErr = sciErrInit();
122
123     int rhs = _iVar - *getNbInputArgument(_pvCtx);
124     types::GatewayStruct* pStr = (types::GatewayStruct*)_pvCtx;
125     types::InternalType** out = pStr->m_pOut;
126
127     //return empty matrix
128     if (_iRows == 0 && _iCols == 0)
129     {
130         types::Double *pDbl = new types::Double(_iRows, _iCols);
131         if (pDbl == NULL)
132         {
133             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
134             return sciErr;
135         }
136
137         out[rhs - 1] = pDbl;
138         return sciErr;
139     }
140
141     types::String* pS = new types::String(_iRows, _iCols);
142     if (pS == NULL)
143     {
144         addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: No more memory to allocated variable"), "createMatrixOfString");
145         return sciErr;
146     }
147
148     for (int i = 0 ; i < pS->getSize() ; i++)
149     {
150         wchar_t* pstTemp = to_wide_string(_pstStrings[i]);
151         pS->set(i, pstTemp);
152         FREE(pstTemp);
153     }
154
155     out[rhs - 1] = pS;
156
157     return sciErr;
158 }
159 /*--------------------------------------------------------------------------*/
160 SciErr createNamedMatrixOfString(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, const char* const* _pstStrings)
161 {
162     SciErr sciErr = sciErrInit();
163
164     // check variable name
165     if (checkNamedVarFormat(_pvCtx, _pstName) == 0)
166     {
167         addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Invalid variable name: %s."), "createNamedMatrixOfString", _pstName);
168         return sciErr;
169     }
170
171     //return empty matrix
172     if (_iRows == 0 && _iCols == 0)
173     {
174         if (createNamedEmptyMatrix(_pvCtx, _pstName))
175         {
176             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
177             return sciErr;
178         }
179
180         return sciErr;
181     }
182
183     types::String* pS = new types::String(_iRows, _iCols);
184     if (pS == NULL)
185     {
186         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createNamedMatrixOfString", _pstName);
187         return sciErr;
188     }
189
190     for (int i = 0 ; i < pS->getSize() ; i++)
191     {
192         wchar_t* pstTemp = to_wide_string(_pstStrings[i]);
193         pS->set(i, pstTemp);
194         FREE(pstTemp);
195     }
196
197     wchar_t* pwstName = to_wide_string(_pstName);
198     symbol::Context* ctx = symbol::Context::getInstance();
199     symbol::Symbol sym = symbol::Symbol(pwstName);
200     FREE(pwstName);
201     if (ctx->isprotected(sym) == false)
202     {
203         ctx->put(sym, pS);
204     }
205     else
206     {
207         delete pS;
208         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
209     }
210     return sciErr;
211 }
212 /*--------------------------------------------------------------------------*/
213 SciErr readNamedMatrixOfString(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piLength, char** _pstStrings)
214 {
215     int* piAddr = NULL;
216
217     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
218     if (sciErr.iErr)
219     {
220         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_STRING, _("%s: Unable to get variable \"%s\""), "readNamedMatrixOfString", _pstName);
221         return sciErr;
222     }
223
224     sciErr = getMatrixOfString(_pvCtx, piAddr, _piRows, _piCols, _piLength, _pstStrings);
225     if (sciErr.iErr)
226     {
227         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_STRING, _("%s: Unable to get variable \"%s\""), "readNamedMatrixOfString", _pstName);
228         return sciErr;
229     }
230
231     return sciErr;
232 }
233 /*--------------------------------------------------------------------------*/
234 SciErr getMatrixOfWideString(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, int* _piwLength, wchar_t** _pwstStrings)
235 {
236     SciErr sciErr = sciErrInit();
237     int iType = 0;
238     char **pstStrings = NULL;
239     int *piLenStrings = NULL;
240     int strSize = 0;
241
242     if (_piAddress == NULL)
243     {
244         addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "getMatrixOfWideString");
245         return sciErr;
246     }
247
248     sciErr = getVarType(_pvCtx, _piAddress, &iType);
249     if (sciErr.iErr)
250     {
251         addErrorMessage(&sciErr, API_ERROR_GET_WIDE_STRING, _("%s: Unable to get argument #%d"), "getMatrixOfWideString", getRhsFromAddress(_pvCtx, _piAddress));
252         return sciErr;
253     }
254
255     if (iType != sci_strings)
256     {
257         addErrorMessage(&sciErr, API_ERROR_INVALID_TYPE, _("%s: Invalid argument type, %s expected"), "getMatrixOfWideString", _("string matrix"));
258         return sciErr;
259     }
260
261     sciErr = getVarDimension(_pvCtx, _piAddress, _piRows, _piCols);
262     if (sciErr.iErr)
263     {
264         addErrorMessage(&sciErr, API_ERROR_GET_WIDE_STRING, _("%s: Unable to get argument #%d"), "getMatrixOfWideString", getRhsFromAddress(_pvCtx, _piAddress));
265         return sciErr;
266     }
267
268     if (_piwLength == NULL)
269     {
270         return sciErr;
271     }
272
273     types::String *pS = ((types::InternalType*)_piAddress)->getAs<types::String>();
274
275     int iSize = pS->getSize();
276     if (_pwstStrings == NULL || *_pwstStrings == NULL)
277     {
278         for (int i = 0 ; i < iSize; i++)
279         {
280             _piwLength[i] = (int)wcslen(pS->get(i));
281         }
282     }
283     else
284     {
285         for (int i = 0 ; i < pS->getSize() ; i++)
286         {
287             if (_pwstStrings[i] == NULL)
288             {
289                 addErrorMessage(&sciErr, API_ERROR_INVALID_SUBSTRING_POINTER, _("%s: Invalid argument address"), "getMatrixOfString");
290                 return sciErr;
291             }
292
293             wcscpy(_pwstStrings[i], pS->get(i));
294         }
295     }
296
297     return sciErr;
298 }
299 /*--------------------------------------------------------------------------*/
300 SciErr createMatrixOfWideString(void* _pvCtx, int _iVar, int _iRows, int _iCols, const wchar_t* const* _pstwStrings)
301 {
302     char **pStrings = NULL;
303
304     //return empty matrix
305     if (_iRows == 0 && _iCols == 0)
306     {
307         double dblReal = 0;
308         SciErr sciErr = createMatrixOfDouble(_pvCtx, _iVar, 0, 0, &dblReal);
309         if (sciErr.iErr)
310         {
311             addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createEmptyMatrix");
312         }
313         return sciErr;
314     }
315
316     pStrings = (char**)MALLOC( sizeof(char*) * (_iRows * _iCols) );
317
318     for (int i = 0; i < (_iRows * _iCols) ; i++)
319     {
320         pStrings[i] = wide_string_to_UTF8(_pstwStrings[i]);
321     }
322
323     SciErr sciErr = createMatrixOfString(_pvCtx, _iVar, _iRows, _iCols, pStrings);
324     if (sciErr.iErr)
325     {
326         addErrorMessage(&sciErr, API_ERROR_CREATE_WIDE_STRING, _("%s: Unable to create variable in Scilab memory"), "createMatrixOfWideString");
327     }
328
329     freeArrayOfString(pStrings, _iRows * _iCols);
330
331     return sciErr;
332 }
333 /*--------------------------------------------------------------------------*/
334 SciErr createNamedMatrixOfWideString(void* _pvCtx, const char* _pstName, int _iRows, int _iCols, const wchar_t* const* _pwstStrings)
335 {
336     SciErr sciErr = sciErrInit();
337     char **pStrings = NULL;
338
339     // check variable name
340     if (checkNamedVarFormat(_pvCtx, _pstName) == 0)
341     {
342         addErrorMessage(&sciErr, API_ERROR_CREATE_EMPTY_MATRIX, _("%s: Invalid variable name: %s."), "createNamedMatrixOfWideString", _pstName);
343         return sciErr;
344     }
345
346     //return named empty matrix
347     if (_iRows == 0 && _iCols == 0)
348     {
349         double dblReal = 0;
350         sciErr = createNamedMatrixOfDouble(_pvCtx, _pstName, 0, 0, &dblReal);
351         if (sciErr.iErr)
352         {
353             addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_EMPTY_MATRIX, _("%s: Unable to create variable in Scilab memory"), "createNamedEmptyMatrix");
354         }
355         return sciErr;
356     }
357
358     types::String* pS = new types::String(_iRows, _iCols);
359     if (pS == NULL)
360     {
361         addErrorMessage(&sciErr, API_ERROR_INVALID_NAME, _("%s: Invalid variable name: %s."), "createNamedMatrixOfWideString", _pstName);
362         return sciErr;
363     }
364
365     for (int i = 0 ; i < pS->getSize() ; i++)
366     {
367         pS->set(i, _pwstStrings[i]);
368     }
369
370     wchar_t* pwstName = to_wide_string(_pstName);
371     symbol::Context* ctx = symbol::Context::getInstance();
372     symbol::Symbol sym = symbol::Symbol(pwstName);
373     FREE(pwstName);
374     if (ctx->isprotected(sym) == false)
375     {
376         ctx->put(sym, pS);
377     }
378     else
379     {
380         delete pS;
381         addErrorMessage(&sciErr, API_ERROR_REDEFINE_PERMANENT_VAR, _("Redefining permanent variable.\n"));
382     }
383     return sciErr;
384 }
385 /*--------------------------------------------------------------------------*/
386 SciErr readNamedMatrixOfWideString(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, int* _piwLength, wchar_t** _pwstStrings)
387 {
388     int* piAddr = NULL;
389
390     SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
391     if (sciErr.iErr)
392     {
393         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_WIDE_STRING, _("%s: Unable to get variable \"%s\""), "readNamedMatrixOfWideString", _pstName);
394         return sciErr;
395     }
396
397     sciErr = getMatrixOfWideString(_pvCtx, piAddr, _piRows, _piCols, _piwLength, _pwstStrings);
398     if (sciErr.iErr)
399     {
400         addErrorMessage(&sciErr, API_ERROR_READ_NAMED_WIDE_STRING, _("%s: Unable to get variable \"%s\""), "readNamedMatrixOfWideString", _pstName);
401         return sciErr;
402     }
403
404     return sciErr;
405 }
406
407 /*shortcut functions*/
408 /*--------------------------------------------------------------------------*/
409 int isStringType(void* _pvCtx, int* _piAddress)
410 {
411     return checkVarType(_pvCtx, _piAddress, sci_strings);
412 }
413 /*--------------------------------------------------------------------------*/
414 int isNamedStringType(void* _pvCtx, const char* _pstName)
415 {
416     return checkNamedVarType(_pvCtx, _pstName, sci_strings);
417 }
418 /*--------------------------------------------------------------------------*/
419 int getAllocatedSingleString(void* _pvCtx, int* _piAddress, char** _pstData)
420 {
421     SciErr sciErr = sciErrInit();
422     int iRows = 0;
423     int iCols = 0;
424     int iLen = 0;
425
426     if (isScalar(_pvCtx, _piAddress) == 0 || isStringType(_pvCtx, _piAddress) == 0)
427     {
428         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SINGLE_STRING, _("%s: Wrong type for input argument #%d: A single string expected.\n"), "getAllocatedSingleString", getRhsFromAddress(_pvCtx, _piAddress));
429         printError(&sciErr, 0);
430         return sciErr.iErr;
431     }
432
433     sciErr = getMatrixOfString(_pvCtx, _piAddress, &iRows, &iCols, &iLen, NULL);
434     if (sciErr.iErr)
435     {
436         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SINGLE_STRING, _("%s: Unable to get argument data"), "getAllocatedSingleString");
437         printError(&sciErr, 0);
438         return sciErr.iErr;
439     }
440
441     *_pstData = (char*)MALLOC(sizeof(char) * (iLen + 1)); //+1 for null termination
442
443     sciErr = getMatrixOfString(_pvCtx, _piAddress, &iRows, &iCols, &iLen, _pstData);
444     if (sciErr.iErr)
445     {
446         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SINGLE_STRING, _("%s: Unable to get argument data"), "getAllocatedSingleString");
447         printError(&sciErr, 0);
448         FREE(*_pstData);
449         return sciErr.iErr;
450     }
451
452     return 0;
453 }
454
455 /*--------------------------------------------------------------------------*/
456 int getAllocatedSingleWideString(void* _pvCtx, int* _piAddress, wchar_t** _pwstData)
457 {
458     SciErr sciErr = sciErrInit();
459     int iRows = 0;
460     int iCols = 0;
461     int iLen = 0;
462
463     if (isScalar(_pvCtx, _piAddress) == 0 || isStringType(_pvCtx, _piAddress) == 0)
464     {
465         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SINGLE_WIDE_STRING, _("%s: Wrong type for input argument #%d: A single string expected.\n"), "getAllocatedSingleWideString", getRhsFromAddress(_pvCtx, _piAddress));
466         printError(&sciErr, 0);
467         return sciErr.iErr;
468     }
469
470     sciErr = getMatrixOfWideString(_pvCtx, _piAddress, &iRows, &iCols, &iLen, NULL);
471     if (sciErr.iErr)
472     {
473         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SINGLE_WIDE_STRING, _("%s: Unable to get argument data"), "getAllocatedSingleWideString");
474         printError(&sciErr, 0);
475         return sciErr.iErr;
476     }
477
478     *_pwstData = (wchar_t*)MALLOC(sizeof(wchar_t) * (iLen + 1)); //+1 for null termination
479
480     sciErr = getMatrixOfWideString(_pvCtx, _piAddress, &iRows, &iCols, &iLen, _pwstData);
481     if (sciErr.iErr)
482     {
483         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_SINGLE_WIDE_STRING, _("%s: Unable to get argument data"), "getAllocatedSingleWideString");
484         printError(&sciErr, 0);
485         FREE(*_pwstData);
486         return sciErr.iErr;
487     }
488
489     return 0;
490 }
491 /*--------------------------------------------------------------------------*/
492 int getAllocatedMatrixOfString(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, char*** _pstData)
493 {
494     SciErr sciErr = getMatrixOfString(_pvCtx, _piAddress, _piRows, _piCols, NULL, NULL);
495     if (sciErr.iErr)
496     {
497         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedMatrixOfString");
498         printError(&sciErr, 0);
499         return sciErr.iErr;
500     }
501
502     int* piLen = (int*)MALLOC(sizeof(int) **_piRows **_piCols);
503
504     sciErr = getMatrixOfString(_pvCtx, _piAddress, _piRows, _piCols, piLen, NULL);
505     if (sciErr.iErr)
506     {
507         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedMatrixOfString");
508         printError(&sciErr, 0);
509         if (piLen)
510         {
511             FREE(piLen);
512             piLen = NULL;
513         }
514         return sciErr.iErr;
515     }
516
517     *_pstData = (char**)MALLOC(sizeof(char*) **_piRows **_piCols);
518     for (int i = 0 ; i < *_piRows **_piCols ; i++)
519     {
520         (*_pstData)[i] = (char*)MALLOC(sizeof(char) * (piLen[i] + 1));//+1 for null termination
521     }
522
523     sciErr = getMatrixOfString(_pvCtx, _piAddress, _piRows, _piCols, piLen, *_pstData);
524     if (piLen)
525     {
526         FREE(piLen);
527         piLen = NULL;
528     }
529     if (sciErr.iErr)
530     {
531         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedMatrixOfString");
532         printError(&sciErr, 0);
533         for (int i = 0 ; i < *_piRows **_piCols ; i++)
534         {
535             FREE((*_pstData)[i]);
536         }
537         FREE(*_pstData);
538         return sciErr.iErr;
539     }
540
541     return 0;
542 }
543 /*--------------------------------------------------------------------------*/
544 int getAllocatedMatrixOfWideString(void* _pvCtx, int* _piAddress, int* _piRows, int* _piCols, wchar_t*** _pwstData)
545 {
546     SciErr sciErr = getMatrixOfWideString(_pvCtx, _piAddress, _piRows, _piCols, NULL, NULL);
547     if (sciErr.iErr)
548     {
549         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_WIDE_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedMatrixOfWideString");
550         printError(&sciErr, 0);
551         return sciErr.iErr;
552     }
553
554     int* piLen = (int*)MALLOC(sizeof(int) **_piRows **_piCols);
555
556     sciErr = getMatrixOfWideString(_pvCtx, _piAddress, _piRows, _piCols, piLen, NULL);
557     if (sciErr.iErr)
558     {
559         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_WIDE_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedMatrixOfWideString");
560         if (piLen)
561         {
562             FREE(piLen);
563             piLen = NULL;
564         }
565         printError(&sciErr, 0);
566         return sciErr.iErr;
567     }
568
569     *_pwstData = (wchar_t**)MALLOC(sizeof(wchar_t*) **_piRows **_piCols);
570     for (int i = 0 ; i < *_piRows **_piCols ; i++)
571     {
572         (*_pwstData)[i] = (wchar_t*)MALLOC(sizeof(wchar_t) * (piLen[i] + 1));//+1 for null termination
573     }
574
575     sciErr = getMatrixOfWideString(_pvCtx, _piAddress, _piRows, _piCols, piLen, *_pwstData);
576
577     if (piLen)
578     {
579         FREE(piLen);
580         piLen = NULL;
581     }
582
583     if (sciErr.iErr)
584     {
585         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_WIDE_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedMatrixOfWideString");
586         printError(&sciErr, 0);
587         for (int i = 0 ; i < *_piRows **_piCols ; i++)
588         {
589             FREE((*_pwstData)[i]);
590         }
591         FREE(*_pwstData);
592         return sciErr.iErr;
593     }
594     return 0;
595 }
596 /*--------------------------------------------------------------------------*/
597 int getAllocatedNamedSingleString(void* _pvCtx, const char* _pstName, char** _pstData)
598 {
599     SciErr sciErr = sciErrInit();
600     int iRows = 0;
601     int iCols = 0;
602     int iLen = 0;
603
604     if (isNamedScalar(_pvCtx, _pstName) == 0 || isNamedStringType(_pvCtx, _pstName) == 0)
605     {
606         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_SINGLE_STRING, _("%s: Wrong type for input argument \"%s\": A single string expected.\n"), "getAllocatedNamedSingleString", _pstName);
607         printError(&sciErr, 0);
608         return sciErr.iErr;
609     }
610
611     sciErr = readNamedMatrixOfString(_pvCtx, _pstName, &iRows, &iCols, &iLen, NULL);
612     if (sciErr.iErr)
613     {
614         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_SINGLE_STRING, _("%s: Unable to get argument data"), "getAllocatedNamedSingleString");
615         printError(&sciErr, 0);
616         return sciErr.iErr;
617     }
618
619     *_pstData = (char*)MALLOC(sizeof(char) * (iLen + 1)); //+1 for null termination
620
621     sciErr = readNamedMatrixOfString(_pvCtx, _pstName, &iRows, &iCols, &iLen, _pstData);
622     if (sciErr.iErr)
623     {
624         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_SINGLE_STRING, _("%s: Unable to get argument data"), "getAllocatedNamedSingleString");
625         printError(&sciErr, 0);
626         FREE(*_pstData);
627         return sciErr.iErr;
628     }
629
630     return 0;
631 }
632 /*--------------------------------------------------------------------------*/
633 int getAllocatedNamedSingleWideString(void* _pvCtx, const char* _pstName, wchar_t** _pwstData)
634 {
635     SciErr sciErr = sciErrInit();
636     int iRows = 0;
637     int iCols = 0;
638     int iLen = 0;
639
640     if (isNamedScalar(_pvCtx, _pstName) == 0 || isNamedStringType(_pvCtx, _pstName) == 0)
641     {
642         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_SINGLE_WIDE_STRING, _("%s: Wrong type for input argument \"%s\": A single string expected.\n"), "getAllocatedNamedSingleWideString", _pstName);
643         printError(&sciErr, 0);
644         return sciErr.iErr;
645     }
646
647     sciErr = readNamedMatrixOfWideString(_pvCtx, _pstName, &iRows, &iCols, &iLen, NULL);
648     if (sciErr.iErr)
649     {
650         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_SINGLE_WIDE_STRING, _("%s: Unable to get argument data"), "getAllocatedNamedSingleWideString");
651         printError(&sciErr, 0);
652         return sciErr.iErr;
653     }
654
655     *_pwstData = (wchar_t*)MALLOC(sizeof(wchar_t) * (iLen + 1)); //+1 for null termination
656
657     sciErr = readNamedMatrixOfWideString(_pvCtx, _pstName, &iRows, &iCols, &iLen, _pwstData);
658     if (sciErr.iErr)
659     {
660         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_SINGLE_WIDE_STRING, _("%s: Unable to get argument data"), "getAllocatedNamedSingleWideString");
661         printError(&sciErr, 0);
662         FREE(*_pwstData);
663         return sciErr.iErr;
664     }
665
666     return 0;
667 }
668 /*--------------------------------------------------------------------------*/
669 int getAllocatedNamedMatrixOfString(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, char*** _pstData)
670 {
671     SciErr sciErr = readNamedMatrixOfString(_pvCtx, _pstName, _piRows, _piCols, NULL, NULL);
672     if (sciErr.iErr)
673     {
674         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedNamedMatrixOfString");
675         printError(&sciErr, 0);
676         return sciErr.iErr;
677     }
678
679     int* piLen = (int*)MALLOC(sizeof(int) **_piRows **_piCols);
680
681     sciErr = readNamedMatrixOfString(_pvCtx, _pstName, _piRows, _piCols, piLen, NULL);
682     if (sciErr.iErr)
683     {
684         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedNamedMatrixOfString");
685         if (piLen)
686         {
687             FREE(piLen);
688             piLen = NULL;
689         }
690         printError(&sciErr, 0);
691         return sciErr.iErr;
692     }
693
694     *_pstData = (char**)MALLOC(sizeof(char*) **_piRows **_piCols);
695     for (int i = 0 ; i < *_piRows **_piCols ; i++)
696     {
697         (*_pstData)[i] = (char*)MALLOC(sizeof(char) * (piLen[i] + 1));//+1 for null termination
698     }
699
700     sciErr = readNamedMatrixOfString(_pvCtx, _pstName, _piRows, _piCols, piLen, *_pstData);
701     if (piLen)
702     {
703         FREE(piLen);
704         piLen = NULL;
705     }
706     if (sciErr.iErr)
707     {
708         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedNamedMatrixOfString");
709         printError(&sciErr, 0);
710         for (int i = 0 ; i < *_piRows **_piCols ; i++)
711         {
712             FREE((*_pstData)[i]);
713         }
714         FREE(*_pstData);
715         return sciErr.iErr;
716     }
717
718     return 0;
719 }
720 /*--------------------------------------------------------------------------*/
721 int getAllocatedNamedMatrixOfWideString(void* _pvCtx, const char* _pstName, int* _piRows, int* _piCols, wchar_t*** _pwstData)
722 {
723     int iRows = 0;
724     int iCols = 0;
725     int* piLen = 0;
726
727     SciErr sciErr = readNamedMatrixOfWideString(_pvCtx, _pstName, &iRows, &iCols, NULL, NULL);
728     if (sciErr.iErr)
729     {
730         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_WIDE_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedNamedMatrixOfWideString");
731         printError(&sciErr, 0);
732         return sciErr.iErr;
733     }
734
735     piLen = (int*)MALLOC(sizeof(int) **_piRows **_piCols);
736
737     sciErr = readNamedMatrixOfWideString(_pvCtx, _pstName, &iRows, &iCols, piLen, NULL);
738     if (sciErr.iErr)
739     {
740         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_WIDE_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedNamedMatrixOfWideString");
741         if (piLen)
742         {
743             FREE(piLen);
744             piLen = NULL;
745         }
746         printError(&sciErr, 0);
747         return sciErr.iErr;
748     }
749
750     *_pwstData = (wchar_t**)MALLOC(sizeof(wchar_t*) **_piRows **_piCols);
751
752     for (int i = 0 ; i < *_piRows **_piCols ; i++)
753     {
754         *_pwstData[i] = (wchar_t*)MALLOC(sizeof(wchar_t) * (piLen[i] + 1));//+1 for null termination
755     }
756
757     sciErr = readNamedMatrixOfWideString(_pvCtx, _pstName, &iRows, &iCols, piLen, *_pwstData);
758     if (piLen)
759     {
760         FREE(piLen);
761         piLen = NULL;
762     }
763     if (sciErr.iErr)
764     {
765         addErrorMessage(&sciErr, API_ERROR_GET_ALLOC_NAMED_WIDE_STRING_MATRIX, _("%s: Unable to get argument data"), "getAllocatedNamedMatrixOfWideString");
766         printError(&sciErr, 0);
767         for (int i = 0 ; i < *_piRows **_piCols ; i++)
768         {
769             FREE((*_pwstData)[i]);
770         }
771         FREE(*_pwstData);
772         return sciErr.iErr;
773     }
774
775     return 0;
776 }
777 /*--------------------------------------------------------------------------*/
778 int createSingleString(void* _pvCtx, int _iVar, const char* _pstStrings)
779 {
780     SciErr sciErr = createMatrixOfString(_pvCtx, _iVar, 1, 1,   &_pstStrings);
781     if (sciErr.iErr)
782     {
783         addErrorMessage(&sciErr, API_ERROR_CREATE_SINGLE_STRING, _("%s: Unable to get argument data"), "createSingleString");
784         printError(&sciErr, 0);
785         return sciErr.iErr;
786     }
787
788     return 0;
789 }
790
791 int allocSingleString(void* _pvCtx, int _iVar, int _iLen, const char** _pstStrings)
792 {
793     SciErr sciErr = sciErrInit();
794
795     types::GatewayStruct* pGstr = (types::GatewayStruct*)_pvCtx;
796     types::typed_list in = *pGstr->m_pIn;
797     types::InternalType** out = pGstr->m_pOut;
798     types::String *pStr = NULL;
799
800     char* pstStrings;
801
802     if (_pstStrings == NULL)
803     {
804         addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: No more memory to allocate variable"), "allocSingleString");
805         return sciErr.iErr;
806     }
807
808     pstStrings = new char[_iLen];
809     memset(pstStrings, ' ', _iLen);
810     _pstStrings[0] = pstStrings;
811
812     pStr = new types::String(pstStrings);
813
814     if (pStr == NULL)
815     {
816         delete[] pstStrings;
817         addErrorMessage(&sciErr, API_ERROR_NO_MORE_MEMORY, _("%s: No more memory to allocate variable"), "allocSingleString");
818         return sciErr.iErr;
819     }
820
821     int rhs = _iVar - *getNbInputArgument(_pvCtx);
822     out[rhs - 1] = pStr;
823
824
825     return sciErr.iErr;
826 }
827
828 /*--------------------------------------------------------------------------*/
829 int createSingleWideString(void* _pvCtx, int _iVar, const wchar_t* _pwstStrings)
830 {
831     SciErr sciErr = createMatrixOfWideString(_pvCtx, _iVar, 1, 1,       &_pwstStrings);
832     if (sciErr.iErr)
833     {
834         addErrorMessage(&sciErr, API_ERROR_CREATE_SINGLE_WIDE_STRING, _("%s: Unable to get argument data"), "createSingleWideString");
835         printError(&sciErr, 0);
836         return sciErr.iErr;
837     }
838
839     return 0;
840 }
841 /*--------------------------------------------------------------------------*/
842 int createNamedSingleString(void* _pvCtx, const char* _pstName, const char* _pstStrings)
843 {
844     SciErr sciErr = createNamedMatrixOfString(_pvCtx, _pstName, 1, 1,   &_pstStrings);
845     if (sciErr.iErr)
846     {
847         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_SINGLE_STRING, _("%s: Unable to get argument data"), "createSingleString");
848         printError(&sciErr, 0);
849         return sciErr.iErr;
850     }
851
852     return 0;
853 }
854 /*--------------------------------------------------------------------------*/
855 int createNamedSingleWideString(void* _pvCtx, const char* _pstName, const wchar_t* _pwstStrings)
856 {
857     SciErr sciErr = createNamedMatrixOfWideString(_pvCtx, _pstName, 1, 1,       &_pwstStrings);
858     if (sciErr.iErr)
859     {
860         addErrorMessage(&sciErr, API_ERROR_CREATE_NAMED_SINGLE_WIDE_STRING, _("%s: Unable to get argument data"), "createSingleWideString");
861         printError(&sciErr, 0);
862         return sciErr.iErr;
863     }
864
865     return 0;
866 }
867 /*--------------------------------------------------------------------------*/
868 void freeAllocatedSingleString(char* _pstData)
869 {
870     FREE(_pstData);
871 }
872 /*--------------------------------------------------------------------------*/
873 void freeAllocatedSingleWideString(wchar_t* _pwstData)
874 {
875     FREE(_pwstData);
876 }
877 /*--------------------------------------------------------------------------*/
878 void freeAllocatedMatrixOfString(int _iRows, int _iCols, char** _pstData)
879 {
880     for (int i = 0 ; i < _iRows * _iCols ; i++)
881     {
882         FREE(_pstData[i]);
883     }
884     FREE(_pstData);
885 }
886 /*--------------------------------------------------------------------------*/
887 void freeAllocatedMatrixOfWideString(int _iRows, int _iCols, wchar_t** _pwstData)
888 {
889     for (int i = 0 ; i < _iRows * _iCols ; i++)
890     {
891         FREE(_pwstData[i]);
892     }
893     FREE(_pwstData);
894 }