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