License Header change: Removed the LICENSE_END before beta
[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->isStruct())
514             {
515                 Struct* pStruct = _pRef->getAs<Struct>();
516
517                 if (_pArgsIn->size() != 1 || pStr->isScalar() == false)
518                 {
519                     bUndefine = true;
520                     continue;
521                 }
522
523                 wchar_t* pFieldName = pStr->get(0);
524
525                 // pCurrent arg is indexed to 1 unlike the return of "getFieldIndex"
526                 int iIndex = pStruct->get(0)->getFieldIndex(pFieldName) + 1;
527                 if (iIndex == -1)
528                 {
529                     bUndefine = true;
530                     continue;
531                 }
532
533                 pCurrentArg = new Double((double)iIndex);
534             }
535             else if (_pRef->isTList())
536             {
537                 // List can't be extract by field and MList must call overload
538                 TList* pTL = _pRef->getAs<TList>();
539                 pCurrentArg = new Double(pStr->getDims(), pStr->getDimsArray());
540                 double* pdbl = pCurrentArg->get();
541                 for (int i = 0; i < pStr->getSize(); i++)
542                 {
543                     wchar_t* pFieldName = pStr->get(i);
544                     int iIndex = pTL->getIndexFromString(pFieldName);
545                     if (iIndex == -1)
546                     {
547                         bUndefine = true;
548                         continue;
549                     }
550                     pdbl[i] = (double)(iIndex + 1);
551                 }
552             }
553             else if (_pRef->isList())
554             {
555                 bUndefine = true;
556                 break;
557             }
558             else if (_pRef->isCell())
559             {
560             }
561         }
562         else if (pIT->isPoly())
563         {
564             //$
565             Polynom* pMP = pIT->getAs<types::Polynom>();
566             int iMaxDim = 0;
567             //if pRef == NULL, use 0 insteadof, to allow a($+1) on new variable
568             if (_pRef)
569             {
570                 iMaxDim = _pRef->getAs<GenericType>()->getVarMaxDim(i, iDims);
571             }
572
573 #ifdef _SCILAB_DEBUGREF_
574             Double* pdbl = new Double(iMaxDim); // $
575             pCurrentArg = pMP->evaluate(pdbl);
576             pdbl->killMe();
577 #else
578             Double dbl(iMaxDim); // $
579             pCurrentArg = pMP->evaluate(&dbl);
580 #endif
581         }
582         else if (pIT->isBool())
583         {
584             //[T F F T F]
585             Bool *pB = pIT->getAs<types::Bool>();
586             int *piB = pB->get();
587             const int size = pB->getSize();
588
589             //find true item count
590             int iItemCount = 0;
591             for (int j = 0; j < size; j++)
592             {
593                 if (piB[j])
594                 {
595                     iItemCount++;
596                 }
597             }
598
599             //allow new Double variable
600             Double* pDbl = new Double(1, iItemCount);
601             double* pdbl = pDbl->getReal();
602
603             int j = 0;
604             for (int l = 0; l < size; l++)
605             {
606                 if (piB[l])
607                 {
608                     pdbl[j++] = l + 1;
609                 }
610             }
611             pCurrentArg = pDbl;
612         }
613         else if (pIT->isInt())
614         {
615             switch (pIT->getType())
616             {
617                 case InternalType::ScilabInt8:
618                 {
619                     pCurrentArg = convertIndex(pIT->getAs<Int8>());
620                     break;
621                 }
622                 case InternalType::ScilabInt16:
623                 {
624                     pCurrentArg = convertIndex(pIT->getAs<Int16>());
625                     break;
626                 }
627                 case InternalType::ScilabInt32:
628                 {
629                     pCurrentArg = convertIndex(pIT->getAs<Int32>());
630                     break;
631                 }
632                 case InternalType::ScilabInt64:
633                 {
634                     pCurrentArg = convertIndex(pIT->getAs<Int64>());
635                     break;
636                 }
637                 case InternalType::ScilabUInt8:
638                 {
639                     pCurrentArg = convertIndex(pIT->getAs<UInt8>());
640                     break;
641                 }
642                 case InternalType::ScilabUInt16:
643                 {
644                     pCurrentArg = convertIndex(pIT->getAs<UInt16>());
645                     break;
646                 }
647                 case InternalType::ScilabUInt32:
648                 {
649                     pCurrentArg = convertIndex(pIT->getAs<UInt32>());
650                     break;
651                 }
652                 case InternalType::ScilabUInt64:
653                 {
654                     pCurrentArg = convertIndex(pIT->getAs<UInt64>());
655                     break;
656                 }
657             }
658         }
659
660         if (bDeleteNeeded)
661         {
662             pIT->killMe();
663         }
664
665         if (pCurrentArg)
666         {
667             const int iCountDim = pCurrentArg->getSize();
668             _piMaxDim[i] = 0;
669             for (int j = 0; j < iCountDim; j++)
670             {
671                 //checks if size < size(int)
672                 if (pCurrentArg->get(j) >= INT_MAX)
673                 {
674                     wchar_t szError[bsiz];
675                     os_swprintf(szError, bsiz, _W("variable size exceeded : less than %d expected.\n").c_str(), INT_MAX);
676                     throw ast::InternalError(szError);
677                 }
678
679                 int d = static_cast<int>(pCurrentArg->get(j));
680                 if (d > _piMaxDim[i])
681                 {
682                     _piMaxDim[i] = d;
683                 }
684             }
685
686             iSeqCount *= iCountDim;
687             if (_piCountDim)
688             {
689                 _piCountDim[i] = iCountDim;
690             }
691         }
692         else
693         {
694             wchar_t szError[bsiz];
695             os_swprintf(szError, bsiz, _W("Invalid index.\n").c_str());
696
697             delete[] _piMaxDim;
698             delete[] _piCountDim;
699             cleanIndexesArguments(_pArgsIn, _pArgsOut);
700
701             throw ast::InternalError(szError);
702         }
703         _pArgsOut->push_back(pCurrentArg);
704
705     }
706
707
708     //return 0 to force extract to create an empty matrix
709     if (_pRef &&
710             (_pRef->isDouble() && _pRef->getAs<Double>()->isEmpty()))
711     {
712         return 0;
713     }
714
715     //returns a negative value if at least one parameter is undefined
716     //case with : or $ for creation by insertion
717     return (!bUndefine ? iSeqCount : -iSeqCount);
718 }
719
720 void cleanIndexesArguments(typed_list* _pArgsOrig, typed_list* _pArgsNew)
721 {
722     if (_pArgsNew)
723     {
724         //free pArg content
725         for (int iArg = 0; iArg < _pArgsNew->size(); iArg++)
726         {
727             if ((*_pArgsNew)[iArg] != (*_pArgsOrig)[iArg])
728             {
729                 if ((*_pArgsNew)[iArg])
730                 {
731                     (*_pArgsNew)[iArg]->killMe();
732                 }
733             }
734         }
735
736         _pArgsNew->clear();
737     }
738 }
739
740 void getIndexesWithDims(int _iIndex, int* _piIndexes, const int* _piDims, int _iDims)
741 {
742     int iMul = 1;
743     for (int i = 0; i < _iDims; i++)
744     {
745         _piIndexes[i] = (int)(_iIndex / iMul) % _piDims[i];
746         iMul *= _piDims[i];
747     }
748
749     //matrix [2,4,3]
750     //index = 12 ( 0,2,1) = 1 * 4 * 2 + 2 * 2 + 0 = 12
751     //loop 1
752     // (12 / 1) % 2 -> 0
753     //loop 2
754     // (12 / 2) % 4 -> 2
755     //loop 3
756     // (12 / 8) % 3 -> 1
757
758     //matrix [3,4,3]
759     //index = 22
760     //loop 1
761     // (22 / 1) % 3 -> 1
762     //loop 2
763     // (22 / 3) % 4 -> 3
764     //loop 3
765     // (22 / 12) % 3 -> 1
766
767     //matrix [3,4,3]
768     //index = 35
769     //loop 1
770     // (35 / 1) % 3 -> 2
771     //loop 2
772     // (35 / 3) % 4 -> 3
773     //loop 3
774     // (35 / 12) % 3 -> 2
775 }
776
777
778 int getIndexWithDims(int* _piIndexes, const int* _piDims, int _iDims)
779 {
780     int idx = 0;
781     int iMult = 1;
782     for (int i = 0; i < _iDims; i++)
783     {
784         idx += _piIndexes[i] * iMult;
785         iMult *= _piDims[i];
786     }
787     return idx;
788 }
789
790 types::Function::ReturnValue VariableToString(types::InternalType* pIT, const wchar_t* wcsVarName)
791 {
792     if (pIT->hasToString() == false)
793     {
794         types::Function::ReturnValue ret = types::Function::Error;
795         //call overload %type_p
796         types::typed_list in;
797         types::typed_list out;
798
799         pIT->IncreaseRef();
800         in.push_back(pIT);
801
802         try
803         {
804             ret = Overload::generateNameAndCall(L"p", in, 1, out);
805             pIT->DecreaseRef();
806             return ret;
807         }
808         catch (const ast::InternalError &ie)
809         {
810             pIT->DecreaseRef();
811             throw ie;
812         }
813     }
814     else
815     {
816         std::wostringstream ostr;
817         if (pIT->isFunction())
818         {
819             pIT->getAs<types::Function>()->toString(ostr);
820         }
821         else if (pIT->isList() || pIT->isCallable())
822         {
823             ostr << wcsVarName;
824         }
825
826         //to manage lines information
827         int iLines = ConfigVariable::getConsoleLines();
828
829         bool bFinish = false;
830         do
831         {
832             //block by block
833             bFinish = pIT->toString(ostr);
834             if (ConfigVariable::isError())
835             {
836                 ConfigVariable::resetError();
837                 ostr.str(L"");
838                 ConfigVariable::resetExecutionBreak();
839                 return types::Function::Error;
840             }
841
842             if (bFinish == false && iLines != 0)
843             {
844                 //show message on prompt
845                 bFinish = linesmore() == 1;
846             }
847
848             if (ConfigVariable::isPrintCompact() == false && ConfigVariable::isPrintInput() == false)
849             {
850                 ostr << std::endl;
851             }
852
853             scilabForcedWriteW(ostr.str().c_str());
854             ostr.str(L"");
855         }
856         while (bFinish == false && ConfigVariable::isExecutionBreak() == false);
857
858         if (bFinish == false)
859         {
860             ConfigVariable::resetExecutionBreak();
861         }
862         pIT->clearPrintState();
863         return types::Function::OK;
864     }
865 }
866
867 //n-uplet in french
868 int computeTuples(int* _piCountDim, int _iDims, int _iCurrentDim, int* _piIndex)
869 {
870     //if bRet == 1, previous dims has reach max value.
871     int iRet = 0;
872
873     if (_iCurrentDim == 0)
874     {
875         //last dims
876         if (_piIndex[_iCurrentDim] >= _piCountDim[_iCurrentDim])
877         {
878             _piIndex[_iCurrentDim] = 0;
879             return 1;
880         }
881     }
882     else
883     {
884         iRet = computeTuples(_piCountDim, _iDims, _iCurrentDim - 1, _piIndex);
885         if (iRet)
886         {
887             _piIndex[_iCurrentDim]++;
888             if (_piIndex[_iCurrentDim] >= _piCountDim[_iCurrentDim])
889             {
890                 _piIndex[_iCurrentDim] = 0;
891                 return 1;
892             }
893         }
894     }
895     return 0;
896 }
897
898 Double* createEmptyDouble()
899 {
900     return Double::Empty();
901 }
902
903 int getIntValueFromDouble(InternalType* _pIT, int _iPos)
904 {
905     return static_cast<int>(_pIT->getAs<Double>()->get(_iPos));
906 }
907
908 double* getDoubleArrayFromDouble(InternalType* _pIT)
909 {
910     return _pIT->getAs<Double>()->get();
911 }
912
913 Double* createDoubleVector(int _iSize)
914 {
915     int piDims[] = {1, _iSize};
916     Double* pOut = new Double(2, piDims);
917     for (int i = 0; i < _iSize; i++)
918     {
919         pOut->set(i, i + 1);
920     }
921     return pOut;
922 }
923
924 bool checkArgValidity(typed_list& _Arg)
925 {
926     for (int i = 0; i < (int)_Arg.size(); i++)
927     {
928         if (_Arg[i]->isDouble() == false)
929         {
930             return false;
931         }
932
933         Double* pDbl = _Arg[i]->getAs<Double>();
934         double* pdbl = pDbl->get();
935         for (int j = 0; j < pDbl->getSize(); j++)
936         {
937             if (pdbl[j] <= 0)
938             {
939                 return false;
940             }
941         }
942     }
943
944     return true;
945 }
946
947 }