67563a222d913345eb8cd4d7eba03ad7d835095b
[scilab.git] / scilab / modules / spreadsheet / sci_gateway / c / sci_csvTextScan.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - 2012 - INRIA - Allan CORNET
4  * Copyright (C) 2011 - INRIA - Michael Baudin
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  * This code is also published under the GPL v3 license.
13  *
14  */
15 #include <string.h>
16 #include "gw_spreadsheet.h"
17 #include "api_scilab.h"
18 #include "Scierror.h"
19 #include "MALLOC.h"
20 #include "Scierror.h"
21 #include "localization.h"
22 #include "freeArrayOfString.h"
23 #ifdef _MSC_VER
24 #include "strdup_windows.h"
25 #endif
26 #include "stringToComplex.h"
27 #include "csvDefault.h"
28 #include "csvRead.h"
29 #include "getRange.h"
30 #include "gw_csv_helpers.h"
31
32 // =============================================================================
33 #define CONVTOSTR "string"
34 #define CONVTODOUBLE "double"
35 // =============================================================================
36 int sci_csvTextScan(char *fname, unsigned long fname_len)
37 {
38     SciErr sciErr;
39     int iErr = 0;
40     int i = 0;
41
42     int *piAddressVarOne = NULL;
43     int m1 = 0, n1 = 0;
44     int iType1 = 0;
45
46     char **text = NULL;
47     int *lengthText = NULL;
48     int nbLines = 0;
49
50     char *separator = NULL;
51     char *decimal = NULL;
52     char *conversion = NULL;
53
54     double * dRealValues = NULL;
55
56     int *iRange = NULL;
57     int haveRange = 0;
58
59     csvResult *result = NULL;
60
61     CheckRhs(1, 5);
62     CheckLhs(1, 1);
63
64     if (Rhs == 5)
65     {
66         int m5 = 0, n5 = 0;
67
68         iRange = csv_getArgumentAsMatrixofIntFromDouble(pvApiCtx, 5, fname, &m5, &n5, &iErr);
69         if (iErr)
70         {
71             return 0;
72         }
73
74         if ((m5 * n5 != SIZE_RANGE_SUPPORTED) )
75         {
76             if (iRange)
77             {
78                 FREE(iRange);
79                 iRange = NULL;
80             }
81             Scierror(999, _("%s: Wrong size for input argument #%d: Four entries expected.\n"), fname, 5);
82             return 0;
83         }
84
85         if ((m5 != 1) && (n5 != 1))
86         {
87             if (iRange)
88             {
89                 FREE(iRange);
90                 iRange = NULL;
91             }
92             Scierror(999, _("%s: Wrong size for input argument #%d: A column or row vector expected.\n"), fname, 5);
93             return 0;
94         }
95
96         if (isValidRange(iRange, m5 * n5))
97         {
98             haveRange = 1;
99         }
100         else
101         {
102             if (iRange)
103             {
104                 FREE(iRange);
105                 iRange = NULL;
106             }
107             Scierror(999, _("%s: Wrong value for input argument #%d: Inconsistent range.\n"), fname, 5);
108             return 0;
109         }
110     }
111
112     if (Rhs >= 4)
113     {
114         conversion = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 4, fname, getCsvDefaultConversion(), &iErr);
115         if (iErr)
116         {
117             if (iRange)
118             {
119                 FREE(iRange);
120                 iRange = NULL;
121             }
122             return 0;
123         }
124
125         if (!((strcmp(conversion, CONVTOSTR) == 0) || (strcmp(conversion, CONVTODOUBLE) == 0)))
126         {
127             if (iRange)
128             {
129                 FREE(iRange);
130                 iRange = NULL;
131             }
132             if (conversion)
133             {
134                 FREE(conversion);
135                 conversion = NULL;
136             }
137
138             Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' string expected.\n"), fname, 4, "double", "string");
139             return 0;
140         }
141     }
142     else
143     {
144         conversion = strdup(getCsvDefaultConversion());
145     }
146
147     if (Rhs >= 3)
148     {
149         decimal = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 3, fname, getCsvDefaultDecimal(), &iErr);
150         if (iErr)
151         {
152             if (iRange)
153             {
154                 FREE(iRange);
155                 iRange = NULL;
156             }
157             if (conversion)
158             {
159                 FREE(conversion);
160                 conversion = NULL;
161             }
162             return 0;
163         }
164
165         if (decimal[0] != '.' && decimal[0] != ',')
166         {
167             if (iRange)
168             {
169                 FREE(iRange);
170                 iRange = NULL;
171             }
172             if (conversion)
173             {
174                 FREE(conversion);
175                 conversion = NULL;
176             }
177
178             Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' string expected.\n"), fname, 3, ",", ".");
179             return 0;
180         }
181     }
182     else
183     {
184         decimal = strdup(getCsvDefaultDecimal());
185     }
186
187     if (Rhs >= 2)
188     {
189         separator = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 2, fname, getCsvDefaultSeparator(), &iErr);
190         if (iErr)
191         {
192             if (iRange)
193             {
194                 FREE(iRange);
195                 iRange = NULL;
196             }
197             if (decimal)
198             {
199                 FREE(decimal);
200                 decimal = NULL;
201             }
202             if (conversion)
203             {
204                 FREE(conversion);
205                 conversion = NULL;
206             }
207             return 0;
208         }
209     }
210     else
211     {
212         separator = strdup(getCsvDefaultSeparator());
213     }
214
215     if (!csv_isRowVector(pvApiCtx, 1) &&
216             !csv_isColumnVector(pvApiCtx, 1) &&
217             !csv_isScalar(pvApiCtx, 1))
218     {
219         if (iRange)
220         {
221             FREE(iRange);
222             iRange = NULL;
223         }
224         if (separator)
225         {
226             FREE(separator);
227             separator = NULL;
228         }
229         if (decimal)
230         {
231             FREE(decimal);
232             decimal = NULL;
233         }
234         if (conversion)
235         {
236             FREE(conversion);
237             conversion = NULL;
238         }
239         Scierror(999, _("%s: Wrong size for input argument #%d: String vector expected.\n"), fname, 1);
240         return 0;
241     }
242
243     text = csv_getArgumentAsMatrixOfString(pvApiCtx, 1, fname, &m1, &n1, &iErr);
244     if (iErr)
245     {
246         if (iRange)
247         {
248             FREE(iRange);
249             iRange = NULL;
250         }
251         if (separator)
252         {
253             FREE(separator);
254             separator = NULL;
255         }
256         if (decimal)
257         {
258             FREE(decimal);
259             decimal = NULL;
260         }
261         if (conversion)
262         {
263             FREE(conversion);
264             conversion = NULL;
265         }
266         return 0;
267     }
268
269     nbLines = m1 * n1;
270     result = csvTextScan((const char**)text, nbLines, separator, decimal);
271
272     if (text)
273     {
274         if (separator)
275         {
276             FREE(separator);
277             separator = NULL;
278         }
279         freeArrayOfString(text, nbLines);
280         text = NULL;
281     }
282
283     if (separator)
284     {
285         FREE(separator);
286         separator = NULL;
287     }
288
289     if (result)
290     {
291         switch (result->err)
292         {
293             case CSV_READ_SEPARATOR_DECIMAL_EQUAL:
294             {
295                 Scierror(999, _("%s: separator and decimal must have different values.\n"), fname);
296             }
297             break;
298
299             case CSV_READ_NO_ERROR:
300             {
301                 if (strcmp(conversion, CONVTOSTR) == 0)
302                 {
303                     if (haveRange)
304                     {
305                         int newM = 0;
306                         int newN = 0;
307
308                         char **pStrRange = getRangeAsString((const char**)result->pstrValues, result->m, result->n, iRange, &newM, &newN);
309                         if (pStrRange)
310                         {
311                             sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, newM, newN, pStrRange);
312                             freeArrayOfString(pStrRange, newM * newN);
313                         }
314                         else
315                         {
316                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
317                         }
318
319                     }
320                     else
321                     {
322                         sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, result->m, result->n, result->pstrValues);
323                     }
324                 }
325                 else /* to double */
326                 {
327                     stringToComplexError ierr = STRINGTOCOMPLEX_ERROR;
328                     csv_complexArray *ptrCsvComplexArray = stringsToCsvComplexArray((const char**)result->pstrValues, result->m * result->n, decimal, TRUE, &ierr);
329                     if (ptrCsvComplexArray == NULL)
330                     {
331                         freeCsvResult(result);
332                         if (decimal)
333                         {
334                             FREE(decimal);
335                             decimal = NULL;
336                         }
337                         if (conversion)
338                         {
339                             FREE(conversion);
340                             conversion = NULL;
341                         }
342                         if (iRange)
343                         {
344                             FREE(iRange);
345                             iRange = NULL;
346                         }
347                         if (ierr == STRINGTOCOMPLEX_ERROR)
348                         {
349                             Scierror(999, _("%s: can not convert data.\n"), fname);
350                         }
351                         else
352                         {
353                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
354                         }
355                         return 0;
356                     }
357
358                     switch (ierr)
359                     {
360                         case STRINGTOCOMPLEX_NOT_A_NUMBER:
361                         case STRINGTOCOMPLEX_NO_ERROR:
362                         {
363                             if (haveRange)
364                             {
365                                 int newM = 0;
366                                 int newN = 0;
367                                 csv_complexArray *csvComplexRange = getRangeAsCsvComplexArray(ptrCsvComplexArray, result->m, result->n, iRange, &newM, &newN);
368                                 if (csvComplexRange)
369                                 {
370                                     if (csvComplexRange->isComplex)
371                                     {
372                                         sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, ptrCsvComplexArray->realPart, ptrCsvComplexArray->imagPart);
373                                     }
374                                     else
375                                     {
376                                         sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, csvComplexRange->realPart);
377                                     }
378                                     freeCsvComplexArray(csvComplexRange);
379                                     csvComplexRange = NULL;
380                                 }
381                                 else
382                                 {
383                                     Scierror(999, _("%s: Memory allocation error.\n"), fname);
384                                 }
385                             }
386                             else
387                             {
388                                 if (ptrCsvComplexArray->isComplex)
389                                 {
390                                     sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrCsvComplexArray->realPart, ptrCsvComplexArray->imagPart);
391                                 }
392                                 else
393                                 {
394                                     sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrCsvComplexArray->realPart);
395                                 }
396                             }
397                             freeCsvComplexArray(ptrCsvComplexArray);
398                             ptrCsvComplexArray = NULL;
399                         }
400                         break;
401
402                         case STRINGTOCOMPLEX_MEMORY_ALLOCATION:
403                         {
404                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
405                         }
406                         default:
407                         case STRINGTOCOMPLEX_ERROR:
408                         {
409                             Scierror(999, _("%s: can not convert data.\n"), fname);
410                         }
411                     }
412                 }
413
414                 if (sciErr.iErr)
415                 {
416                     freeCsvResult(result);
417                     if (decimal)
418                     {
419                         FREE(decimal);
420                         decimal = NULL;
421                     }
422                     if (conversion)
423                     {
424                         FREE(conversion);
425                         conversion = NULL;
426                     }
427                     if (iRange)
428                     {
429                         FREE(iRange);
430                         iRange = NULL;
431                     }
432                     printError(&sciErr, 0);
433                     Scierror(17, _("%s: Memory allocation error.\n"), fname);
434                     return 0;
435                 }
436                 else
437                 {
438                     LhsVar(1) = Rhs + 1;
439                     PutLhsVar();
440                 }
441             }
442             break;
443
444             case CSV_READ_MEMORY_ALLOCATION:
445             {
446                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
447             }
448             break;
449
450             case CSV_READ_COLUMNS_ERROR:
451             {
452                 Scierror(999, _("%s: can not read text: Error in the column structure\n"), fname);
453             }
454             break;
455
456             case CSV_READ_READLINES_ERROR:
457             case CSV_READ_ERROR:
458             {
459                 Scierror(999, _("%s: can not read text.\n"), fname);
460             }
461             break;
462         }
463     }
464     else
465     {
466         Scierror(999, _("%s: Memory allocation error.\n"), fname);
467     }
468     freeCsvResult(result);
469     if (decimal)
470     {
471         FREE(decimal);
472         decimal = NULL;
473     }
474     if (conversion)
475     {
476         FREE(conversion);
477         conversion = NULL;
478     }
479     if (iRange)
480     {
481         FREE(iRange);
482         iRange = NULL;
483     }
484
485     return 0;
486 }
487 // =============================================================================