a6a5c4a29a689345c8434e7a1a6889c1ac77d4c3
[scilab.git] / scilab / modules / spreadsheet / src / c / splitLine.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2011 - DIGITEO - Allan CORNET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 #include <string.h>
13 #include <stdio.h>
14 #include "splitLine.h"
15 #include "csv_strsubst.h"
16 #include "MALLOC.h"
17 /* ==================================================================== */
18 char **splitLineCSV(const char *str, const char *sep, int *toks, char meta)
19 {
20 #define EMPTYFIELD "__EMPTY_FIELD_CSV__"
21     char **retstr = NULL;
22     const char *idx = NULL;
23     const char *end = NULL;
24     const char *sep_end = NULL;
25     const char *sep_idx = NULL;
26     int len = 0;
27     int curr_str = 0;
28     char last_char = 0xFF;
29
30     /* Usually, it should be ,, or ;; */
31     char tokenstring_to_search[64] = "";
32     /* Previous item will be replaced by ;__EMPTY_FIELD_CSV__; */
33     char tokenreplacement_string[64] = "";
34     char *substitutedstring = NULL;
35
36     sprintf(tokenstring_to_search, "%s%s", sep, sep);
37     sprintf(tokenreplacement_string, "%s%s%s", sep, EMPTYFIELD, sep);
38     substitutedstring = csv_strsubst(str, tokenstring_to_search, tokenreplacement_string);
39     /* in a string like foo;bar;;;, replace all the ;;, not only the first and last one */
40     while (strstr(substitutedstring, tokenstring_to_search) != NULL) {
41         substitutedstring = csv_strsubst(substitutedstring, tokenstring_to_search, tokenreplacement_string);
42     }
43
44     if (strncmp(substitutedstring, sep, strlen(sep)) == 0)
45     {
46         char *tmp = NULL;
47         size_t l = strlen(substitutedstring) + strlen(EMPTYFIELD) + strlen(sep) + 1;
48         tmp = (char*)MALLOC(sizeof(char) * l);
49         sprintf(tmp, "%s%s%s", EMPTYFIELD, sep, &substitutedstring[1]);
50         FREE(substitutedstring);
51         substitutedstring = tmp;
52     }
53
54     if (substitutedstring[strlen(substitutedstring) - 1] == sep[0])
55     {
56         char *tmp = NULL;
57         size_t l = strlen(substitutedstring) + strlen(EMPTYFIELD) + 1;
58         tmp = (char*)MALLOC(sizeof(char) * l);
59         sprintf(tmp, "%s%s", substitutedstring, EMPTYFIELD);
60         FREE(substitutedstring);
61         substitutedstring = tmp;
62
63     }
64
65     sep_end = sep + strlen(sep);
66     end = substitutedstring + strlen(substitutedstring);
67
68     sep_idx = sep;
69     idx = substitutedstring;
70
71     if (strstr(substitutedstring, sep) == NULL)
72     {
73         *toks = 0;
74         FREE(substitutedstring);
75         substitutedstring = NULL;
76         return NULL;
77     }
78
79     retstr = (char **) MALLOC((sizeof(char *) * (int)strlen(substitutedstring)));
80     if (retstr == NULL)
81     {
82         *toks = 0;
83         FREE(substitutedstring);
84         substitutedstring = NULL;
85         return NULL;
86     }
87
88     while (idx < end)
89     {
90         while (sep_idx < sep_end)
91         {
92             if ((*idx == *sep_idx) && (last_char != meta))
93             {
94                 if (len > 0)
95                 {
96                     if (curr_str < (int)strlen(substitutedstring))
97                     {
98                         retstr[curr_str] = (char *) MALLOC((sizeof(char) * len) + 1);
99
100                         if (retstr[curr_str] == NULL)
101                         {
102                             *toks = 0;
103                             FREE(substitutedstring);
104                             substitutedstring = NULL;
105                             return NULL;
106                         }
107                         memcpy(retstr[curr_str], (idx - len), len);
108                         retstr[curr_str][len] = 0;
109                         if (strcmp(retstr[curr_str], EMPTYFIELD) == 0)
110                         {
111                             strcpy(retstr[curr_str], "");
112                         }
113                         len = 0;
114                         curr_str++;
115                         last_char = *idx;
116                         idx++;
117                     }
118
119                     if (curr_str >= (int)strlen(substitutedstring))
120                     {
121                         *toks = curr_str + 1;
122                         FREE(substitutedstring);
123                         substitutedstring = NULL;
124                         return retstr;
125                     }
126                 }
127                 else
128                 {
129                     last_char = *idx;
130                     idx++;
131                     sep_idx = sep;
132                     len = 0;
133                 }
134             }
135             else
136             {
137                 sep_idx++;
138             }
139         }
140
141         sep_idx = sep;
142         len++;
143         last_char = *idx;
144         idx++;
145     }
146
147     if (len > 0)
148     {
149         retstr[curr_str] = (char *) MALLOC((sizeof(char) * len) + 1);
150
151         if (retstr[curr_str] == NULL)
152         {
153             *toks = 0;
154             if (substitutedstring)
155             {
156                 FREE(substitutedstring);
157                 substitutedstring = NULL;
158             }
159             return NULL;
160         }
161
162         memcpy(retstr[curr_str], (idx - len), len);
163         retstr[curr_str][len] = 0;
164         if (strcmp(retstr[curr_str], EMPTYFIELD) == 0)
165         {
166             strcpy(retstr[curr_str], "");
167         }
168
169         *toks = curr_str + 1;
170     }
171
172     if (substitutedstring)
173     {
174         FREE(substitutedstring);
175         substitutedstring = NULL;
176     }
177
178     return retstr;
179 }
180 /* ==================================================================== */