Coverity: Matio module memory leaks fixed
[scilab.git] / scilab / modules / matio / sci_gateway / c / sci_matfile_listvar.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent COUVERT
4  * Copyright (C) 2010 - DIGITEO - Yann COLLETTE
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 #include "api_scilab.h"
18 #include "matfile_manager.h"
19 #include "gw_matio.h"
20 #include "localization.h"
21 #include "Scierror.h"
22 #include "sci_malloc.h"
23 #include "freeArrayOfString.h"
24 #include "os_string.h"
25
26 int sci_matfile_listvar(char *fname, void* pvApiCtx)
27 {
28     int nbRow = 0, nbCol = 0;
29     mat_t *matfile = NULL;
30     matvar_t *matvar = NULL;
31     int fileIndex = 0;
32     char **varnames = NULL;
33     double *varclasses = NULL;
34     double *vartypes = NULL;
35     int nbvar = 0, var_type;
36     int * fd_addr = NULL;
37     double tmp_dbl;
38     SciErr sciErr;
39     int iErr = 0;
40
41     CheckRhs(1, 1);
42     CheckLhs(1, 3);
43
44     /* First Rhs is the index of the file to read */
45
46     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &fd_addr);
47     if (sciErr.iErr)
48     {
49         printError(&sciErr, 0);
50         return 0;
51     }
52     sciErr = getVarType(pvApiCtx, fd_addr, &var_type);
53     if (sciErr.iErr)
54     {
55         printError(&sciErr, 0);
56         return 0;
57     }
58
59     if (var_type == sci_matrix)
60     {
61         getScalarDouble(pvApiCtx, fd_addr, &tmp_dbl);
62         if (!isScalar(pvApiCtx, fd_addr))
63         {
64             Scierror(999, _("%s: Wrong size for first input argument: Single double expected.\n"), fname);
65             return FALSE;
66         }
67         fileIndex = (int)tmp_dbl;
68     }
69     else
70     {
71         Scierror(999, _("%s: Wrong type for first input argument: Double expected.\n"), fname);
72         return FALSE;
73     }
74
75     /* Gets the corresponding matfile */
76     matfile_manager(MATFILEMANAGER_GETFILE, &fileIndex, &matfile);
77
78     if (matfile == NULL)
79     {
80         Scierror(999, _("%s: Invalid file identifier.\n"), fname);
81         return FALSE;
82     }
83
84     /* Back to the beginning of the file */
85     if (Mat_Rewind(matfile) != 0)
86     {
87         Scierror(999, _("%s: Could not rewind the file %s.\n"), "matfile_listvar", Mat_GetFilename(matfile));
88         return FALSE;
89     }
90
91     matvar = Mat_VarReadNext(matfile);
92     while (matvar != NULL && matvar->name != NULL)
93     {
94         nbvar++;
95         varnames = (char**) REALLOC(varnames, nbvar * sizeof(char*));
96         if (varnames == NULL)
97         {
98             Scierror(999, _("%s: No more memory.\n"), "matfile_listvar");
99             FREE(varclasses);
100             FREE(vartypes);
101             return FALSE;
102         }
103         varnames[nbvar - 1] = os_strdup(matvar->name);
104         varclasses = (double*) REALLOC(varclasses, nbvar * sizeof(double));
105         if (varclasses  == NULL)
106         {
107             Scierror(999, _("%s: No more memory.\n"), "matfile_listvar");
108             FREE(vartypes);
109             FREE(varnames);
110             return FALSE;
111         }
112         varclasses[nbvar - 1] = (double) matvar->class_type;
113         vartypes = (double*) REALLOC(vartypes, nbvar * sizeof(double));
114         if (vartypes == NULL)
115         {
116             Scierror(999, _("%s: No more memory.\n"), "matfile_listvar");
117             FREE(varnames);
118             FREE(varclasses);
119             return FALSE;
120         }
121         vartypes[nbvar - 1] = (double) matvar->data_type;
122
123         Mat_VarFree(matvar);
124         matvar = Mat_VarReadNext(matfile);
125     }
126
127     Mat_VarFree(matvar);
128
129     /* Return the variable names list */
130     if (nbvar == 0)
131     {
132         /* No variables found in MatFile */
133
134         /* Return the empty names */
135         iErr = createEmptyMatrix(pvApiCtx, Rhs + 1);
136         if (iErr)
137         {
138             Scierror(999, _("%s: Memory allocation error.\n"), fname);
139             return 0;
140         }
141         LhsVar(1) = Rhs + 1;
142
143         /* Return the empty classes if asked */
144         if (Lhs >= 2)
145         {
146             iErr = createEmptyMatrix(pvApiCtx, Rhs + 2);
147             if (iErr)
148             {
149                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
150                 return 0;
151             }
152             LhsVar(2) = Rhs + 2;
153         }
154
155         /* Return the empty types if asked */
156         if (Lhs >= 3)
157         {
158             iErr = createEmptyMatrix(pvApiCtx, Rhs + 3);
159             if (iErr)
160             {
161                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
162                 return 0;
163             }
164             LhsVar(3) = Rhs + 3;
165         }
166     }
167     else
168     {
169         nbRow = nbvar;
170         nbCol = 1;
171         sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, nbRow, nbCol, varnames);
172         if (sciErr.iErr)
173         {
174             printError(&sciErr, 0);
175             return 0;
176         }
177         LhsVar(1) = Rhs + 1;
178
179         /* Return the variable classes */
180         if (Lhs >= 2)
181         {
182             sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 2, nbRow, nbCol, varclasses);
183             if (sciErr.iErr)
184             {
185                 printError(&sciErr, 0);
186                 return 0;
187             }
188             LhsVar(2) = Rhs + 2;
189         }
190
191         /* Return the variable types */
192         if (Lhs >= 3)
193         {
194             sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 3, nbRow, nbCol, vartypes);
195             if (sciErr.iErr)
196             {
197                 printError(&sciErr, 0);
198                 return 0;
199             }
200             LhsVar(3) = Rhs + 3;
201         }
202     }
203
204     freeArrayOfString(varnames, nbvar);
205     FREE(varclasses);
206     FREE(vartypes);
207
208     PutLhsVar();
209
210     return TRUE;
211 }