Coverity #1099405 fixed
[scilab.git] / scilab / modules / parameters / src / c / parameters.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - Yann COLLETTE
4  * Copyright (C) 2010 - DIGITEO - Allan CORNET
5  * Copyright (C) 2010 - DIGITEO - Bernard HUGUENEY
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 /*--------------------------------------------------------------------------*/
17 #include <string.h>
18 #include <stdarg.h>
19 /*--------------------------------------------------------------------------*/
20 #include "parameters.h"
21 #include "sci_types.h"
22 #include "sci_malloc.h"
23 #include "freeArrayOfString.h"
24 #include "Scierror.h"
25 #include "sciprint.h"
26 #include "api_scilab.h"
27 #include "localization.h"
28 #include "os_string.h"
29 /*--------------------------------------------------------------------------*/
30 static int commonFindLabel(void* _pvCtx, int * _piAddress, char const * const _pstLabelToFind);
31 static int commonFindLabelPartial(void* _pvCtx, int * _piAddress, char const * const _pstLabelToFind);
32 static void int_fill_n(int* dst, size_t n, int v);
33 static void double_fill_n(double* dst, size_t n, int v);
34 /*--------------------------------------------------------------------------*/
35 SciErr initPList(void* _pvCtx, int _iVar, int ** _piAddress)
36 {
37     SciErr _SciErr;
38     _SciErr.iErr = 0;
39     _SciErr.iMsgCount = 0;
40     _SciErr = getVarAddressFromPosition(_pvCtx, _iVar, _piAddress);
41     return _SciErr;
42 }
43 /*--------------------------------------------------------------------------*/
44 int checkPList(void* _pvCtx, int * _piAddress)
45 {
46     int nb_param = 0, i = 0, var_type = 0;
47     int m_label = 0, n_label = 0;
48     int * len_label = NULL;
49     char ** label_list = NULL;
50     int result = 0;
51     SciErr _SciErr;
52
53     _SciErr.iErr = 0;
54     _SciErr.iMsgCount = 0;
55
56     _SciErr = getVarType(_pvCtx, _piAddress, &var_type);
57     if (var_type != sci_mlist)
58     {
59         return 0;
60     }
61
62     _SciErr = getListItemNumber(_pvCtx, _piAddress, &nb_param);
63
64     if (nb_param != 0)
65     {
66         _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, NULL, NULL);
67
68         len_label = (int *)MALLOC(m_label * n_label * sizeof(int));
69         _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, len_label, NULL);
70
71         label_list = (char **)MALLOC(m_label * n_label * sizeof(char *));
72         for (i = 0; i < n_label * m_label; i++)
73         {
74             label_list[i] = (char *)MALLOC((len_label[i] + 1) * sizeof(char));
75         }
76         _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, len_label, label_list);
77         if (strcmp(label_list[0], "plist") != 0)
78         {
79             if (len_label)
80             {
81                 FREE(len_label);
82                 len_label = NULL;
83             }
84             freeArrayOfString(label_list, m_label * n_label);
85
86             return 0;
87         }
88
89         if (len_label)
90         {
91             FREE(len_label);
92             len_label = NULL;
93         }
94         freeArrayOfString(label_list, m_label * n_label);
95     }
96
97     result = 1;
98
99     return result;
100 }
101 /*--------------------------------------------------------------------------*/
102 int hasPartialLabelInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel)
103 {
104     SciErr _SciErr;
105     _SciErr.iErr = 0;
106     _SciErr.iMsgCount = 0;
107
108     return commonFindLabelPartial(_pvCtx, _piAddress, _pstLabel);
109 }
110 /*--------------------------------------------------------------------------*/
111 int hasLabelInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel)
112 {
113     SciErr _SciErr;
114     _SciErr.iErr = 0;
115     _SciErr.iMsgCount = 0;
116
117     return commonFindLabel(_pvCtx, _piAddress, _pstLabel);
118 }
119 /*--------------------------------------------------------------------------*/
120 SciErr getIntInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel, int * _piValue, int * _piFound,
121                      int _iDefaultValue, int _iLog, enum type_check _eCheck, ...)
122 {
123     int pos_label = 0, i = 0;
124     int m_tmp = 0, n_tmp = 0;
125     double * tmp_dbl = NULL;
126     SciErr _SciErr = sciErrInit();
127
128     pos_label = commonFindLabel(_pvCtx, _piAddress, _pstLabel);
129     *_piFound = pos_label;
130
131     if (pos_label != -1)
132     {
133         _SciErr = getMatrixOfDoubleInList(_pvCtx, _piAddress, pos_label + 1, &m_tmp, &n_tmp, &tmp_dbl);
134         if (!_SciErr.iErr)
135         {
136             *_piValue = (int)tmp_dbl[0];
137         }
138         else
139         {
140             if (_iLog)
141             {
142                 sciprint(_("%s: wrong parameter type. %s expected. Return default value %d.\n"), "getIntInPList", "int", _iDefaultValue);
143             }
144             *_piValue = _iDefaultValue;
145         }
146     }
147     else
148     {
149         if (_iLog)
150         {
151             sciprint(_("%s: parameter not found. Return default value %d.\n"), "getIntInPList", _iDefaultValue);
152         }
153         *_piValue = _iDefaultValue;
154     }
155
156     /* Now check parameters */
157
158     if (_eCheck != CHECK_NONE)
159     {
160         va_list vl;
161         int nb_value_to_check = 0;
162         int value_to_check = 0;
163         int check_res = 0;
164
165         va_start(vl, _eCheck);
166
167         switch (_eCheck)
168         {
169             case CHECK_MIN:
170                 value_to_check = va_arg(vl, int);
171                 va_end(vl);
172                 if (value_to_check > *_piValue)
173                 {
174                     if ((*_piFound != -1) && (_iLog))
175                     {
176                         sciprint(_("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
177                     }
178                     *_piValue = _iDefaultValue;
179                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
180                     return _SciErr;
181                 }
182                 break;
183             case CHECK_MAX:
184                 value_to_check = va_arg(vl, int);
185                 va_end(vl);
186                 if (value_to_check < *_piValue)
187                 {
188                     if ((*_piFound != -1) && (_iLog))
189                     {
190                         sciprint(_("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
191                     }
192                     *_piValue = _iDefaultValue;
193                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
194                     return _SciErr;
195                 }
196                 break;
197             case CHECK_BOTH:
198                 // First value is the min bound
199                 value_to_check = va_arg(vl, int);
200                 if (value_to_check > *_piValue)
201                 {
202                     if ((*_piFound != -1) && (_iLog))
203                     {
204                         sciprint(_("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
205                     }
206                     *_piValue = _iDefaultValue;
207                     va_end(vl);
208                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
209                     return _SciErr;
210                 }
211                 // Second value is the max bound
212                 value_to_check = va_arg(vl, int);
213                 va_end(vl);
214                 if (value_to_check < *_piValue)
215                 {
216                     if ((*_piFound != -1) && (_iLog))
217                     {
218                         sciprint(_("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
219                     }
220                     *_piValue = _iDefaultValue;
221                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getIntInPList", _pstLabel, value_to_check, *_piValue);
222                     return _SciErr;
223                 }
224                 break;
225             case CHECK_VALUES:
226                 // First parameters is int and contains the number of values to check
227                 nb_value_to_check = va_arg(vl, int);
228                 check_res = 0;
229                 for (i = 0; i < nb_value_to_check; i++)
230                 {
231                     value_to_check = va_arg(vl, int);
232                     check_res = check_res || (value_to_check == *_piValue);
233                 }
234
235                 if (!check_res)
236                 {
237                     if ((*_piFound != -1) && (_iLog))
238                     {
239                         sciprint(_("%s: wrong value for parameter %s: value %d\n"), "getIntInPList", _pstLabel, *_piValue);
240                         sciprint(_("%s: awaited parameters: "), "getIntInPList");
241                         va_start(vl, _eCheck);
242                         nb_value_to_check = va_arg(vl, int);
243                         for (i = 0; i < nb_value_to_check; i++)
244                         {
245                             value_to_check = va_arg(vl, int);
246                             sciprint(" %d", value_to_check);
247                         }
248                         sciprint("\n");
249                     }
250
251                     *_piValue = _iDefaultValue;
252
253                     va_end(vl);
254                     addErrorMessage(&_SciErr, 999, _("%s: wrong value for parameter %s: value %d\n"), "getIntInPList", _pstLabel, *_piValue);
255                     return _SciErr;
256                 }
257
258                 va_end(vl);
259                 break;
260             default:
261                 va_end(vl);
262         }
263     }
264     return _SciErr;
265 }
266 /*--------------------------------------------------------------------------*/
267 SciErr getDoubleInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel, double * _pdblValue, int * _piFound,
268                         double _dblDefaultValue, int _iLog, enum type_check _eCheck, ...)
269 {
270     int pos_label = 0, i = 0;
271     int m_tmp = 0, n_tmp = 0;
272     double * tmp_values = NULL;
273     SciErr _SciErr = sciErrInit();
274
275     pos_label = commonFindLabel(_pvCtx, _piAddress, _pstLabel);
276     *_piFound = pos_label;
277
278     if (pos_label != -1)
279     {
280         _SciErr = getMatrixOfDoubleInList(_pvCtx, _piAddress, pos_label + 1, &m_tmp, &n_tmp, &tmp_values);
281         if (!_SciErr.iErr)
282         {
283             *_pdblValue = tmp_values[0];
284         }
285         else
286         {
287             if (_iLog)
288             {
289                 sciprint(_("%s: wrong parameter type. %s expected. Return default value %f.\n"), "getDoubleInPList", "double", _dblDefaultValue);
290             }
291             *_pdblValue = _dblDefaultValue;
292         }
293     }
294     else
295     {
296         if (_iLog)
297         {
298             sciprint(_("%s: parameter not found. Return default value %f.\n"), "getDoubleInPList", _dblDefaultValue);
299         }
300         *_pdblValue = _dblDefaultValue;
301     }
302
303     /* Now check parameters */
304
305     if (_eCheck != CHECK_NONE)
306     {
307         va_list vl;
308         int nb_value_to_check = 0;
309         double value_to_check = 0;
310         int check_res = 0;
311
312         va_start(vl, _eCheck);
313
314         switch (_eCheck)
315         {
316             case CHECK_MIN:
317                 value_to_check = va_arg(vl, double);
318                 va_end(vl);
319                 if (value_to_check > *_pdblValue)
320                 {
321                     if ((*_piFound != -1) && (_iLog))
322                     {
323                         sciprint(_("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
324                     }
325                     *_pdblValue = _dblDefaultValue;
326                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
327                     return _SciErr;
328                 }
329                 break;
330             case CHECK_MAX:
331                 value_to_check = va_arg(vl, double);
332                 va_end(vl);
333                 if (value_to_check < *_pdblValue)
334                 {
335                     if ((*_piFound != -1) && (_iLog))
336                     {
337                         sciprint(_("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
338                     }
339                     *_pdblValue = _dblDefaultValue;
340                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
341                     return _SciErr;
342                 }
343                 break;
344             case CHECK_BOTH:
345                 /* First value is the min bound */
346                 value_to_check = va_arg(vl, double);
347                 if (value_to_check > *_pdblValue)
348                 {
349                     if ((*_piFound != -1) && (_iLog))
350                     {
351                         sciprint(_("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
352                     }
353                     *_pdblValue = _dblDefaultValue;
354                     va_end(vl);
355                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
356                     return _SciErr;
357                 }
358                 /* Second value is the max bound */
359                 value_to_check = va_arg(vl, double);
360                 va_end(vl);
361                 if (value_to_check < *_pdblValue)
362                 {
363                     if ((*_piFound != -1) && (_iLog))
364                     {
365                         sciprint(_("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
366                     }
367                     *_pdblValue = _dblDefaultValue;
368                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
369                     return _SciErr;
370                 }
371                 break;
372             case CHECK_VALUES:
373                 /* First parameters is int and contains the number of values to check */
374                 nb_value_to_check = va_arg(vl, int);
375                 check_res = 0;
376                 for (i = 0; i < nb_value_to_check; i++)
377                 {
378                     value_to_check = va_arg(vl, double);
379                     check_res = check_res || (value_to_check == *_pdblValue);
380                 }
381
382                 if (!check_res)
383                 {
384                     if ((*_piFound != -1) && (_iLog))
385                     {
386                         sciprint(_("%s: wrong value for parameter %s: value %f\n"), "getDoubleInPList", _pstLabel, *_pdblValue);
387                         sciprint(_("%s: awaited parameters: "), "getDoubleInPList");
388                         va_start(vl, _eCheck);
389                         nb_value_to_check = va_arg(vl, int);
390                         for (i = 0; i < nb_value_to_check; i++)
391                         {
392                             value_to_check = va_arg(vl, double);
393                             sciprint(" %f", value_to_check);
394                         }
395                         sciprint("\n");
396                     }
397
398                     *_pdblValue = _dblDefaultValue;
399
400                     va_end(vl);
401                     addErrorMessage(&_SciErr, 999, _("%s: wrong value for parameter %s: value %f\n"), "getDoubleInPList", _pstLabel, *_pdblValue);
402                     return _SciErr;
403                 }
404                 va_end(vl);
405                 break;
406             default:
407                 va_end(vl);
408         }
409     }
410
411     return _SciErr;
412 }
413 /*--------------------------------------------------------------------------*/
414 SciErr getStringInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel, char ** _pstValue, int * _piFound,
415                         const char * _pstDefaultValue, int _iLog, enum type_check _eCheck, ...)
416 {
417     int pos_label = 0, i = 0;
418     int m_label = 0, n_label = 0;
419     int * len_label = NULL;
420     char ** label_list = NULL;
421     SciErr _SciErr = sciErrInit();
422
423     pos_label = commonFindLabel(_pvCtx, _piAddress, _pstLabel);
424     *_piFound = pos_label;
425
426     if (pos_label != -1)
427     {
428         _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, pos_label + 1, &m_label, &n_label, NULL, NULL);
429         len_label = (int *)MALLOC(m_label * n_label * sizeof(int));
430         _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, pos_label + 1, &m_label, &n_label, len_label, NULL);
431         label_list = (char **)MALLOC(m_label * n_label * sizeof(char *));
432         for (i = 0; i < n_label * m_label; i++)
433         {
434             label_list[i] = (char *)MALLOC((len_label[i] + 1) * sizeof(char));
435         }
436         _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, pos_label + 1, &m_label, &n_label, len_label, label_list);
437
438         if (!_SciErr.iErr)
439         {
440             if (label_list[0])
441             {
442                 *_pstValue = os_strdup(label_list[0]);
443             }
444             else
445             {
446                 if (_iLog)
447                 {
448                     sciprint(_("%s: wrong parameter type. %s expected. Return default value %s.\n"), "getStringInPList", "string", _pstDefaultValue);
449                 }
450                 *_pstValue = os_strdup(_pstDefaultValue);
451             }
452         }
453         else
454         {
455             if (_iLog)
456             {
457                 sciprint(_("%s: parameter not found. Return default value %s.\n"), "getStringInPList", _pstDefaultValue);
458             }
459             *_pstValue = os_strdup(_pstDefaultValue);
460         }
461
462         if (len_label)
463         {
464             FREE(len_label);
465             len_label = NULL;
466         }
467         freeArrayOfString(label_list, m_label * n_label);
468     }
469     else
470     {
471         *_pstValue = os_strdup(_pstDefaultValue);
472     }
473
474     /* Now check parameters */
475
476     if (_eCheck != CHECK_NONE)
477     {
478         va_list vl;
479         int nb_value_to_check = 0;
480         char * value_to_check = 0;
481         int check_res = 0;
482
483         va_start(vl, _eCheck);
484
485         switch (_eCheck)
486         {
487             case CHECK_VALUES:
488                 /* First parameters is int and contains the number of values to check */
489                 nb_value_to_check = va_arg(vl, int);
490                 check_res = 0;
491                 for (i = 0; i < nb_value_to_check; i++)
492                 {
493                     value_to_check = va_arg(vl, char *);
494                     check_res = check_res || (strcmp(value_to_check, *_pstValue) == 0);
495                 }
496
497                 if (!check_res)
498                 {
499                     if ((*_piFound != -1) && (_iLog))
500                     {
501                         sciprint(_("%s: wrong value for parameter %s: value %s\n"), "getStringInPList", _pstLabel, *_pstValue);
502                         sciprint(_("%s: awaited parameters: "), "getStringInPList");
503                         va_start(vl, _eCheck);
504                         nb_value_to_check = va_arg(vl, int);
505                         for (i = 0; i < nb_value_to_check; i++)
506                         {
507                             value_to_check = va_arg(vl, char *);
508                             sciprint(" \"%s\"", value_to_check);
509                         }
510                         sciprint("\n");
511                     }
512
513                     if (*_pstValue)
514                     {
515                         FREE(*_pstValue);
516                         *_pstValue = NULL;
517                     }
518
519                     *_pstValue = os_strdup(_pstDefaultValue);
520
521                     va_end(vl);
522                     addErrorMessage(&_SciErr, 999, _("%s: wrong value for parameter %s: value %s\n"), "getStringInPList", _pstLabel, *_pstValue);
523                     return _SciErr;
524                 }
525
526                 va_end(vl);
527                 break;
528             default:
529                 va_end(vl);
530         }
531     }
532
533     return _SciErr;
534 }
535 /*--------------------------------------------------------------------------*/
536 /* get vector of double / integers */
537 SciErr getColVectorOfIntInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel, int * _piValue, int * _piFound,
538                                 int _iDefaultValue, int _iDefaultSize, int * _piSize, int _iLog, enum type_check _eCheck, ...)
539 {
540     int pos_label = 0, i = 0;
541     int m_tmp = 0, n_tmp = 0;
542     double * tmp_dbl = 0;
543     SciErr _SciErr = sciErrInit();
544
545     *_piSize = -1;
546
547     pos_label = commonFindLabel(_pvCtx, _piAddress, _pstLabel);
548     *_piFound = pos_label;
549
550     if (pos_label != -1)
551     {
552         _SciErr = getMatrixOfDoubleInList(_pvCtx, _piAddress, pos_label + 1, &m_tmp, &n_tmp, &tmp_dbl);
553         if (!_SciErr.iErr)
554         {
555             *_piSize  = m_tmp * n_tmp;
556             for (i = 0; i < *_piSize; i++)
557             {
558                 _piValue[i] = (int)tmp_dbl[i];
559             }
560         }
561         else
562         {
563             if (_iLog)
564             {
565                 sciprint(_("%s: wrong parameter type. %s expected. Return default value %d.\n"), "getColVectorOfIntInPList", "int", _iDefaultValue);
566             }
567             *_piSize  = _iDefaultSize;
568             int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
569         }
570     }
571     else
572     {
573         if (_iLog)
574         {
575             sciprint(_("%s: parameter not found. Return default value %d.\n"), "getColVectorOfIntInPList", _iDefaultValue);
576         }
577         *_piSize  = _iDefaultSize;
578         int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
579     }
580
581     /* Now check parameters */
582
583     if (_eCheck != CHECK_NONE)
584     {
585         va_list vl;
586         int nb_value_to_check = 0;
587         int value_to_check = 0;
588         int check_res = 0;
589
590         va_start(vl, _eCheck);
591
592         switch (_eCheck)
593         {
594             case CHECK_SIZE:
595                 value_to_check = va_arg(vl, int);
596                 va_end(vl);
597                 if (value_to_check != *_piSize)
598                 {
599                     if ((*_piFound != -1) && (_iLog))
600                     {
601                         sciprint(_("%s: wrong size for parameter %s: %d requested, got %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piSize);
602                     }
603                     int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
604                     addErrorMessage(&_SciErr, 999, _("%s: wrong size for parameter %s: %d requested, got %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piSize);
605                     return _SciErr;
606                 }
607                 break;
608             case CHECK_MIN:
609                 value_to_check = va_arg(vl, int);
610                 va_end(vl);
611                 if (value_to_check > *_piValue)
612                 {
613                     if ((*_piFound != -1) && (_iLog))
614                     {
615                         sciprint(_("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
616                     }
617                     int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
618                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
619                     return _SciErr;
620                 }
621                 break;
622             case CHECK_MAX:
623                 value_to_check = va_arg(vl, int);
624                 va_end(vl);
625                 if (value_to_check < *_piValue)
626                 {
627                     if ((*_piFound != -1) && (_iLog))
628                     {
629                         sciprint(_("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
630                     }
631                     int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
632                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
633                     return _SciErr;
634                 }
635                 break;
636             case CHECK_BOTH:
637                 /* First value is the min bound */
638                 value_to_check = va_arg(vl, int);
639                 if (value_to_check > *_piValue)
640                 {
641                     if ((*_piFound != -1) && (_iLog))
642                     {
643                         sciprint(_("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
644                     }
645                     int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
646                     va_end(vl);
647                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
648                     return _SciErr;
649                 }
650                 /* Second value is the max bound */
651                 value_to_check = va_arg(vl, int);
652                 va_end(vl);
653                 if (value_to_check < *_piValue)
654                 {
655                     if ((*_piFound != -1) && (_iLog))
656                     {
657                         sciprint(_("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
658                     }
659                     int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
660                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %d, value %d\n"), "getColVectorOfIntInPList", _pstLabel, value_to_check, *_piValue);
661                     return _SciErr;
662                 }
663                 break;
664             case CHECK_VALUES:
665                 /* First parameters is int and contains the number of values to check */
666                 nb_value_to_check = va_arg(vl, int);
667                 check_res = 0;
668                 for (i = 0; i < nb_value_to_check; i++)
669                 {
670                     value_to_check = va_arg(vl, int);
671                     check_res = check_res || (value_to_check == *_piValue);
672                 }
673
674                 if (!check_res)
675                 {
676                     if ((*_piFound != -1) && (_iLog))
677                     {
678                         sciprint(_("%s: wrong value for parameter %s: value %d\n"), "getColVectorOfIntInPList", _pstLabel, *_piValue);
679                         sciprint(_("%s: awaited parameters: "), "getColVectorOfIntInPList");
680                         va_start(vl, _eCheck);
681                         nb_value_to_check = va_arg(vl, int);
682                         for (i = 0; i < nb_value_to_check; i++)
683                         {
684                             value_to_check = va_arg(vl, int);
685                             sciprint(" %d", value_to_check);
686                         }
687                         sciprint("\n");
688                     }
689
690                     int_fill_n(_piValue, _iDefaultSize, _iDefaultValue);
691
692                     va_end(vl);
693                     addErrorMessage(&_SciErr, 999, _("%s: wrong value for parameter %s: value %d\n"), "getColVectorOfIntInPList", _pstLabel, *_piValue);
694                     return _SciErr;
695                 }
696
697                 va_end(vl);
698                 break;
699             default:
700                 va_end(vl);
701         }
702     }
703
704     return _SciErr;
705 }
706
707 SciErr getColVectorOfDoubleInPList(void* _pvCtx, int * _piAddress, const char * _pstLabel, double * _pdblValue, int * _piFound,
708                                    double _dblDefaultValue, int _iDefaultSize, int * _piSize, int _iLog, enum type_check _eCheck, ...)
709 {
710     int pos_label = 0, i = 0;
711     int m_label = 0, n_label = 0;
712     int m_tmp = 0, n_tmp = 0;
713     double * tmp_values = NULL;
714     char ** label_list = NULL;
715     SciErr _SciErr = sciErrInit();
716
717     *_piSize = -1;
718
719     pos_label = commonFindLabel(_pvCtx, _piAddress, _pstLabel);
720     *_piFound = pos_label;
721
722     freeArrayOfString(label_list, m_label * n_label);
723
724     if (pos_label != -1)
725     {
726         _SciErr = getMatrixOfDoubleInList(_pvCtx, _piAddress, pos_label + 1, &m_tmp, &n_tmp, &tmp_values);
727         if (!_SciErr.iErr)
728         {
729             *_piSize  = m_tmp * n_tmp;
730
731             memcpy( _pdblValue,  tmp_values, sizeof(double) * (*_piSize));
732         }
733         else
734         {
735             if (_iLog)
736             {
737                 sciprint(_("%s: wrong parameter type. %s expected. Return default value %f.\n"), "getColVectorOfDoubleInPList", "double", _dblDefaultValue);
738             }
739             *_piSize  = _iDefaultSize;
740             double_fill_n(_pdblValue, (size_t)_iDefaultSize, (int)_dblDefaultValue);
741         }
742     }
743     else
744     {
745         if (_iLog)
746         {
747             sciprint(_("%s: parameter not found. Return default value %f.\n"), "getColVectorOfDoubleInPList", _dblDefaultValue);
748         }
749         *_piSize  = _iDefaultSize;
750         double_fill_n(_pdblValue, (size_t)_iDefaultSize, (int)_dblDefaultValue);
751     }
752
753     /* Now check parameters */
754
755     if (_eCheck != CHECK_NONE)
756     {
757         va_list vl;
758         int nb_value_to_check = 0;
759         double value_to_check = 0;
760         int check_res = 0;
761
762         va_start(vl, _eCheck);
763
764         switch (_eCheck)
765         {
766             case CHECK_SIZE:
767                 value_to_check = va_arg(vl, double);
768                 va_end(vl);
769                 if (value_to_check != *_piSize)
770                 {
771                     if ((*_piFound != -1) && (_iLog))
772                     {
773                         sciprint(_("%s: wrong size for parameter %s: %d requested, got %d\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_piSize);
774                     }
775
776                     for (i = 0; i < _iDefaultSize; i++)
777                     {
778                         _pdblValue[i] = _dblDefaultValue;
779                     }
780
781                     addErrorMessage(&_SciErr, 999, _("%s: wrong size for parameter %s: %d requested, got %d\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_piSize);
782                     return _SciErr;
783                 }
784                 break;
785             case CHECK_MIN:
786                 value_to_check = va_arg(vl, double);
787                 va_end(vl);
788                 if (value_to_check > *_pdblValue)
789                 {
790                     if ((*_piFound != -1) && (_iLog))
791                     {
792                         sciprint(_("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
793                     }
794
795                     for (i = 0; i < _iDefaultSize; i++)
796                     {
797                         _pdblValue[i] = _dblDefaultValue;
798                     }
799
800                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
801                     return _SciErr;
802                 }
803                 break;
804             case CHECK_MAX:
805                 value_to_check = va_arg(vl, double);
806                 va_end(vl);
807                 if (value_to_check < *_pdblValue)
808                 {
809                     if ((*_piFound != -1) && (_iLog))
810                     {
811                         sciprint(_("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
812                     }
813
814                     for (i = 0; i < _iDefaultSize; i++)
815                     {
816                         _pdblValue[i] = _dblDefaultValue;
817                     }
818
819                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
820                     return _SciErr;
821                 }
822                 break;
823             case CHECK_BOTH:
824                 /* First value is the min bound */
825                 value_to_check = va_arg(vl, double);
826                 if (value_to_check > *_pdblValue)
827                 {
828                     if ((*_piFound != -1) && (_iLog))
829                     {
830                         sciprint(_("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
831                     }
832
833                     for (i = 0; i < _iDefaultSize; i++)
834                     {
835                         _pdblValue[i] = _dblDefaultValue;
836                     }
837
838                     va_end(vl);
839                     addErrorMessage(&_SciErr, 999, _("%s: wrong min bound for parameter %s: min bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
840                     return _SciErr;
841                 }
842                 /* Second value is the max bound */
843                 value_to_check = va_arg(vl, double);
844                 va_end(vl);
845                 if (value_to_check < *_pdblValue)
846                 {
847                     if ((*_piFound != -1) && (_iLog))
848                     {
849                         sciprint(_("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
850                     }
851
852                     for (i = 0; i < _iDefaultSize; i++)
853                     {
854                         _pdblValue[i] = _dblDefaultValue;
855                     }
856
857                     addErrorMessage(&_SciErr, 999, _("%s: wrong max bound for parameter %s: max bound %f, value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, value_to_check, *_pdblValue);
858                     return _SciErr;
859                 }
860                 break;
861             case CHECK_VALUES:
862                 /* First parameters is int and contains the number of values to check */
863                 nb_value_to_check = va_arg(vl, int);
864                 check_res = 0;
865                 for (i = 0; i < nb_value_to_check; i++)
866                 {
867                     value_to_check = va_arg(vl, double);
868                     check_res = check_res || (value_to_check == *_pdblValue);
869                 }
870                 if (!check_res)
871                 {
872                     if ((*_piFound != -1) && (_iLog))
873                     {
874                         sciprint(_("%s: wrong value for parameter %s: value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, *_pdblValue);
875                         sciprint(_("%s: awaited parameters: "), "getColVectorOfDoubleInPList");
876                         va_start(vl, _eCheck);
877                         nb_value_to_check = va_arg(vl, int);
878                         for (i = 0; i < nb_value_to_check; i++)
879                         {
880                             value_to_check = va_arg(vl, double);
881                             sciprint(" %f", value_to_check);
882                         }
883                         sciprint("\n");
884                     }
885
886                     for (i = 0; i < _iDefaultSize; i++)
887                     {
888                         _pdblValue[i] = _dblDefaultValue;
889                     }
890                     va_end(vl);
891                     addErrorMessage(&_SciErr, 999, _("%s: wrong value for parameter %s: value %f\n"), "getColVectorOfDoubleInPList", _pstLabel, *_pdblValue);
892                     return _SciErr;
893                 }
894                 va_end(vl);
895                 break;
896             default:
897                 va_end(vl);
898         }
899     }
900
901     return _SciErr;
902 }
903 /*--------------------------------------------------------------------------*/
904 SciErr createPList(void* _pvCtx, int _iVar, int ** _piAddress, char ** _pstLabelNames, int _iNbParams)
905 {
906     SciErr _SciErr;
907     int i = 0;
908     char ** label_list = NULL;
909
910     _SciErr.iErr = 0;
911     _SciErr.iMsgCount = 0;
912
913     _SciErr = createMList(_pvCtx, _iVar, _iNbParams + 1, _piAddress);
914     label_list = (char **)MALLOC((_iNbParams + 1) * sizeof(char *));
915     label_list[0] = os_strdup("plist");
916
917     for (i = 1; i <= _iNbParams; i++)
918     {
919         label_list[i] = os_strdup(_pstLabelNames[i - 1]);
920     }
921
922     _SciErr = createMatrixOfStringInList(_pvCtx, _iVar, *_piAddress, 1, 1, _iNbParams + 1, (char const * const*) label_list);
923
924     freeArrayOfString(label_list, _iNbParams + 1);
925
926     return _SciErr;
927 }
928 /*--------------------------------------------------------------------------*/
929 SciErr createIntInPList(void* _pvCtx, int _iVar, int * _piAddress, char * _pstLabelName, int _iValue)
930 {
931     int itemPos = -1;
932     double tmp_val[1];
933     SciErr _SciErr;
934
935     _SciErr.iErr = 0;
936     _SciErr.iMsgCount = 0;
937
938     itemPos = commonFindLabel(_pvCtx, _piAddress, _pstLabelName) + 1;
939
940 #ifdef DEBUG
941     sciprint("DEBUG: addIntInPList - itemPos = %d _pstLabelName = %s\n", itemPos, _pstLabelName);
942 #endif
943
944     tmp_val[0] = (double)_iValue;
945     _SciErr = createMatrixOfDoubleInList(_pvCtx, _iVar, _piAddress, itemPos, 1, 1, tmp_val);
946
947     return _SciErr;
948 }
949 /*--------------------------------------------------------------------------*/
950 SciErr createDoubleInPList(void* _pvCtx, int _iVar, int * _piAddress, char * _pstLabelName, double _dblValue)
951 {
952     int itemPos = -1;
953     double tmp_val[1];
954     SciErr _SciErr;
955
956     _SciErr.iErr = 0;
957     _SciErr.iMsgCount = 0;
958
959     itemPos = commonFindLabel(_pvCtx, _piAddress, _pstLabelName) + 1;
960
961 #ifdef DEBUG
962     sciprint("DEBUG: addDoubleInPList - itemPos = %d _pstLabelName = %s\n", itemPos, _pstLabelName);
963 #endif
964
965     tmp_val[0] = _dblValue;
966     _SciErr = createMatrixOfDoubleInList(_pvCtx, _iVar, _piAddress, itemPos, 1, 1, tmp_val);
967
968     return _SciErr;
969 }
970 /*--------------------------------------------------------------------------*/
971 SciErr createStringInPList(void* _pvCtx, int _iVar, int * _piAddress, char * _pstLabelName, char * _pstValue)
972 {
973     int itemPos = -1;
974     char * tmp_val[1];
975     SciErr _SciErr;
976
977     _SciErr.iErr = 0;
978     _SciErr.iMsgCount = 0;
979
980     itemPos = commonFindLabel(_pvCtx, _piAddress, _pstLabelName) + 1;
981
982 #ifdef DEBUG
983     sciprint("DEBUG: addStringInPList - itemPos = %d _pstLabelName = %s\n", itemPos, _pstLabelName);
984 #endif
985
986     tmp_val[0] = os_strdup(_pstValue);
987     _SciErr = createMatrixOfStringInList(_pvCtx, _iVar, _piAddress, itemPos, 1, 1, (char const * const*) tmp_val);
988
989     if (tmp_val[0])
990     {
991         FREE(tmp_val[0]);
992         tmp_val[0] = NULL;
993
994     }
995
996     return _SciErr;
997 }
998 /*--------------------------------------------------------------------------*/
999 SciErr createColVectorOfIntInPList(void* _pvCtx, int _iVar, int * _piAddress, char * _pstLabelName, int _iNbValues, int * _piValue)
1000 {
1001     int itemPos = -1, i = 0;
1002     double * tmp_val = NULL;
1003     SciErr _SciErr;
1004
1005     _SciErr.iErr = 0;
1006     _SciErr.iMsgCount = 0;
1007
1008     itemPos = commonFindLabel(_pvCtx, _piAddress, _pstLabelName) + 1;
1009
1010 #ifdef DEBUG
1011     sciprint("DEBUG: addVectorOfIntInPList - itemPos = %d _pstLabelName = %s\n", itemPos, _pstLabelName);
1012 #endif
1013
1014     tmp_val = (double *)MALLOC(_iNbValues * sizeof(double));
1015     for (i = 0; i < _iNbValues; i++)
1016     {
1017         tmp_val[i] = (double)_piValue[i];
1018     }
1019     _SciErr = createMatrixOfDoubleInList(_pvCtx, _iVar, _piAddress, itemPos, _iNbValues, 1, tmp_val);
1020
1021     if (tmp_val)
1022     {
1023         FREE(tmp_val);
1024         tmp_val = NULL;
1025     }
1026
1027     return _SciErr;
1028 }
1029 /*--------------------------------------------------------------------------*/
1030 SciErr createColVectorOfDoubleInPList(void* _pvCtx, int _iVar, int * _piAddress, char * _pstLabelName, int _iNbValues, double * _pdblValue)
1031 {
1032     int itemPos = -1;
1033     SciErr _SciErr;
1034
1035     _SciErr.iErr = 0;
1036     _SciErr.iMsgCount = 0;
1037
1038     itemPos = commonFindLabel(_pvCtx, _piAddress, _pstLabelName) + 1;
1039
1040 #ifdef DEBUG
1041     sciprint("DEBUG: addVectorOfDoubleInPList - itemPos = %d _pstLabelName = %s\n", itemPos, _pstLabelName);
1042 #endif
1043
1044     _SciErr = createMatrixOfDoubleInList(_pvCtx, _iVar, _piAddress, itemPos, _iNbValues, 1, _pdblValue);
1045
1046     return _SciErr;
1047 }
1048 /*--------------------------------------------------------------------------*/
1049 /* Utility functions */
1050 static int commonFindLabelPartial(void* _pvCtx, int * _piAddress, char const * const _pstLabelToFind)
1051 {
1052     int Pos = -1, i = 0;
1053     int m_label = 0, n_label = 0;
1054     int * len_label = NULL;
1055     char ** label_list = NULL;
1056     SciErr _SciErr;
1057
1058     _SciErr.iErr = 0;
1059     _SciErr.iMsgCount = 0;
1060
1061     _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, NULL, NULL);
1062     len_label = (int *)MALLOC(m_label * n_label * sizeof(int));
1063     _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, len_label, NULL);
1064     label_list = (char **)MALLOC(m_label * n_label * sizeof(char *));
1065
1066     for (i = 0;  i < n_label * m_label; i++)
1067     {
1068         label_list[i] = (char *)MALLOC((len_label[i] + 1) * sizeof(char));
1069     }
1070     _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, len_label, label_list);
1071
1072     if (label_list != NULL)
1073     {
1074         for (i = 0; i < m_label * n_label; i++)
1075         {
1076             /* A bug in scilab: if the mlist contains only the type, the C API returns m_label*n_label==2 !! */
1077             if (label_list[i] != NULL)
1078             {
1079                 if (strncmp(label_list[i], _pstLabelToFind, strlen(_pstLabelToFind)) == 0)
1080                 {
1081                     Pos = i;
1082
1083                     if (len_label)
1084                     {
1085                         FREE(len_label);
1086                         len_label = NULL;
1087                     }
1088                     freeArrayOfString(label_list, m_label * n_label);
1089
1090                     return Pos;
1091                 }
1092             }
1093         }
1094     }
1095
1096     if (len_label)
1097     {
1098         FREE(len_label);
1099         len_label = NULL;
1100     }
1101     freeArrayOfString(label_list, m_label * n_label);
1102
1103     return Pos;
1104 }
1105 /*--------------------------------------------------------------------------*/
1106 static int commonFindLabel(void* _pvCtx, int * _piAddress, char const * const _pstLabelToFind)
1107 {
1108     int Pos = -1, i = 0;
1109     int m_label = 0, n_label = 0;
1110     int * len_label = NULL;
1111     char ** label_list = NULL;
1112     SciErr _SciErr;
1113
1114     _SciErr.iErr = 0;
1115     _SciErr.iMsgCount = 0;
1116
1117     _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, NULL, NULL);
1118     len_label = (int *)MALLOC(m_label * n_label * sizeof(int));
1119     _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, len_label, NULL);
1120     label_list = (char **)MALLOC(m_label * n_label * sizeof(char *));
1121     for (i = 0; i < n_label * m_label; i++)
1122     {
1123         label_list[i] = (char *)MALLOC((len_label[i] + 1) * sizeof(char));
1124     }
1125     _SciErr = getMatrixOfStringInList(_pvCtx, _piAddress, 1, &m_label, &n_label, len_label, label_list);
1126
1127     if (label_list != NULL)
1128     {
1129         for (i = 0; i < m_label * n_label; i++)
1130         {
1131             /* A bug in scilab: if the mlist contains only the type, the C API returns m_label*n_label==2 !! */
1132             if (label_list[i] != NULL)
1133             {
1134                 if (strcmp(label_list[i], (char *)_pstLabelToFind) == 0)
1135                 {
1136                     Pos = i;
1137
1138                     if (len_label)
1139                     {
1140                         FREE(len_label);
1141                         len_label = NULL;
1142                     }
1143                     freeArrayOfString(label_list, m_label * n_label);
1144
1145                     return Pos;
1146                 }
1147             }
1148         }
1149     }
1150
1151     if (len_label)
1152     {
1153         FREE(len_label);
1154         len_label = NULL;
1155     }
1156     freeArrayOfString(label_list, m_label * n_label);
1157
1158     return Pos;
1159 }
1160 /*--------------------------------------------------------------------------*/
1161 // c versions of std::fill_n
1162 void int_fill_n(int* dst, size_t n, int v)
1163 {
1164     for (; n; --n, ++dst)
1165     {
1166         *dst = v;
1167     }
1168 }
1169 /*--------------------------------------------------------------------------*/
1170 void double_fill_n(double* dst, size_t n, int v)
1171 {
1172     for (; n; --n, ++dst)
1173     {
1174         *dst = v;
1175     }
1176 }
1177 /*--------------------------------------------------------------------------*/
1178