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