9135e34316e7ff8af1c837bbc5fdb180fac9b5f8
[scilab.git] / scilab / modules / fileio / sci_gateway / c / sci_fscanfMat.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Allan CORNET
4  * Copyright (C) 2010 - 2011 - DIGITEO - Allan CORNET
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 <string.h>
18 #include "api_scilab.h"
19 #include "sci_malloc.h"
20 #include "gw_fileio.h"
21 #include "Scierror.h"
22 #include "localization.h"
23 #include "freeArrayOfString.h"
24 #include "expandPathVariable.h"
25 #include "os_string.h"
26 #include "fscanfMat.h"
27
28 /*--------------------------------------------------------------------------*/
29 static void freeVar(char** filename, char** expandedFilename, char** Format, char** separator);
30 /*--------------------------------------------------------------------------*/
31 int sci_fscanfMat(char *fname, void* pvApiCtx)
32 {
33     SciErr sciErr;
34     int *piAddressVarOne = NULL;
35     int m1 = 0, n1 = 0;
36     int iType1 = 0;
37
38     char *filename = NULL;
39     char *expandedFilename = NULL;
40     char *Format = NULL;
41     char *separator = NULL;
42     BOOL bIsDefaultSeparator = TRUE;
43
44     fscanfMatResult *results = NULL;
45
46     CheckRhs(1, 3);
47     CheckLhs(1, 2);
48
49     if (Rhs == 3)
50     {
51         int *piAddressVarThree = NULL;
52         int m3 = 0, n3 = 0;
53         int iType3 = 0;
54
55         sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddressVarThree);
56         if (sciErr.iErr)
57         {
58             printError(&sciErr, 0);
59             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
60             return 0;
61         }
62
63         if (isStringType(pvApiCtx, piAddressVarThree) == 0 || isScalar(pvApiCtx, piAddressVarThree) == 0)
64         {
65             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), fname, 3);
66             return 0;
67         }
68
69         if (getAllocatedSingleString(pvApiCtx, piAddressVarThree, &separator))
70         {
71             freeVar(&filename, &expandedFilename, &Format, &separator);
72             Scierror(999, _("%s: Memory allocation error.\n"), fname);
73             return 0;
74         }
75
76         bIsDefaultSeparator = FALSE;
77     }
78
79     if (Rhs >= 2)
80     {
81         int *piAddressVarTwo = NULL;
82         int m2 = 0, n2 = 0;
83         int iType2 = 0;
84
85         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo);
86         if (sciErr.iErr)
87         {
88             freeVar(&filename, &expandedFilename, &Format, &separator);
89             printError(&sciErr, 0);
90             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
91             return 0;
92         }
93
94         sciErr = getVarType(pvApiCtx, piAddressVarTwo, &iType2);
95         if (sciErr.iErr)
96         {
97             freeVar(&filename, &expandedFilename, &Format, &separator);
98             printError(&sciErr, 0);
99             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
100             return 0;
101         }
102
103         if (isStringType(pvApiCtx, piAddressVarTwo) == 0 || isScalar(pvApiCtx, piAddressVarTwo) == 0)
104         {
105             freeVar(&filename, &expandedFilename, &Format, &separator);
106             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), fname, 2);
107             return 0;
108         }
109
110         if (getAllocatedSingleString(pvApiCtx, piAddressVarTwo, &Format))
111         {
112             freeVar(&filename, &expandedFilename, &Format, &separator);
113             Scierror(999, _("%s: Memory allocation error.\n"), fname);
114             return 0;
115         }
116     }
117     else
118     {
119         Format = os_strdup(DEFAULT_FSCANFMAT_FORMAT);
120     }
121
122     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
123     if (sciErr.iErr)
124     {
125         freeVar(&filename, &expandedFilename, &Format, &separator);
126         printError(&sciErr, 0);
127         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
128         return 0;
129     }
130
131     if (isStringType(pvApiCtx, piAddressVarOne) == 0 || isScalar(pvApiCtx, piAddressVarOne) == 0)
132     {
133         freeVar(&filename, &expandedFilename, &Format, &separator);
134         Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), fname, 1);
135         return 0;
136     }
137
138     if (getAllocatedSingleString(pvApiCtx, piAddressVarOne, &filename))
139     {
140         freeVar(&filename, &expandedFilename, &Format, &separator);
141         Scierror(999, _("%s: Memory allocation error.\n"), fname);
142         return 0;
143     }
144
145     expandedFilename = expandPathVariable(filename);
146     if (bIsDefaultSeparator)
147     {
148 #define NB_DEFAULT_SUPPORTED_SEPARATORS 2
149
150         /* bug 8148 */
151         /* default separator can be a space or a tabulation */
152         char *supportedSeparators[NB_DEFAULT_SUPPORTED_SEPARATORS] = {DEFAULT_FSCANFMAT_SEPARATOR, "\t"};
153         int i = 0;
154
155         for (i = 0; i < NB_DEFAULT_SUPPORTED_SEPARATORS; i++)
156         {
157             results = fscanfMat(expandedFilename, Format, supportedSeparators[i]);
158             if (results && results->err == FSCANFMAT_NO_ERROR)
159             {
160                 break;
161             }
162
163             freeFscanfMatResult(results);
164         }
165     }
166     else
167     {
168         results = fscanfMat(expandedFilename, Format, separator);
169         if (results && results->err != FSCANFMAT_NO_ERROR)
170         {
171             freeFscanfMatResult(results);
172         }
173     }
174
175     if (results == NULL)
176     {
177         freeVar(&filename, &expandedFilename, &Format, &separator);
178         Scierror(999, _("%s: Memory allocation error.\n"), fname);
179         return 0;
180     }
181
182     freeVar(NULL, &expandedFilename, &Format, &separator);
183     switch (results->err)
184     {
185         case FSCANFMAT_NO_ERROR:
186         {
187             if ( (results->values) && (results->m > 0) && (results->n > 0))
188             {
189                 sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, results->m, results->n, results->values);
190                 if (sciErr.iErr)
191                 {
192                     FREE(filename);
193                     freeFscanfMatResult(results);
194                     printError(&sciErr, 0);
195                     Scierror(999, _("%s: Memory allocation error.\n"), fname);
196                     return 0;
197                 }
198             }
199             else
200             {
201                 if (createEmptyMatrix(pvApiCtx, Rhs + 1))
202                 {
203                     FREE(filename);
204                     freeFscanfMatResult(results);
205                     Scierror(999, _("%s: Memory allocation error.\n"), fname);
206                     return 0;
207                 }
208             }
209
210             LhsVar(1) = Rhs + 1;
211
212             if (Lhs == 2)
213             {
214                 if (results->text)
215                 {
216                     sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, results->sizeText, 1, (char const * const*) results->text);
217                     if (sciErr.iErr)
218                     {
219                         FREE(filename);
220                         freeFscanfMatResult(results);
221                         printError(&sciErr, 0);
222                         Scierror(999, _("%s: Memory allocation error.\n"), fname);
223                         return 0;
224                     }
225                 }
226                 else
227                 {
228                     if (createSingleString(pvApiCtx, Rhs + 2, ""))
229                     {
230                         FREE(filename);
231                         freeFscanfMatResult(results);
232                         Scierror(999, _("%s: Memory allocation error.\n"), fname);
233                         return 0;
234                     }
235                 }
236
237                 LhsVar(2) = Rhs + 2;
238             }
239
240             freeFscanfMatResult(results);
241             FREE(filename);
242             PutLhsVar();
243             return 0;
244         }
245         case FSCANFMAT_MOPEN_ERROR:
246         {
247             Scierror(999, _("%s: can not open file %s.\n"), fname, filename);
248             FREE(filename);
249             return 0;
250         }
251         case FSCANFMAT_READLINES_ERROR:
252         {
253             Scierror(999, _("%s: can not read file %s.\n"), fname, filename);
254             FREE(filename);
255             return 0;
256         }
257         case FSCANFMAT_FORMAT_ERROR:
258         {
259             Scierror(999, _("%s: Invalid format.\n"), fname);
260             FREE(filename);
261             return 0;
262         }
263         case FSCANFMAT_MEMORY_ALLOCATION:
264         {
265             Scierror(999, _("%s: Memory allocation error.\n"), fname);
266             FREE(filename);
267             return 0;
268         }
269         default:
270         case FSCANFMAT_ERROR:
271         {
272             Scierror(999, _("%s: error.\n"), fname);
273             FREE(filename);
274             return 0;
275         }
276     }
277 }
278 /*--------------------------------------------------------------------------*/
279 static void freeVar(char** filename, char** expandedFilename, char** Format, char** separator)
280 {
281     if (filename && *filename)
282     {
283         FREE(*filename);
284         *filename = NULL;
285     }
286
287     if (expandedFilename && *expandedFilename)
288     {
289         FREE(*expandedFilename);
290         *expandedFilename = NULL;
291     }
292
293     if (Format && *Format)
294     {
295         FREE(*Format);
296         *Format = NULL;
297     }
298
299     if (separator && *separator)
300     {
301         FREE(*separator);
302         *separator = NULL;
303     }
304 }