tidy up your spreadsheet module
[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     else
166     {
167         decimal = strdup(getCsvDefaultDecimal());
168     }
169
170     if (Rhs >= 2)
171     {
172         separator = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 2, fname, getCsvDefaultSeparator(), &iErr);
173         if (iErr)
174         {
175             if (iRange)
176             {
177                 FREE(iRange);
178                 iRange = NULL;
179             }
180             if (decimal)
181             {
182                 FREE(decimal);
183                 decimal = NULL;
184             }
185             if (conversion)
186             {
187                 FREE(conversion);
188                 conversion = NULL;
189             }
190             return 0;
191         }
192     }
193     else
194     {
195         separator = strdup(getCsvDefaultSeparator());
196     }
197
198     if (!csv_isRowVector(pvApiCtx, 1) &&
199             !csv_isColumnVector(pvApiCtx, 1) &&
200             !csv_isScalar(pvApiCtx, 1))
201     {
202         if (iRange)
203         {
204             FREE(iRange);
205             iRange = NULL;
206         }
207         if (separator)
208         {
209             FREE(separator);
210             separator = NULL;
211         }
212         if (decimal)
213         {
214             FREE(decimal);
215             decimal = NULL;
216         }
217         if (conversion)
218         {
219             FREE(conversion);
220             conversion = NULL;
221         }
222         Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), fname, 1);
223         return 0;
224     }
225
226     text = csv_getArgumentAsMatrixOfString(pvApiCtx, 1, fname, &m1, &n1, &iErr);
227     if (iErr)
228     {
229         if (iRange)
230         {
231             FREE(iRange);
232             iRange = NULL;
233         }
234         if (separator)
235         {
236             FREE(separator);
237             separator = NULL;
238         }
239         if (decimal)
240         {
241             FREE(decimal);
242             decimal = NULL;
243         }
244         if (conversion)
245         {
246             FREE(conversion);
247             conversion = NULL;
248         }
249         return 0;
250     }
251
252     nbLines = m1 * n1;
253     result = csvTextScan((const char**)text, nbLines, separator, decimal);
254
255     if (text)
256     {
257         if (separator)
258         {
259             FREE(separator);
260             separator = NULL;
261         }
262         freeArrayOfString(text, nbLines);
263         text = NULL;
264     }
265
266     if (separator)
267     {
268         FREE(separator);
269         separator = NULL;
270     }
271
272     if (result)
273     {
274         switch (result->err)
275         {
276             case CSV_READ_SEPARATOR_DECIMAL_EQUAL:
277             {
278                 Scierror(999, _("%s: separator and decimal must have different values.\n"), fname);
279             }
280             break;
281
282             case CSV_READ_NO_ERROR:
283             {
284                 if (strcmp(conversion, CONVTOSTR) == 0)
285                 {
286                     if (haveRange)
287                     {
288                         int newM = 0;
289                         int newN = 0;
290
291                         char **pStrRange = getRangeAsString((const char**)result->pstrValues, result->m, result->n, iRange, &newM, &newN);
292                         if (pStrRange)
293                         {
294                             sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, newM, newN, pStrRange);
295                             freeArrayOfString(pStrRange, newM * newN);
296                         }
297                         else
298                         {
299                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
300                         }
301
302                     }
303                     else
304                     {
305                         sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, result->m, result->n, result->pstrValues);
306                     }
307                 }
308                 else /* to double */
309                 {
310                     stringToComplexError ierr = STRINGTOCOMPLEX_ERROR;
311                     csv_complexArray *ptrCsvComplexArray = stringsToCsvComplexArray((const char**)result->pstrValues, result->m * result->n, decimal, TRUE, &ierr);
312                     if (ptrCsvComplexArray == NULL)
313                     {
314                         freeCsvResult(result);
315                         if (decimal)
316                         {
317                             FREE(decimal);
318                             decimal = NULL;
319                         }
320                         if (conversion)
321                         {
322                             FREE(conversion);
323                             conversion = NULL;
324                         }
325                         if (iRange)
326                         {
327                             FREE(iRange);
328                             iRange = NULL;
329                         }
330                         if (ierr == STRINGTOCOMPLEX_ERROR)
331                         {
332                             Scierror(999, _("%s: can not convert data.\n"), fname);
333                         }
334                         else
335                         {
336                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
337                         }
338                         return 0;
339                     }
340
341                     switch (ierr)
342                     {
343                         case STRINGTOCOMPLEX_NOT_A_NUMBER:
344                         case STRINGTOCOMPLEX_NO_ERROR:
345                         {
346                             if (haveRange)
347                             {
348                                 int newM = 0;
349                                 int newN = 0;
350                                 csv_complexArray *csvComplexRange = getRangeAsCsvComplexArray(ptrCsvComplexArray, result->m, result->n, iRange, &newM, &newN);
351                                 if (csvComplexRange)
352                                 {
353                                     if (csvComplexRange->isComplex)
354                                     {
355                                         sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, ptrCsvComplexArray->realPart, ptrCsvComplexArray->imagPart);
356                                     }
357                                     else
358                                     {
359                                         sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, newM, newN, csvComplexRange->realPart);
360                                     }
361                                     freeCsvComplexArray(csvComplexRange);
362                                     csvComplexRange = NULL;
363                                 }
364                                 else
365                                 {
366                                     Scierror(999, _("%s: Memory allocation error.\n"), fname);
367                                 }
368                             }
369                             else
370                             {
371                                 if (ptrCsvComplexArray->isComplex)
372                                 {
373                                     sciErr = createComplexMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrCsvComplexArray->realPart, ptrCsvComplexArray->imagPart);
374                                 }
375                                 else
376                                 {
377                                     sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, result->m, result->n, ptrCsvComplexArray->realPart);
378                                 }
379                             }
380                             freeCsvComplexArray(ptrCsvComplexArray);
381                             ptrCsvComplexArray = NULL;
382                         }
383                         break;
384
385                         case STRINGTOCOMPLEX_MEMORY_ALLOCATION:
386                         {
387                             Scierror(999, _("%s: Memory allocation error.\n"), fname);
388                         }
389                         default:
390                         case STRINGTOCOMPLEX_ERROR:
391                         {
392                             Scierror(999, _("%s: can not convert data.\n"), fname);
393                         }
394                     }
395                 }
396
397                 if (sciErr.iErr)
398                 {
399                     freeCsvResult(result);
400                     if (decimal)
401                     {
402                         FREE(decimal);
403                         decimal = NULL;
404                     }
405                     if (conversion)
406                     {
407                         FREE(conversion);
408                         conversion = NULL;
409                     }
410                     if (iRange)
411                     {
412                         FREE(iRange);
413                         iRange = NULL;
414                     }
415                     printError(&sciErr, 0);
416                     Scierror(17, _("%s: Memory allocation error.\n"), fname);
417                     return 0;
418                 }
419                 else
420                 {
421                     LhsVar(1) = Rhs + 1;
422                     PutLhsVar();
423                 }
424             }
425             break;
426
427             case CSV_READ_MEMORY_ALLOCATION:
428             {
429                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
430             }
431             break;
432
433             case CSV_READ_COLUMNS_ERROR:
434             {
435                 Scierror(999, _("%s: can not read text: Error in the column structure\n"), fname);
436             }
437             break;
438
439             case CSV_READ_READLINES_ERROR:
440             case CSV_READ_ERROR:
441             {
442                 Scierror(999, _("%s: can not read text.\n"), fname);
443             }
444             break;
445         }
446     }
447     else
448     {
449         Scierror(999, _("%s: Memory allocation error.\n"), fname);
450     }
451     freeCsvResult(result);
452     if (decimal)
453     {
454         FREE(decimal);
455         decimal = NULL;
456     }
457     if (conversion)
458     {
459         FREE(conversion);
460         conversion = NULL;
461     }
462     if (iRange)
463     {
464         FREE(iRange);
465         iRange = NULL;
466     }
467
468     return 0;
469 }
470 // =============================================================================