Merge remote-tracking branch 'origin/master' into YaSp
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / elem_func_gw.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4 *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
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 "elem_func_gw.hxx"
15 #include "context.hxx"
16 #include "overload.hxx"
17 #include "execvisitor.hxx"
18 #include "Scierror.h"
19 #include "localization.h"
20 #include "charEncoding.h"
21
22 #define MODULE_NAME L"elementary_functions"
23 extern "C"
24 {
25 #include "gw_elementary_functions.h"
26 }
27
28 int ElemFuncModule::Load()
29 {
30     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"abs", &sci_abs, MODULE_NAME));
31     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"acos", &sci_acos, MODULE_NAME));
32     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"asin", &sci_asin, MODULE_NAME));
33     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"atan", &sci_atan, MODULE_NAME));
34     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"ceil", &sci_ceil, MODULE_NAME));
35     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"clean", &sci_clean, MODULE_NAME));
36     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"conj", &sci_conj, MODULE_NAME));
37     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cos", &sci_cos, MODULE_NAME));
38     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cumprod", &sci_cumprod, MODULE_NAME));
39     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"cumsum", &sci_cumsum, MODULE_NAME));
40     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"diag", &sci_diag, MODULE_NAME));
41     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"dsearch", &sci_dsearch, MODULE_NAME));
42     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"exp", &sci_exp, MODULE_NAME));
43     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"expm", &sci_expm, MODULE_NAME));
44     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"eye", &sci_eye, MODULE_NAME));
45     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"floor", &sci_floor, MODULE_NAME));
46     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"frexp", &sci_frexp, MODULE_NAME));
47     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"gsort", &sci_gsort, MODULE_NAME));
48     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"imag", &sci_imag, MODULE_NAME));
49     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"imult", &sci_imult, MODULE_NAME));
50     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"int", &sci_int, MODULE_NAME));
51     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isreal", &sci_isreal, MODULE_NAME));
52     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isequal", &sci_isequal, MODULE_NAME));
53     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"kron", &sci_kron, MODULE_NAME));
54     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log", &sci_log, MODULE_NAME));
55     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log1p", &sci_log1p, MODULE_NAME));
56     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"matrix", &sci_matrix, MODULE_NAME));
57     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"max", &sci_max, MODULE_NAME));
58     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"min", &sci_min, MODULE_NAME));
59     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"nearfloat", &sci_nearfloat, MODULE_NAME));
60     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"number_properties", &sci_number_properties, MODULE_NAME));
61     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"ones", &sci_ones, MODULE_NAME));
62     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"prod", &sci_prod, MODULE_NAME));
63     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"rand", &sci_rand, MODULE_NAME));
64     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"real", &sci_real, MODULE_NAME));
65     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"round", &sci_round, MODULE_NAME));
66     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sign", &sci_sign, MODULE_NAME));
67     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sin", &sci_sin, MODULE_NAME));
68     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"size", &sci_size, MODULE_NAME));
69     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sqrt", &sci_sqrt, MODULE_NAME));
70     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"sum", &sci_sum, MODULE_NAME));
71     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tan", &sci_tan, MODULE_NAME));
72     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"testmatrix", &sci_testmatrix, MODULE_NAME));
73     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"tril", &sci_tril, MODULE_NAME));
74     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"triu", &sci_triu, MODULE_NAME));
75     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"zeros", &sci_zeros, MODULE_NAME));
76     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"rat", &sci_rat, MODULE_NAME));
77     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"base2dec", &sci_base2dec, MODULE_NAME));
78     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"dec2base", &sci_dec2base, MODULE_NAME));
79     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"log10", &sci_log10, MODULE_NAME));
80     return 1;
81 }
82
83
84 bool getDimsFromArguments(types::typed_list& in, char* _pstName, int* _iDims, int** _piDims, bool* _alloc)
85 {
86     types::Double* pOut = 0;
87
88     *_alloc = false;
89     *_iDims = 0;
90     *_piDims = NULL;
91
92     if (in.size() == 0)
93     {
94         *_iDims = 2;
95         *_piDims = new int[*_iDims];
96         (*_piDims)[0] = 1;
97         (*_piDims)[1] = 1;
98         *_alloc = true;
99         return true;
100     }
101     else if (in.size() == 1)
102     {
103         *_iDims = 1;
104         // :
105         if (in[0]->isColon())
106         {
107             *_iDims = -1;
108             return false;
109         }
110
111         if (in[0]->isArrayOf() == false)
112         {
113             if (in[0]->isSparse())
114             {
115                 Sparse* sp = in[0]->getAs<Sparse>();
116                 *_iDims = sp->getDims();
117                 *_piDims = sp->getDimsArray();
118                 return true;
119             }
120             else if (in[0]->isSparseBool())
121             {
122                 SparseBool* sp = in[0]->getAs<SparseBool>();
123                 *_iDims = sp->getDims();
124                 *_piDims = sp->getDimsArray();
125                 return true;
126             }
127             return false;
128         }
129
130         GenericType* pIn = in[0]->getAs<GenericType>();
131         *_iDims = pIn->getDims();
132         *_piDims = pIn->getDimsArray();
133
134         return true;
135     }
136     else
137     {
138         *_iDims = static_cast<int>(in.size());
139         *_piDims = new int[*_iDims];
140         *_alloc = true;
141         for (int i = 0; i < *_iDims; i++)
142         {
143             if (in[i]->isArrayOf() == false)
144             {
145                 delete[] * _piDims;
146                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), _pstName, i + 1);
147                 return false;
148             }
149
150             types::GenericType* pGTIn = in[i]->getAs<types::GenericType>();
151             if (pGTIn->isScalar() == false || pGTIn->isComplex())
152             {
153                 delete[] * _piDims;
154                 Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), _pstName, i + 1);
155                 return false;
156             }
157
158             switch (in[i]->getType())
159             {
160                 case types::InternalType::ScilabDouble:
161                 {
162                     double dValue = in[i]->getAs<types::Double>()->get(0);
163                     if (dValue >= INT_MAX)
164                     {
165                         delete[] * _piDims;
166                         Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName, INT_MAX);
167                         return false;
168                     }
169                     (*_piDims)[i] = static_cast<int>(dValue);
170                 }
171                 break;
172                 case types::InternalType::ScilabInt8:
173                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::Int8>()->get()[0]);
174                     break;
175                 case types::InternalType::ScilabUInt8:
176                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt8>()->get()[0]);
177                     break;
178                 case types::InternalType::ScilabInt16:
179                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::Int16>()->get()[0]);
180                     break;
181                 case types::InternalType::ScilabUInt16:
182                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt16>()->get()[0]);
183                     break;
184                 case types::InternalType::ScilabInt32:
185                     (*_piDims)[i] = in[i]->getAs<types::Int32>()->get()[0];
186                     break;
187                 case types::InternalType::ScilabUInt32:
188                     (*_piDims)[i] = static_cast<int>(in[i]->getAs<types::UInt32>()->get()[0]);
189                     break;
190                 case types::InternalType::ScilabInt64:
191                 {
192                     long long llValue = in[i]->getAs<types::Int64>()->get(0);
193                     if (llValue >= INT_MAX)
194                     {
195                         delete[] * _piDims;
196                         Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName, INT_MAX);
197                         return types::Function::Error;
198                     }
199                     (*_piDims)[i] = static_cast<int>(llValue);
200                     break;
201                 }
202                 case types::InternalType::ScilabUInt64:
203                 {
204                     unsigned long long ullValue = in[i]->getAs<types::UInt64>()->get(0);
205                     if (ullValue >= INT_MAX)
206                     {
207                         delete[] * _piDims;
208                         Scierror(999, _("%s: variable size exceeded : less than %d expected.\n"), _pstName, INT_MAX);
209                         return false;
210                     }
211                     (*_piDims)[i] = static_cast<int>(ullValue);
212                     break;
213                 }
214                 default:
215                     Scierror(999, _("%s: Wrong size for input argument #%d: A scalar expected.\n"), _pstName, i + 1);
216                     return false;
217             }
218         }
219
220         return true;
221     }
222
223     return false;
224 }