877278bd36f3b06b1bc9ae18e1c35e5989e1085c
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_tokens.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) Digiteo 2011 - Cedric DELAMARRE
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
13
14 #include "function.hxx"
15 #include "string.hxx"
16 #include "list.hxx"
17 #include "double.hxx"
18 #include "function.hxx"
19 #include "string_gw.hxx"
20
21 extern "C"
22 {
23 #include "sci_malloc.h"
24 #include "os_string.h"
25 #include "tokens.h"
26 #include "core_math.h"
27 #include "localization.h"
28 #include "Scierror.h"
29 }
30
31 #include <sciprint.h>
32
33 types::Function::ReturnValue sci_tokens(types::typed_list &in, int _iRetCount, types::typed_list &out)
34 {
35     types::String* pOutString   = NULL;
36     types::String* pString      = NULL;
37     types::String* pCharSample  = NULL;
38     char* seps                  = NULL;
39     int sizeSeps                = 0;
40
41     if (in.size() > 2 || in.size() == 0)
42     {
43         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "tokens", 1, 2);
44         return types::Function::Error;
45     }
46     if (_iRetCount != 1)
47     {
48         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "tokens", 1);
49         return types::Function::Error;
50     }
51
52     // first arg
53     if (in[0]->isString() == false)
54     {
55         Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "tokens", 1);
56         return types::Function::Error;
57     }
58     pString = in[0]->getAs<types::String>();
59     if (pString->isScalar() == false)
60     {
61         Scierror(999, _("%s: Wrong size for input argument #%d.\n"), "tokens", 1);
62         return types::Function::Error;
63     }
64     if (strlen(pString->get(0)) == 0)
65     {
66         types::Double* pOutDouble = types::Double::Empty();
67         out.push_back(pOutDouble);
68         return types::Function::OK;
69     }
70
71     // second arg
72     if (in.size() == 2)
73     {
74         if (in[1]->isString() == false)
75         {
76             Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "tokens", 2);
77             return types::Function::Error;
78         }
79         pCharSample = in[1]->getAs<types::String>();
80
81         if (pCharSample->getSize() == 0)
82         {
83             Scierror(999, _("%s: Wrong size for input argument #%d.\n"), "tokens", 2);
84             return types::Function::Error;
85         }
86         sizeSeps = pCharSample->getSize();
87         seps = (char*)MALLOC((sizeSeps + 1) * sizeof(char));
88         for (int i = 0; i < sizeSeps ; i++)
89         {
90             int iLen = (int)strlen(pCharSample->get(i));
91             if (iLen > 1 || iLen < 0)
92             {
93                 Scierror(999, _("%s: Wrong type for input argument #%d: Char(s) expected.\n"), "tokens", 2);
94                 delete pOutString;
95                 return types::Function::Error;
96             }
97             seps[i] = pCharSample->get(i)[0];
98         }
99     }
100     else // default delimiters are ' ' and Tabulation
101     {
102         sizeSeps = 2;
103         seps = (char*)MALLOC((sizeSeps + 1) * sizeof(char));
104         seps[0] = ' ';
105         seps[1] = '\t';
106     }
107
108     seps[sizeSeps] = '\0';
109
110     // perfom operation
111     int dimsArray[2] = {0, 1};
112     int dims = 2;
113
114     char** Output_Strings = stringTokens(pString->get(0), seps, &dimsArray[0]);
115     FREE(seps);
116     if (Output_Strings == NULL)
117     {
118         //return empty matrix
119         out.push_back(types::Double::Empty());
120         return types::Function::OK;
121     }
122     else
123     {
124         pOutString  = new types::String(dims, dimsArray);
125         pOutString->set(Output_Strings);
126
127         for (int i = 0 ; i < dimsArray[0] ; i++)
128         {
129             FREE(Output_Strings[i]);
130         }
131         FREE(Output_Strings);
132     }
133
134     out.push_back(pOutString);
135     return types::Function::OK;
136 }
137