Coverity: graphics module resource leaks fixed
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_drawaxis.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) 2011 - DIGITEO - Manuel Juliachs
6  * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7  *
8  * Copyright (C) 2012 - 2016 - Scilab Enterprises
9  *
10  * This file is hereby licensed under the terms of the GNU GPL v2.0,
11  * pursuant to article 5.3.4 of the CeCILL v.2.1.
12  * This file was originally licensed under the terms of the CeCILL v2.1,
13  * and continues to be available under such terms.
14  * For more information, see the COPYING file which you should have received
15  * along with this program.
16  *
17  */
18
19 /*------------------------------------------------------------------------*/
20 /* file: sci_drawaxis.c                                                   */
21 /* desc : interface for sci_drawaxis routine                              */
22 /*------------------------------------------------------------------------*/
23
24 #include "gw_graphics.h"
25 #include "api_scilab.h"
26 #include "GetProperty.h"
27 #include "sciCall.h"
28 #include "Scierror.h"
29 #include "localization.h"
30 #include "BuildObjects.h"
31
32 #include "getGraphicObjectProperty.h"
33 #include "graphicObjectProperties.h"
34 #include "CurrentSubwin.h"
35 #include "HandleManagement.h"
36
37 /*--------------------------------------------------------------------------*/
38 // get_optionals not yet managed
39 /*--------------------------------------------------------------------------*/
40 static int check_xy(char *fname, char dir, int mn, int xpos, int xm, int xn,
41                     double* pdblX, int ypos, int yRow, int yCol, double* pdblY, int *ntics);
42
43 /*--------------------------------------------------------------------------*/
44 int sci_drawaxis(char *fname, void* pvApiCtx)
45 {
46     /** XXXXX : un point en suspens c'est le "S" ou une adresse est
47      *  stockees ds un unsigned long : est ce sufisant ?
48      */
49     static rhs_opts opts[] =
50     {
51         { -1, "dir", -1, 0, 0, NULL},
52         { -1, "fontsize", -1, 0, 0, NULL},
53         { -1, "format_n", -1, 0, 0, NULL},
54         { -1, "seg", -1, 0, 0, NULL},
55         { -1, "sub_int", -1, 0, 0, NULL},
56         { -1, "textcolor", -1, 0, 0, NULL},
57         { -1, "tics", -1, 0, 0, NULL},
58         { -1, "ticscolor", -1, 0, 0, NULL},
59         { -1, "val", -1, 0, 0, NULL},
60         { -1, "x", -1, 0, 0, NULL},
61         { -1, "y", -1, 0, 0, NULL},
62         { -1, NULL, -1, 0, 0, NULL}
63     };
64
65     int iSubwinUID = 0;
66     int minrhs = -1, maxrhs = 0, minlhs = 0, maxlhs = 1, nopt = 0;
67     char dir = 'l', *format = NULL, tics = 'v', **val = NULL;
68     int fontsize = -1, sub_int = 2, seg_flag = 1, textcolor = -1, ticscolor = -1;
69     double *x = NULL, *y = NULL;
70     int nx = 0, ny = 0, ntics;
71     int nb_tics_labels = -1;
72     int iRhs = nbInputArgument(pvApiCtx);
73
74     nopt = NumOpt(pvApiCtx);
75
76     CheckInputArgument(pvApiCtx, minrhs, maxrhs + nopt);
77     CheckOutputArgument(pvApiCtx, minlhs, maxlhs);
78
79     if (getOptionals(pvApiCtx, fname, opts) == 0)
80     {
81         /* error */
82         return 0;
83     }
84
85     iSubwinUID = getOrCreateDefaultSubwin();
86
87     if (opts[0].iPos != -1)
88     {
89         char* pstDir = NULL;
90         //CheckLength
91         if (opts[0].iRows != 1 || opts[0].iCols != 1)
92         {
93             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[0].iPos, opts[0].iRows);
94             return 1;
95         }
96
97         if (getAllocatedSingleString(pvApiCtx, opts[0].piAddr, &pstDir))
98         {
99             return 1;
100         }
101         dir = pstDir[0];
102         freeAllocatedSingleString(pstDir);
103     }
104     if (opts[1].iPos != -1)
105     {
106         double dblSize = 0;
107         //CheckScalar
108         if (opts[1].iRows != 1 || opts[1].iCols != 1)
109         {
110             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[1].iPos);
111             return 1;
112         }
113
114         getScalarDouble(pvApiCtx, opts[1].piAddr, &dblSize);
115         fontsize = (int)dblSize;
116     }
117     if (opts[2].iPos != -1)
118     {
119         /* verfier ce que l'on recoit avec "" XXX */
120         if (getAllocatedSingleString(pvApiCtx, opts[2].piAddr, &format))
121         {
122             return 1;
123         }
124     }
125
126     if (opts[3].iPos != -1)
127     {
128         double dblSeq = 0;
129         //CheckScalar
130         if (opts[3].iRows != 1 || opts[3].iCols != 1)
131         {
132             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[3].iPos);
133             freeAllocatedSingleString(format);
134             return 1;
135         }
136
137
138         getScalarDouble(pvApiCtx, opts[3].piAddr, &dblSeq);
139         seg_flag = (int)dblSeq;
140     }
141
142     if (opts[4].iPos != -1)
143     {
144         double dblSub = 0;
145         //CheckScalar
146         if (opts[4].iRows != 1 || opts[4].iCols != 1)
147         {
148             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[4].iPos);
149             freeAllocatedSingleString(format);
150             return 1;
151         }
152
153         getScalarDouble(pvApiCtx, opts[4].piAddr, &dblSub);
154         sub_int = (int)dblSub;
155     }
156
157     if (opts[5].iPos != -1)
158     {
159         double dblColor = 0;
160         //CheckScalar
161         if (opts[5].iRows != 1 || opts[5].iCols != 1)
162         {
163             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[5].iPos);
164             freeAllocatedSingleString(format);
165             return 1;
166         }
167
168         getScalarDouble(pvApiCtx, opts[5].piAddr, &dblColor);
169         textcolor = (int)dblColor;
170     }
171
172     if (opts[6].iPos != -1)
173     {
174         char* pstTics = NULL;
175         //CheckLength
176         if (opts[6].iRows != 1 || opts[6].iCols != 1)
177         {
178             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[6].iPos, opts[6].iRows);
179             freeAllocatedSingleString(format);
180             return 1;
181         }
182
183         if (getAllocatedSingleString(pvApiCtx, opts[6].piAddr, &pstTics))
184         {
185             freeAllocatedSingleString(format);
186             return 1;
187         }
188         tics = pstTics[0];
189         freeAllocatedSingleString(pstTics);
190     }
191
192     if (opts[7].iPos != -1)
193     {
194         double dblColor = 0;
195         //CheckScalar
196         if (opts[7].iRows != 1 || opts[7].iCols != 1)
197         {
198             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[7].iPos);
199             freeAllocatedSingleString(format);
200             return 1;
201         }
202
203         getScalarDouble(pvApiCtx, opts[7].piAddr, &dblColor);
204         ticscolor = (int)dblColor;
205     }
206
207     if (opts[8].iPos != -1)
208     {
209         if (getAllocatedMatrixOfString(pvApiCtx, opts[8].piAddr, &opts[8].iRows, &opts[8].iCols, &val))
210         {
211             freeAllocatedSingleString(format);
212             return 1;
213         }
214     }
215
216     if (opts[9].iPos != -1)
217     {
218         getMatrixOfDouble(pvApiCtx, opts[9].piAddr, &opts[9].iRows, &opts[9].iCols, &x);
219         nx = opts[9].iRows * opts[9].iCols; /* F.Leray OK here opts[9].iRows and opts[9].iCols are integers. */
220     }
221     else
222     {
223         static double x_def[1];
224         double *bounds;
225         int iCurrentSubwinUID = getCurrentSubWin();
226
227         getGraphicObjectProperty(iCurrentSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&bounds);
228         nx = 1;
229         x = x_def;
230         if (dir == 'l')
231         {
232             x_def[0] = bounds[0];    /* xMin */
233         }
234         else if (dir == 'r')
235         {
236             x_def[0] = bounds[1];    /* xMax */
237         }
238     }
239
240     if (opts[10].iPos != -1)
241     {
242         getMatrixOfDouble(pvApiCtx, opts[10].piAddr, &opts[10].iRows, &opts[10].iCols, &y);
243         ny = opts[10].iRows * opts[10].iCols;
244     }
245     else
246     {
247         static double y_def[1];
248         double *bounds;
249         int iCurrentSubwinUID = getCurrentSubWin();
250
251         getGraphicObjectProperty(iCurrentSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&bounds);
252         ny = 1;
253         y = y_def;
254         if (dir == 'd')
255         {
256             y_def[0] = bounds[2];    /* yMin */
257         }
258         else if (dir == 'u')
259         {
260             y_def[0] = bounds[3];    /* yMax */
261         }
262     }
263
264     /* compatibility test */
265     switch (tics)
266     {
267         case 'r':
268             if (check_xy(fname, dir, 3, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
269                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
270             {
271                 ReturnArguments(pvApiCtx);
272                 freeAllocatedSingleString(format);
273                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
274                 return 0;
275             }
276             break;
277         case 'i':
278             if (check_xy(fname, dir, 4, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
279                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
280             {
281                 ReturnArguments(pvApiCtx);
282                 freeAllocatedSingleString(format);
283                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
284                 return 0;
285             }
286             break;
287         case 'v':
288             if (check_xy(fname, dir, -1, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
289                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
290             {
291                 ReturnArguments(pvApiCtx);
292                 freeAllocatedSingleString(format);
293                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
294                 return 0;
295             }
296             break;
297         default:
298             Scierror(999, _("%: Wrong value for %s '%c': '%s', '%s' and '%s' expected.\n"), fname, "tics", dir, "r", "v", "i");
299             freeAllocatedSingleString(format);
300             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
301             return 0;
302     }
303
304     if (val != NULL)
305     {
306         //CheckLength
307         if (opts[8].iRows * opts[8].iCols != ntics)
308         {
309             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[8].iPos, opts[8].iRows * opts[8].iCols);
310             freeAllocatedSingleString(format);
311             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
312             return 1;
313         }
314
315         nb_tics_labels = opts[8].iRows * opts[8].iCols;
316     }
317
318     Objdrawaxis(dir, tics, x, &nx, y, &ny, val, sub_int, format, fontsize, textcolor, ticscolor, 'n', seg_flag, nb_tics_labels);
319
320     freeAllocatedSingleString(format);
321     if (val != NULL)
322     {
323         freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
324     }
325     createScalarHandle(pvApiCtx, iRhs + 1, getHandle(getCurrentObject()));
326     AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
327     ReturnArguments(pvApiCtx);
328     return 0;
329 }
330
331 /*--------------------------------------------------------------------------*/
332 static int check_xy(char *fname, char dir, int mn, int xpos,
333                     int xm, int xn, double* pdblX,
334                     int ypos, int yRow, int yCol, double* pdblY,
335                     int *ntics)
336 {
337     switch (dir)
338     {
339         case 'l':
340         case 'r':
341             /* x must be scalar */
342             if (xpos != -1)
343                 //CheckScalar
344                 if (xm != 1 || xn != 1)
345                 {
346                     Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, xpos);
347                     return 1;
348                 }
349
350             /* y must be of size mn */
351             if (mn != -1)
352                 //CheckDims
353                 if (yRow != 1 || yCol != mn)
354                 {
355                     Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, ypos, 1, mn);
356                     return 1;
357                 }
358
359             switch (mn)
360             {
361                 case 3:
362                     *ntics = (int)pdblY[2] + 1;
363                     break;
364                 case 4:
365                     *ntics = (int)pdblY[3] + 1;
366                     break;
367                 case -1:
368                     *ntics = yRow * yCol;
369                     break;
370             }
371             break;
372         case 'u':
373         case 'd':
374             /* y must be scalar */
375             if (ypos != -1)
376                 //CheckScalar
377                 if (yRow != 1 || yCol != 1)
378                 {
379                     Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, ypos);
380                     return 1;
381                 }
382
383             /* x must be of size mn */
384             if (mn != -1)
385                 //CheckDims
386                 if (xm != 1 || xn != mn)
387                 {
388                     Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, xpos, 1, mn);
389                     return 1;
390                 }
391
392             switch (mn)
393             {
394                 case 3:
395                     *ntics = (int)pdblX[2] + 1;
396                     break;
397                 case 4:
398                     *ntics = (int)pdblX[3] + 1;
399                     break;
400                 case -1:
401                     *ntics = xm * xn;
402                     break;
403             }
404             break;
405         default:
406             Scierror(999, "%s: Wrong value for %s '%c': '%s','%s','%s' and '%s' expected.\n", fname, "dir", dir, "u", "d", "r", "l");
407             return 0;
408     }
409     return 1;
410 }
411
412 /*--------------------------------------------------------------------------*/