c8eb462e7b1918bd0ed72374bf75876a474c177c
[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         if (iType != 10)
214         {
215             Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), fname, pos);
216             return 0;
217         }
218
219         getAllocatedSingleString(_pvCtx, piAddr, &pstData);
220         if ((int)strlen(pstData) != 3)
221         {
222             freeAllocatedSingleString(pstData);
223             Scierror(999, _("%s: Wrong size for input argument #%d: String of %d characters expected.\n"), fname, pos, 3);
224             return 0;
225         }
226         *strf = pstData;
227     }
228     else if ((kopt = FindOpt(_pvCtx, "strf", opts)) >= 0)
229     {
230         char* pstData = NULL;
231         int iType = 0;
232         getVarType(_pvCtx, opts[kopt].piAddr, &iType);
233         if (iType != 10)
234         {
235             Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), fname, pos);
236             return 0;
237         }
238
239         getAllocatedSingleString(_pvCtx, opts[kopt].piAddr, &pstData);
240         if ((int)strlen(pstData) != 3)
241         {
242             freeAllocatedSingleString(pstData);
243             Scierror(999, _("%s: Wrong size for input argument #%d: String of %d characters expected.\n"), fname, kopt, 3);
244             return 0;
245         }
246         *strf = pstData;
247     }
248     else
249     {
250         /* def value can be changed */
251         reinitDefStrfN();
252         *strf = getDefStrf();
253     }
254     return 1;
255 }
256
257 /*--------------------------------------------------------------------------*/
258 int get_legend_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** legend)
259 {
260     int first_opt = FirstOpt(_pvCtx), kopt;
261
262     if (pos < first_opt)
263     {
264         int* piAddr = 0;
265         int iType = 0;
266         char* pstData = NULL;
267         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
268         getVarType(_pvCtx, piAddr, &iType);
269
270         if (iType)
271         {
272             getAllocatedSingleString(_pvCtx, piAddr, &pstData);
273             *legend = pstData;
274         }
275         else
276         {
277             *legend = getDefLegend();
278         }
279     }
280     else if ((kopt = FindOpt(_pvCtx, "leg", opts)) >= 0)
281     {
282         char* pstData = NULL;
283         getAllocatedSingleString(_pvCtx, opts[kopt].piAddr, &pstData);
284         *legend = pstData;
285     }
286     else
287     {
288         *legend = getDefLegend();
289     }
290     return 1;
291 }
292 /*--------------------------------------------------------------------------*/
293 /**
294  * retrieve the labels from the command line and store them into labels
295  */
296 int get_labels_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** labels)
297 {
298     int first_opt = FirstOpt(_pvCtx), kopt;
299
300     if (pos < first_opt)
301     {
302         int* piAddr = 0;
303         int iType = 0;
304         char* pstData = NULL;
305         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
306         getVarType(_pvCtx, piAddr, &iType);
307
308         if (iType)
309         {
310             getAllocatedSingleString(_pvCtx, piAddr, &pstData);
311             *labels = pstData;
312         }
313         else
314         {
315             /* jb silvy 03/2006 */
316             /* do not change the legend if one already exists */
317             if (sciGetLegendDefined(getOrCreateDefaultSubwin()))
318             {
319                 *labels = NULL;
320             }
321             else
322             {
323                 *labels = getDefLegend();
324             }
325         }
326     }
327     else if ((kopt = FindOpt(_pvCtx, "leg", opts)) >= 0)
328     {
329         char* pstData = NULL;
330         getAllocatedSingleString(_pvCtx, opts[kopt].piAddr, &pstData);
331         *labels = pstData;
332     }
333     else
334     {
335         /* jb silvy 03/2006 */
336         /* do not change the legend if one already exists */
337         if (sciGetLegendDefined(getOrCreateDefaultSubwin()))
338         {
339             *labels = NULL;
340         }
341         else
342         {
343             *labels = getDefLegend();
344         }
345     }
346     return 1;
347 }
348
349 /*--------------------------------------------------------------------------*/
350 int get_nax_arg(void* _pvCtx, int pos, rhs_opts opts[], int ** nax, BOOL * flagNax)
351 {
352     int i, m, n, first_opt = FirstOpt(_pvCtx), kopt;
353
354     if (pos < first_opt)
355     {
356         int* piAddr = 0;
357         int iType = 0;
358         int* piData = NULL;
359         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
360         getVarType(_pvCtx, piAddr, &iType);
361
362         if (iType)
363         {
364             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
365             if (n * m != 4)
366             {
367                 return 1;
368             }
369
370             for (i = 0 ; i < 4; ++i)
371             {
372                 // When i = 1 or 3 we talk about the number of ticks, this value can be -1 to say 'AutoTicks'
373                 piData[i] = Max(piData[i], -(i % 2));
374             }
375             *nax = piData;
376             *flagNax = TRUE;
377         }
378         else
379         {
380             *nax = getDefNax();
381             *flagNax = FALSE;
382         }
383     }
384     else if ((kopt = FindOpt(_pvCtx, "nax", opts)) >= 0)
385     {
386         int* piData = NULL;
387
388         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
389         if (m * n != 4)
390         {
391             return 1;
392         }
393
394         for (i = 0 ; i < 4; ++i)
395         {
396             // When i = 1 or 3 we talk about the number of ticks, this value can be -1 to say 'AutoTicks'
397             piData[i] = Max(piData[i], -(i % 2));
398         }
399         *nax = piData;
400         *flagNax = TRUE;
401     }
402     else
403     {
404         *nax = getDefNax();
405         *flagNax = FALSE;
406     }
407     return 1;
408 }
409
410
411 /*--------------------------------------------------------------------------*/
412 int get_zminmax_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], double ** zminmax)
413 {
414     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
415
416     if (pos < first_opt)
417     {
418         int* piAddr = 0;
419         int iType = 0;
420         double* pdblData = NULL;
421         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
422         getVarType(_pvCtx, piAddr, &iType);
423
424         if (iType)
425         {
426             getMatrixOfDouble(_pvCtx, piAddr, &m, &n, &pdblData);
427             if (m * n != 2)
428             {
429                 Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, pos, 2);
430                 return 0;
431             }
432             *zminmax = pdblData;
433         }
434         else
435         {
436             /** global value can be modified  **/
437             double zeros[2] = { 0.0, 0.0 };
438             setDefZminMax(zeros);
439             *zminmax = getDefZminMax();
440         }
441     }
442     else if ((kopt = FindOpt(_pvCtx, "zminmax", opts)) >= 0) /* named argument: rect=value */
443     {
444         double* pdblData = NULL;
445         getMatrixOfDouble(_pvCtx, opts[kopt].piAddr, &m, &n, &pdblData);
446         if (m * n != 2)
447         {
448             Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, kopt, 2);
449             return 0;
450         }
451         *zminmax = pdblData;
452     }
453     else
454     {
455         /** global value can be modified  **/
456         double zeros[2] = { 0.0, 0.0 };
457         setDefZminMax(zeros);
458         *zminmax = getDefZminMax();
459     }
460
461     return 1;
462 }
463
464 /*--------------------------------------------------------------------------*/
465 int get_colminmax_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], int ** colminmax)
466 {
467     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
468
469     if (pos < first_opt)
470     {
471         int* piAddr = 0;
472         int iType = 0;
473         int* piData = NULL;
474         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
475         getVarType(_pvCtx, piAddr, &iType);
476
477         if (iType)
478         {
479             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
480             if (m * n != 2)
481             {
482                 return 1;
483             }
484             *colminmax = piData;
485         }
486         else
487         {
488             /** global value can be modified  **/
489             int zeros[2] = { 0, 0 };
490             setDefColMinMax(zeros);
491             *colminmax = getDefColMinMax();
492         }
493     }
494     else if ((kopt = FindOpt(_pvCtx, "colminmax", opts)) >= 0)
495     {
496         int* piData = NULL;
497
498         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
499         if (m * n != 2)
500         {
501             return 1;
502         }
503         *colminmax = piData;
504     }
505     else
506     {
507         /** global value can be modified  **/
508         int zeros[2] = { 0, 0 };
509         setDefColMinMax(zeros);
510         *colminmax = getDefColMinMax();
511     }
512     return 1;
513 }
514
515 /*--------------------------------------------------------------------------*/
516 int get_colout_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], int ** colout)
517 {
518     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
519
520     if (pos < first_opt)
521     {
522         int* piAddr = 0;
523         int iType = 0;
524         int* piData = NULL;
525         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
526         getVarType(_pvCtx, piAddr, &iType);
527
528         if (iType)
529         {
530             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
531             if (m * n != 2)
532             {
533                 return 1;
534             }
535             *colout = piData;
536         }
537         else
538         {
539             /** global value can be modified  **/
540             int newDefCO[2] = { -1, -1 };
541             setDefColOut(newDefCO);
542             *colout = getDefColOut();
543         }
544     }
545     else if ((kopt = FindOpt(_pvCtx, "colout", opts)) >= 0)
546     {
547         int* piData = NULL;
548
549         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
550         if (m * n != 2)
551         {
552             return 1;
553         }
554         *colout = piData;
555     }
556     else
557     {
558         /** global value can be modified  **/
559         int newDefCO[2] = { -1, -1 };
560         setDefColOut(newDefCO);
561         *colout = getDefColOut();
562     }
563     return 1;
564 }
565 /*--------------------------------------------------------------------------*/
566 int get_with_mesh_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], BOOL * withMesh)
567 {
568     int first_opt = FirstOpt(_pvCtx), kopt;
569
570     if (pos < first_opt)
571     {
572         int* piAddr = 0;
573         int iType = 0;
574         int iData = 0;
575         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
576         getVarType(_pvCtx, piAddr, &iType);
577
578         if (iType)
579         {
580             getScalarBoolean(_pvCtx, piAddr, &iData);
581             *withMesh = iData;
582         }
583         else
584         {
585             /** global value can be modified  **/
586             setDefWithMesh(FALSE);
587             *withMesh = getDefWithMesh();
588         }
589     }
590     else if ((kopt = FindOpt(_pvCtx, "mesh", opts)) >= 0)
591     {
592         int iData = 0;
593
594         getScalarBoolean(_pvCtx, opts[kopt].piAddr, &iData);
595         *withMesh = iData;
596     }
597     else
598     {
599         /** global value can be modified  **/
600         setDefWithMesh(FALSE);
601         *withMesh = getDefWithMesh();
602     }
603     return 1;
604 }
605
606 /*--------------------------------------------------------------------------*/
607 int get_logflags_arg(void* _pvCtx, char *fname, int pos, rhs_opts opts[], char ** logFlags)
608 {
609     int kopt = 0;
610     int* piAddr = NULL;
611
612     int iLog = 0;
613     char* pstLog = NULL;
614     if (pos < FirstOpt(_pvCtx)) //input argument  */
615     {
616         //no idea of the real goal of this, how input var can have type == 0 Oo
617         if (getInputArgumentType(_pvCtx, pos) == 0)
618         {
619             *logFlags = getDefLogFlags();
620             return 1;
621         }
622
623         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
624     }
625     else if ((kopt = FindOpt(_pvCtx, "logflag", opts)) >= 0)//optional argument
626     {
627         piAddr = opts[kopt].piAddr;
628     }
629     else
630     {
631         //take default value
632         *logFlags = getDefLogFlags();
633         return 1;
634     }
635
636     getAllocatedSingleString(_pvCtx, piAddr, &pstLog);
637     iLog = (int)strlen(pstLog);
638     if (iLog != 2 && iLog != 3)
639     {
640         Scierror(999, "%s: Wrong size for input argument #%d: %d or %d expected\n", fname, pos, 2, 3);
641         return 0;
642     }
643
644     if (iLog == 2)
645     {
646         if ((pstLog[0] != 'l' && pstLog[0] != 'n') || (pstLog[1] != 'l' && pstLog[1] != 'n'))
647         {
648             //Err = pos;
649             SciError(116);
650             return 0;
651         }
652
653         logFlagsCpy[0] = 'g';
654         logFlagsCpy[1] = pstLog[0];
655         logFlagsCpy[2] = pstLog[1];
656         *logFlags = logFlagsCpy;
657     }
658     else //iLog == 3
659     {
660         if (((pstLog[0] != 'g') && (pstLog[0] != 'e') && (pstLog[0] != 'o')) ||
661                 (pstLog[1] != 'l' && pstLog[1] != 'n') ||
662                 (pstLog[2] != 'l' && pstLog[2] != 'n'))
663         {
664             //Err = pos;
665             SciError(116);
666             return 0;
667         }
668
669         *logFlags = pstLog;
670     }
671
672     return 1;
673 }
674 /*--------------------------------------------------------------------------*/
675 int get_optional_double_arg(void* _pvCtx, char* fname, int pos, char* name, double** value, int sz, rhs_opts opts[])
676 {
677     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
678
679     if (pos < first_opt)
680     {
681         int* piAddr = 0;
682         int iType = 0;
683         double* pdblData = NULL;
684         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
685         getVarType(_pvCtx, piAddr, &iType);
686
687         if (iType)
688         {
689             getMatrixOfDouble(_pvCtx, piAddr, &m, &n, &pdblData);
690             if (m * n != sz)
691             {
692                 return 1;
693             }
694             *value = pdblData;
695         }
696     }
697     else if ((kopt = FindOpt(_pvCtx, name, opts)) >= 0)
698     {
699         double* pdblData = NULL;
700         getMatrixOfDouble(_pvCtx, opts[kopt].piAddr, &m, &n, &pdblData);
701         if (m * n != sz)
702         {
703             Scierror(999, "%s: Wrong size for input argument #%d: %d expected\n", fname, kopt, 4);
704             return 0;
705         }
706
707         *value = pdblData;
708     }
709     return 1;
710 }
711 /*--------------------------------------------------------------------------*/
712 int get_optional_int_arg(void* _pvCtx, char* fname, int pos, char* name, int** value, int sz, rhs_opts opts[])
713 {
714     int m, n, first_opt = FirstOpt(_pvCtx), kopt;
715
716     if (pos < first_opt)
717     {
718         int* piAddr = 0;
719         int iType = 0;
720         int* piData = NULL;
721         getVarAddressFromPosition(_pvCtx, pos, &piAddr);
722         getVarType(_pvCtx, piAddr, &iType);
723
724         if (iType)
725         {
726             getMatrixOfDoubleAsInteger(_pvCtx, piAddr, &m, &n, &piData);
727             if (m * n != sz)
728             {
729                 return 1;
730             }
731             *value = piData;
732         }
733     }
734     else if ((kopt = FindOpt(_pvCtx, name, opts)) >= 0)
735     {
736         int* piData = NULL;
737
738         getMatrixOfDoubleAsInteger(_pvCtx, opts[kopt].piAddr, &m, &n, &piData);
739         if (m * n < 1)
740         {
741             return 1;
742         }
743         *value = piData;
744     }
745     return 1;
746 }
747 /*--------------------------------------------------------------------------*/