* Bug 16365 fixed: median(m,'r'|'c') was wrong after 5dc990
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_strsubst.cpp
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  * 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 #include "funcmanager.hxx"
18 #include "string_gw.hxx"
19 #include "function.hxx"
20 #include "string.hxx"
21 #include "double.hxx"
22
23 extern "C"
24 {
25 #include "strsubst.h"
26 #include "localization.h"
27 #include "Scierror.h"
28 #include "pcre_error.h"
29 #include "pcre_private.h"
30 #include "freeArrayOfString.h"
31 }
32 /*-------------------------------------------------------------------------------------*/
33 #define WCHAR_R L'r'
34 #define WCHAR_S L's'
35 /*-------------------------------------------------------------------------------------*/
36 types::Function::ReturnValue sci_strsubst(types::typed_list &in, int _iRetCount, types::typed_list &out)
37 {
38     bool bRegExp = false;
39     if (in.size() < 3 || in.size() > 4)
40     {
41         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "strsubst", 3, 4);
42         return types::Function::Error;
43     }
44
45     if (in.size() > 3)
46     {
47         if (in[3]->isString() == false && in[3]->getAs<types::String>()->getSize() != 1)
48         {
49             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "strsubst", 4);
50         }
51
52         if (in[3]->getAs<types::String>()->get(0)[0] == WCHAR_R)
53         {
54             bRegExp = true;
55         }
56         else if (in[3]->getAs<types::String>()->get(0)[0] == WCHAR_S)
57         {
58             bRegExp = false;
59         }
60         else
61         {
62             Scierror(999, _("%s: Wrong value for input argument #%d: 's' or 'r' expected.\n"), "strsubst", 4);
63             return types::Function::Error;
64         }
65     }
66
67     if (in[2]->isString() == false || in[2]->getAs<types::String>()->getSize() != 1)
68     {
69         Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "strsubst", 3);
70         return types::Function::Error;
71     }
72
73     wchar_t* pwstReplace = in[2]->getAs<types::String>()->get()[0];
74
75     if (in[1]->isString() == false || in[1]->getAs<types::String>()->getSize() != 1)
76     {
77         Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "strsubst", 2);
78         return types::Function::Error;
79     }
80
81     wchar_t* pwstSearch = in[1]->getAs<types::String>()->get()[0];
82
83     if (in[0]->isDouble() && in[0]->getAs<types::Double>()->isEmpty())
84     {
85         out.push_back(types::Double::Empty());
86         return types::Function::OK;
87     }
88
89     if (in[0]->isString() == false)
90     {
91         Scierror(999, _("%s: Wrong type for input argument #%d: A string matrix expected.\n"), "strsubst", 1);
92         return types::Function::Error;
93     }
94
95     types::String* pS = in[0]->getAs<types::String>();
96
97     types::String* pOut = new types::String(pS->getRows(), pS->getCols());
98     wchar_t** pwstOutput = NULL;
99
100     if (bRegExp)
101     {
102         int iErr = 0;
103         pwstOutput = wcssubst_reg(const_cast<const wchar_t**>(pS->get()), pS->getSize(), pwstSearch, pwstReplace, &iErr);
104         if (iErr != NO_MATCH && iErr != PCRE_FINISHED_OK && iErr != PCRE_EXIT)
105         {
106             freeArrayOfWideString(pwstOutput, pOut->getSize());
107             pcre_error("strsubst", iErr);
108             delete pOut;
109             return types::Function::Error;
110         }
111     }
112     else
113     {
114         pwstOutput = wcssubst(const_cast<const wchar_t**>(pS->get()), pS->getSize(), pwstSearch, pwstReplace);
115     }
116
117     pOut->set(pwstOutput);
118     freeArrayOfWideString(pwstOutput, pOut->getSize());
119     out.push_back(pOut);
120     return types::Function::OK;
121 }
122 /*-------------------------------------------------------------------------------------*/