tidy up your spreadsheet module
[scilab.git] / scilab / modules / spreadsheet / sci_gateway / c / sci_csvWrite.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 <stdio.h>
17 #include "api_scilab.h"
18 #include "Scierror.h"
19 #include "MALLOC.h"
20 #include "csvWrite.h"
21 #include "localization.h"
22 #include "freeArrayOfString.h"
23 #ifdef _MSC_VER
24 #include "strdup_windows.h"
25 #endif
26 #include "csvDefault.h"
27 #include "checkCsvWriteFormat.h"
28 #include "gw_csv_helpers.h"
29
30 // =============================================================================
31 // csvWrite(M, filename[, separator, decimal, precision]) */
32 // with M string or double (not complex)
33 // =============================================================================
34 int sci_csvWrite(char *fname, unsigned long fname_len)
35 {
36     SciErr sciErr;
37     int iErr = 0;
38     csvWriteError csvError = CSV_WRITE_ERROR;
39
40     char *separator = NULL;
41     char *decimal = NULL;
42     char *filename = NULL;
43     char *precisionFormat = NULL;
44     char **pHeadersLines = NULL;
45     int nbHeadersLines = 0;
46
47     char **pStringValues = NULL;
48     double *pDoubleValuesReal = NULL;
49     double *pDoubleValuesImag = NULL;
50     int bIsComplex = 0;
51     int mValues = 0;
52     int nValues = 0;
53
54     int *piAddressVarTwo = NULL;
55     int m2 = 0, n2 = 0;
56     int iType2 = 0;
57
58     int *piAddressVarOne = NULL;
59     int m1 = 0, n1 = 0;
60     int iType1 = 0;
61
62     CheckRhs(2, 6);
63     CheckLhs(1, 1);
64
65     if (Rhs > 5)
66     {
67         int isOnlyRowOrCol = 0;
68         int m6 = 0;
69         int n6 = 0;
70         pHeadersLines = csv_getArgumentAsMatrixOfString(pvApiCtx, 6, fname, &m6, &n6, &iErr);
71         if (iErr)
72         {
73             return 0;
74         }
75         isOnlyRowOrCol = ((m6 > 1) && (n6 == 1)) || ((m6 == 1) && (n6 > 1)) || ((m6 == 1) && (n6 == 1));
76         if (!isOnlyRowOrCol)
77         {
78             if (pHeadersLines)
79             {
80                 freeArrayOfString(pHeadersLines, nbHeadersLines);
81                 pHeadersLines = NULL;
82             }
83             Scierror(999, _("%s: Wrong size for input argument #%d: A 1-by-n or m-by-1 array of strings expected.\n"), fname, 6);
84             return 0;
85         }
86         nbHeadersLines = m6 * n6;
87     }
88
89     if (Rhs > 4)
90     {
91         if (csv_isDoubleScalar(pvApiCtx, 5))
92         {
93 #define FORMAT_FIELDVALUESTR "%%.%dlg"
94             int iFormatValue = (int) csv_getArgumentAsScalarDouble(pvApiCtx, 5, fname, &iErr);
95             if (iErr)
96             {
97                 if (pHeadersLines)
98                 {
99                     freeArrayOfString(pHeadersLines, nbHeadersLines);
100                     pHeadersLines = NULL;
101                 }
102                 return 0;
103             }
104
105             if ((iFormatValue < 1) || (iFormatValue > 17))
106             {
107                 Scierror(999, _("%s: Wrong value for input argument #%d: A double (value 1 to 17) expected.\n"), fname, 5);
108                 if (pHeadersLines)
109                 {
110                     freeArrayOfString(pHeadersLines, nbHeadersLines);
111                     pHeadersLines = NULL;
112                 }
113                 return 0;
114             }
115
116             precisionFormat = (char*)MALLOC(sizeof(char) * ((int)strlen(FORMAT_FIELDVALUESTR) + 1));
117             if (precisionFormat == NULL)
118             {
119                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
120                 if (pHeadersLines)
121                 {
122                     freeArrayOfString(pHeadersLines, nbHeadersLines);
123                     pHeadersLines = NULL;
124                 }
125                 return 0;
126             }
127             sprintf(precisionFormat, FORMAT_FIELDVALUESTR, iFormatValue);
128         }
129         else
130         {
131             precisionFormat = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 5, fname, getCsvDefaultPrecision(), &iErr);
132             if (iErr)
133             {
134                 return 0;
135             }
136             if (checkCsvWriteFormat(precisionFormat))
137             {
138                 Scierror(999, _("%s: Not supported format %s.\n"), fname, precisionFormat);
139                 if (precisionFormat)
140                 {
141                     FREE(precisionFormat);
142                     precisionFormat = NULL;
143                 }
144                 if (pHeadersLines)
145                 {
146                     freeArrayOfString(pHeadersLines, nbHeadersLines);
147                     pHeadersLines = NULL;
148                 }
149                 return 0;
150             }
151         }
152     }
153     else
154     {
155         precisionFormat = strdup(getCsvDefaultPrecision());
156     }
157
158     if (Rhs > 3)
159     {
160         decimal = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 4, fname, getCsvDefaultDecimal(), &iErr);
161         if (iErr)
162         {
163             if (precisionFormat)
164             {
165                 FREE(precisionFormat);
166                 precisionFormat = NULL;
167             }
168             if (pHeadersLines)
169             {
170                 freeArrayOfString(pHeadersLines, nbHeadersLines);
171                 pHeadersLines = NULL;
172             }
173             return 0;
174         }
175
176         if (strcmp(decimal, ".") && strcmp(decimal, ","))
177         {
178             //invalid value
179             Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), "write_csv", 4, ".", ",");
180             FREE(precisionFormat);
181             return 1;
182         }
183     }
184     else
185     {
186         decimal = strdup(getCsvDefaultDecimal());
187     }
188
189     if (Rhs > 2)
190     {
191         separator = csv_getArgumentAsStringWithEmptyManagement(pvApiCtx, 3, fname, getCsvDefaultSeparator(), &iErr);
192         if (iErr)
193         {
194             if (pHeadersLines)
195             {
196                 freeArrayOfString(pHeadersLines, nbHeadersLines);
197                 pHeadersLines = NULL;
198             }
199             if (precisionFormat)
200             {
201                 FREE(precisionFormat);
202                 precisionFormat = NULL;
203             }
204             if (decimal)
205             {
206                 FREE(decimal);
207                 decimal = NULL;
208             }
209             return 0;
210         }
211     }
212     else
213     {
214         separator = strdup(getCsvDefaultSeparator());
215     }
216
217     filename = csv_getArgumentAsString(pvApiCtx, 2, fname, &iErr);
218     if (iErr)
219     {
220         if (pHeadersLines)
221         {
222             freeArrayOfString(pHeadersLines, nbHeadersLines);
223             pHeadersLines = NULL;
224         }
225         if (separator)
226         {
227             FREE(separator);
228             separator = NULL;
229         }
230         if (precisionFormat)
231         {
232             FREE(precisionFormat);
233             precisionFormat = NULL;
234         }
235         if (decimal)
236         {
237             FREE(decimal);
238             decimal = NULL;
239         }
240         return 0;
241     }
242
243     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
244     if (sciErr.iErr)
245     {
246         if (pHeadersLines)
247         {
248             freeArrayOfString(pHeadersLines, nbHeadersLines);
249             pHeadersLines = NULL;
250         }
251         if (filename)
252         {
253             FREE(filename);
254             filename = NULL;
255         }
256         if (precisionFormat)
257         {
258             FREE(precisionFormat);
259             precisionFormat = NULL;
260         }
261         if (decimal)
262         {
263             FREE(decimal);
264             decimal = NULL;
265         }
266         if (separator)
267         {
268             FREE(separator);
269             separator = NULL;
270         }
271         printError(&sciErr, 0);
272         return 0;
273     }
274
275     sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType1);
276     if (sciErr.iErr)
277     {
278         if (pHeadersLines)
279         {
280             freeArrayOfString(pHeadersLines, nbHeadersLines);
281             pHeadersLines = NULL;
282         }
283         if (filename)
284         {
285             FREE(filename);
286             filename = NULL;
287         }
288         if (precisionFormat)
289         {
290             FREE(precisionFormat);
291             precisionFormat = NULL;
292         }
293         if (decimal)
294         {
295             FREE(decimal);
296             decimal = NULL;
297         }
298         if (separator)
299         {
300             FREE(separator);
301             separator = NULL;
302         }
303         printError(&sciErr, 0);
304         return 0;
305     }
306
307     if (iType1 == sci_strings)
308     {
309         pStringValues = csv_getArgumentAsMatrixOfString(pvApiCtx, 1, fname, &m1, &n1, &iErr);
310         if (iErr)
311         {
312             if (pHeadersLines)
313             {
314                 freeArrayOfString(pHeadersLines, nbHeadersLines);
315                 pHeadersLines = NULL;
316             }
317             if (filename)
318             {
319                 FREE(filename);
320                 filename = NULL;
321             }
322             if (precisionFormat)
323             {
324                 FREE(precisionFormat);
325                 precisionFormat = NULL;
326             }
327             if (decimal)
328             {
329                 FREE(decimal);
330                 decimal = NULL;
331             }
332             if (separator)
333             {
334                 FREE(separator);
335                 separator = NULL;
336             }
337             return 0;
338         }
339     }
340     else if (iType1 == sci_matrix)
341     {
342         if (isVarComplex(pvApiCtx, piAddressVarOne))
343         {
344             bIsComplex = 1;
345             sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddressVarOne, &m1, &n1, &pDoubleValuesReal, &pDoubleValuesImag);
346         }
347         else
348         {
349             sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarOne, &m1, &n1, &pDoubleValuesReal);
350         }
351
352         if (sciErr.iErr)
353         {
354             if (pHeadersLines)
355             {
356                 freeArrayOfString(pHeadersLines, nbHeadersLines);
357                 pHeadersLines = NULL;
358             }
359             if (precisionFormat)
360             {
361                 FREE(precisionFormat);
362                 precisionFormat = NULL;
363             }
364             if (filename)
365             {
366                 FREE(filename);
367                 filename = NULL;
368             }
369             if (decimal)
370             {
371                 FREE(decimal);
372                 decimal = NULL;
373             }
374             if (separator)
375             {
376                 FREE(separator);
377                 separator = NULL;
378             }
379             printError(&sciErr, 0);
380             return 0;
381         }
382     }
383     else
384     {
385         if (pHeadersLines)
386         {
387             freeArrayOfString(pHeadersLines, nbHeadersLines);
388             pHeadersLines = NULL;
389         }
390         if (precisionFormat)
391         {
392             FREE(precisionFormat);
393             precisionFormat = NULL;
394         }
395         if (filename)
396         {
397             FREE(filename);
398             filename = NULL;
399         }
400         if (decimal)
401         {
402             FREE(decimal);
403             decimal = NULL;
404         }
405         if (separator)
406         {
407             FREE(separator);
408             separator = NULL;
409         }
410
411         Scierror(999, _("%s: Wrong type for input argument #%d: A matrix of string or a matrix of real expected.\n"), fname, 1);
412         return 0;
413     }
414
415     if (pStringValues)
416     {
417         csvError = csvWrite_string(filename,
418                                    (const char**)pStringValues, m1, n1,
419                                    separator,
420                                    decimal,
421                                    (const char**)pHeadersLines, nbHeadersLines);
422     }
423     else
424     {
425         if (bIsComplex)
426         {
427             csvError = csvWrite_complex(filename,
428                                         pDoubleValuesReal,
429                                         pDoubleValuesImag,
430                                         m1, n1,
431                                         separator,
432                                         decimal,
433                                         precisionFormat,
434                                         (const char**)pHeadersLines, nbHeadersLines);
435         }
436         else
437         {
438             csvError = csvWrite_double(filename,
439                                        pDoubleValuesReal, m1, n1,
440                                        separator,
441                                        decimal,
442                                        precisionFormat,
443                                        (const char**)pHeadersLines, nbHeadersLines);
444         }
445     }
446
447     if (pHeadersLines)
448     {
449         freeArrayOfString(pHeadersLines, nbHeadersLines);
450         pHeadersLines = NULL;
451     }
452     if (pStringValues)
453     {
454         freeArrayOfString(pStringValues, m1 * n1);
455         pStringValues = NULL;
456     }
457     if (decimal)
458     {
459         FREE(decimal);
460         decimal = NULL;
461     }
462     if (separator)
463     {
464         FREE(separator);
465         separator = NULL;
466     }
467     if (precisionFormat)
468     {
469         FREE(precisionFormat);
470         precisionFormat = NULL;
471     }
472
473     switch (csvError)
474     {
475         case CSV_WRITE_SEPARATOR_DECIMAL_EQUAL:
476         {
477             Scierror(999, _("%s: separator and decimal must have different values.\n"), fname);
478         }
479         break;
480         case CSV_WRITE_NO_ERROR:
481         {
482             LhsVar(1) = 0;
483             PutLhsVar();
484         }
485         break;
486
487         case CSV_WRITE_FOPEN_ERROR:
488         {
489             Scierror(999, _("%s: can not open file %s.\n"), fname, filename);
490         }
491         break;
492         default:
493         case CSV_WRITE_ERROR:
494         {
495             Scierror(999, _("%s: error.\n"), fname);
496         }
497         break;
498     }
499
500     if (filename)
501     {
502         FREE(filename);
503         filename = NULL;
504     }
505
506     return 0;
507 }
508 // =============================================================================
509