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