Coverity #1321202 fixed
[scilab.git] / scilab / modules / ast / src / cpp / types / types_tools.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2011 - DIGITEO - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
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.
13 *
14 */
15
16 #include <list>
17 #include <vector>
18
19 #include "alltypes.hxx"
20 #include "types_tools.hxx"
21 #include "overload.hxx"
22 #include "scilabWrite.hxx"
23
24 extern "C"
25 {
26 #include "elem_common.h"
27 #include "os_string.h"
28 #include "more.h"
29 }
30
31 namespace types
32 {
33 template<typename T>
34 void getIndexes(T* val, std::vector<int>& vec)
35 {
36     typename T::type* p = val->get();
37     int size = val->getSize();
38     for (int i = 0; i < size; ++i)
39     {
40         vec.push_back(static_cast<int>(p[i]));
41     }
42 }
43
44 template<typename T>
45 double getIndex(T* val)
46 {
47     typename T::type* p = val->get();
48     return static_cast<double>(p[0]);
49 }
50
51 template<typename T>
52 Double* convertIndex(T* pI)
53 {
54     int size = pI->getSize();
55     Double* pCurrentArg = new Double(1, size);
56     double* pdbl = pCurrentArg->get();
57     for (int l = 0; l < size; l++)
58     {
59         pdbl[l] = static_cast<double>(pI->get(l));
60     }
61     return pCurrentArg;
62 }
63
64 double getIndex(InternalType* val)
65 {
66     switch (val->getType())
67     {
68         //scalar
69         case InternalType::ScilabDouble:
70         {
71             return getIndex(val->getAs<Double>());
72         }
73         case InternalType::ScilabInt8:
74         {
75             return getIndex(val->getAs<Int8>());
76         }
77         case InternalType::ScilabInt16:
78         {
79             return getIndex(val->getAs<Int16>());
80         }
81         case InternalType::ScilabInt32:
82         {
83             return getIndex(val->getAs<Int32>());
84         }
85         case InternalType::ScilabInt64:
86         {
87             return getIndex(val->getAs<Int64>());
88         }
89         case InternalType::ScilabUInt8:
90         {
91             return getIndex(val->getAs<UInt8>());
92         }
93         case InternalType::ScilabUInt16:
94         {
95             return getIndex(val->getAs<UInt16>());
96         }
97         case InternalType::ScilabUInt32:
98         {
99             return getIndex(val->getAs<UInt32>());
100         }
101         case InternalType::ScilabUInt64:
102         {
103             return getIndex(val->getAs<UInt64>());
104         }
105     }
106
107     return 0;
108 }
109
110 //get only scalar index
111 bool getScalarIndex(GenericType* _pRef, typed_list* _pArgsIn, int* index)
112 {
113     //input size must be equal to ref dims
114     int dimsRef = _pRef->getDims();
115     int dimsIn = static_cast<int>(_pArgsIn->size());
116
117     //same dims and less than internal limit
118     if (dimsIn != 1 && (dimsIn != dimsRef || dimsIn > MAX_DIMS))
119     {
120         return false;
121     }
122
123     int* pdims = _pRef->getDimsArray();
124     int ind[MAX_DIMS];
125     for (int i = 0; i < dimsIn; ++i)
126     {
127         InternalType* in = (*_pArgsIn)[i];
128         //input arg type must be scalar double, int8, int16, ...
129         if (in->isGenericType() && in->getAs<GenericType>()->isScalar())
130         {
131             ind[i] = static_cast<int>(getIndex(in)) - 1;
132             if (ind[i] == -1)
133             {
134                 return false;
135             }
136         }
137         else
138         {
139             //failed, so use entire process
140             return false;
141         }
142     }
143
144     int idx = 0;
145     int previousDims = 1;
146     for (int i = 0; i < dimsIn; ++i)
147     {
148         if (dimsIn != 1 && ind[i] >= pdims[i])
149         {
150             return false;
151         }
152
153         idx += ind[i] * previousDims;
154         previousDims *= pdims[i];
155     }
156
157     *index = idx;
158     return true;
159 }
160
161 static double evalute(InternalType* pIT, int sizeRef)
162 {
163     double real;
164     double img;
165     if (pIT->getId() == InternalType::IdScalarPolynom)
166     {
167         SinglePoly* pSP = pIT->getAs<Polynom>()->get()[0];
168         pSP->evaluate(sizeRef, 0, &real, &img);
169     }
170     else
171     {
172         real = getIndex(pIT);
173     }
174
175     return real;
176 }
177
178 bool getScalarImplicitIndex(GenericType* _pRef, typed_list* _pArgsIn, std::vector<double>& index)
179 {
180     int dimsIn = static_cast<int>(_pArgsIn->size());
181     if (dimsIn != 1)
182     {
183         return false;
184     }
185
186     InternalType* pIT = (*_pArgsIn)[0];
187
188     if (pIT->isImplicitList() == false)
189     {
190         return false;
191     }
192
193     index.reserve(4);
194     if (pIT->isColon())
195     {
196         index.push_back(1);
197         index.push_back(1);
198         index.push_back(_pRef->getSize());
199         //use to know we have a real ":" to shape return matrix in col vector
200         index.push_back(0);
201     }
202     else
203     {
204         ImplicitList* pIL = pIT->getAs<ImplicitList>();
205         int sizeRef = _pRef->getSize();
206         index.push_back(evalute(pIL->getStart(), sizeRef));
207         index.push_back(evalute(pIL->getStep(), sizeRef));
208         index.push_back(evalute(pIL->getEnd(), sizeRef));
209     }
210
211     return true;
212 }
213
214 //get index from implicit or colon index + scalar
215 bool getImplicitIndex(GenericType* _pRef, typed_list* _pArgsIn, std::vector<int>& index, std::vector<int>& dims)
216 {
217     int dimsRef = _pRef->getDims();
218     int dimsIn = static_cast<int>(_pArgsIn->size());
219     bool viewAsVector = dimsIn == 1;
220     dims.reserve(dimsIn);
221     //same dims and less than internal limit
222     if (dimsIn != 1 && (dimsIn != dimsRef || dimsIn > MAX_DIMS))
223     {
224         return false;
225     }
226
227     int* pdims = _pRef->getDimsArray();
228     //input arg type must be computable ( double, $, :, ... )
229     std::list<std::vector<int>> lstIdx;
230     int finalSize = 1;
231     for (int i = 0; i < dimsIn; ++i)
232     {
233         InternalType* in = (*_pArgsIn)[i];
234         if (in->isGenericType() && in->getAs<GenericType>()->isScalar())
235         {
236             int idx = static_cast<int>(getIndex(in)) - 1;
237             if (idx == -1)
238             {
239                 return false;
240             }
241
242             lstIdx.emplace_back(1, idx);
243             dims.push_back(1);
244         }
245         else if (in->isColon())
246         {
247             std::vector<int> idx(2);
248             idx[0] = -1;
249             idx[1] = viewAsVector ? _pRef->getSize() : pdims[i];
250             lstIdx.push_back(idx);
251             finalSize *= idx[1];
252             dims.push_back(idx[1]);
253         }
254         else if (in->isImplicitList())
255         {
256             ImplicitList* pIL = in->getAs<ImplicitList>();
257             InternalType* piStart = pIL->getStart();
258             InternalType* piStep = pIL->getStep();
259             InternalType* piEnd = pIL->getEnd();
260
261             bool isColon = false;
262             if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
263             {
264                 if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
265                 {
266                     SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
267                     if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
268                     {
269                         std::vector<int> idx(2);
270                         idx[0] = -1;
271                         idx[1] = viewAsVector ? _pRef->getSize() : pdims[i];
272                         lstIdx.push_back(idx);
273                         finalSize *= idx[1];
274                         isColon = true;
275                         dims.push_back(idx[1]);
276                     }
277                 }
278             }
279
280             if (isColon == false)
281             {
282                 int sizeRef = viewAsVector ? _pRef->getSize() : pdims[i];
283                 double start = evalute(pIL->getStart(), sizeRef);
284                 double step = evalute(pIL->getStep(), sizeRef);
285                 double end = evalute(pIL->getEnd(), sizeRef);
286
287                 //printf("%.2f : %.2f : %.2f\n", start, step, end);
288
289                 int size = (end - start) / step + 1;
290                 if (size <= 0)
291                 {
292                     //manage implicit that return []
293                     index.clear();
294                     return true;
295                 }
296
297                 std::vector<int> idx(size);
298                 int* pi = idx.data();
299                 pi[0] = start - 1; //0-indexed
300                 for (int j = 1; j < size; ++j)
301                 {
302                     pi[j] = pi[j - 1] + step;
303                 }
304
305                 lstIdx.push_back(idx);
306                 finalSize *= size;
307                 dims.push_back(size);
308             }
309         }
310         else
311         {
312             return false;
313         }
314     }
315
316     index.resize(finalSize, 0);
317
318     if (finalSize == 0)
319     {
320         return true;
321     }
322
323     //compute tuples
324     int previousSize = 1;
325     int currentDim = 0;
326     int previousDims = 1;
327     while (lstIdx.empty() == false)
328     {
329         std::vector<int>& v = lstIdx.front();
330         int currentSize = static_cast<int>(v.size());
331         const int* pv = v.data();
332
333         if (pv[0] == -1 && currentSize == 2)
334         {
335             currentSize = pv[1];
336             int occ = finalSize / (currentSize * previousSize);
337             for (int n = 0; n < occ; ++n)
338             {
339                 int idx = currentSize * previousSize * n;
340                 for (int m = 0; m < currentSize; ++m)
341                 {
342                     if (dimsIn > 1 && m >= pdims[currentDim])
343                     {
344                         return false;
345                     }
346                     int idx2 = idx + previousSize * m;
347                     int idx3 = previousDims * m;
348                     for (int j = 0; j < previousSize; ++j)
349                     {
350                         index[idx2 + j] += idx3;
351                     }
352                 }
353             }
354         }
355         else
356         {
357             int occ = finalSize / (currentSize * previousSize);
358             for (int n = 0; n < occ; ++n)
359             {
360                 int idx = currentSize * previousSize * n;
361                 for (int m = 0; m < currentSize; ++m)
362                 {
363                     if (dimsIn > 1 && pv[m] >= pdims[currentDim])
364                     {
365                         return false;
366                     }
367                     int idx2 = idx + previousSize * m;
368                     int idx3 = previousDims * pv[m];
369                     for (int j = 0; j < previousSize; ++j)
370                     {
371                         index[idx2 + j] += idx3;
372                     }
373                 }
374             }
375         }
376
377         previousSize *= currentSize;
378         previousDims *= pdims[currentDim];
379         ++currentDim;
380         //remove used vector
381         lstIdx.pop_front();
382     }
383
384     return true;
385 }
386
387 //check argument types and compute, dimensions, count of combinations, max indexes
388 int checkIndexesArguments(InternalType* _pRef, typed_list* _pArgsIn, typed_list* _pArgsOut, int* _piMaxDim, int* _piCountDim)
389 {
390     int iDims = static_cast<int>(_pArgsIn->size());
391     int iSeqCount = 1;
392     bool bUndefine = false;
393
394     for (int i = 0; i < iDims; i++)
395     {
396         bool bDeleteNeeded = false;
397         InternalType* pIT = (*_pArgsIn)[i];
398         Double *pCurrentArg = NULL;
399
400         if (pIT->isDouble())
401         {
402             pCurrentArg = pIT->getAs<Double>();
403             if (pCurrentArg->isEmpty())
404             {
405                 return 0;
406             }
407
408             if (pCurrentArg->isIdentity())
409             {
410                 //extract with eye() <=> :
411                 pIT = new Colon();
412                 bDeleteNeeded = true;
413             }
414             else if (pIT->isDeletable())
415             {
416                 // Clone pIT when this ref is equal to zero
417                 // will prevent double delete.
418                 pCurrentArg = pIT->clone()->getAs<Double>();
419             }
420
421             //check valid values neg or complex
422             if (pCurrentArg->isComplex())
423             {
424                 if (pCurrentArg->isDeletable())
425                 {
426                     pCurrentArg->killMe();
427                 }
428                 pCurrentArg = NULL;
429             }
430
431             if (pCurrentArg)
432             {
433                 int size = pCurrentArg->getSize();
434                 double* dbl = pCurrentArg->get();
435                 for (int j = 0; j < size; ++j)
436                 {
437                     if (dbl[j] < 0)
438                     {
439                         if (pCurrentArg->isDeletable())
440                         {
441                             pCurrentArg->killMe();
442                         }
443                         pCurrentArg = NULL;
444                         break;
445                     }
446                 }
447             }
448         }
449
450         //previous  if can update pIT to Colon
451         if (pIT->isColon() || pIT->isImplicitList())
452         {
453             //: or a:b:c
454             ImplicitList* pIL = pIT->getAs<ImplicitList>()->clone()->getAs<ImplicitList>();
455             if (pIL->isComputable() == false)
456             {
457                 //: or $
458                 if (_pRef == NULL)
459                 {
460                     //not enough information to compute indexes.
461                     _pArgsOut->push_back(NULL);
462                     bUndefine = true;
463                     pIL->killMe();;
464                     continue;
465                 }
466                 //evalute polynom with "MaxDim"
467                 int iMaxDim = _pRef->getAs<GenericType>()->getVarMaxDim(i, iDims);
468 #if defined(_SCILAB_DEBUGREF_)
469                 Double* pdbl = new Double(iMaxDim);
470 #else
471                 Double dbl(iMaxDim);
472 #endif
473                 if (pIL->getStart()->isPoly())
474                 {
475                     Polynom *poPoly = pIL->getStart()->getAs<types::Polynom>();
476 #if defined(_SCILAB_DEBUGREF_)
477                     pIL->setStart(poPoly->evaluate(pdbl));
478 #else
479                     pIL->setStart(poPoly->evaluate(&dbl));
480 #endif
481                 }
482                 if (pIL->getStep()->isPoly())
483                 {
484                     Polynom *poPoly = pIL->getStep()->getAs<types::Polynom>();
485 #if defined(_SCILAB_DEBUGREF_)
486                     pIL->setStep(poPoly->evaluate(pdbl));
487 #else
488                     pIL->setStep(poPoly->evaluate(&dbl));
489 #endif
490                 }
491                 if (pIL->getEnd()->isPoly())
492                 {
493                     Polynom *poPoly = pIL->getEnd()->getAs<types::Polynom>();
494 #if defined(_SCILAB_DEBUGREF_)
495                     pIL->setEnd(poPoly->evaluate(pdbl));
496 #else
497                     pIL->setEnd(poPoly->evaluate(&dbl));
498 #endif
499                 }
500
501 #if defined(_SCILAB_DEBUGREF_)
502                 pdbl->killMe();
503 #endif
504             }
505
506
507             pCurrentArg = pIL->extractFullMatrix()->getAs<Double>();
508             pIL->killMe();
509         }
510         else if (pIT->isString())
511         {
512             String* pStr = pIT->getAs<String>();
513             if(!_pRef)
514             {
515                 bUndefine = true;
516                 continue;
517             }
518             if (_pRef->isStruct())
519             {
520                 Struct* pStruct = _pRef->getAs<Struct>();
521
522                 if (_pArgsIn->size() != 1 || pStr->isScalar() == false)
523                 {
524                     bUndefine = true;
525                     continue;
526                 }
527
528                 wchar_t* pFieldName = pStr->get(0);
529
530                 // pCurrent arg is indexed to 1 unlike the return of "getFieldIndex"
531                 int iIndex = pStruct->get(0)->getFieldIndex(pFieldName) + 1;
532                 if (iIndex == -1)
533                 {
534                     bUndefine = true;
535                     continue;
536                 }
537
538                 pCurrentArg = new Double((double)iIndex);
539             }
540             else if (_pRef->isTList())
541             {
542                 // List can't be extract by field and MList must call overload
543                 TList* pTL = _pRef->getAs<TList>();
544                 pCurrentArg = new Double(pStr->getDims(), pStr->getDimsArray());
545                 double* pdbl = pCurrentArg->get();
546                 for (int i = 0; i < pStr->getSize(); i++)
547                 {
548                     wchar_t* pFieldName = pStr->get(i);
549                     int iIndex = pTL->getIndexFromString(pFieldName);
550                     if (iIndex == -1)
551                     {
552                         bUndefine = true;
553                         continue;
554                     }
555                     pdbl[i] = (double)(iIndex + 1);
556                 }
557             }
558             else if (_pRef->isList())
559             {
560                 bUndefine = true;
561                 break;
562             }
563             else if (_pRef->isCell())
564             {
565             }
566         }
567         else if (pIT->isPoly())
568         {
569             //$
570             Polynom* pMP = pIT->getAs<types::Polynom>();
571             int iMaxDim = 0;
572             //if pRef == NULL, use 0 insteadof, to allow a($+1) on new variable
573             if (_pRef)
574             {
575                 iMaxDim = _pRef->getAs<GenericType>()->getVarMaxDim(i, iDims);
576             }
577
578 #ifdef _SCILAB_DEBUGREF_
579             Double* pdbl = new Double(iMaxDim); // $
580             pCurrentArg = pMP->evaluate(pdbl);
581             pdbl->killMe();
582 #else
583             Double dbl(iMaxDim); // $
584             pCurrentArg = pMP->evaluate(&dbl);
585 #endif
586         }
587         else if (pIT->isBool())
588         {
589             //[T F F T F]
590             Bool *pB = pIT->getAs<types::Bool>();
591             int *piB = pB->get();
592             const int size = pB->getSize();
593
594             //find true item count
595             int iItemCount = 0;
596             for (int j = 0; j < size; j++)
597             {
598                 if (piB[j])
599                 {
600                     iItemCount++;
601                 }
602             }
603
604             //allow new Double variable
605             Double* pDbl = new Double(1, iItemCount);
606             double* pdbl = pDbl->getReal();
607
608             int j = 0;
609             for (int l = 0; l < size; l++)
610             {
611                 if (piB[l])
612                 {
613                     pdbl[j++] = l + 1;
614                 }
615             }
616             pCurrentArg = pDbl;
617         }
618         else if (pIT->isInt())
619         {
620             switch (pIT->getType())
621             {
622                 case InternalType::ScilabInt8:
623                 {
624                     pCurrentArg = convertIndex(pIT->getAs<Int8>());
625                     break;
626                 }
627                 case InternalType::ScilabInt16:
628                 {
629                     pCurrentArg = convertIndex(pIT->getAs<Int16>());
630                     break;
631                 }
632                 case InternalType::ScilabInt32:
633                 {
634                     pCurrentArg = convertIndex(pIT->getAs<Int32>());
635                     break;
636                 }
637                 case InternalType::ScilabInt64:
638                 {
639                     pCurrentArg = convertIndex(pIT->getAs<Int64>());
640                     break;
641                 }
642                 case InternalType::ScilabUInt8:
643                 {
644                     pCurrentArg = convertIndex(pIT->getAs<UInt8>());
645                     break;
646                 }
647                 case InternalType::ScilabUInt16:
648                 {
649                     pCurrentArg = convertIndex(pIT->getAs<UInt16>());
650                     break;
651                 }
652                 case InternalType::ScilabUInt32:
653                 {
654                     pCurrentArg = convertIndex(pIT->getAs<UInt32>());
655                     break;
656                 }
657                 case InternalType::ScilabUInt64:
658                 {
659                     pCurrentArg = convertIndex(pIT->getAs<UInt64>());
660                     break;
661                 }
662             }
663         }
664
665         if (bDeleteNeeded)
666         {
667             pIT->killMe();
668         }
669
670         if (pCurrentArg)
671         {
672             const int iCountDim = pCurrentArg->getSize();
673             _piMaxDim[i] = 0;
674             for (int j = 0; j < iCountDim; j++)
675             {
676                 //checks if size < size(int)
677                 if (pCurrentArg->get(j) >= INT_MAX)
678                 {
679                     wchar_t szError[bsiz];
680                     os_swprintf(szError, bsiz, _W("variable size exceeded : less than %d expected.\n").c_str(), INT_MAX);
681                     throw ast::InternalError(szError);
682                 }
683
684                 int d = static_cast<int>(pCurrentArg->get(j));
685                 if (d > _piMaxDim[i])
686                 {
687                     _piMaxDim[i] = d;
688                 }
689             }
690
691             iSeqCount *= iCountDim;
692             if (_piCountDim)
693             {
694                 _piCountDim[i] = iCountDim;
695             }
696         }
697         else
698         {
699             wchar_t szError[bsiz];
700             os_swprintf(szError, bsiz, _W("Invalid index.\n").c_str());
701
702             delete[] _piMaxDim;
703             delete[] _piCountDim;
704             cleanIndexesArguments(_pArgsIn, _pArgsOut);
705
706             throw ast::InternalError(szError);
707         }
708         _pArgsOut->push_back(pCurrentArg);
709
710     }
711
712
713     //return 0 to force extract to create an empty matrix
714     if (_pRef &&
715             (_pRef->isDouble() && _pRef->getAs<Double>()->isEmpty()))
716     {
717         return 0;
718     }
719
720     //returns a negative value if at least one parameter is undefined
721     //case with : or $ for creation by insertion
722     return (!bUndefine ? iSeqCount : -iSeqCount);
723 }
724
725 void cleanIndexesArguments(typed_list* _pArgsOrig, typed_list* _pArgsNew)
726 {
727     if (_pArgsNew)
728     {
729         //free pArg content
730         for (int iArg = 0; iArg < _pArgsNew->size(); iArg++)
731         {
732             if ((*_pArgsNew)[iArg] != (*_pArgsOrig)[iArg])
733             {
734                 if ((*_pArgsNew)[iArg])
735                 {
736                     (*_pArgsNew)[iArg]->killMe();
737                 }
738             }
739         }
740
741         _pArgsNew->clear();
742     }
743 }
744
745 void getIndexesWithDims(int _iIndex, int* _piIndexes, const int* _piDims, int _iDims)
746 {
747     int iMul = 1;
748     for (int i = 0; i < _iDims; i++)
749     {
750         _piIndexes[i] = (int)(_iIndex / iMul) % _piDims[i];
751         iMul *= _piDims[i];
752     }
753
754     //matrix [2,4,3]
755     //index = 12 ( 0,2,1) = 1 * 4 * 2 + 2 * 2 + 0 = 12
756     //loop 1
757     // (12 / 1) % 2 -> 0
758     //loop 2
759     // (12 / 2) % 4 -> 2
760     //loop 3
761     // (12 / 8) % 3 -> 1
762
763     //matrix [3,4,3]
764     //index = 22
765     //loop 1
766     // (22 / 1) % 3 -> 1
767     //loop 2
768     // (22 / 3) % 4 -> 3
769     //loop 3
770     // (22 / 12) % 3 -> 1
771
772     //matrix [3,4,3]
773     //index = 35
774     //loop 1
775     // (35 / 1) % 3 -> 2
776     //loop 2
777     // (35 / 3) % 4 -> 3
778     //loop 3
779     // (35 / 12) % 3 -> 2
780 }
781
782
783 int getIndexWithDims(int* _piIndexes, const int* _piDims, int _iDims)
784 {
785     int idx = 0;
786     int iMult = 1;
787     for (int i = 0; i < _iDims; i++)
788     {
789         idx += _piIndexes[i] * iMult;
790         iMult *= _piDims[i];
791     }
792     return idx;
793 }
794
795 types::Function::ReturnValue VariableToString(types::InternalType* pIT, const wchar_t* wcsVarName)
796 {
797     if (pIT->hasToString() == false)
798     {
799         types::Function::ReturnValue ret = types::Function::Error;
800         //call overload %type_p
801         types::typed_list in;
802         types::typed_list out;
803
804         pIT->IncreaseRef();
805         in.push_back(pIT);
806
807         try
808         {
809             ret = Overload::generateNameAndCall(L"p", in, 1, out);
810             pIT->DecreaseRef();
811             return ret;
812         }
813         catch (const ast::InternalError &ie)
814         {
815             pIT->DecreaseRef();
816             throw ie;
817         }
818     }
819     else
820     {
821         std::wostringstream ostr;
822         if (pIT->isFunction())
823         {
824             pIT->getAs<types::Function>()->toString(ostr);
825         }
826         else if (pIT->isList() || pIT->isCallable())
827         {
828             ostr << wcsVarName;
829         }
830
831         //to manage lines information
832         int iLines = ConfigVariable::getConsoleLines();
833
834         bool bFinish = false;
835         do
836         {
837             //block by block
838             bFinish = pIT->toString(ostr);
839             if (ConfigVariable::isError())
840             {
841                 ConfigVariable::resetError();
842                 ostr.str(L"");
843                 ConfigVariable::resetExecutionBreak();
844                 return types::Function::Error;
845             }
846
847             if (bFinish == false && iLines != 0)
848             {
849                 //show message on prompt
850                 bFinish = linesmore() == 1;
851             }
852
853             if (ConfigVariable::isPrintCompact() == false && ConfigVariable::isPrintInput() == false)
854             {
855                 ostr << std::endl;
856             }
857
858             scilabForcedWriteW(ostr.str().c_str());
859             ostr.str(L"");
860         }
861         while (bFinish == false && ConfigVariable::isExecutionBreak() == false);
862
863         if (bFinish == false)
864         {
865             ConfigVariable::resetExecutionBreak();
866         }
867         pIT->clearPrintState();
868         return types::Function::OK;
869     }
870 }
871
872 //n-uplet in french
873 int computeTuples(int* _piCountDim, int _iDims, int _iCurrentDim, int* _piIndex)
874 {
875     //if bRet == 1, previous dims has reach max value.
876     int iRet = 0;
877
878     if (_iCurrentDim == 0)
879     {
880         //last dims
881         if (_piIndex[_iCurrentDim] >= _piCountDim[_iCurrentDim])
882         {
883             _piIndex[_iCurrentDim] = 0;
884             return 1;
885         }
886     }
887     else
888     {
889         iRet = computeTuples(_piCountDim, _iDims, _iCurrentDim - 1, _piIndex);
890         if (iRet)
891         {
892             _piIndex[_iCurrentDim]++;
893             if (_piIndex[_iCurrentDim] >= _piCountDim[_iCurrentDim])
894             {
895                 _piIndex[_iCurrentDim] = 0;
896                 return 1;
897             }
898         }
899     }
900     return 0;
901 }
902
903 Double* createEmptyDouble()
904 {
905     return Double::Empty();
906 }
907
908 int getIntValueFromDouble(InternalType* _pIT, int _iPos)
909 {
910     return static_cast<int>(_pIT->getAs<Double>()->get(_iPos));
911 }
912
913 double* getDoubleArrayFromDouble(InternalType* _pIT)
914 {
915     return _pIT->getAs<Double>()->get();
916 }
917
918 Double* createDoubleVector(int _iSize)
919 {
920     int piDims[] = {1, _iSize};
921     Double* pOut = new Double(2, piDims);
922     for (int i = 0; i < _iSize; i++)
923     {
924         pOut->set(i, i + 1);
925     }
926     return pOut;
927 }
928
929 bool checkArgValidity(typed_list& _Arg)
930 {
931     for (int i = 0; i < (int)_Arg.size(); i++)
932     {
933         if (_Arg[i]->isDouble() == false)
934         {
935             return false;
936         }
937
938         Double* pDbl = _Arg[i]->getAs<Double>();
939         double* pdbl = pDbl->get();
940         for (int j = 0; j < pDbl->getSize(); j++)
941         {
942             if (pdbl[j] <= 0)
943             {
944                 return false;
945             }
946         }
947     }
948
949     return true;
950 }
951
952 }