Restrict multiple insertion. 40/15940/9
Cedric Delamarre [Thu, 12 Feb 2015 10:41:19 +0000 (11:41 +0100)]
test_run ast insert

Change-Id: I79cd3f44815ab2bb86a25f8c72dddc82ddd9816f

scilab/modules/ast/src/cpp/ast/visitor_common.cpp
scilab/modules/ast/tests/unit_tests/insert.dia.ref
scilab/modules/ast/tests/unit_tests/insert.tst

index 10f6253..a586ff2 100644 (file)
@@ -944,29 +944,37 @@ InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fiel
                     }
                     else
                     {
+                        // Avoid insertion in most of one element.
+                        if (pStruct->isScalar() == false)
+                        {
+                            std::wostringstream os;
+                            os << _W("Unable to insert multiple item in a Struct.");
+                            throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                        }
+
                         // extract field x and append it to elements for next recursion.
                         List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
-                        for (int iList = 0; iList < pLOut->getSize(); iList++)
-                        {
-                            InternalType* pIT = pLOut->get(iList);
-                            if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
-                            {
-                                // clone element before modify it.
-                                //pIT->DecreaseRef();
-                                pIT = pIT->clone();
-                                pStruct->get(iList)->set(pwcsFieldname, pIT);
-                            }
 
-                            ExpHistory* pEHChield = new ExpHistory(pEH,
-                                                                   (*iterFields)->getExp(),
-                                                                   (*iterFields)->getArgs(),
-                                                                   (*iterFields)->getLevel(),
-                                                                   (*iterFields)->isCellExp(),
-                                                                   pIT);
-                            pEHChield->setWhereReinsert(iList);
-                            workFields.push_back(pEHChield);
+                        // pStruct must be scalar because we cant insert most of one element in the same insertion
+                        InternalType* pIT = pLOut->get(0);
+                        if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
+                        {
+                            // clone element before modify it.
+                            //pIT->DecreaseRef();
+                            pIT = pIT->clone();
+                            pStruct->get(0)->set(pwcsFieldname, pIT);
                         }
 
+                        ExpHistory* pEHChield = new ExpHistory(pEH,
+                                                               (*iterFields)->getExp(),
+                                                               (*iterFields)->getArgs(),
+                                                               (*iterFields)->getLevel(),
+                                                               (*iterFields)->isCellExp(),
+                                                               pIT);
+
+                        pEHChield->setWhereReinsert(0);
+                        workFields.push_back(pEHChield);
+
                         pLOut->killMe();
                     }
                 }
@@ -1010,30 +1018,30 @@ InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fiel
 
                         InternalType* pIT = pTL->extract(pArgs);
                         List* pList = pIT->getAs<List>();
-                        double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
 
-                        int listSize = pList->getSize();
+                        if (pList->getSize() > 1)
+                        {
+                            std::wostringstream os;
+                            os << _W("Unable to insert multiple item in a List.");
+                            throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                        }
+
+                        double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
                         if ((*iterFields)->getExp() == NULL)
                         {
                             // a(x)(y)
                             // extract a(x) and push_BACK to extract y
-                            for (int i = 0; i < listSize; i++)
-                            {
-                                ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(i));
-                                pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
-                                workFields.push_back(pEHExtract);
-                            }
+                            ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(0));
+                            pEHExtract->setWhereReinsert((int)(pdblArgs[0] - 1));
+                            workFields.push_back(pEHExtract);
                         }
                         else
                         {
                             // a(x).b
                             // extract a(x) and push_FRONT to extract b
-                            for (int i = 0; i < listSize; i++)
-                            {
-                                ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(i));
-                                pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
-                                workFields.push_front(pEHExtract);
-                            }
+                            ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(0));
+                            pEHExtract->setWhereReinsert((int)(pdblArgs[0] - 1));
+                            workFields.push_front(pEHExtract);
                         }
 
                         //extract create a list to store items
