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  * 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  * This code is also published under the GPL v3 license.
16  *
17  */
18 
19 #include <string.h>
20 #include <stdio.h>
21 #include "gw_spreadsheet.h"
22 #include "api_scilab.h"
23 #include "Scierror.h"
24 #include "sci_malloc.h"
25 #include "Scierror.h"
26 #include "localization.h"
27 #include "freeArrayOfString.h"
28 #include "os_string.h"
29 #include "csvDefault.h"
30 #include "gw_csv_helpers.h"
31 #include "csvDefault.h"
32 
33 // =============================================================================
34 #define SEPARATOR_FIELDNAME "separator"
35 #define DECIMAL_FIELDNAME "decimal"
36 #define CONVERSION_FIELDNAME "conversion"
37 #define PRECISION_FIELDNAME "precision"
38 #define COMMENTSREGEXP_FIELDNAME "regexp"
39 #define EOL_FIELDNAME "eol"
40 #define ENCODING_FIELDNAME "encoding"
41 #define RESET_PARAMATERS "reset"
42 #define BLANK_FIELDNAME "blank"
43 // =============================================================================
44 #define MACOS9_EOL_STRING "macos9"
45 #define MACOS9_EOL "\r"
46 #define WINDOWS_EOL_STRING "windows"
47 #define WINDOWS_EOL "\r\n"
48 #define LINUX_EOL_STRING "linux"
49 #define LINUX_EOL "\n"
50 // =============================================================================
51 #define NUMBER_FIELD 8
52 // =============================================================================
53 static void freeVar(char** fieldname, char** fieldvalue);
54 static int sci_csvDefault_no_rhs(char *fname, void* pvApiCtx);
55 static int sci_csvDefault_one_rhs(char *fname, void* pvApiCtx);
56 static int sci_csvDefault_two_rhs(char *fname, void* pvApiCtx);
57 // =============================================================================
sci_csvDefault(char * fname,void * pvApiCtx)58 int sci_csvDefault(char *fname, void* pvApiCtx)
59 {
60     Rhs = Max(0, Rhs);
61     CheckRhs(0, 2);
62     CheckLhs(0, 1);
63 
64     switch (Rhs)
65     {
66         case 0:
67             return sci_csvDefault_no_rhs(fname, pvApiCtx);
68         case 1:
69             return sci_csvDefault_one_rhs(fname, pvApiCtx);
70         case 2:
71             return sci_csvDefault_two_rhs(fname, pvApiCtx);
72     }
73     return 0;
74 }
75 // =============================================================================
sci_csvDefault_no_rhs(char * fname,void * pvApiCtx)76 static int sci_csvDefault_no_rhs(char *fname, void* pvApiCtx)
77 {
78     int sizeArray = NUMBER_FIELD * 2;
79     char **arrayOut = (char**)MALLOC(sizeof(char*) * sizeArray);
80 
81     if (arrayOut)
82     {
83         SciErr sciErr;
84 
85         int nbRows = NUMBER_FIELD;
86         int nbCols = 2;
87         const char *currentEol = getCsvDefaultEOL();
88 
89         arrayOut[0] = os_strdup(SEPARATOR_FIELDNAME);
90         arrayOut[1] = os_strdup(DECIMAL_FIELDNAME);
91         arrayOut[2] = os_strdup(CONVERSION_FIELDNAME);
92         arrayOut[3] = os_strdup(PRECISION_FIELDNAME);
93         arrayOut[4] = os_strdup(COMMENTSREGEXP_FIELDNAME);
94         arrayOut[5] = os_strdup(EOL_FIELDNAME);
95         arrayOut[6] = os_strdup(ENCODING_FIELDNAME);
96         arrayOut[7] = os_strdup(BLANK_FIELDNAME);
97 
98         arrayOut[8] = os_strdup(getCsvDefaultSeparator());
99         arrayOut[9] = os_strdup(getCsvDefaultDecimal());
100         arrayOut[10] = os_strdup(getCsvDefaultConversion());
101         arrayOut[11] = os_strdup(getCsvDefaultPrecision());
102         arrayOut[12] = os_strdup(getCsvDefaultCommentsRegExp());
103 
104         if (currentEol)
105         {
106             if (strcmp(currentEol, MACOS9_EOL) == 0)
107             {
108                 arrayOut[13] = os_strdup(MACOS9_EOL_STRING);
109             }
110             else if (strcmp(currentEol, WINDOWS_EOL) == 0)
111             {
112                 arrayOut[13] = os_strdup(WINDOWS_EOL_STRING);
113             }
114             else if (strcmp(currentEol, LINUX_EOL) == 0)
115             {
116                 arrayOut[13] = os_strdup(LINUX_EOL_STRING);
117             }
118             else
119             {
120                 arrayOut[13] = os_strdup("ERROR");
121             }
122         }
123         else
124         {
125             arrayOut[13] = os_strdup("ERROR");
126         }
127 
128         arrayOut[14] = os_strdup(getCsvDefaultEncoding());
129         arrayOut[15] = os_strdup(getCsvDefaultCsvIgnoreBlankLine());
130 
131         sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, nbRows, nbCols, arrayOut);
132         freeArrayOfString(arrayOut, sizeArray);
133         if (sciErr.iErr)
134         {
135             printError(&sciErr, 0);
136             return 0;
137         }
138 
139         LhsVar(1) = Rhs + 1;
140         PutLhsVar();
141     }
142     else
143     {
144         Scierror(999, _("%s: Memory allocation error.\n"), fname);
145     }
146 
147     return 0;
148 }
149 // =============================================================================
sci_csvDefault_one_rhs(char * fname,void * pvApiCtx)150 static int sci_csvDefault_one_rhs(char *fname, void* pvApiCtx)
151 {
152     int iErr = 0;
153 
154     char *fieldname = NULL;
155     char *fieldvalue = NULL;
156 
157     fieldname = csv_getArgumentAsString(pvApiCtx, 1, fname, &iErr);
158     if (iErr)
159     {
160         freeVar(&fieldname, &fieldvalue);
161         return 0;
162     }
163 
164     if (strcmp(fieldname, SEPARATOR_FIELDNAME) == 0)
165     {
166         fieldvalue = os_strdup(getCsvDefaultSeparator());
167     }
168     else if (strcmp(fieldname, DECIMAL_FIELDNAME) == 0)
169     {
170         fieldvalue = os_strdup(getCsvDefaultDecimal());
171     }
172     else if (strcmp(fieldname, CONVERSION_FIELDNAME) == 0)
173     {
174         fieldvalue = os_strdup(getCsvDefaultConversion());
175     }
176     else if (strcmp(fieldname, PRECISION_FIELDNAME) == 0)
177     {
178         fieldvalue = os_strdup(getCsvDefaultPrecision());
179     }
180     else if (strcmp(fieldname, COMMENTSREGEXP_FIELDNAME) == 0)
181     {
182         fieldvalue = os_strdup(getCsvDefaultCommentsRegExp());
183     }
184     else if (strcmp(fieldname, EOL_FIELDNAME) == 0)
185     {
186         const char *currentEol = getCsvDefaultEOL();
187         if (currentEol)
188         {
189             if (strcmp(currentEol, MACOS9_EOL) == 0)
190             {
191                 fieldvalue = os_strdup(MACOS9_EOL_STRING);
192             }
193             else if (strcmp(currentEol, WINDOWS_EOL) == 0)
194             {
195                 fieldvalue = os_strdup(WINDOWS_EOL_STRING);
196             }
197             else if (strcmp(currentEol, LINUX_EOL) == 0)
198             {
199                 fieldvalue = os_strdup(LINUX_EOL_STRING);
200             }
201             else
202             {
203                 fieldvalue = os_strdup("ERROR");
204             }
205         }
206         else
207         {
208             fieldvalue = os_strdup("ERROR");
209         }
210     }
211     else if (strcmp(fieldname, ENCODING_FIELDNAME) == 0)
212     {
213         fieldvalue = os_strdup(getCsvDefaultEncoding());
214     }
215     else if (strcmp(fieldname, BLANK_FIELDNAME) == 0)
216     {
217         fieldvalue = os_strdup(getCsvDefaultCsvIgnoreBlankLine());
218     }
219     else if (strcmp(fieldname, RESET_PARAMATERS) == 0)
220     {
221         freeVar(&fieldname, &fieldvalue);
222 
223         setCsvDefaultClear();
224 
225         createEmptyMatrix(pvApiCtx, Rhs + 1);
226 
227         LhsVar(1) = Rhs + 1;
228         PutLhsVar();
229         return 0;
230     }
231     else
232     {
233         Scierror(999, _("%s: Wrong value for input argument #%d: '%s', '%s', '%s', '%s', '%s' or '%s' expected.\n"), fname, 1, SEPARATOR_FIELDNAME, DECIMAL_FIELDNAME, CONVERSION_FIELDNAME, COMMENTSREGEXP_FIELDNAME, EOL_FIELDNAME, BLANK_FIELDNAME);
234         freeVar(&fieldname, &fieldvalue);
235         return 0;
236     }
237 
238     iErr = createSingleString(pvApiCtx, Rhs + 1, fieldvalue);
239     freeVar(&fieldname, &fieldvalue);
240     if (iErr)
241     {
242         return 0;
243     }
244 
245     LhsVar(1) = Rhs + 1;
246     PutLhsVar();
247 
248     return 0;
249 }
250 // =============================================================================
sci_csvDefault_two_rhs(char * fname,void * pvApiCtx)251 static int sci_csvDefault_two_rhs(char *fname, void* pvApiCtx)
252 {
253     int iErr = 0;
254     int resultSet = 0;
255 
256     char *fieldname = NULL;
257     char *fieldvalue = NULL;
258     int  ifieldvalue = 0;
259 
260     fieldname = csv_getArgumentAsString(pvApiCtx, 1, fname, &iErr);
261     if (iErr)
262     {
263         freeVar(&fieldname, &fieldvalue);
264         return 0;
265     }
266 
267     if (strcmp(fieldname, PRECISION_FIELDNAME) == 0)
268     {
269         if (csv_isEmpty(pvApiCtx, 2))
270         {
271             freeVar(&fieldname, &fieldvalue);
272             Scierror(999, _("%s: Wrong type for input argument #%d: A double expected.\n"), fname, 2);
273             return 0;
274         }
275 
276         if (csv_isDoubleScalar(pvApiCtx, 2))
277         {
278 #define FORMAT_FIELDVALUESTR "%%.%dlg"
279             ifieldvalue = (int) csv_getArgumentAsScalarDouble(pvApiCtx, 2, fname, &iErr);
280             if (iErr)
281             {
282                 freeVar(&fieldname, &fieldvalue);
283                 return 0;
284             }
285 
286             if ((ifieldvalue < 1) || (ifieldvalue > 17))
287             {
288                 freeVar(&fieldname, &fieldvalue);
289                 Scierror(999, _("%s: Wrong value for input argument #%d: A double (value %d to %d) expected.\n"), fname, 2, 1, 17);
290                 return 0;
291             }
292 
293             fieldvalue = (char*)MALLOC(sizeof(char) * ((int)strlen(FORMAT_FIELDVALUESTR) + 1));
294             if (fieldvalue == NULL)
295             {
296                 freeVar(&fieldname, &fieldvalue);
297                 Scierror(999, _("%s: Memory allocation error.\n"), fname);
298                 return 0;
299             }
300             sprintf(fieldvalue, FORMAT_FIELDVALUESTR, ifieldvalue);
301         }
302         else
303         {
304             fieldvalue = csv_getArgumentAsString(pvApiCtx, 2, fname, &iErr);
305             if (iErr)
306             {
307                 freeVar(&fieldname, &fieldvalue);
308                 return 0;
309             }
310         }
311     }
312     else
313     {
314         fieldvalue = csv_getArgumentAsString(pvApiCtx, 2, fname, &iErr);
315         if (iErr)
316         {
317             freeVar(&fieldname, &fieldvalue);
318             return 0;
319         }
320     }
321 
322     if (strcmp(fieldname, SEPARATOR_FIELDNAME) == 0)
323     {
324         resultSet = setCsvDefaultSeparator(fieldvalue);
325     }
326     else if (strcmp(fieldname, DECIMAL_FIELDNAME) == 0)
327     {
328         resultSet = setCsvDefaultDecimal(fieldvalue);
329     }
330     else if (strcmp(fieldname, CONVERSION_FIELDNAME) == 0)
331     {
332         resultSet = setCsvDefaultConversion(fieldvalue);
333     }
334     else if (strcmp(fieldname, PRECISION_FIELDNAME) == 0)
335     {
336         resultSet = setCsvDefaultPrecision(fieldvalue);
337     }
338     else if (strcmp(fieldname, COMMENTSREGEXP_FIELDNAME) == 0)
339     {
340         resultSet = setCsvDefaultCommentsRegExp(fieldvalue);
341     }
342     else if (strcmp(fieldname, EOL_FIELDNAME) == 0)
343     {
344         if (strcmp(fieldvalue, MACOS9_EOL_STRING) == 0)
345         {
346             resultSet = setCsvDefaultEOL(MACOS9_EOL);
347         }
348         else if (strcmp(fieldvalue, WINDOWS_EOL_STRING) == 0)
349         {
350             resultSet = setCsvDefaultEOL(WINDOWS_EOL);
351         }
352         else if (strcmp(fieldvalue, LINUX_EOL_STRING) == 0)
353         {
354             resultSet = setCsvDefaultEOL(LINUX_EOL);
355         }
356         else
357         {
358             resultSet = 1;
359         }
360     }
361     else if (strcmp(fieldname, ENCODING_FIELDNAME) == 0)
362     {
363         resultSet = setCsvDefaultEncoding(fieldvalue);
364     }
365     else if (strcmp(fieldname, BLANK_FIELDNAME) == 0)
366     {
367         resultSet = setCsvDefaultCsvIgnoreBlankLine(fieldvalue);
368     }
369     else
370     {
371         Scierror(999, _("%s: Wrong value for input argument #%d: '%s', '%s', '%s' , '%s', '%s', '%s', '%s' or '%s' expected.\n"), fname, 1, SEPARATOR_FIELDNAME, DECIMAL_FIELDNAME, CONVERSION_FIELDNAME, PRECISION_FIELDNAME, COMMENTSREGEXP_FIELDNAME, EOL_FIELDNAME, ENCODING_FIELDNAME, BLANK_FIELDNAME);
372         freeVar(&fieldname, &fieldvalue);
373         return 0;
374     }
375 
376     createScalarBoolean(pvApiCtx, Rhs + 1, (resultSet == 0));
377 
378     freeVar(&fieldname, &fieldvalue);
379 
380     LhsVar(1) = Rhs + 1;
381     PutLhsVar();
382 
383     return 0;
384 }
385 // =============================================================================
freeVar(char ** fieldname,char ** fieldvalue)386 static void freeVar(char** fieldname, char** fieldvalue)
387 {
388     if (fieldname && *fieldname)
389     {
390         FREE(*fieldname);
391         *fieldname = NULL;
392     }
393 
394     if (fieldvalue && *fieldvalue)
395     {
396         FREE(*fieldvalue);
397         *fieldvalue = NULL;
398     }
399 }
400