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