@@ -1113,13 +1121,17 @@ InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fiel
                 List* pL = pITCurrent->getAs<List>();
                 if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
                 {
-                    // pITCurrent is an extraction of other Type
-                    for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
-                    {
-                        ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
-                        pEHExtract->setWhereReinsert(iLoop);
-                        workFields.push_front(pEHExtract);
-                    }
+                    std::wostringstream os;
+                    os << _W("Wrong insertion.");
+                    throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+
+                    //                    // pITCurrent is an extraction of other Type
+                    //                    for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
+                    //                    {
+                    //                        ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
+                    //                        pEHExtract->setWhereReinsert(iLoop);
+                    //                        workFields.push_front(pEHExtract);
+                    //                    }
                 }
                 else
                 {
index 2311ce7..f1a8730 100644 (file)
@@ -91,31 +91,29 @@ assert_checkequal(a.b.den, [2 2 2]);
 a(2).b = [rl rl rl] * %s;
 assert_checkequal(size(a), [2 1]);
 assert_checkequal(a(2).b.num, [%s**2 %s**2 %s**2]);
-a.b(1,3).num = 5;
-assert_checkequal(a.b(1).num, [%s 14 5]);
-assert_checkequal(a(2).b.num, [%s**2 %s**2 5]);
+err = execstr("a.b(1,3).num = 5;", "errcatch");
+assert_checktrue(err <> 0);
 a(3).b.num = 12;
-a.b(1,1).num = -9;
-assert_checkequal(a.b(1).num, [-9 14 5]+(0*%s));
-assert_checkequal(a(2).b.num, [-9 %s**2 5]);
-assert_checkequal(a(3).b.num, -9);
+assert_checkequal(a(3).b.num, 12);
+execstr("a.b(1,1).num = -9;", "errcatch");
+assert_checktrue(err <> 0);
 clear a;
 tt = tlist(["toto" "gg" "ff"] , 12, 13);
 tt(3).c = 23;
 assert_checkequal(tt.ff.c, 23);
 tt(2).c = 22;
 assert_checkequal(tt.gg.c, 22);
-tt([2 3]).d = 99;
-assert_checkequal(tt.gg.d, 99);
-assert_checkequal(tt.ff.d, 99);
-tt([2 3]).d.e = 98;
-assert_checkequal(tt.gg.d.e, 98);
-assert_checkequal(tt.ff.d.e, 98);
-tt([2 3]).d(3).e = 78;
-assert_checkequal(tt.ff.d.e, list(98, [], 78));
-assert_checkequal(tt.gg.d.e, list(98, [], 78));
+err = execstr("tt([2 3]).d = 99;", "errcatch");
+assert_checktrue(err <> 0);
+err = execstr("tt([2 3]).d.e = 98;", "errcatch");
+assert_checktrue(err <> 0);
+err = execstr("tt([2 3]).d(3).e = 78;", "errcatch");
+assert_checktrue(err <> 0);
 tt(2).d.e(4) = 12;
-assert_checkequal(tt.gg.d.e, list([98; 0; 0; 12], [0; 0; 0; 12], [78; 0; 0; 12]));
+assert_checkequal(tt(2).d.e, [0; 0; 0; 12]);
+tt(2).d(2).o = 15;
+err = execstr("tt(2).d.e(4) = 16;", "errcatch");
+assert_checktrue(err <> 0);
 clear tt;
 tl=tlist(["toto" "gg"],11);
 function tutu(tl)
@@ -170,17 +168,17 @@ mm(3).c = 23;
 assert_checkequal(mm.ff.c, 23);
 mm(2).c = 22;
 assert_checkequal(mm.gg.c, 22);
-mm([2 3]).d = 99;
-assert_checkequal(mm.gg.d, 99);
-assert_checkequal(mm.ff.d, 99);
-mm([2 3]).d.e = 98;
-assert_checkequal(mm.gg.d.e, 98);
-assert_checkequal(mm.ff.d.e, 98);
-mm([2 3]).d(3).e = 78;
-assert_checkequal(mm.ff.d.e, list(98, [], 78));
-assert_checkequal(mm.gg.d.e, list(98, [], 78));
+err = execstr("mm([2 3]).d = 99;", "errcatch");
+assert_checktrue(err <> 0);
+err = execstr("mm([2 3]).d.e = 98;", "errcatch");
+assert_checktrue(err <> 0);
+err = execstr("mm([2 3]).d(3).e = 78;", "errcatch");
+assert_checktrue(err <> 0);
 mm(2).d.e(4) = 12;
-assert_checkequal(mm.gg.d.e, list([98; 0; 0; 12], [0; 0; 0; 12], [78; 0; 0; 12]));
+assert_checkequal(mm(2).d.e, [0; 0; 0; 12]);
+mm(2).d(2).o = 15;
+err = execstr("mm(2).d.e(4) = 16;", "errcatch");
+assert_checktrue(err <> 0);
 clear mm;
 ml = mlist(["tutu" "t"], 12);
 std=struct("d", 5);
@@ -199,7 +197,6 @@ assert_checkequal(ml.t, 21);
 function r=%s_i_tutu(varargin)
     s1=varargin($-1);
     s2=varargin($);
-    //s2(i,j)=s1 s1 matrix of scalar
     r=s2;
     r.t = s1;
 endfunction
@@ -234,7 +231,6 @@ endfunction
 function r=%toto_i_tata(varargin)
     s1=varargin($-1);
     s2=varargin($);
-    //s2(i,j)=s1 s1 is a struct
     r=s2;
     r.ff = s1;
 endfunction
@@ -399,3 +395,20 @@ assert_checkequal(tl.f1, 12);
 assert_checkequal(ml.f.f1, 12);
 assert_checkequal(mml.ff1.f.f1, 14);
 funcprot(oldFuncProt);
+// multiple insertion in struct
+function r = initst()
+    r.f.e = list()
+    r.f(3).e = 3
+endfunction
+st=initst();
+st.f(:).e = 5;
+assert_checkequal(st.f.e, list(5,5,5));
+st=initst();
+st.f(1:4).e = 5;
+assert_checkequal(st.f.e, list(5,5,5,5));
+st=initst();
+err=execstr("st.f(1:2).e(2) = 5;", "errcatch");
+assert_checktrue(err <> 0);
+st=initst();
+err=execstr("st(1:2).f(1:4).e = 5;", "errcatch");
+assert_checktrue(err <> 0);
index 6930b32..40ae4fe 100644 (file)
@@ -112,15 +112,14 @@ a(2).b = [rl rl rl] * %s;
 assert_checkequal(size(a), [2 1]);
 assert_checkequal(a(2).b.num, [%s**2 %s**2 %s**2]);
 
-a.b(1,3).num = 5;
-assert_checkequal(a.b(1).num, [%s 14 5]);
-assert_checkequal(a(2).b.num, [%s**2 %s**2 5]);
+err = execstr("a.b(1,3).num = 5;", "errcatch");
+assert_checktrue(err <> 0);
 
 a(3).b.num = 12;
-a.b(1,1).num = -9;
-assert_checkequal(a.b(1).num, [-9 14 5]+(0*%s));
-assert_checkequal(a(2).b.num, [-9 %s**2 5]);
-assert_checkequal(a(3).b.num, -9);
+assert_checkequal(a(3).b.num, 12);
+
+execstr("a.b(1,1).num = -9;", "errcatch");
+assert_checktrue(err <> 0);
 clear a;
 
 tt = tlist(["toto" "gg" "ff"] , 12, 13);
@@ -128,19 +127,22 @@ tt(3).c = 23;
 assert_checkequal(tt.ff.c, 23);
 tt(2).c = 22;
 assert_checkequal(tt.gg.c, 22);
-tt([2 3]).d = 99;
-assert_checkequal(tt.gg.d, 99);
-assert_checkequal(tt.ff.d, 99);
-tt([2 3]).d.e = 98;
-assert_checkequal(tt.gg.d.e, 98);
-assert_checkequal(tt.ff.d.e, 98);
 
-tt([2 3]).d(3).e = 78;
-assert_checkequal(tt.ff.d.e, list(98, [], 78));
-assert_checkequal(tt.gg.d.e, list(98, [], 78));
+err = execstr("tt([2 3]).d = 99;", "errcatch");
+assert_checktrue(err <> 0);
+
+err = execstr("tt([2 3]).d.e = 98;", "errcatch");
+assert_checktrue(err <> 0);
+
+err = execstr("tt([2 3]).d(3).e = 78;", "errcatch");
+assert_checktrue(err <> 0);
 
 tt(2).d.e(4) = 12;
-assert_checkequal(tt.gg.d.e, list([98; 0; 0; 12], [0; 0; 0; 12], [78; 0; 0; 12]));
+assert_checkequal(tt(2).d.e, [0; 0; 0; 12]);
+
+tt(2).d(2).o = 15;
+err = execstr("tt(2).d.e(4) = 16;", "errcatch");
+assert_checktrue(err <> 0);
 
 clear tt;
 
@@ -204,19 +206,22 @@ mm(3).c = 23;
 assert_checkequal(mm.ff.c, 23);
 mm(2).c = 22;
 assert_checkequal(mm.gg.c, 22);
-mm([2 3]).d = 99;
-assert_checkequal(mm.gg.d, 99);
-assert_checkequal(mm.ff.d, 99);
-mm([2 3]).d.e = 98;
-assert_checkequal(mm.gg.d.e, 98);
-assert_checkequal(mm.ff.d.e, 98);
 
-mm([2 3]).d(3).e = 78;
-assert_checkequal(mm.ff.d.e, list(98, [], 78));
-assert_checkequal(mm.gg.d.e, list(98, [], 78));
+err = execstr("mm([2 3]).d = 99;", "errcatch");
+assert_checktrue(err <> 0);
+
+err = execstr("mm([2 3]).d.e = 98;", "errcatch");
+assert_checktrue(err <> 0);
+
+err = execstr("mm([2 3]).d(3).e = 78;", "errcatch");
+assert_checktrue(err <> 0);
 
 mm(2).d.e(4) = 12;
-assert_checkequal(mm.gg.d.e, list([98; 0; 0; 12], [0; 0; 0; 12], [78; 0; 0; 12]));
+assert_checkequal(mm(2).d.e, [0; 0; 0; 12]);
+
+mm(2).d(2).o = 15;
+err = execstr("mm(2).d.e(4) = 16;", "errcatch");
+assert_checktrue(err <> 0);
 
 clear mm;
 
@@ -239,7 +244,6 @@ assert_checkequal(ml.t, 21);
 function r=%s_i_tutu(varargin)
     s1=varargin($-1);
     s2=varargin($);
-    //s2(i,j)=s1 s1 matrix of scalar
     r=s2;
     r.t = s1;
 endfunction
@@ -282,7 +286,6 @@ endfunction
 function r=%toto_i_tata(varargin)
     s1=varargin($-1);
     s2=varargin($);
-    //s2(i,j)=s1 s1 is a struct
     r=s2;
     r.ff = s1;
 endfunction
@@ -490,3 +493,26 @@ assert_checkequal(mml.ff1.f.f1, 14);
 
 funcprot(oldFuncProt);
 
+
+// multiple insertion in struct
+function r = initst()
+    r.f.e = list()
+    r.f(3).e = 3
+endfunction
+
+st=initst();
+st.f(:).e = 5;
+assert_checkequal(st.f.e, list(5,5,5));
+
+st=initst();
+st.f(1:4).e = 5;
+assert_checkequal(st.f.e, list(5,5,5,5));
+
+st=initst();
+err=execstr("st.f(1:2).e(2) = 5;", "errcatch");
+assert_checktrue(err <> 0);
+
+st=initst();
+err=execstr("st(1:2).f(1:4).e = 5;", "errcatch");
+assert_checktrue(err <> 0);
+