Fix some easy to fix warnings
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_sum.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Allan CORNET
4  * Copyright (C) 2011 - DIGITEO - Antoine ELIAS
5  * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17 /*--------------------------------------------------------------------------*/
18 #include "elem_func_gw.hxx"
19 #include "function.hxx"
20 #include "double.hxx"
21 #include "string.hxx"
22 #include "overload.hxx"
23 #include "sum.hxx"
24 #include "int.hxx"
25 #include "polynom.hxx"
26
27 extern "C"
28 {
29 #include "Scierror.h"
30 #include "localization.h"
31 #include "charEncoding.h"
32 #include "basic_functions.h"
33 }
34
35 /*--------------------------------------------------------------------------*/
36 types::Function::ReturnValue sci_sum(types::typed_list &in, int _iRetCount, types::typed_list &out)
37 {
38     types::Double* pDblIn       = NULL;
39     types::Double* pDblOut      = NULL;
40     types::Polynom* pPolyIn     = NULL;
41     types::Polynom* pPolyOut    = NULL;
42
43     int iOrientation    = 0;
44     int iOuttype        = 1; // 1 = native | 2 = double (type of output value)
45
46     if (in.size() < 1 || in.size() > 3)
47     {
48         Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "sum", 1, 3);
49         return types::Function::Error;
50     }
51
52     if (_iRetCount > 1)
53     {
54         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "sum", 1);
55         return types::Function::Error;
56     }
57
58     bool isCopy = true;
59     /***** get data *****/
60     switch (in[0]->getType())
61     {
62         case types::InternalType::ScilabDouble:
63         {
64             pDblIn = in[0]->getAs<types::Double>();
65             isCopy = false;
66             break;
67         }
68         case types::InternalType::ScilabBool:
69         {
70             pDblIn = getAsDouble(in[0]->getAs<types::Bool>());
71             iOuttype = 2;
72             break;
73         }
74         case types::InternalType::ScilabPolynom:
75         {
76             pPolyIn = in[0]->getAs<types::Polynom>();
77             break;
78         }
79         case types::InternalType::ScilabInt8:
80         {
81             pDblIn = getAsDouble(in[0]->getAs<types::Int8>());
82             break;
83         }
84         case types::InternalType::ScilabInt16:
85         {
86             pDblIn = getAsDouble(in[0]->getAs<types::Int16>());
87             break;
88         }
89         case types::InternalType::ScilabInt32:
90         {
91             pDblIn = getAsDouble(in[0]->getAs<types::Int32>());
92             break;
93         }
94         case types::InternalType::ScilabInt64:
95         {
96             pDblIn = getAsDouble(in[0]->getAs<types::Int64>());
97             break;
98         }
99         case types::InternalType::ScilabUInt8:
100         {
101             pDblIn = getAsDouble(in[0]->getAs<types::UInt8>());
102             break;
103         }
104         case types::InternalType::ScilabUInt16:
105         {
106             pDblIn = getAsDouble(in[0]->getAs<types::UInt16>());
107             break;
108         }
109         case types::InternalType::ScilabUInt32:
110         {
111             pDblIn = getAsDouble(in[0]->getAs<types::UInt32>());
112             break;
113         }
114         case types::InternalType::ScilabUInt64:
115         {
116             pDblIn = getAsDouble(in[0]->getAs<types::UInt64>());
117             break;
118         }
119         default:
120         {
121             std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_sum";
122             types::Function::ReturnValue ret = Overload::call(wstFuncName, in, _iRetCount, out);
123
124             if (isCopy && pDblIn)
125             {
126                 pDblIn->killMe();
127             }
128
129             return ret;
130         }
131     }
132
133     if (in.size() >= 2)
134     {
135         if (in[1]->isDouble())
136         {
137             types::Double* pDbl = in[1]->getAs<types::Double>();
138
139             if (pDbl->isScalar() == false)
140             {
141                 if (isCopy && pDblIn)
142                 {
143                     pDblIn->killMe();
144                 }
145
146                 Scierror(999, _("%s: Wrong value for input argument #%d: A positive scalar expected.\n"), "sum", 2);
147                 return types::Function::Error;
148             }
149
150             iOrientation = static_cast<int>(pDbl->get(0));
151
152             if (iOrientation <= 0)
153             {
154                 if (isCopy && pDblIn)
155                 {
156                     pDblIn->killMe();
157                 }
158
159                 Scierror(999, _("%s: Wrong value for input argument #%d: A positive scalar expected.\n"), "sum", 2);
160                 return types::Function::Error;
161             }
162         }
163         else if (in[1]->isString())
164         {
165             types::String* pStr = in[1]->getAs<types::String>();
166
167             if (pStr->isScalar() == false)
168             {
169                 if (isCopy && pDblIn)
170                 {
171                     pDblIn->killMe();
172                 }
173
174                 Scierror(999, _("%s: Wrong size for input argument #%d: A scalar string expected.\n"), "sum", 2);
175                 return types::Function::Error;
176             }
177
178             wchar_t* wcsString = pStr->get(0);
179
180             if (wcscmp(wcsString, L"*") == 0)
181             {
182                 iOrientation = 0;
183             }
184             else if (wcscmp(wcsString, L"r") == 0)
185             {
186                 iOrientation = 1;
187             }
188             else if (wcscmp(wcsString, L"c") == 0)
189             {
190                 iOrientation = 2;
191             }
192             else if (wcscmp(wcsString, L"m") == 0)
193             {
194                 int iDims = 0;
195                 int* piDimsArray = NULL;
196
197                 if (pDblIn)
198                 {
199                     iDims = pDblIn->getDims();
200                     piDimsArray = pDblIn->getDimsArray();
201                 }
202                 else
203                 {
204                     iDims = pPolyIn->getDims();
205                     piDimsArray = pPolyIn->getDimsArray();
206                 }
207
208                 // old function was "mtlsel"
209                 for (int i = 0; i < iDims; i++)
210                 {
211                     if (piDimsArray[i] > 1)
212                     {
213                         iOrientation = i + 1;
214                         break;
215                     }
216                 }
217             }
218             else if ((wcscmp(wcsString, L"native") == 0) && (in.size() == 2))
219             {
220                 iOuttype = 1;
221             }
222             else if ((wcscmp(wcsString, L"double") == 0) && (in.size() == 2))
223             {
224                 iOuttype = 2;
225             }
226             else
227             {
228                 const char* pstrExpected = NULL;
229                 if (in.size() == 2)
230                 {
231                     pstrExpected = "\"*\",\"r\",\"c\",\"m\",\"native\",\"double\"";
232                 }
233                 else
234                 {
235                     pstrExpected = "\"*\",\"r\",\"c\",\"m\"";
236                 }
237
238                 if (isCopy && pDblIn)
239                 {
240                     pDblIn->killMe();
241                 }
242
243                 Scierror(999, _("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "sum", 2, pstrExpected);
244                 return types::Function::Error;
245             }
246         }
247         else
248         {
249             if (isCopy && pDblIn)
250             {
251                 pDblIn->killMe();
252             }
253
254             Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix or a string expected.\n"), "sum", 2);
255             return types::Function::Error;
256         }
257     }
258
259     if (in.size() == 3)
260     {
261         if (in[2]->isString() == false)
262         {
263             if (isCopy && pDblIn)
264             {
265                 pDblIn->killMe();
266             }
267
268             Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), "sum", 3);
269             return types::Function::Error;
270         }
271
272         types::String* pStr = in[2]->getAs<types::String>();
273
274         if (pStr->isScalar() == false)
275         {
276             if (isCopy && pDblIn)
277             {
278                 pDblIn->killMe();
279             }
280
281             Scierror(999, _("%s: Wrong size for input argument #%d: A scalar string expected.\n"), "sum", 3);
282             return types::Function::Error;
283         }
284
285         wchar_t* wcsString = pStr->get(0);
286
287         if (wcscmp(wcsString, L"native") == 0)
288         {
289             iOuttype = 1;
290         }
291         else if (wcscmp(wcsString, L"double") == 0)
292         {
293             iOuttype = 2;
294         }
295         else
296         {
297             if (isCopy && pDblIn)
298             {
299                 pDblIn->killMe();
300             }
301
302             Scierror(999, _("%s: Wrong value for input argument #%d: %s or %s expected.\n"), "sum", 3, "\"native\"", "\"double\"");
303             return types::Function::Error;
304         }
305     }
306
307     /***** perform operation *****/
308     if (pDblIn)
309     {
310         if (pDblIn->isEmpty())
311         {
312             if (iOrientation == 0)
313             {
314                 out.push_back(new types::Double(0));
315             }
316             else
317             {
318                 out.push_back(types::Double::Empty());
319             }
320
321             if (isCopy)
322             {
323                 pDblIn->killMe();
324             }
325
326             return types::Function::OK;
327         }
328         else if (iOrientation > pDblIn->getDims())
329         {
330             pDblOut = pDblIn;
331
332             if (in[0]->isBool() == false)
333             {
334                 iOuttype = 2;
335             }
336         }
337         else
338         {
339             pDblOut = sum(pDblIn, iOrientation);
340             if (isCopy)
341             {
342                 pDblIn->killMe();
343             }
344         }
345     }
346     else if (pPolyIn)
347     {
348         iOuttype = 1;
349         if (iOrientation > pPolyIn->getDims())
350         {
351             pPolyOut = pPolyIn->getAs<types::Polynom>();
352         }
353         else
354         {
355             pPolyOut = sum(pPolyIn, iOrientation);
356         }
357     }
358
359     /***** set result *****/
360     if ((iOuttype == 1) && isCopy)
361     {
362         switch (in[0]->getType())
363         {
364             case types::InternalType::ScilabBool:
365             {
366                 types::Bool* pB = new types::Bool(pDblOut->getDims(), pDblOut->getDimsArray());
367                 int* p = pB->get();
368                 double* pd = pDblOut->get();
369                 int size = pB->getSize();
370                 for (int i = 0; i < size; ++i)
371                 {
372                     p[i] = pd[i] != 0 ? 1 : 0;
373                 }
374                 out.push_back(pB);
375                 break;
376             }
377             case types::InternalType::ScilabPolynom:
378             {
379                 out.push_back(pPolyOut);
380                 break;
381             }
382             case types::InternalType::ScilabInt8:
383             {
384                 out.push_back(toInt<types::Int8>(pDblOut));
385                 break;
386             }
387             case types::InternalType::ScilabInt16:
388             {
389                 out.push_back(toInt<types::Int16>(pDblOut));
390                 break;
391             }
392             case types::InternalType::ScilabInt32:
393             {
394                 out.push_back(toInt<types::Int32>(pDblOut));
395                 break;
396             }
397             case types::InternalType::ScilabInt64:
398             {
399                 out.push_back(toInt<types::Int64>(pDblOut));
400                 break;
401             }
402             case types::InternalType::ScilabUInt8:
403             {
404                 out.push_back(toInt<types::UInt8>(pDblOut));
405                 break;
406             }
407             case types::InternalType::ScilabUInt16:
408             {
409                 out.push_back(toInt<types::UInt16>(pDblOut));
410                 break;
411             }
412             case types::InternalType::ScilabUInt32:
413             {
414                 out.push_back(toInt<types::UInt32>(pDblOut));
415                 break;
416             }
417             case types::InternalType::ScilabUInt64:
418             {
419                 out.push_back(toInt<types::UInt64>(pDblOut));
420                 break;
421             }
422             default:
423                 return types::Function::Error;
424         }
425
426         if (pDblOut)
427         {
428             pDblOut->killMe();
429         }
430     }
431     else
432     {
433         out.push_back(pDblOut);
434     }
435
436     return types::Function::OK;
437 }
438 /*--------------------------------------------------------------------------*/