2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
16 /* desc : search position of a character string in an other string
17 using regular express . */
18 /*------------------------------------------------------------------------*/
20 #include "string_gw.hxx"
21 #include "function.hxx"
27 #include "os_string.h"
29 #include "localization.h"
31 #include "pcreposix.h"
32 #include "sci_malloc.h" /* MALLOC */
33 #include "charEncoding.h"
34 #include "pcre_private.h"
35 #include "pcre_error.h"
38 /*------------------------------------------------------------------------*/
41 #define MEMORY_ALLOC_ERROR -1
42 /*------------------------------------------------------------------------*/
43 typedef struct grep_results
50 /*------------------------------------------------------------------------*/
51 static int GREP_NEW(GREPRESULTS *results, char **Inputs_param_one, int mn_one, char **Inputs_param_two, int mn_two);
52 static int GREP_OLD(GREPRESULTS *results, char **Inputs_param_one, int mn_one, char **Inputs_param_two, int mn_two);
53 /*------------------------------------------------------------------------*/
54 types::Function::ReturnValue sci_grep(types::typed_list &in, int _iRetCount, types::typed_list &out)
56 bool bRegularExpression = false;
58 //check input paramters
59 if (in.size() < 2 || in.size() > 3)
61 Scierror(999, _("%s: Wrong number of input arguments: %d or %d expected.\n"), "grep", 2, 3);
62 return types::Function::Error;
67 Scierror(999, _("%s: Wrong number of output arguments: %d or %d expected.\n"), "grep", 1, 2);
68 return types::Function::Error;
71 if (in[0]->isDouble() && in[0]->getAs<types::Double>()->getSize() == 0)
73 types::Double *pD = types::Double::Empty();
75 return types::Function::OK;
80 //"r" for regular expression
81 if (in[2]->isString() == false)
83 Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "grep", 3);
84 return types::Function::Error;
87 types::String* pS = in[2]->getAs<types::String>();
88 if (pS->getSize() != 1)
90 Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "grep", 3);
91 return types::Function::Error;
94 if (pS->get(0)[0] == 'r')
96 bRegularExpression = true;
100 if (in[0]->isString() == false)
102 Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "grep", 1);
103 return types::Function::Error;
106 if (in[1]->isString() == false)
108 Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "grep", 2);
109 return types::Function::Error;
112 types::String* pS1 = in[0]->getAs<types::String>();
113 types::String* pS2 = in[1]->getAs<types::String>();
116 for (int i = 0 ; i < pS2->getSize() ; i++)
118 if (wcslen(pS2->get(i)) == 0)
120 Scierror(249, _("%s: Wrong values for input argument #%d: Non-empty strings expected.\n"), "grep", 2);
121 return types::Function::Error;
125 GREPRESULTS grepresults;
126 int code_error_grep = GREP_OK;
128 grepresults.currentLength = 0;
129 grepresults.sizeArraysMax = 0;
130 grepresults.positions = NULL;
131 grepresults.values = NULL;
133 char** pStr1 = (char**)MALLOC(sizeof(char*) * pS1->getSize());
134 for (int i = 0 ; i < pS1->getSize() ; i++)
136 pStr1[i] = wide_string_to_UTF8(pS1->get(i));
139 char** pStr2 = (char**)MALLOC(sizeof(char*) * pS2->getSize());
140 for (int i = 0 ; i < pS2->getSize() ; i++)
142 pStr2[i] = wide_string_to_UTF8(pS2->get(i));
145 if (bRegularExpression)
147 code_error_grep = GREP_NEW(&grepresults, pStr1, pS1->getSize(), pStr2, pS2->getSize());
151 code_error_grep = GREP_OLD(&grepresults, pStr1, pS1->getSize(), pStr2, pS2->getSize());
154 for (int i = 0; i < pS1->getSize(); i++)
160 for (int i = 0; i < pS2->getSize(); i++)
166 switch (code_error_grep)
170 types::Double* pD1 = NULL;
171 if (grepresults.currentLength == 0)
173 pD1 = types::Double::Empty();
177 pD1 = new types::Double(1, grepresults.currentLength);
178 double* pDbl1 = pD1->getReal();
179 for (int i = 0 ; i < grepresults.currentLength ; i++ )
181 pDbl1[i] = static_cast<double>(grepresults.values[i]);
189 types::Double* pD2 = NULL;
190 if (grepresults.currentLength == 0)
192 pD2 = types::Double::Empty();
196 pD2 = new types::Double(1, grepresults.currentLength);
197 double* pDbl2 = pD2->getReal();
198 for (int i = 0 ; i < grepresults.currentLength ; i++ )
200 pDbl2[i] = static_cast<double>(grepresults.positions[i]);
207 if (grepresults.values)
209 FREE(grepresults.values);
210 grepresults.values = NULL;
212 if (grepresults.positions)
214 FREE(grepresults.positions);
215 grepresults.positions = NULL;
220 case MEMORY_ALLOC_ERROR :
221 Scierror(999, _("%s: No more memory.\n"), "grep");
222 //no break, to free reserved memory.
225 if (grepresults.values)
227 FREE(grepresults.values);
228 grepresults.values = NULL;
230 if (grepresults.positions)
232 FREE(grepresults.positions);
233 grepresults.positions = NULL;
235 return types::Function::Error;
240 return types::Function::OK;
242 //Function::ReturnValue sci_grep(typed_list &in, int _iRetCount, typed_list &out)
247 // if (VarType(1) == sci_matrix)
249 // int m1 = 0, n1 = 0;
252 // GetRhsVar(1,MATRIX_OF_DOUBLE_DATATYPE,&m1,&n1,&Str);
254 // if ((m1 == 0) && (n1 == 0))
257 // CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,&m1,&n1,&l);
258 // LhsVar(1) = Rhs+1 ;
267 // if (VarType(3) == sci_strings)
269 // char typ = 'd'; /*default */
270 // int m3 = 0,n3 = 0,l3 = 0;
272 // GetRhsVar(3,STRING_DATATYPE,&m3,&n3,&l3);
273 // if ( m3*n3 != 0) typ = cstk(l3)[0];
277 // sci_grep_common(fname,TRUE);
281 // Scierror(999,_("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),fname,3,"s");
287 // Scierror(999,_("%s: Wrong type for input argument #%d: String expected.\n"),fname,3);
291 // else /* Rhs == 2 */
293 // sci_grep_common(fname,FALSE);
297 /*-----------------------------------------------------------------------------------*/
298 static int GREP_NEW(GREPRESULTS *results, char **Inputs_param_one, int mn_one, char **Inputs_param_two, int mn_two)
303 pcre_error_code answer = PCRE_FINISHED_OK;
304 results->sizeArraysMax = mn_one * mn_two;
306 results->values = (int *)MALLOC(sizeof(int) * results->sizeArraysMax);
307 results->positions = (int *)MALLOC(sizeof(int) * results->sizeArraysMax);
309 if ( (results->values == NULL) || (results->positions == NULL) )
313 FREE(results->values);
314 results->values = NULL;
316 if (results->positions)
318 FREE(results->positions);
319 results->positions = NULL;
321 return MEMORY_ALLOC_ERROR;
324 results->currentLength = 0;
325 for ( y = 0; y < mn_one; ++y)
327 for ( x = 0; x < mn_two; ++x)
329 int Output_Start = 0;
331 save = os_strdup(Inputs_param_two[x]);
332 answer = pcre_private(Inputs_param_one[y], save, &Output_Start, &Output_End, NULL, NULL);
334 if ( answer == PCRE_FINISHED_OK )
336 results->values[results->currentLength] = y + 1;
337 results->positions[results->currentLength] = x + 1;
338 results->currentLength++;
340 else if (answer != NO_MATCH)
342 pcre_error("grep", answer);
356 /*-----------------------------------------------------------------------------------*/
357 static int GREP_OLD(GREPRESULTS *results, char **Inputs_param_one, int mn_one, char **Inputs_param_two, int mn_two)
361 results->values = (int *)MALLOC(sizeof(int) * (mn_one * mn_two + 1));
362 results->positions = (int *)MALLOC(sizeof(int) * (mn_one * mn_two + 1));
364 for (y = 0; y < mn_one; ++y)
366 for (x = 0; x < mn_two; ++x)
368 wchar_t* wcInputOne = to_wide_string(Inputs_param_one[y]);
369 wchar_t* wcInputTwo = to_wide_string(Inputs_param_two[x]);
371 if (wcInputOne && wcInputTwo)
373 if (wcsstr(wcInputOne, wcInputTwo) != NULL)
375 results->values[results->currentLength] = y + 1;
376 results->positions[results->currentLength] = x + 1;
377 results->currentLength++;
395 /*-----------------------------------------------------------------------------------*/
396 //static int sci_grep_common(char *fname,BOOL new_grep)
400 // int m1 = 0, n1 = 0;
401 // char **Strings_Input_One = NULL;
402 // int m1n1 = 0; /* m1 * n1 */
404 // int m2 = 0, n2 = 0;
405 // char **Strings_Input_Two = NULL;
406 // int m2n2 = 0; /* m2 * n2 */
408 // GREPRESULTS grepresults;
409 // int code_error_grep = GREP_OK;
411 // GetRhsVar(1,MATRIX_OF_STRING_DATATYPE,&m1,&n1,&Strings_Input_One);
413 // GetRhsVar(2,MATRIX_OF_STRING_DATATYPE,&m2,&n2,&Strings_Input_Two);
416 // for (i = 0;i < m2n2;i++)
418 // if ( strlen(Strings_Input_Two[i]) == 0)
420 // freeArrayOfString(Strings_Input_One,m1n1);
421 // freeArrayOfString(Strings_Input_Two,m2n2);
422 // Scierror(249,_("%s: Wrong values for input argument #%d: Non-empty strings expected.\n"),fname,2);
427 // grepresults.currentLength = 0;
428 // grepresults.sizeArraysMax = 0;
429 // grepresults.positions = NULL;
430 // grepresults.values = NULL;
434 // code_error_grep = GREP_NEW(&grepresults,Strings_Input_One,m1n1,Strings_Input_Two,m2n2);
438 // code_error_grep = GREP_OLD(&grepresults,Strings_Input_One,m1n1,Strings_Input_Two,m2n2);
441 // freeArrayOfString(Strings_Input_One,m1n1);
442 // freeArrayOfString(Strings_Input_Two,m2n2);
444 // switch (code_error_grep)
452 // numRow = 1; /* Output values[]*/
454 // CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,&numRow,&grepresults.currentLength,&outIndex);
455 // for ( x = 0 ; x < grepresults.currentLength ; x++ )
457 // stk(outIndex)[x] = (double)grepresults.values[x] ;
459 // LhsVar(1) = Rhs+1 ;
462 // /* Output positions[]*/
465 // CreateVar(Rhs+2,MATRIX_OF_DOUBLE_DATATYPE,&numRow,&grepresults.currentLength,&outIndex);
466 // for ( x = 0 ; x < grepresults.currentLength ; x++ )
468 // stk(outIndex)[x] = (double)grepresults.positions[x] ;
470 // LhsVar(2) = Rhs+2;
473 // if (grepresults.values) {FREE(grepresults.values); grepresults.values = NULL;}
474 // if (grepresults.positions) {FREE(grepresults.positions); grepresults.positions = NULL;}
478 // case MEMORY_ALLOC_ERROR :
480 // if (grepresults.values) {FREE(grepresults.values); grepresults.values = NULL;}
481 // if (grepresults.positions) {FREE(grepresults.positions); grepresults.positions = NULL;}
482 // Scierror(999,_("%s: No more memory.\n"),fname);
489 /*-----------------------------------------------------------------------------------*/