12ec0743e3fac6012abe1053a71e1684f346f990
[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             if (results)
158             {
159                 freeFscanfMatResult(results);
160             }
161             results = fscanfMat(expandedFilename, Format, supportedSeparators[i]);
162             if (results && results->err == FSCANFMAT_NO_ERROR)
163             {
164                 break;
165             }
166         }
167     }
168     else
169     {
170         results = fscanfMat(expandedFilename, Format, separator);
171         if (results && results->err != FSCANFMAT_NO_ERROR)
172         {
173             freeFscanfMatResult(results);
174             results = NULL;
175         }
176     }
177
178     if (results == NULL)
179     {
180         freeVar(&filename, &expandedFilename, &Format, &separator);
181         Scierror(999, _("%s: Memory allocation error.\n"), fname);
182         return 0;
183     }
184
185     freeVar(NULL, &expandedFilename, &Format, &separator);
186     switch (results->err)
187     {
188         case FSCANFMAT_NO_ERROR:
189         {
190             if ( (results->values) && (results->m > 0) && (results->n > 0))
191             {
192                 sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, results->m, results->n, results->values);
193                 if (sciErr.iErr)
194                 {
195                     FREE(filename);
196                     freeFscanfMatResult(results);
197                     printError(&sciErr, 0);
198                     Scierror(999, _("%s: Memory allocation error.\n"), fname);
199                     return 0;
200                 }
201             }
202             else
203             {
204                 if (createEmptyMatrix(pvApiCtx, Rhs + 1))
205                 {
206                     FREE(filename);
207                     freeFscanfMatResult(results);
208                     Scierror(999, _("%s: Memory allocation error.\n"), fname);
209                     return 0;
210                 }
211             }
212
213             LhsVar(1) = Rhs + 1;
214
215             if (Lhs == 2)
216             {
217                 if (results->text)
218                 {
219                     sciErr = createMatrixOfString(pvApiCtx, Rhs + 2, results->sizeText, 1, (char const * const*) results->text);
220                     if (sciErr.iErr)
221                     {
222                         FREE(filename);
223                         freeFscanfMatResult(results);
224                         printError(&sciErr, 0);
225                         Scierror(999, _("%s: Memory allocation error.\n"), fname);
226                         return 0;
227                     }
228                 }
229                 else
230                 {
231                     if (createSingleString(pvApiCtx, Rhs + 2, ""))
232                     {
233                         FREE(filename);
234                         freeFscanfMatResult(results);
235                         Scierror(999, _("%s: Memory allocation error.\n"), fname);
236                         return 0;
237                     }
238                 }
239
240                 LhsVar(2) = Rhs + 2;
241             }
242
243             freeFscanfMatResult(results);
244             FREE(filename);
245             PutLhsVar();
246             return 0;
247         }
248         case FSCANFMAT_MOPEN_ERROR:
249         {
250             Scierror(999, _("%s: can not open file %s.\n"), fname, filename);
251             FREE(filename);
252             return 0;
253         }
254         case FSCANFMAT_READLINES_ERROR:
255         {
256             Scierror(999, _("%s: can not read file %s.\n"), fname, filename);
257             FREE(filename);
258             return 0;
259         }
260         case FSCANFMAT_FORMAT_ERROR:
261         {
262             Scierror(999, _("%s: Invalid format.\n"), fname);
263             FREE(filename);
264             return 0;
265         }
266         case FSCANFMAT_MEMORY_ALLOCATION:
267         {
268             Scierror(999, _("%s: Memory allocation error.\n"), fname);
269             FREE(filename);
270             return 0;
271         }
272         default:
273         case FSCANFMAT_ERROR:
274         {
275             Scierror(999, _("%s: error.\n"), fname);
276             FREE(filename);
277             return 0;
278         }
279     }
280 }
281 /*--------------------------------------------------------------------------*/
282 static void freeVar(char** filename, char** expandedFilename, char** Format, char** separator)
283 {
284     if (filename && *filename)
285     {
286         FREE(*filename);
287         *filename = NULL;
288     }
289
290     if (expandedFilename && *expandedFilename)
291     {
292         FREE(*expandedFilename);
293         *expandedFilename = NULL;
294     }
295
296     if (Format && *Format)
297     {
298         FREE(*Format);
299         *Format = NULL;
300     }
301
302     if (separator && *separator)
303     {
304         FREE(*separator);
305         *separator = NULL;
306     }
307 }