add some Scierror after printError to create an error in Scilab
[scilab.git] / scilab / modules / string / sci_gateway / c / sci_strsubst.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA - Cong WU , Allan CORNET
4  * Copyright (C) DIGITEO - 2009 - Allan CORNET
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  */
13 /*------------------------------------------------------------------------*/
14 #include <string.h>
15 #include "gw_string.h"
16 #include "stack-c.h"
17 #include "MALLOC.h"
18 #include "api_scilab.h"
19 #include "freeArrayOfString.h"
20 #include "strsubst.h"
21 #include "localization.h"
22 #include "Scierror.h"
23 #include "pcre_error.h"
24 #include "pcre_private.h"
25 #include "BOOL.h"
26 /*-------------------------------------------------------------------------------------*/
27 #define CHAR_R "r"
28 #define CHAR_S "s"
29 /*-------------------------------------------------------------------------------------*/
30 int sci_strsubst(char *fname, unsigned long fname_len)
31 {
32     SciErr sciErr;
33     int *piAddressVarOne = NULL;
34     int iType = 0;
35     int mOne = 0, nOne = 0;
36
37     CheckRhs(3, 4);
38     CheckLhs(1, 1);
39
40     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
41     if (sciErr.iErr)
42     {
43         printError(&sciErr, 0);
44         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
45         return 0;
46     }
47     sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType);
48     if (sciErr.iErr)
49     {
50         printError(&sciErr, 0);
51         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
52         return 0;
53     }
54
55     if (iType == sci_strings)
56     {
57         char **pStVarOne = NULL;
58         int *lenStVarOne = NULL;
59
60         int *piAddressVarTwo = NULL;
61         int iType2 = 0;
62         int mTwo = 0, nTwo = 0;
63         char *pStVarTwo = NULL;
64         int lenStVarTwo = 0;
65
66         int *piAddressVarThree = NULL;
67         int mThree = 0, nThree = 0;
68         char *pStVarThree = NULL;
69         int lenStVarThree = 0;
70         int iType3 = 0;
71
72         BOOL isRegExp = FALSE;
73
74         if (Rhs == 4)
75         {
76             int *piAddressVarFour = NULL;
77             int iType4 = 0;
78             int mFour = 0, nFour = 0;
79             char *pStVarFour = NULL;
80             int lenStVarFour = 0;
81
82             sciErr = getVarAddressFromPosition(pvApiCtx, 4, &piAddressVarFour);
83             if (sciErr.iErr)
84             {
85                 printError(&sciErr, 0);
86                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4);
87                 return 0;
88             }
89
90             sciErr = getVarType(pvApiCtx, piAddressVarFour, &iType4);
91             if (sciErr.iErr)
92             {
93                 printError(&sciErr, 0);
94                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4);
95                 return 0;
96             }
97
98             if (iType4 != sci_strings)
99             {
100                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 4);
101                 return 0;
102             }
103
104             sciErr = getMatrixOfString(pvApiCtx, piAddressVarFour, &mFour, &nFour, &lenStVarFour, NULL);
105             if (sciErr.iErr)
106             {
107                 printError(&sciErr, 0);
108                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4);
109                 return 0;
110             }
111
112             if ((mFour != nFour) && (nFour != 1))
113             {
114                 Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 4);
115                 return 0;
116             }
117
118             pStVarFour = (char *)MALLOC(sizeof(char) * (lenStVarFour + 1));
119             if (pStVarFour)
120             {
121                 sciErr = getMatrixOfString(pvApiCtx, piAddressVarFour, &mFour, &nFour, &lenStVarFour, &pStVarFour);
122                 if (sciErr.iErr)
123                 {
124                     printError(&sciErr, 0);
125                     Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 4);
126                     return 0;
127                 }
128
129                 if ((strcmp(pStVarFour, CHAR_R) == 0) || (strcmp(pStVarFour, CHAR_S) == 0))
130                 {
131                     if (strcmp(pStVarFour, CHAR_R) == 0)
132                     {
133                         isRegExp = TRUE;
134                     }
135                     else
136                     {
137                         isRegExp = FALSE;
138                     }
139                     FREE(pStVarFour);
140                     pStVarFour = NULL;
141                 }
142                 else
143                 {
144                     FREE(pStVarFour);
145                     pStVarFour = NULL;
146                     Scierror(999, _("%s: Wrong value for input argument #%d: '%s' or '%s' expected.\n"), fname, 4, "s", "r");
147                     return 0;
148                 }
149             }
150             else
151             {
152                 Scierror(999, _("%s: No more memory.\n"), fname);
153                 return 0;
154             }
155         }
156
157         sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddressVarThree);
158         if (sciErr.iErr)
159         {
160             printError(&sciErr, 0);
161             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
162             return 0;
163         }
164
165         // checks type 3th input argument
166         sciErr = getVarType(pvApiCtx, piAddressVarThree, &iType3);
167         if (sciErr.iErr)
168         {
169             printError(&sciErr, 0);
170             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
171             return 0;
172         }
173
174         if (iType3 != sci_strings)
175         {
176             Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 3);
177             return 0;
178         }
179
180         // checks dimension 3th input argument
181         sciErr = getMatrixOfString(pvApiCtx, piAddressVarThree, &mThree, &nThree, &lenStVarThree, NULL);
182         if (sciErr.iErr)
183         {
184             printError(&sciErr, 0);
185             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
186             return 0;
187         }
188
189         if ((mThree != nThree) && (nThree != 1))
190         {
191             Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 3);
192             return 0;
193         }
194
195         sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo);
196         if (sciErr.iErr)
197         {
198             printError(&sciErr, 0);
199             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
200             return 0;
201         }
202
203         // checks type 2nd input argument
204         sciErr = getVarType(pvApiCtx, piAddressVarTwo, &iType2);
205         if (sciErr.iErr)
206         {
207             printError(&sciErr, 0);
208             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
209             return 0;
210         }
211
212         if (iType2 != sci_strings)
213         {
214             Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 2);
215             return 0;
216         }
217
218         // checks dimension 2nd input argument
219         sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &mTwo, &nTwo, &lenStVarTwo, NULL);
220         if (sciErr.iErr)
221         {
222             printError(&sciErr, 0);
223             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
224             return 0;
225         }
226
227         if ((mTwo != nTwo) && (nTwo != 1))
228         {
229             Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 2);
230             return 0;
231         }
232
233         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne);
234         if (sciErr.iErr)
235         {
236             printError(&sciErr, 0);
237             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
238             return 0;
239         }
240
241         // checks type 1st input argument
242         sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType);
243         if (iType != sci_strings)
244         {
245             Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 1);
246             return 0;
247         }
248
249         // get length 3th input argument
250         sciErr = getMatrixOfString(pvApiCtx, piAddressVarThree, &mThree, &nThree, &lenStVarThree, NULL);
251         if (sciErr.iErr)
252         {
253             printError(&sciErr, 0);
254             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
255             return 0;
256         }
257
258         pStVarThree = (char *)MALLOC(sizeof(char) * (lenStVarThree + 1));
259         if (pStVarThree)
260         {
261             // get value 3th input argument
262             sciErr = getMatrixOfString(pvApiCtx, piAddressVarThree, &mThree, &nThree, &lenStVarThree, &pStVarThree);
263             if (sciErr.iErr)
264             {
265                 printError(&sciErr, 0);
266                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
267                 return 0;
268             }
269
270             // get length 2nd input argument
271             sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &mTwo, &nTwo, &lenStVarTwo, NULL);
272             if (sciErr.iErr)
273             {
274                 printError(&sciErr, 0);
275                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
276                 return 0;
277             }
278
279             pStVarTwo = (char *)MALLOC(sizeof(char) * (lenStVarTwo + 1));
280             if (pStVarTwo)
281             {
282                 // get value 2nd input argument
283                 sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &mTwo, &nTwo, &lenStVarTwo, &pStVarTwo);
284                 if (sciErr.iErr)
285                 {
286                     printError(&sciErr, 0);
287                     Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
288                     return 0;
289                 }
290
291                 sciErr = getMatrixOfString(pvApiCtx, piAddressVarOne, &mOne, &nOne, lenStVarOne, NULL);
292                 if (sciErr.iErr)
293                 {
294                     printError(&sciErr, 0);
295                     Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
296                     return 0;
297                 }
298
299                 lenStVarOne = (int *)MALLOC(sizeof(int) * (mOne * nOne));
300                 if (lenStVarOne)
301                 {
302                     sciErr = getMatrixOfString(pvApiCtx, piAddressVarOne, &mOne, &nOne, lenStVarOne, NULL);
303                     if (sciErr.iErr)
304                     {
305                         printError(&sciErr, 0);
306                         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
307                         return 0;
308                     }
309
310                     pStVarOne = (char **)MALLOC(sizeof(char *) * (mOne * nOne));
311                     if (pStVarOne)
312                     {
313                         char **Output_StringMatrix = NULL;
314
315                         int i = 0;
316
317                         for (i = 0; i < mOne * nOne; i++)
318                         {
319                             pStVarOne[i] = (char *)MALLOC(sizeof(char) * (lenStVarOne[i] + 1));
320                             if (pStVarOne[i] == NULL)
321                             {
322                                 FREE(pStVarThree);
323                                 pStVarThree = NULL;
324                                 FREE(pStVarTwo);
325                                 pStVarTwo = NULL;
326                                 FREE(lenStVarOne);
327                                 lenStVarOne = NULL;
328                                 freeArrayOfString(pStVarOne, i);
329                                 Scierror(999, _("%s: No more memory.\n"), fname);
330                                 return 0;
331                             }
332                         }
333
334                         sciErr = getMatrixOfString(pvApiCtx, piAddressVarOne, &mOne, &nOne, lenStVarOne, pStVarOne);
335                         if (sciErr.iErr)
336                         {
337                             printError(&sciErr, 0);
338                             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
339                             return 0;
340                         }
341
342                         FREE(lenStVarOne);
343                         lenStVarOne = NULL;
344
345                         if (isRegExp)
346                         {
347                             int ierr = (int)PCRE_FINISHED_OK;
348
349                             Output_StringMatrix = strsubst_reg(pStVarOne, mOne * nOne, pStVarTwo, pStVarThree, &ierr);
350                             if ((ierr != PCRE_FINISHED_OK) && (ierr != NO_MATCH) && (ierr != PCRE_EXIT))
351                             {
352                                 FREE(pStVarThree);
353                                 pStVarThree = NULL;
354                                 FREE(pStVarTwo);
355                                 pStVarTwo = NULL;
356                                 pcre_error(fname, ierr);
357                                 return 0;
358                             }
359                         }
360                         else
361                         {
362                             Output_StringMatrix = strsubst(pStVarOne, mOne * nOne, pStVarTwo, pStVarThree);
363                         }
364
365                         FREE(pStVarThree);
366                         pStVarThree = NULL;
367                         FREE(pStVarTwo);
368                         pStVarTwo = NULL;
369                         freeArrayOfString(pStVarOne, mOne * nOne);
370
371                         sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, mOne, nOne, Output_StringMatrix);
372                         freeArrayOfString(Output_StringMatrix, mOne * nOne);
373                         if (sciErr.iErr)
374                         {
375                             printError(&sciErr, 0);
376                             Scierror(999,_("%s: Memory allocation error.\n"), fname);
377                             return 0;
378                         }
379
380                         LhsVar(1) = Rhs + 1;
381                         PutLhsVar();
382                         return 0;
383                     }
384                     else
385                     {
386                         FREE(pStVarThree);
387                         pStVarThree = NULL;
388                         FREE(pStVarTwo);
389                         pStVarTwo = NULL;
390                         FREE(lenStVarOne);
391                         lenStVarOne = NULL;
392                         Scierror(999, _("%s: No more memory.\n"), fname);
393                         return 0;
394                     }
395                 }
396                 else
397                 {
398                     FREE(pStVarThree);
399                     pStVarThree = NULL;
400                     FREE(pStVarTwo);
401                     pStVarTwo = NULL;
402                     Scierror(999, _("%s: No more memory.\n"), fname);
403                     return 0;
404                 }
405             }
406             else
407             {
408                 FREE(pStVarThree);
409                 pStVarThree = NULL;
410                 Scierror(999, _("%s: No more memory.\n"), fname);
411                 return 0;
412             }
413         }
414         else
415         {
416             Scierror(999, _("%s: No more memory.\n"), fname);
417             return 0;
418         }
419     }
420     else if (iType == sci_matrix)
421     {
422         sciErr = getVarDimension(pvApiCtx, piAddressVarOne, &mOne, &nOne);
423         if (sciErr.iErr)
424         {
425             printError(&sciErr, 0);
426             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
427             return 0;
428         }
429
430         if ((mOne == 0) && (nOne == 0)) /* strsubst([],...) returns [] */
431         {
432             sciErr = createMatrixOfDouble(pvApiCtx, Rhs + 1, mOne, nOne, NULL);
433             if (sciErr.iErr)
434             {
435                 printError(&sciErr, 0);
436                 Scierror(999,_("%s: Memory allocation error.\n"), fname);
437                 return 0;
438             }
439
440             LhsVar(1) = Rhs + 1;
441             PutLhsVar();
442         }
443         else
444         {
445             Scierror(999, _("%s: Wrong type for input argument #%d: Matrix of strings or empty matrix expected.\n"), fname);
446         }
447     }
448     else
449     {
450         Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 1);
451     }
452     return 0;
453 }
454
455 /*-------------------------------------------------------------------------------------*/