Coverity: String module Resource Leaks fixed
[scilab.git] / scilab / modules / string / src / c / strsubst.c
1
2 /*
3  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4  * Copyright (C) INRIA - Allan CORNET
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  */
16
17 /*--------------------------------------------------------------------------*/
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <wchar.h>
22 #include "strsubst.h"
23 #include "sci_malloc.h"
24 #include "pcre_private.h"
25 #include "os_string.h"
26 #include "charEncoding.h"
27 /*--------------------------------------------------------------------------*/
28 char **strsubst(const char **strings_input, int strings_dim, const char *string_to_search, const char *replacement_string)
29 {
30     char **replacedStrings = NULL;
31
32     if ( (strings_input) && (string_to_search) && (replacement_string) )
33     {
34         int i = 0;
35         replacedStrings = (char**)MALLOC(sizeof(char*) * strings_dim);
36         for (i = 0; i < strings_dim; i++)
37         {
38             const char *str = strings_input[i];
39             replacedStrings[i] = strsub (str, string_to_search, replacement_string);
40         }
41     }
42     return replacedStrings;
43 }
44 /*--------------------------------------------------------------------------*/
45 char **strsubst_reg(const char **strings_input, int strings_dim, const char *string_to_search, const char *replacement_string, int *ierr)
46 {
47     char **replacedStrings = NULL;
48
49     if ( (strings_input) && (string_to_search) && (replacement_string) )
50     {
51         int i = 0;
52         replacedStrings = (char**)MALLOC(sizeof(char*) * strings_dim);
53         for (i = 0; i < strings_dim; i++)
54         {
55             const char *str = strings_input[i];
56             replacedStrings[i] = strsub_reg(str, string_to_search, replacement_string, ierr);
57         }
58     }
59     return replacedStrings;
60 }
61 /*-------------------------------------------------------------------------------------*/
62 char *strsub(const char* input_string, const char* string_to_search, const char* replacement_string)
63 {
64     const char *occurrence_str = NULL;
65     char* result_str = NULL;
66     char *replacedString = NULL;
67     int count = 0, len = 0;
68
69     if (input_string == NULL)
70     {
71         return NULL;
72     }
73
74     if (string_to_search == NULL || replacement_string == NULL)
75     {
76         return os_strdup(input_string);
77     }
78
79     occurrence_str = strstr (input_string, string_to_search);
80     if (occurrence_str == NULL)
81     {
82         return os_strdup(input_string);
83     }
84
85     if (strlen (replacement_string) > strlen (string_to_search))
86     {
87         count = 0;
88         len = (int)strlen (string_to_search);
89         if (len)
90         {
91             occurrence_str = input_string;
92             while (occurrence_str != NULL && *occurrence_str != '\0')
93             {
94                 occurrence_str = strstr (occurrence_str, string_to_search);
95                 if (occurrence_str != NULL)
96                 {
97                     occurrence_str += len;
98                     count++;
99                 }
100             }
101         }
102         len = count * ((int)strlen(replacement_string) - (int)strlen(string_to_search)) + (int)strlen(input_string);
103     }
104     else
105     {
106         len = (int)strlen(input_string);
107     }
108
109     replacedString = (char*)MALLOC (sizeof(char) * (len + 1));
110     if (replacedString == NULL)
111     {
112         return NULL;
113     }
114
115     occurrence_str = input_string;
116     result_str = replacedString;
117     len = (int)strlen (string_to_search);
118     while (*occurrence_str != '\0')
119     {
120         if (*occurrence_str == string_to_search[0] && strncmp (occurrence_str, string_to_search, len) == 0)
121         {
122             const char *N = NULL;
123             N = replacement_string;
124             while (*N != '\0')
125             {
126                 *result_str++ = *N++;
127             }
128             occurrence_str += len;
129         }
130         else
131         {
132             *result_str++ = *occurrence_str++;
133         }
134     }
135     *result_str = '\0';
136
137     return replacedString;
138 }/*-------------------------------------------------------------------------------------*/
139 char *strsub_reg(const char* input_string, const char* string_to_search, const char* replacement_string, int *ierr)
140 {
141     pcre_error_code w = PCRE_FINISHED_OK;
142
143     int Output_Start = 0;
144     int Output_End = 0;
145
146     char *replacedString = NULL;
147     wchar_t *wcreplacedString = NULL;
148
149     wchar_t *wcreplacement_string = NULL;
150     wchar_t *wcinput_string = NULL;
151
152     int len = 0;
153
154     *ierr = (int)PCRE_FINISHED_OK;
155
156     if (input_string == NULL)
157     {
158         return NULL;
159     }
160
161     if (string_to_search == NULL || replacement_string == NULL)
162     {
163         return os_strdup(input_string);
164     }
165
166     w = pcre_private((char*)input_string, (char*)string_to_search, &Output_Start, &Output_End, NULL, NULL);
167     if (w != PCRE_FINISHED_OK)
168     {
169         *ierr = (int)w;
170         return os_strdup(input_string);
171     }
172
173     wcreplacement_string = to_wide_string((char*)replacement_string);
174     wcinput_string = to_wide_string((char*)input_string);
175
176     if (wcreplacement_string == NULL)
177     {
178         FREE(wcinput_string);
179         *ierr = (int)NOT_ENOUGH_MEMORY_FOR_VECTOR;
180         return os_strdup(input_string);
181     }
182
183     len = (int)wcslen(wcreplacement_string) + (int)wcslen(wcinput_string);
184
185     wcreplacedString = (wchar_t*)MALLOC (sizeof(wchar_t) * (len + 1));
186     if (wcreplacedString == NULL)
187     {
188         FREE(wcreplacement_string);
189         FREE(wcinput_string);
190         return NULL;
191     }
192
193     {
194         /* converts to wide characters */
195
196         wchar_t *wctail = NULL;
197
198         int wcOutput_Start = 0;
199         int wcOutput_End = 0;
200
201         char *  strOutput_Start = os_strdup(input_string);
202         char *  strOutput_End =  os_strdup(input_string);
203
204         wchar_t *wcstrOutput_Start = NULL;
205         wchar_t *wcstrOutput_End = NULL;
206
207         /* calculates positions with wide characters */
208         strOutput_Start[Output_Start] = '\0';
209         strOutput_End[Output_End] = '\0';
210
211         wcstrOutput_Start = to_wide_string(strOutput_Start);
212         wcstrOutput_End = to_wide_string(strOutput_End);
213
214         FREE(strOutput_Start);
215         FREE(strOutput_End);
216
217         if (wcstrOutput_Start)
218         {
219             wcOutput_Start = (int)wcslen(wcstrOutput_Start);
220             FREE(wcstrOutput_Start);
221         }
222         else
223         {
224             wcOutput_Start = 0;
225         }
226
227         if (wcstrOutput_End)
228         {
229             wcOutput_End = (int)wcslen(wcstrOutput_End);
230             FREE(wcstrOutput_End);
231         }
232         else
233         {
234             wcOutput_End = 0;
235         }
236
237         wcsncpy(wcreplacedString, wcinput_string, wcOutput_Start);
238         wcreplacedString[wcOutput_Start] = L'\0';
239         wcscat(wcreplacedString, wcreplacement_string);
240         wctail = wcinput_string + wcOutput_End;
241         wcscat(wcreplacedString, wctail);
242         replacedString = wide_string_to_UTF8(wcreplacedString);
243
244         FREE(wcreplacedString);
245     }
246
247     FREE(wcinput_string);
248     FREE(wcreplacement_string);
249
250     return replacedString;
251 }
252 /*-------------------------------------------------------------------------------------*/
253 wchar_t *wcssub_reg(const wchar_t* _pwstInput, const wchar_t* _pwstSearch, const wchar_t* _pwstReplace, int* _piErr)
254 {
255     pcre_error_code iPcreStatus = PCRE_FINISHED_OK;
256     int iStart = 0;
257     int iEnd = 0;
258     int iLen = 0;
259
260     wchar_t* pwstOutput = NULL;
261
262     if (_pwstInput == NULL)
263     {
264         return NULL;
265     }
266
267     if (_pwstSearch == NULL || _pwstReplace == NULL)
268     {
269         return os_wcsdup(_pwstInput);
270     }
271
272     iPcreStatus = wide_pcre_private((wchar_t*)_pwstInput, (wchar_t*)_pwstSearch, &iStart, &iEnd, NULL, NULL);
273     if (iPcreStatus != PCRE_FINISHED_OK)
274     {
275         *_piErr = iPcreStatus;
276         return os_wcsdup(_pwstInput);
277     }
278
279     //compute new size of output string
280     iLen += (int)wcslen(_pwstReplace) - (iEnd - iStart);
281
282     pwstOutput = (wchar_t*)MALLOC(sizeof(wchar_t) * (wcslen(_pwstInput) + iLen + 1));
283     memset(pwstOutput, 0x00, sizeof(wchar_t) * (wcslen(_pwstInput) + iLen + 1));
284
285     //copy start of original string
286     wcsncpy(pwstOutput, _pwstInput, iStart);
287     //copy replace string
288     wcscpy(pwstOutput + wcslen(pwstOutput), _pwstReplace);
289     //copy end of original string
290     wcscpy(pwstOutput + wcslen(pwstOutput), _pwstInput + iEnd);
291
292     *_piErr = iPcreStatus;
293     return pwstOutput;
294 }
295 /*-------------------------------------------------------------------------------------*/
296 wchar_t **wcssubst_reg(const wchar_t** _pwstInput, int _iInputSize, const wchar_t* _pwstSearch, const wchar_t* _pwstReplace, int* _piErr)
297 {
298     wchar_t** pwstOutput = NULL;
299
300     if (_pwstInput != NULL && _pwstSearch != NULL && _pwstReplace != NULL)
301     {
302         int i = 0;
303         pwstOutput = (wchar_t**)MALLOC(sizeof(wchar_t*) * _iInputSize);
304         for (i = 0 ; i < _iInputSize ; i++)
305         {
306             const wchar_t* pwst = _pwstInput[i];
307             pwstOutput[i] = wcssub_reg(pwst, _pwstSearch, _pwstReplace, _piErr);
308         }
309     }
310     return pwstOutput;
311 }
312 /*-------------------------------------------------------------------------------------*/
313 wchar_t **wcssubst(const wchar_t** _pwstInput, int _iInputSize, const wchar_t* _pwstSearch, const wchar_t* _pwstReplace)
314 {
315     wchar_t** pwstOutput = NULL;
316
317     if (_pwstInput != NULL && _pwstSearch != NULL && _pwstReplace != NULL)
318     {
319         int i = 0;
320         pwstOutput = (wchar_t**)MALLOC(sizeof(wchar_t*) * _iInputSize);
321         for (i = 0 ; i < _iInputSize ; i++)
322         {
323             const wchar_t* pwst = _pwstInput[i];
324             if (wcslen(pwst) == 0)
325             {
326                 pwstOutput[i] = os_wcsdup(L"");
327             }
328             else
329             {
330                 pwstOutput[i] = wcssub(pwst, _pwstSearch, _pwstReplace);
331             }
332         }
333     }
334     return pwstOutput;
335 }
336 /*-------------------------------------------------------------------------------------*/
337 wchar_t *wcssub(const wchar_t* _pwstInput, const wchar_t* _pwstSearch, const wchar_t* _pwstReplace)
338 {
339     int i               = 0;
340     int iOccurs         = 0;
341     size_t iReplace     = 0;
342     size_t iSearch      = 0;
343     size_t iOffset      = 0;
344
345     size_t* piStart     = NULL;
346
347     const wchar_t* pwstPos  = NULL;
348     wchar_t* pwstOutput     = NULL;
349
350     if (_pwstInput == NULL)
351     {
352         return NULL;
353     }
354
355     if (_pwstInput[0] == L'\0')
356     {
357         return os_wcsdup(L"");
358     }
359
360     if (_pwstSearch == NULL || _pwstReplace == NULL)
361     {
362         return os_wcsdup(_pwstInput);
363     }
364
365     iSearch     = wcslen(_pwstSearch);
366     iReplace    = wcslen(_pwstReplace);
367     piStart     = (size_t*)MALLOC(sizeof(size_t) * wcslen(_pwstInput));
368     pwstPos     = _pwstInput;
369
370     while (pwstPos)
371     {
372         pwstPos = wcsstr(pwstPos, _pwstSearch);
373         if (pwstPos)
374         {
375             piStart[iOccurs++]  = pwstPos - _pwstInput;
376             iOffset             += iReplace - iSearch;
377             pwstPos++;
378         }
379     }
380
381     pwstOutput = (wchar_t*)MALLOC(sizeof(wchar_t) * (wcslen(_pwstInput) + iOffset + 1));
382     memset(pwstOutput, 0x00, sizeof(wchar_t) * (wcslen(_pwstInput) + iOffset + 1));
383
384     if (iOccurs == 0)
385     {
386         wcscpy(pwstOutput, _pwstInput);
387     }
388     else
389     {
390         for (i = 0 ; i < iOccurs ; i++)
391         {
392             if (i == 0)
393             {
394                 //copy start of original string
395                 wcsncpy(pwstOutput, _pwstInput, piStart[i]);
396             }
397             else
398             {
399                 //copy start of original string
400                 wcsncpy(pwstOutput + wcslen(pwstOutput), _pwstInput + piStart[i - 1] + iSearch, piStart[i] - (iSearch + piStart[i - 1]));
401             }
402             //copy replace string
403             wcscpy(pwstOutput + wcslen(pwstOutput), _pwstReplace);
404         }
405         //copy end of original string
406         wcscpy(pwstOutput + wcslen(pwstOutput), _pwstInput + piStart[iOccurs - 1] + iSearch);
407     }
408
409     FREE(piStart);
410     return pwstOutput;
411 }
412 /*-------------------------------------------------------------------------------------*/