* Bug #13750 fixed - Calling ss2ss function with flag = 2 returned an error.
[scilab.git] / scilab / modules / graphics / src / c / GetCommandArg.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
5  * Copyright (C) 2009 - INRIA - Pierre Lando
6  * Copyright (C) 2011 - DIGITEO - Manuel Juliachs
7  *
8  * This file must be used under the terms of the CeCILL.
9  * This source file is licensed as described in the file COPYING, which
10  * you should have received as part of this distribution.  The terms
11  * are also available at
12  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
13  *
14  */
15
16 /*------------------------------------------------------------------------*/
17 /* file: GetCommandArg.h                                                  */
18 /* desc : tools to retrieve parameters within the command line for        */
19 /*        graphic routines.                                               */
20 /*------------------------------------------------------------------------*/
21
22 #include <string.h>
23 #include "GetCommandArg.h"
24 #include "GetProperty.h"
25 #include "DefaultCommandArg.h"
26 #include "CurrentSubwin.h"
27 #include "localization.h"
28 #include "Scierror.h"
29 #include "BuildObjects.h"
30 #include "api_scilab.h"
31 #include "sci_malloc.h"
32
33 static char logFlagsCpy[3] ; /* real logflags may use either this or the stack */
34
35 /*--------------------------------------------------------------------------*/
36 /* get_style */
37 /*--------------------------------------------------------------------------*/
38 int get_style_arg(void* _pvCtx, char *fname, int pos, int n1, rhs_opts opts[], int ** style)
39 {
40     int m = 0, n = 0, first_opt = FirstOpt(_pvCtx), kopt = 0, un = 1, ix = 0, i = 0, l1 = 0;
41
42     if ( pos < first_opt ) /* regular argument  */
43     {
44         int* piAddr = 0;
45         int iType = 0;
46         int* piData = NULL;
47         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
48         getVarType(_pvCtx, piAddr, &iType);
49
50         if (iType)
51         {
52             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
53             if (m * n < n1)
54             {
55                 Scierror(999, _("%s: Wrong size for input argument #%d: %d < %d expected.\n"), fname, pos, m * n, n1);
56                 return 0;
57             }
58
59             if ( n1 == 1 && m * n == 1 )
60             {
61                 *style = (int*)MALLOC(2 * sizeof(int));
62                 (*style)[0] = piData[0];
63                 (*style)[1] = 1;
64             }
65             else
66             {
67                 *style = (int*)MALLOC(m * n * sizeof(int));
68                 for (i = 0; i < m * n; i++)
69                 {
70                     (*style)[i] = piData[i];
71                 }
72             }
73         }
74         else /* zero type argument --> default value */
75         {
76             ix = Max(n1, 2);
77             *style = (int*)MALLOC(ix * sizeof(int));
78             (*style)[1] = 1;
79
80             for ( i = 0 ; i < n1 ; ++i )
81             {
82                 (*style)[i] = i + 1;
83             }
84         }
85     }
86     else if ((kopt = FindOpt(_pvCtx, "style", opts)) >= 0)
87     {
88         /* optinal argument: style=value */
89         int* piData = NULL;
90
91         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
92         if (m * n < n1)
93         {
94             Scierror(999, _("%s: Wrong size for input argument #%d: %d < %d expected.\n"), fname, kopt, m * n, n1);
95             return 0;
96         }
97
98         if (n1 == 1 && m * n == 1)
99         {
100             *style = (int*)MALLOC(2 * sizeof(int));
101             (*style)[0] = piData[0];
102             (*style)[1] = 1;
103         }
104         else
105         {
106             *style = (int*)MALLOC(m * n * sizeof(int));
107             for (i = 0; i < m * n; i++)
108             {
109                 (*style)[i] = piData[i];
110             }
111         }
112     }
113     else /* unspecified argument --> default value */
114     {
115         ix = Max(n1, 2);
116         *style = (int*)MALLOC(ix * sizeof(int));
117         (*style)[1] = 1;
118
119         for (i = 0 ; i < n1 ; ++i)
120         {
121             (*style)[i] = i + 1;
122         }
123     }
124
125     return 1;
126 }
127 /*--------------------------------------------------------------------------*/
128 /* get_rect */
129 /*--------------------------------------------------------------------------*/
130 int get_rect_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], double ** rect)
131 {
132     int m, n, first_opt = FirstOpt(_pvCtx), kopt, i;
133
134     if (pos < first_opt)
135     {
136         int* piAddr = 0;
137         int iType = 0;
138         double* pdblData = NULL;
139         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
140         getVarType(_pvCtx, piAddr, &iType);
141
142         if (iType)
143         {
144             getMatrixOfDouble(_pvCtx, piAddr, &m, &n, &pdblData);
145             if (m * n != 4)
146             {
147                 Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, pos, 4);
148                 return 0;
149             }
150
151             *rect = pdblData;
152
153             for (i = 0; i < 4; i++)
154             {
155                 if (finite((*rect)[i]) == 0)
156                 {
157                     Scierror(999, "%s: Wrong values (Nan or Inf) for input argument: %d finite values expected\n", fname, 4);
158                     return 0;
159                 }
160             }
161         }
162         else
163         {
164             /** global value can be modified  **/
165             double zeros[4] = { 0.0, 0.0, 0.0, 0.0 };
166             setDefRect(zeros);
167             *rect = getDefRect();
168         }
169     }
170     else if ((kopt = FindOpt(_pvCtx, "rect", opts)) >= 0) /* named argument: rect=value */
171     {
172         double* pdblData = NULL;
173         getMatrixOfDouble(_pvCtx, opts[kopt].piAddr, &m, &n, &pdblData);
174         if (m * n != 4)
175         {
176             Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, kopt, 4);
177             return 0;
178         }
179
180         *rect = pdblData;
181
182         for (i = 0; i < 4; i++)
183         {
184             if (finite((*rect)[i]) == 0)
185             {
186                 Scierror(999, "%s: Wrong values (Nan or Inf) for input argument: %d finite values expected\n", fname, 4);
187                 return 0;
188             }
189         }
190     }
191     else
192     {
193         /** global value can be modified  **/
194         double zeros[4] = { 0.0, 0.0, 0.0, 0.0 };
195         setDefRect(zeros);
196         *rect = getDefRect();
197     }
198
199     return 1;
200 }
201 /*--------------------------------------------------------------------------*/
202 int get_strf_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** strf)
203 {
204     int first_opt = FirstOpt(_pvCtx), kopt;
205
206     if (pos < first_opt)
207     {
208         int* piAddr = 0;
209         int iType = 0;
210         char* pstData = NULL;
211         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
212         getVarType(_pvCtx, piAddr, &iType);
213
214         if (iType)
215         {
216             getAllocatedSingleString(_pvCtx, piAddr, &pstData);
217             if ((int)strlen(pstData) != 3)
218             {
219                 freeAllocatedSingleString(pstData);
220                 Scierror(999, _("%s: Wrong size for input argument #%d: String of %d characters expected.\n"), fname, pos, 3);
221                 return 0;
222             }
223             *strf = pstData;
224         }
225         else
226         {
227             /* def value can be changed */
228             reinitDefStrf();
229             *strf = getDefStrf();
230         }
231     }
232     else if ((kopt = FindOpt(_pvCtx, "strf", opts)) >= 0)
233     {
234         char* pstData = NULL;
235         getAllocatedSingleString(_pvCtx, opts[kopt].piAddr, &pstData);
236         if ((int)strlen(pstData) != 3)
237         {
238             freeAllocatedSingleString(pstData);
239             Scierror(999, _("%s: Wrong size for input argument #%d: String of %d characters expected.\n"), fname, kopt, 3);
240             return 0;
241         }
242         *strf = pstData;
243     }
244     else
245     {
246         /* def value can be changed */
247         reinitDefStrfN();
248         *strf = getDefStrf();
249     }
250     return 1;
251 }
252
253 /*--------------------------------------------------------------------------*/
254 int get_legend_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** legend)
255 {
256     int first_opt = FirstOpt(_pvCtx), kopt;
257
258     if (pos < first_opt)
259     {
260         int* piAddr = 0;
261         int iType = 0;
262         char* pstData = NULL;
263         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
264         getVarType(_pvCtx, piAddr, &iType);
265
266         if (iType)
267         {
268             getAllocatedSingleString(_pvCtx, piAddr, &pstData);
269             *legend = pstData;
270         }
271         else
272         {
273             *legend = getDefLegend();
274         }
275     }
276     else if ((kopt = FindOpt(_pvCtx, "leg", opts)) >= 0)
277     {
278         char* pstData = NULL;
279         getAllocatedSingleString(_pvCtx, opts[kopt].piAddr, &pstData);
280         *legend = pstData;
281     }
282     else
283     {
284         *legend = getDefLegend();
285     }
286     return 1;
287 }
288 /*--------------------------------------------------------------------------*/
289 /**
290  * retrieve the labels from the command line and store them into labels
291  */
292 int get_labels_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** labels)
293 {
294     int first_opt = FirstOpt(_pvCtx), kopt;
295
296     if (pos < first_opt)
297     {
298         int* piAddr = 0;
299         int iType = 0;
300         char* pstData = NULL;
301         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
302         getVarType(_pvCtx, piAddr, &iType);
303
304         if (iType)
305         {
306             getAllocatedSingleString(_pvCtx, piAddr, &pstData);
307             *labels = pstData;
308         }
309         else
310         {
311             /* jb silvy 03/2006 */
312             /* do not change the legend if one already exists */
313             if (sciGetLegendDefined(getOrCreateDefaultSubwin()))
314             {
315                 *labels = NULL;
316             }
317             else
318             {
319                 *labels = getDefLegend();
320             }
321         }
322     }
323     else if ((kopt = FindOpt(_pvCtx, "leg", opts)) >= 0)
324     {
325         char* pstData = NULL;
326         getAllocatedSingleString(_pvCtx, opts[kopt].piAddr, &pstData);
327         *labels = pstData;
328     }
329     else
330     {
331         /* jb silvy 03/2006 */
332         /* do not change the legend if one already exists */
333         if (sciGetLegendDefined(getOrCreateDefaultSubwin()))
334         {
335             *labels = NULL;
336         }
337         else
338         {
339             *labels = getDefLegend();
340         }
341     }
342     return 1;
343 }
344
345 /*--------------------------------------------------------------------------*/
346 int get_nax_arg(void* _pvCtx, int pos, rhs_opts opts[], int ** nax, BOOL * flagNax)
347 {
348     int i, m, n, first_opt = FirstOpt(_pvCtx), kopt;
349
350     if (pos < first_opt)
351     {
352         int* piAddr = 0;
353         int iType = 0;
354         int* piData = NULL;
355         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
356         getVarType(_pvCtx, piAddr, &iType);
357
358         if (iType)
359         {
360             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
361             if (n * m != 4)
362             {
363                 return 1;
364             }
365
366             for (i = 0 ; i < 4; ++i)
367             {
368                 // When i = 1 or 3 we talk about the number of ticks, this value can be -1 to say 'AutoTicks'
369                 piData[i] = Max(piData[i], -(i % 2));
370             }
371             *nax = piData;
372             *flagNax = TRUE;
373         }
374         else
375         {
376             *nax = getDefNax();
377             *flagNax = FALSE;
378         }
379     }
380     else if ((kopt = FindOpt(_pvCtx, "nax", opts)) >= 0)
381     {
382         int* piData = NULL;
383
384         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
385         if (m * n != 4)
386         {
387             return 1;
388         }
389
390         for (i = 0 ; i < 4; ++i)
391         {
392             // When i = 1 or 3 we talk about the number of ticks, this value can be -1 to say 'AutoTicks'
393             piData[i] = Max(piData[i], -(i % 2));
394         }
395         *nax = piData;
396         *flagNax = TRUE;
397     }
398     else
399     {
400         *nax = getDefNax();
401         *flagNax = FALSE;
402     }
403     return 1;
404 }
405
406
407 /*--------------------------------------------------------------------------*/
408 int get_zminmax_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], double ** zminmax)
409 {
410     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
411
412     if (pos < first_opt)
413     {
414         int* piAddr = 0;
415         int iType = 0;
416         double* pdblData = NULL;
417         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
418         getVarType(_pvCtx, piAddr, &iType);
419
420         if (iType)
421         {
422             getMatrixOfDouble(_pvCtx, piAddr, &m, &n, &pdblData);
423             if (m * n != 2)
424             {
425                 Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, pos, 2);
426                 return 0;
427             }
428             *zminmax = pdblData;
429         }
430         else
431         {
432             /** global value can be modified  **/
433             double zeros[2] = { 0.0, 0.0 };
434             setDefZminMax(zeros);
435             *zminmax = getDefZminMax();
436         }
437     }
438     else if ((kopt = FindOpt(_pvCtx, "zminmax", opts)) >= 0) /* named argument: rect=value */
439     {
440         double* pdblData = NULL;
441         getMatrixOfDouble(_pvCtx, opts[kopt].piAddr, &m, &n, &pdblData);
442         if (m * n != 2)
443         {
444             Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, kopt, 2);
445             return 0;
446         }
447         *zminmax = pdblData;
448     }
449     else
450     {
451         /** global value can be modified  **/
452         double zeros[2] = { 0.0, 0.0 };
453         setDefZminMax(zeros);
454         *zminmax = getDefZminMax();
455     }
456
457     return 1;
458 }
459
460 /*--------------------------------------------------------------------------*/
461 int get_colminmax_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], int ** colminmax)
462 {
463     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
464
465     if (pos < first_opt)
466     {
467         int* piAddr = 0;
468         int iType = 0;
469         int* piData = NULL;
470         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
471         getVarType(_pvCtx, piAddr, &iType);
472
473         if (iType)
474         {
475             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
476             if (m * n != 2)
477             {
478                 return 1;
479             }
480             *colminmax = piData;
481         }
482         else
483         {
484             /** global value can be modified  **/
485             int zeros[2] = { 0, 0 };
486             setDefColMinMax(zeros);
487             *colminmax = getDefColMinMax();
488         }
489     }
490     else if ((kopt = FindOpt(_pvCtx, "colminmax", opts)) >= 0)
491     {
492         int* piData = NULL;
493
494         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
495         if (m * n != 2)
496         {
497             return 1;
498         }
499         *colminmax = piData;
500     }
501     else
502     {
503         /** global value can be modified  **/
504         int zeros[2] = { 0, 0 };
505         setDefColMinMax(zeros);
506         *colminmax = getDefColMinMax();
507     }
508     return 1;
509 }
510
511 /*--------------------------------------------------------------------------*/
512 int get_colout_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], int ** colout)
513 {
514     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
515
516     if (pos < first_opt)
517     {
518         int* piAddr = 0;
519         int iType = 0;
520         int* piData = NULL;
521         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
522         getVarType(_pvCtx, piAddr, &iType);
523
524         if (iType)
525         {
526             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
527             if (m * n != 2)
528             {
529                 return 1;
530             }
531             *colout = piData;
532         }
533         else
534         {
535             /** global value can be modified  **/
536             int newDefCO[2] = { -1, -1 };
537             setDefColOut(newDefCO);
538             *colout = getDefColOut();
539         }
540     }
541     else if ((kopt = FindOpt(_pvCtx, "colout", opts)) >= 0)
542     {
543         int* piData = NULL;
544
545         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
546         if (m * n != 2)
547         {
548             return 1;
549         }
550         *colout = piData;
551     }
552     else
553     {
554         /** global value can be modified  **/
555         int newDefCO[2] = { -1, -1 };
556         setDefColOut(newDefCO);
557         *colout = getDefColOut();
558     }
559     return 1;
560 }
561 /*--------------------------------------------------------------------------*/
562 int get_with_mesh_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], BOOL * withMesh)
563 {
564     int first_opt = FirstOpt(_pvCtx), kopt;
565
566     if (pos < first_opt)
567     {
568         int* piAddr = 0;
569         int iType = 0;
570         int iData = 0;
571         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
572         getVarType(_pvCtx, piAddr, &iType);
573
574         if (iType)
575         {
576             getScalarBoolean(_pvCtx, piAddr, &iData);
577             *withMesh = iData;
578         }
579         else
580         {
581             /** global value can be modified  **/
582             setDefWithMesh(FALSE);
583             *withMesh = getDefWithMesh();
584         }
585     }
586     else if ((kopt = FindOpt(_pvCtx, "mesh", opts)) >= 0)
587     {
588         int iData = 0;
589
590         getScalarBoolean(_pvCtx, opts[kopt].piAddr, &iData);
591         *withMesh = iData;
592     }
593     else
594     {
595         /** global value can be modified  **/
596         setDefWithMesh(FALSE);
597         *withMesh = getDefWithMesh();
598     }
599     return 1;
600 }
601
602 /*--------------------------------------------------------------------------*/
603 int get_logflags_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** logFlags)
604 {
605     int kopt = 0;
606     int* piAddr = NULL;
607
608     int iLog = 0;
609     char* pstLog = NULL;
610     if (pos < FirstOpt(_pvCtx)) //input argument  */
611     {
612         //no idea of the real goal of this, how input var can have type == 0 Oo
613         if (getInputArgumentType(_pvCtx, pos) == 0)
614         {
615             *logFlags = getDefLogFlags();
616             return 1;
617         }
618
619         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
620     }
621     else if ((kopt = FindOpt(_pvCtx, "logflag", opts)) >= 0)//optional argument
622     {
623         piAddr = opts[kopt].piAddr;
624     }
625     else
626     {
627         //take default value
628         *logFlags = getDefLogFlags();
629         return 1;
630     }
631
632     getAllocatedSingleString(_pvCtx, piAddr, &pstLog);
633     iLog = (int)strlen(pstLog);
634     if (iLog != 2 && iLog != 3)
635     {
636         Scierror(999, "%s: Wrong size for input argument #%d: %d or %d expected\n", fname, pos, 2, 3);
637         return 0;
638     }
639
640     if (iLog == 2)
641     {
642         if ((pstLog[0] != 'l' && pstLog[0] != 'n') || (pstLog[1] != 'l' && pstLog[1] != 'n'))
643         {
644             //Err = pos;
645             SciError(116);
646             return 0;
647         }
648
649         logFlagsCpy[0] = 'g';
650         logFlagsCpy[1] = pstLog[0];
651         logFlagsCpy[2] = pstLog[1];
652         *logFlags = logFlagsCpy;
653     }
654     else //iLog == 3
655     {
656         if (((pstLog[0] != 'g') && (pstLog[0] != 'e') && (pstLog[0] != 'o')) ||
657                 (pstLog[1] != 'l' && pstLog[1] != 'n') ||
658                 (pstLog[2] != 'l' && pstLog[2] != 'n'))
659         {
660             //Err = pos;
661             SciError(116);
662             return 0;
663         }
664
665         *logFlags = pstLog;
666     }
667
668     return 1;
669 }
670 /*--------------------------------------------------------------------------*/
671 int get_optional_double_arg(void* _pvCtx, char* fname, int pos, char* name, double** value, int sz, rhs_opts opts[])
672 {
673     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
674
675     if (pos < first_opt)
676     {
677         int* piAddr = 0;
678         int iType = 0;
679         double* pdblData = NULL;
680         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
681         getVarType(_pvCtx, piAddr, &iType);
682
683         if (iType)
684         {
685             getMatrixOfDouble(_pvCtx, piAddr, &m, &n, &pdblData);
686             if (m * n != sz)
687             {
688                 return 1;
689             }
690             *value = pdblData;
691         }
692     }
693     else if ((kopt = FindOpt(_pvCtx, name, opts)) >= 0)
694     {
695         double* pdblData = NULL;
696         getMatrixOfDouble(_pvCtx, opts[kopt].piAddr, &m, &n, &pdblData);
697         if (m * n != sz)
698         {
699             Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, kopt, 4);
700             return 0;
701         }
702
703         *value = pdblData;
704     }
705     return 1;
706 }
707 /*--------------------------------------------------------------------------*/
708 int get_optional_int_arg(void* _pvCtx, char* fname, int pos, char* name, int** value, int sz, rhs_opts opts[])
709 {
710     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
711
712     if (pos < first_opt)
713     {
714         int* piAddr = 0;
715         int iType = 0;
716         int* piData = NULL;
717         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
718         getVarType(_pvCtx, piAddr, &iType);
719
720         if (iType)
721         {
722             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
723             if (m * n != sz)
724             {
725                 return 1;
726             }
727             *value = piData;
728         }
729     }
730     else if ((kopt = FindOpt(_pvCtx, name, opts)) >= 0)
731     {
732         int* piData = NULL;
733
734         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
735         if (m * n < 1)
736         {
737             return 1;
738         }
739         *value = piData;
740     }
741     return 1;
742 }
743 /*--------------------------------------------------------------------------*/