Graphics: avoid crash due to scope problem
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_plot2d1.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  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 /*------------------------------------------------------------------------*/
15 /* file: sci_plot2d1.c                                                    */
16 /* desc : interface for plot2d1, plot2d2, plot2d3 and plot2d4 routines    */
17 /*------------------------------------------------------------------------*/
18
19 #include "gw_graphics.h"
20 #include "api_scilab.h"
21 #include "GetCommandArg.h"
22 #include "DefaultCommandArg.h"
23 #include "sciCall.h"
24 #include "localization.h"
25 #include "Scierror.h"
26 #include "MALLOC.h"
27
28 /*--------------------------------------------------------------------------*/
29 int sci_plot2d1_1 (char *fname, unsigned long fname_len)
30 {
31     return sci_plot2d1_G("plot2d1", 1, fname_len); /* NG */
32 }
33 /*--------------------------------------------------------------------------*/
34 int sci_plot2d1_2 (char *fname, unsigned long fname_len)
35 {
36     return sci_plot2d1_G("plot2d2", 2, fname_len); /* NG */
37 }
38 /*--------------------------------------------------------------------------*/
39 int sci_plot2d1_3 (char *fname, unsigned long fname_len)
40 {
41     return sci_plot2d1_G("plot2d3", 3, fname_len); /* NG */
42 }
43 /*--------------------------------------------------------------------------*/
44 int sci_plot2d1_4 (char *fname, unsigned long fname_len)
45 {
46     return sci_plot2d1_G("plot2d4", 4, fname_len); /* NG */
47 }
48 /*--------------------------------------------------------------------------*/
49 int sci_plot2d1_G(char * fname, int ptype, unsigned long fname_len)
50 {
51     SciErr sciErr;
52     int* piAddrl1 = NULL;
53     double* l1 = NULL;
54     int* piAddrl2 = NULL;
55     double* l2 = NULL;
56     double* lt = NULL;
57
58     int frame_def = 8;
59     int *frame = &frame_def;
60     int axes_def = 1;
61     int *axes = &axes_def;
62     int iskip = 0, test  = 0;
63     int m1 = 0, n1 = 0, m2 = 0, n2 = 0, i = 0, j = 0;
64
65     static rhs_opts opts[] =
66     {
67         { -1, "axesflag", -1, 0, 0, NULL},
68         { -1, "frameflag", -1, 0, 0, NULL},
69         { -1, "leg", -1, 0, 0, NULL},
70         { -1, "logflag", -1, 0, 0, NULL},
71         { -1, "nax", -1, 0, 0, NULL},
72         { -1, "rect", -1, 0, 0, NULL},
73         { -1, "strf", -1, 0, 0, NULL},
74         { -1, "style", -1, 0, 0, NULL},
75         { -1, NULL, -1, 0, 0, NULL}
76     };
77
78     int    * style    = NULL ;
79     double* rect     = NULL ;
80     int    * nax      = NULL ;
81     BOOL     flagNax  = FALSE;
82     char   * strf     = NULL ;
83     char strfl[4];
84     char   * legend   = NULL ;
85     char   * logFlags = NULL ;
86
87     if (nbInputArgument(pvApiCtx) <= 0)
88     {
89         /* lauch the default routines depending on the name of the calling function */
90         sci_demo(fname, fname_len);
91         return 0;
92     }
93     CheckInputArgument(pvApiCtx, 1, 9); /* to allow plot2dxx(y) */
94
95
96     iskip = 0;
97     if (getOptionals(pvApiCtx, fname, opts) == 0)
98     {
99         ReturnArguments(pvApiCtx);
100         return 0;
101     }
102
103     if (checkInputArgumentType(pvApiCtx, 1, sci_strings))
104     {
105         /* logflags */
106         GetLogflags(pvApiCtx, fname, 1, opts, &logFlags);
107         iskip = 1;
108     }
109
110     /* added to support plot2dxx([logflags],y) */
111     if (nbInputArgument(pvApiCtx) == 1 + iskip)
112     {
113         if (FirstOpt() <= nbInputArgument(pvApiCtx))
114         {
115             Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"), fname, 1, 3 + iskip);
116             return (0);
117         }
118
119         sciErr = getVarAddressFromPosition(pvApiCtx, 1 + iskip, &piAddrl2);
120         if (sciErr.iErr)
121         {
122             printError(&sciErr, 0);
123             return 1;
124         }
125
126         // Retrieve a matrix of double at position 1 + iskip.
127         sciErr = getMatrixOfDouble(pvApiCtx, piAddrl2, &m2, &n2, &l2);
128         if (sciErr.iErr)
129         {
130             printError(&sciErr, 0);
131             Scierror(202, _("%s: Wrong type for argument %d: A real expected.\n"), fname, 1 + iskip);
132             return 1;
133         }
134
135         sciErr = allocMatrixOfDouble(pvApiCtx, 2 + iskip, m2, n2, &l1);
136         if (sciErr.iErr)
137         {
138             printError(&sciErr, 0);
139             Scierror(999, _("%s: Memory allocation error.\n"), fname);
140             return 1;
141         }
142
143         if (m2 == 1 && n2 > 1)
144         {
145             m2 = n2;
146             n2 = 1;
147         }
148
149         m1 = m2;
150         n1 = n2;
151
152         for (i = 0; i < m2 ; ++i)
153         {
154             for (j = 0 ; j < n2 ;  ++j)
155             {
156                 *(l1 + i + m2 * j) = (double) i + 1;
157             }
158         }
159     }
160
161
162     if (nbInputArgument(pvApiCtx) >= 2 + iskip)
163     {
164         if (FirstOpt() < 3 + iskip)
165         {
166             Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"),
167                      fname, 1, 3 + iskip);
168             return (0);
169         }
170
171
172         /* x */
173         sciErr = getVarAddressFromPosition(pvApiCtx, 1 + iskip, &piAddrl1);
174         if (sciErr.iErr)
175         {
176             printError(&sciErr, 0);
177             return 1;
178         }
179
180         // Retrieve a matrix of double at position 1 + iskip.
181         sciErr = getMatrixOfDouble(pvApiCtx, piAddrl1, &m1, &n1, &l1);
182         if (sciErr.iErr)
183         {
184             printError(&sciErr, 0);
185             Scierror(202, _("%s: Wrong type for argument %d: A real expected.\n"), fname, 1 + iskip);
186             return 1;
187         }
188
189         if (iskip == 1)
190         {
191             if (logFlags[0] == 'e')
192             {
193                 m1 = 0;
194                 n1 = 0;
195             }
196         }
197
198         /* y */
199         sciErr = getVarAddressFromPosition(pvApiCtx, 2 + iskip, &piAddrl2);
200         if (sciErr.iErr)
201         {
202             printError(&sciErr, 0);
203             return 1;
204         }
205
206         // Retrieve a matrix of double at position 2 + iskip.
207         sciErr = getMatrixOfDouble(pvApiCtx, piAddrl2, &m2, &n2, &l2);
208         if (sciErr.iErr)
209         {
210             printError(&sciErr, 0);
211             Scierror(202, _("%s: Wrong type for argument %d: A real expected.\n"), fname, 2 + iskip);
212             return 1;
213         }
214
215         /* if (m2 * n2 == 0) { m1 = 0; n1 = 0;}  */
216
217         test = (m1 * n1 == 0) /* x = [] */
218                /* x,y vectors of same length */
219                || ((m1 == 1 || n1 == 1) && (m2 == 1 || n2 == 1) && (m1 * n1 == m2 * n2))
220                || ((m1 == m2) && (n1 == n2)) /* size(x) == size(y) */
221                /* x vector size(y)==[size(x),.] */
222                || ((m1 == 1 && n1 == m2) || (n1 == 1 && m1 == m2));
223
224         //CheckDimProp
225         if (!test)
226         {
227             Scierror(999, _("%s: Wrong size for input arguments: Incompatible sizes.\n"), fname);
228             return 1;
229         }
230
231
232         if (m1 * n1 == 0)
233         {
234             /* default x=1:n */
235             sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m2, n2, &lt);
236             if (sciErr.iErr)
237             {
238                 printError(&sciErr, 0);
239                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
240                 return 1;
241             }
242
243             if (m2 == 1 && n2 > 1)
244             {
245                 m2 = n2;
246                 n2 = 1;
247             }
248             for (i = 0; i < m2 ; ++i)
249             {
250                 for (j = 0 ; j < n2 ;  ++j)
251                 {
252                     *(lt + i + m2 * j) = (double) i + 1;
253                 }
254             }
255             m1 = m2;
256             n1 = n2;
257             l1 = lt;
258         }
259         else if ((m1 == 1 || n1 == 1) && (m2 != 1 && n2 != 1))
260         {
261             /* a single x vector for mutiple columns for y */
262             sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m2, n2, &lt);
263             if (sciErr.iErr)
264             {
265                 printError(&sciErr, 0);
266                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
267                 return 1;
268             }
269
270             for (i = 0; i < m2 ; ++i)
271             {
272                 for (j = 0 ; j < n2 ;  ++j)
273                 {
274                     *(lt + i + m2 * j) = l1[i];
275                 }
276             }
277             m1 = m2;
278             n1 = n2;
279             l1 = lt;
280         }
281         else if ((m1 == 1 && n1 == 1) && (n2 != 1))
282         {
283             /* a single y row vector  for a single x */
284             sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m1, n2, &lt);
285             if (sciErr.iErr)
286             {
287                 printError(&sciErr, 0);
288                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
289                 return 1;
290             }
291
292             for (j = 0 ; j < n2 ;  ++j)
293             {
294                 lt[j] = *l1;
295             }
296             n1 = n2;
297             l1 = lt;
298         }
299         else
300         {
301             if (m2 == 1 && n2 > 1)
302             {
303                 m2 = n2;
304                 n2 = 1;
305             }
306             if (m1 == 1 && n1 > 1)
307             {
308                 m1 = n1;
309                 n1 = 1;
310             }
311         }
312     }
313
314     sciGetStyle(pvApiCtx, fname, 3 + iskip, n1, opts, &style);
315     GetStrf(pvApiCtx, fname, 4 + iskip, opts, &strf);
316     GetLegend(pvApiCtx, fname, 5 + iskip, opts, &legend);
317     GetRect(pvApiCtx, fname, 6 + iskip, opts, &rect);
318     GetNax(pvApiCtx, 7 + iskip, opts, &nax, &flagNax);
319     if (iskip == 0)
320     {
321         GetLogflags(pvApiCtx, fname, 8, opts, &logFlags);
322     }
323
324     if (isDefStrf(strf))
325     {
326         strcpy(strfl, DEFSTRFN);
327
328         strf = strfl;
329         if (!isDefRect(rect))
330         {
331             strfl[1] = '7';
332         }
333         if (!isDefLegend(legend))
334         {
335             strfl[0] = '1';
336         }
337         GetOptionalIntArg(pvApiCtx, fname, 9, "frameflag", &frame, 1, opts);
338         if (frame != &frame_def)
339         {
340             strfl[1] = (char)(*frame + 48);
341         }
342         GetOptionalIntArg(pvApiCtx, fname, 9, "axesflag", &axes, 1, opts);
343         if (axes != &axes_def)
344         {
345             strfl[2] = (char)(*axes + 48);
346         }
347     }
348
349     if (ptype == 0)
350     {
351         ptype = 1;
352     }
353
354     Objplot2d (ptype, logFlags, (l1), (l2), &n1, &m1, style, strf, legend, rect, nax, flagNax);
355
356     // Allocated by sciGetStyle (get_style_arg function in GetCommandArg.c)
357     FREE(style);
358
359     AssignOutputVariable(pvApiCtx, 1) = 0;
360     ReturnArguments(pvApiCtx);
361     return 0;
362 }
363 /*--------------------------------------------------------------------------*/