Coverity: graphics module resource leaks fixed
[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  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 /*------------------------------------------------------------------------*/
18 /* file: sci_plot2d1.c                                                    */
19 /* desc : interface for plot2d2, plot2d3 and plot2d4 routines    */
20 /*------------------------------------------------------------------------*/
21 #include <string.h>
22 #include "gw_graphics.h"
23 #include "api_scilab.h"
24 #include "GetCommandArg.h"
25 #include "DefaultCommandArg.h"
26 #include "sciCall.h"
27 #include "localization.h"
28 #include "Scierror.h"
29 #include "sci_malloc.h"
30
31 /*--------------------------------------------------------------------------*/
32 int sci_plot2d1_2 (char *fname, void *pvApiCtx)
33 {
34     return sci_plot2d1_G("plot2d2", 2, pvApiCtx); /* NG */
35 }
36 /*--------------------------------------------------------------------------*/
37 int sci_plot2d1_3 (char *fname, void *pvApiCtx)
38 {
39     return sci_plot2d1_G("plot2d3", 3, pvApiCtx); /* NG */
40 }
41 /*--------------------------------------------------------------------------*/
42 int sci_plot2d1_4 (char *fname, void *pvApiCtx)
43 {
44     return sci_plot2d1_G("plot2d4", 4, pvApiCtx); /* NG */
45 }
46 /*--------------------------------------------------------------------------*/
47 int sci_plot2d1_G(char * fname, int ptype, void *pvApiCtx)
48 {
49     SciErr sciErr;
50     int* piAddrl1 = NULL;
51     double* l1 = NULL;
52     int* piAddrl2 = NULL;
53     double* l2 = NULL;
54     double* lt = NULL;
55
56     int frame_def = 8;
57     int *frame = &frame_def;
58     int axes_def = 1;
59     int *axes = &axes_def;
60     int iskip = 0, test  = 0;
61     int m1 = 0, n1 = 0, m2 = 0, n2 = 0, i = 0, j = 0;
62
63     static rhs_opts opts[] =
64     {
65         { -1, "axesflag", -1, 0, 0, NULL},
66         { -1, "frameflag", -1, 0, 0, NULL},
67         { -1, "leg", -1, 0, 0, NULL},
68         { -1, "logflag", -1, 0, 0, NULL},
69         { -1, "nax", -1, 0, 0, NULL},
70         { -1, "rect", -1, 0, 0, NULL},
71         { -1, "strf", -1, 0, 0, NULL},
72         { -1, "style", -1, 0, 0, NULL},
73         { -1, NULL, -1, 0, 0, NULL}
74     };
75
76     int    * style    = NULL ;
77     double* rect      = NULL ;
78     int    * nax      = NULL ;
79     BOOL     flagNax  = FALSE;
80     char   * strf     = NULL ;
81     char strfl[4];
82     BOOL freeStrf     = FALSE;
83     char   * legend   = NULL ;
84     BOOL freeLegend   = FALSE;
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, pvApiCtx);
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         if (get_logflags_arg(pvApiCtx, fname, 1, opts, &logFlags) == 0)
107         {
108             return 0;
109         }
110         iskip = 1;
111     }
112
113     /* added to support plot2dxx([logflags],y) */
114     if (nbInputArgument(pvApiCtx) == 1 + iskip)
115     {
116         if (FirstOpt(pvApiCtx) <= nbInputArgument(pvApiCtx))
117         {
118             Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"), fname, 1, 3 + iskip);
119             return (0);
120         }
121
122         sciErr = getVarAddressFromPosition(pvApiCtx, 1 + iskip, &piAddrl2);
123         if (sciErr.iErr)
124         {
125             printError(&sciErr, 0);
126             return 1;
127         }
128
129         // Retrieve a matrix of double at position 1 + iskip.
130         sciErr = getMatrixOfDouble(pvApiCtx, piAddrl2, &m2, &n2, &l2);
131         if (sciErr.iErr)
132         {
133             printError(&sciErr, 0);
134             Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 1 + iskip);
135             return 1;
136         }
137
138         sciErr = allocMatrixOfDouble(pvApiCtx, 2 + iskip, m2, n2, &l1);
139         if (sciErr.iErr)
140         {
141             printError(&sciErr, 0);
142             Scierror(999, _("%s: Memory allocation error.\n"), fname);
143             return 1;
144         }
145
146         if (m2 == 1 && n2 > 1)
147         {
148             m2 = n2;
149             n2 = 1;
150         }
151
152         m1 = m2;
153         n1 = n2;
154
155         for (i = 0; i < m2 ; ++i)
156         {
157             for (j = 0 ; j < n2 ;  ++j)
158             {
159                 *(l1 + i + m2 * j) = (double) i + 1;
160             }
161         }
162     }
163
164
165     if (nbInputArgument(pvApiCtx) >= 2 + iskip)
166     {
167         if (FirstOpt(pvApiCtx) < 3 + iskip)
168         {
169             Scierror(999, _("%s: Misplaced optional argument: #%d must be at position %d.\n"),
170                      fname, 1, 3 + iskip);
171             return (0);
172         }
173
174
175         /* x */
176         sciErr = getVarAddressFromPosition(pvApiCtx, 1 + iskip, &piAddrl1);
177         if (sciErr.iErr)
178         {
179             printError(&sciErr, 0);
180             return 1;
181         }
182
183         // Retrieve a matrix of double at position 1 + iskip.
184         sciErr = getMatrixOfDouble(pvApiCtx, piAddrl1, &m1, &n1, &l1);
185         if (sciErr.iErr)
186         {
187             printError(&sciErr, 0);
188             Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 1 + iskip);
189             return 1;
190         }
191
192         if (iskip == 1)
193         {
194             if (logFlags[0] == 'e')
195             {
196                 m1 = 0;
197                 n1 = 0;
198             }
199         }
200
201         /* y */
202         sciErr = getVarAddressFromPosition(pvApiCtx, 2 + iskip, &piAddrl2);
203         if (sciErr.iErr)
204         {
205             printError(&sciErr, 0);
206             return 1;
207         }
208
209         // Retrieve a matrix of double at position 2 + iskip.
210         sciErr = getMatrixOfDouble(pvApiCtx, piAddrl2, &m2, &n2, &l2);
211         if (sciErr.iErr)
212         {
213             printError(&sciErr, 0);
214             Scierror(202, _("%s: Wrong type for argument #%d: A real expected.\n"), fname, 2 + iskip);
215             return 1;
216         }
217
218         /* if (m2 * n2 == 0) { m1 = 0; n1 = 0;}  */
219
220         test = (m1 * n1 == 0) /* x = [] */
221                /* x,y vectors of same length */
222                || ((m1 == 1 || n1 == 1) && (m2 == 1 || n2 == 1) && (m1 * n1 == m2 * n2))
223                || ((m1 == m2) && (n1 == n2)) /* size(x) == size(y) */
224                /* x vector size(y)==[size(x),.] */
225                || ((m1 == 1 && n1 == m2) || (n1 == 1 && m1 == m2));
226
227         //CheckDimProp
228         if (!test)
229         {
230             Scierror(999, _("%s: Wrong size for input arguments: Incompatible sizes.\n"), fname);
231             return 1;
232         }
233
234
235         if (m1 * n1 == 0)
236         {
237             /* default x=1:n */
238             sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m2, n2, &lt);
239             if (sciErr.iErr)
240             {
241                 printError(&sciErr, 0);
242                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
243                 return 1;
244             }
245
246             if (m2 == 1 && n2 > 1)
247             {
248                 m2 = n2;
249                 n2 = 1;
250             }
251             for (i = 0; i < m2 ; ++i)
252             {
253                 for (j = 0 ; j < n2 ;  ++j)
254                 {
255                     *(lt + i + m2 * j) = (double) i + 1;
256                 }
257             }
258             m1 = m2;
259             n1 = n2;
260             l1 = lt;
261         }
262         else if ((m1 == 1 || n1 == 1) && (m2 != 1 && n2 != 1))
263         {
264             /* a single x vector for mutiple columns for y */
265             sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m2, n2, &lt);
266             if (sciErr.iErr)
267             {
268                 printError(&sciErr, 0);
269                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
270                 return 1;
271             }
272
273             for (i = 0; i < m2 ; ++i)
274             {
275                 for (j = 0 ; j < n2 ;  ++j)
276                 {
277                     *(lt + i + m2 * j) = l1[i];
278                 }
279             }
280             m1 = m2;
281             n1 = n2;
282             l1 = lt;
283         }
284         else if ((m1 == 1 && n1 == 1) && (n2 != 1))
285         {
286             /* a single y row vector  for a single x */
287             sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m1, n2, &lt);
288             if (sciErr.iErr)
289             {
290                 printError(&sciErr, 0);
291                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
292                 return 1;
293             }
294
295             for (j = 0 ; j < n2 ;  ++j)
296             {
297                 lt[j] = *l1;
298             }
299             n1 = n2;
300             l1 = lt;
301         }
302         else
303         {
304             if (m2 == 1 && n2 > 1)
305             {
306                 m2 = n2;
307                 n2 = 1;
308             }
309             if (m1 == 1 && n1 > 1)
310             {
311                 m1 = n1;
312                 n1 = 1;
313             }
314         }
315     }
316
317     if (get_style_arg(pvApiCtx, fname, 3 + iskip, n1, opts, &style) == 0)
318     {
319         return 0;
320     }
321     if (get_strf_arg(pvApiCtx, fname, 4 + iskip, opts, &strf) == 0)
322     {
323         FREE(style);
324         return 0;
325     }
326     freeStrf = isDefStrf(strf);
327     if (get_legend_arg(pvApiCtx, fname, 5 + iskip, opts, &legend) == 0)
328     {
329         if (freeStrf)
330         {
331             freeAllocatedSingleString(strf);
332         }
333         FREE(style);
334         return 0;
335     }
336     freeLegend = isDefLegend(legend);
337     if (get_rect_arg(pvApiCtx, fname, 6 + iskip, opts, &rect) == 0)
338     {
339         if (freeLegend)
340         {
341             freeAllocatedSingleString(legend);
342         }
343         if (freeStrf)
344         {
345             freeAllocatedSingleString(strf);
346         }
347         FREE(style);
348         return 0;
349     }
350     if (get_nax_arg(pvApiCtx, 7 + iskip, opts, &nax, &flagNax)==0)
351     {
352         if (freeLegend)
353         {
354             freeAllocatedSingleString(legend);
355         }
356         if (freeStrf)
357         {
358             freeAllocatedSingleString(strf);
359         }
360         FREE(style);
361         return 0;
362     }
363
364     if (iskip == 0)
365     {
366         if (get_logflags_arg(pvApiCtx, fname, 8, opts, &logFlags) == 0)
367         {
368             if (freeLegend)
369             {
370                 freeAllocatedSingleString(legend);
371             }
372             if (freeStrf)
373             {
374                 freeAllocatedSingleString(strf);
375             }
376             FREE(style);
377             return 0;
378         }
379     }
380
381     if (isDefStrf(strf))
382     {
383         strcpy(strfl, DEFSTRFN);
384
385         strf = strfl;
386         if (!isDefRect(rect))
387         {
388             strfl[1] = '7';
389         }
390         if (!isDefLegend(legend))
391         {
392             strfl[0] = '1';
393         }
394         if (get_optional_int_arg(pvApiCtx, fname, 9, "frameflag", &frame, 1, opts) == 0)
395         {
396             if (freeLegend)
397             {
398                 freeAllocatedSingleString(legend);
399             }
400             FREE(style);
401             return 0;
402         }
403         if (frame != &frame_def)
404         {
405             strfl[1] = (char)(*frame + 48);
406         }
407         if (get_optional_int_arg(pvApiCtx, fname, 9, "axesflag", &axes, 1, opts) == 0)
408         {
409             if (freeLegend)
410             {
411                 freeAllocatedSingleString(legend);
412             }
413             FREE(style);
414             return 0;
415         }
416         if (axes != &axes_def)
417         {
418             strfl[2] = (char)(*axes + 48);
419         }
420     }
421
422     if (ptype == 0)
423     {
424         ptype = 1;
425     }
426
427     Objplot2d (ptype, logFlags, (l1), (l2), &n1, &m1, style, strf, legend, rect, nax, flagNax);
428
429     // Allocated by sciGetStyle (get_style_arg function in GetCommandArg.c)
430     FREE(style);
431     if (freeStrf)
432     {
433         freeAllocatedSingleString(strf);
434     }
435     if (freeLegend)
436     {
437         freeAllocatedSingleString(legend);
438     }
439
440     AssignOutputVariable(pvApiCtx, 1) = 0;
441     ReturnArguments(pvApiCtx);
442     return 0;
443 }
444 /*--------------------------------------------------------------------------*/