Coverity: fftw module memory errors fixed
[scilab.git] / scilab / modules / fftw / sci_gateway / c / sci_fftw_flags.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2006/2007 - INRIA - Alan LAYEC
4 * Copyright (C) 2007 - INRIA - Allan CORNET
5 * Copyright (C) 2012 - DIGITEO - Allan CORNET
6 * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
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 #include <string.h>
20 #include "api_scilab.h"
21 #include "fftw_utilities.h"
22 #include "sci_malloc.h"
23 #include "gw_fftw.h"
24 #include "localization.h"
25 #include "freeArrayOfString.h"
26 #include "Scierror.h"
27 #include "os_string.h"
28 /*--------------------------------------------------------------------------*/
29 /* fftw_flags function.
30 *
31 * Scilab Syntax :
32 *   -->[a,b]=fftw_flags();
33 * or
34 *   -->[a,b]=fftw_flags(S);
35 *
36 *  a is an int scalar. (the int value of
37 *                            the flag parameter of fftw)
38 *  b is a string matrix.(the string values of
39 *                             the flag parameter of fftw)
40 *  S is a string matrix or an int or a double scalar
41 *  given the value(s) of the fftw flag parameter.
42 *
43 *  This function gives and set the flag parameter of fftw
44 *  when creating a new plan.
45 *  This should be done before calling fftw function.
46 *  (default is FFTW_ESTIMATE)
47 */
48 /*--------------------------------------------------------------------------*/
49 int sci_fftw_flags(char *fname,  void* pvApiCtx)
50 {
51     /* declaration of variables to store scilab parameters address */
52     static int m1 = 0, n1 = 0;
53
54     char **Str1 = NULL;
55     char **Str3 = NULL;
56
57     unsigned int uiVar1 = 0;
58     int* piDataOut = NULL;
59     int* piAddr1 = NULL;
60     int* piLen = NULL;
61     int iType = 0;
62
63     /* please update me ! */
64     static int nb_flag = 22;
65     static char *Str[] =
66     {
67         /* documented flags */
68         "FFTW_MEASURE",
69         "FFTW_DESTROY_INPUT",
70         "FFTW_UNALIGNED",
71         "FFTW_CONSERVE_MEMORY",
72         "FFTW_EXHAUSTIVE",
73         "FFTW_PRESERVE_INPUT",
74         "FFTW_PATIENT",
75         "FFTW_ESTIMATE",
76
77         /* undocumented beyond-guru flags */
78         "FFTW_ESTIMATE_PATIENT",
79         "FFTW_BELIEVE_PCOST",
80         "FFTW_NO_DFT_R2HC",
81         "FFTW_NO_NONTHREADED",
82         "FFTW_NO_BUFFERING",
83         "FFTW_NO_INDIRECT_OP",
84         "FFTW_ALLOW_LARGE_GENERIC",
85         "FFTW_NO_RANK_SPLITS",
86         "FFTW_NO_VRANK_SPLITS",
87         "FFTW_NO_VRECURSE",
88         "FFTW_NO_SIMD",
89         "FFTW_NO_SLOW",
90         "FFTW_NO_FIXED_RADIX_LARGE_N",
91         "FFTW_ALLOW_PRUNING"
92     };
93
94     static unsigned flagt[] =
95     {
96         /* documented flags */
97         FFTW_MEASURE,
98         FFTW_DESTROY_INPUT,
99         FFTW_UNALIGNED,
100         FFTW_CONSERVE_MEMORY,
101         FFTW_EXHAUSTIVE,
102         FFTW_PRESERVE_INPUT,
103         FFTW_PATIENT,
104         FFTW_ESTIMATE,
105
106         /* undocumented beyond-guru flags */
107         FFTW_ESTIMATE_PATIENT,
108         FFTW_BELIEVE_PCOST,
109         FFTW_NO_DFT_R2HC,
110         FFTW_NO_NONTHREADED,
111         FFTW_NO_BUFFERING,
112         FFTW_NO_INDIRECT_OP,
113         FFTW_ALLOW_LARGE_GENERIC,
114         FFTW_NO_RANK_SPLITS,
115         FFTW_NO_VRANK_SPLITS,
116         FFTW_NO_VRECURSE,
117         FFTW_NO_SIMD,
118         FFTW_NO_SLOW,
119         FFTW_NO_FIXED_RADIX_LARGE_N,
120         FFTW_ALLOW_PRUNING
121     };
122
123     unsigned flagv = 0;
124
125     int i = 0, j = 0;
126
127     SciErr sciErr;
128     CheckInputArgument(pvApiCtx, 0, 1);
129
130     if (nbInputArgument(pvApiCtx) == 0)
131     {
132         // nothing
133     }
134     else
135     {
136         //get variable address of the input argument
137         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
138         if (sciErr.iErr)
139         {
140             printError(&sciErr, 0);
141             return 1;
142         }
143
144         getVarType(pvApiCtx, piAddr1, &iType);
145         switch (iType)
146         {
147             case sci_ints:
148             {
149                 /* int */
150                 int iPrecision = 0;
151                 int* pi32Data = NULL;
152                 unsigned int* pui32Data = NULL;
153
154                 getMatrixOfIntegerPrecision(pvApiCtx, piAddr1, &iPrecision);
155                 if (iPrecision != SCI_INT32 && iPrecision != SCI_UINT32)
156                 {
157                     Scierror(999, _("%s: Wrong type for input argument #%d: A int32 expected.\n"), fname, 1);
158                     return 1;
159                 }
160
161                 if (iPrecision == SCI_INT32)
162                 {
163                     sciErr = getMatrixOfInteger32(pvApiCtx, piAddr1, &m1, &n1, &pi32Data);
164                     uiVar1 = (unsigned int)pi32Data[0];
165                 }
166                 else
167                 {
168                     sciErr = getMatrixOfUnsignedInteger32(pvApiCtx, piAddr1, &m1, &n1, &pui32Data);
169                     uiVar1 = pui32Data[0];
170                 }
171
172                 if (sciErr.iErr)
173                 {
174                     Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
175                     printError(&sciErr, 0);
176                     return 1;
177                 }
178                 break;
179             }
180             case sci_matrix:
181             {
182                 /* double */
183                 double* pdblData = NULL;
184                 sciErr = getMatrixOfDouble(pvApiCtx, piAddr1, &m1, &n1, &pdblData);
185                 if (sciErr.iErr)
186                 {
187                     Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
188                     printError(&sciErr, 0);
189                     return 1;
190                 }
191
192                 uiVar1 = (unsigned int)pdblData[0];
193                 break;
194             }
195             case sci_strings:
196             {
197                 /* string */
198                 //fisrt call to retrieve dimensions
199                 sciErr = getMatrixOfString(pvApiCtx, piAddr1, &m1, &n1, NULL, NULL);
200                 if (sciErr.iErr)
201                 {
202                     printError(&sciErr, 0);
203                     return 1;
204                 }
205
206                 piLen = (int*)MALLOC(sizeof(int) * m1 * n1);
207
208                 //second call to retrieve length of each string
209                 sciErr = getMatrixOfString(pvApiCtx, piAddr1, &m1, &n1, piLen, NULL);
210                 if (sciErr.iErr)
211                 {
212                     free(piLen);
213                     printError(&sciErr, 0);
214                     return 1;
215                 }
216
217                 Str1 = (char**)MALLOC(sizeof(char*) * m1 * n1);
218                 for (i = 0 ; i < m1 * n1 ; i++)
219                 {
220                     Str1[i] = (char*)MALLOC(sizeof(char) * (piLen[i] + 1));//+ 1 for null termination
221                 }
222
223                 //third call to retrieve data
224                 sciErr = getMatrixOfString(pvApiCtx, piAddr1, &m1, &n1, piLen, Str1);
225                 if (sciErr.iErr)
226                 {
227                     free(piLen);
228                     freeArrayOfString(Str1, m1 * n1);
229                     printError(&sciErr, 0);
230                     return 1;
231                 }
232
233                 for (j = 0; j < m1 * n1; j++)
234                 {
235                     for (i = 0; i < nb_flag; i++)
236                     {
237                         if (strcmp(Str1[j], Str[i]) == 0)
238                         {
239                             break;
240                         }
241                     }
242
243                     if (i == nb_flag)
244                     {
245                         free(piLen);
246                         freeArrayOfString(Str1, m1 * n1);
247                         Scierror(999, _("%s: Wrong values for input argument #%d: FFTW flag expected.\n"), fname, 1);
248                         return 0;
249                     }
250                     else
251                     {
252                         if (i > 0)
253                         {
254                             flagv = ( flagv | (1U << (i - 1)) );
255                         }
256                     }
257                 }
258
259                 uiVar1 = (unsigned int)flagv;
260                 free(piLen);
261                 freeArrayOfString(Str1, m1 * n1);
262                 m1 = 1;
263                 n1 = 1;
264                 break;
265             }
266             default:
267                 Scierror(53, _("%s: Wrong type for input argument #%d.\n"), fname, 1);
268                 return 1;
269         }
270
271         if (m1 != 1 || n1 != 1)
272         {
273             Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, 1, 1, 1);
274             return 1;
275         }
276
277         setCurrentFftwFlags(uiVar1);
278     }
279
280     /* return value of Sci_Plan.flags in position 2 */
281     sciErr = allocMatrixOfInteger32(pvApiCtx, nbInputArgument(pvApiCtx) + 2, 1, 1, &piDataOut);
282     if (sciErr.iErr)
283     {
284         printError(&sciErr, 0);
285         Scierror(999, _("%s: No more memory.\n"), fname);
286         return 1;
287     }
288
289     piDataOut[0] = (int) getCurrentFftwFlags();
290
291     /*Test for only FFTW_MEASURE*/
292     if (getCurrentFftwFlags() == 0)
293     {
294         j = 1;
295         if ((Str3 = (char **)MALLOC(sizeof(char *))) == NULL)
296         {
297             Scierror(999, _("%s: No more memory.\n"), fname);
298             return 1;
299         }
300
301         Str3[0] = os_strdup(Str[0]);
302         if (Str3[0] == NULL)
303         {
304             Scierror(999, _("%s: No more memory.\n"), fname);
305             FREE(Str3);
306             return 1;
307         }
308     }
309     else
310     {
311         j = 0;
312         for (i = 1; i < nb_flag; i++)
313         {
314             if ((getCurrentFftwFlags() & flagt[i]) == flagt[i])
315             {
316                 j++;
317                 if (Str3)
318                 {
319                     Str3 = (char **)REALLOC(Str3, sizeof(char *) * j);
320                 }
321                 else
322                 {
323                     Str3 = (char **)MALLOC(sizeof(char *) * j);
324                 }
325
326                 if (Str3 == NULL)
327                 {
328                     Scierror(999, _("%s: No more memory.\n"), fname);
329                     return 1;
330                 }
331
332                 Str3[j - 1] = os_strdup(Str[i]);
333                 if (Str3[j - 1] == NULL)
334                 {
335                     Scierror(999, _("%s: No more memory.\n"), fname);
336                     freeArrayOfString(Str3, j);
337                     return 1;
338                 }
339             }
340         }
341     }
342
343     if (Str3 == NULL)
344     {
345         Scierror(999, _("%s: Failed to generate the planner name.\n"), fname);
346         return 1;
347     }
348
349     /* Create the string matrix as return of the function */
350     sciErr = createMatrixOfString(pvApiCtx, nbInputArgument(pvApiCtx) + 3, j, 1, Str3);
351     freeArrayOfString(Str3, j); // Data have been copied into Scilab memory
352
353     if (sciErr.iErr)
354     {
355         printError(&sciErr, 0);
356         return 1;
357     }
358
359     AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 2;
360     AssignOutputVariable(pvApiCtx, 2) = nbInputArgument(pvApiCtx) + 3;
361     ReturnArguments(pvApiCtx);
362     return 0;
363 }
364 /*--------------------------------------------------------------------------*/