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