Remove a memory leak in splitline
[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 #include "freeArrayOfString.h"
18 /* ==================================================================== */
19 char **splitLineCSV(const char *str, const char *sep, int *toks, char meta)
20 {
21 #define EMPTYFIELD "__EMPTY_FIELD_CSV__"
22     char **retstr = NULL;
23     const char *idx = NULL;
24     const char *end = NULL;
25     const char *sep_end = NULL;
26     const char *sep_idx = NULL;
27     int len = 0;
28     int curr_str = 0;
29     char last_char = 0xFF;
30
31     /* Usually, it should be ,, or ;; */
32     char tokenstring_to_search[64] = "";
33     /* Previous item will be replaced by ;__EMPTY_FIELD_CSV__; */
34     char tokenreplacement_string[64] = "";
35     char *substitutedstring = NULL;
36
37     sprintf(tokenstring_to_search, "%s%s", sep, sep);
38     sprintf(tokenreplacement_string, "%s%s%s", sep, EMPTYFIELD, sep);
39     substitutedstring = csv_strsubst(str, tokenstring_to_search, tokenreplacement_string);
40     /* in a string like foo;bar;;;, replace all the ;;, not only the first and last one */
41     while (strstr(substitutedstring, tokenstring_to_search) != NULL)
42     {
43         substitutedstring = csv_strsubst(substitutedstring, tokenstring_to_search, tokenreplacement_string);
44     }
45
46     if (strncmp(substitutedstring, sep, strlen(sep)) == 0)
47     {
48         char *tmp = NULL;
49         size_t l = strlen(substitutedstring) + strlen(EMPTYFIELD) + strlen(sep) + 1;
50         tmp = (char*)MALLOC(sizeof(char) * l);
51         sprintf(tmp, "%s%s%s", EMPTYFIELD, sep, &substitutedstring[1]);
52         FREE(substitutedstring);
53         substitutedstring = tmp;
54     }
55
56     if (substitutedstring[strlen(substitutedstring) - 1] == sep[0])
57     {
58         char *tmp = NULL;
59         size_t l = strlen(substitutedstring) + strlen(EMPTYFIELD) + 1;
60         tmp = (char*)MALLOC(sizeof(char) * l);
61         sprintf(tmp, "%s%s", substitutedstring, EMPTYFIELD);
62         FREE(substitutedstring);
63         substitutedstring = tmp;
64
65     }
66
67     sep_end = sep + strlen(sep);
68     end = substitutedstring + strlen(substitutedstring);
69
70     sep_idx = sep;
71     idx = substitutedstring;
72
73     if (strstr(substitutedstring, sep) == NULL)
74     {
75         *toks = 0;
76         FREE(substitutedstring);
77         substitutedstring = NULL;
78         return NULL;
79     }
80
81     retstr = (char **) MALLOC((sizeof(char *) * (int)strlen(substitutedstring)));
82     if (retstr == NULL)
83     {
84         *toks = 0;
85         FREE(substitutedstring);
86         substitutedstring = NULL;
87         return NULL;
88     }
89
90     while (idx < end)
91     {
92         while (sep_idx < sep_end)
93         {
94             if ((*idx == *sep_idx) && (last_char != meta))
95             {
96                 if (len > 0)
97                 {
98                     if (curr_str < (int)strlen(substitutedstring))
99                     {
100                         retstr[curr_str] = (char *) MALLOC((sizeof(char) * len) + 1);
101
102                         if (retstr[curr_str] == NULL)
103                         {
104                             *toks = 0;
105                             FREE(substitutedstring);
106                             substitutedstring = NULL;
107                             freeArrayOfString(retstr, strlen(substitutedstring));
108                             return NULL;
109                         }
110                         memcpy(retstr[curr_str], (idx - len), len);
111                         retstr[curr_str][len] = 0;
112                         if (strcmp(retstr[curr_str], EMPTYFIELD) == 0)
113                         {
114                             strcpy(retstr[curr_str], "");
115                         }
116                         len = 0;
117                         curr_str++;
118                         last_char = *idx;
119                         idx++;
120                     }
121
122                     if (curr_str >= (int)strlen(substitutedstring))
123                     {
124                         *toks = curr_str + 1;
125                         FREE(substitutedstring);
126                         substitutedstring = NULL;
127                         return retstr;
128                     }
129                 }
130                 else
131                 {
132                     last_char = *idx;
133                     idx++;
134                     sep_idx = sep;
135                     len = 0;
136                 }
137             }
138             else
139             {
140                 sep_idx++;
141             }
142         }
143
144         sep_idx = sep;
145         len++;
146         last_char = *idx;
147         idx++;
148     }
149
150     if (len > 0)
151     {
152         retstr[curr_str] = (char *) MALLOC((sizeof(char) * len) + 1);
153
154         if (retstr[curr_str] == NULL)
155         {
156             *toks = 0;
157             if (substitutedstring)
158             {
159                 FREE(substitutedstring);
160                 substitutedstring = NULL;
161             }
162             freeArrayOfString(retstr, strlen(substitutedstring));
163             return NULL;
164         }
165
166         memcpy(retstr[curr_str], (idx - len), len);
167         retstr[curr_str][len] = 0;
168         if (strcmp(retstr[curr_str], EMPTYFIELD) == 0)
169         {
170             strcpy(retstr[curr_str], "");
171         }
172
173         *toks = curr_str + 1;
174     }
175
176     if (substitutedstring)
177     {
178         FREE(substitutedstring);
179         substitutedstring = NULL;
180     }
181
182     return retstr;
183 }
184 /* ==================================================================== */