* Bug 14573 & 14623 fixed: varargout management when is not alone and in mlist overload 13/19413/5
Antoine ELIAS [Mon, 4 Sep 2017 07:02:21 +0000 (09:02 +0200)]
Change-Id: I2abc9f06ace6741b9c0deed72ef802aa9e639c3c

scilab/CHANGES.md
scilab/modules/ast/src/cpp/types/macro.cpp
scilab/modules/ast/src/cpp/types/mlist.cpp
scilab/modules/ast/src/cpp/types/tlist.cpp
scilab/modules/ast/tests/nonreg_tests/bug_14573.tst [new file with mode: 0644]
scilab/modules/ast/tests/nonreg_tests/bug_14623.tst [new file with mode: 0644]

index b505367..0bc9d7d 100644 (file)
@@ -360,7 +360,9 @@ the [development mailing list](dev@lists.scilab.org) for a particular toolbox.
 * [#14376](http://bugzilla.scilab.org/show_bug.cgi?id=14376): input() is broken: \n introduced before prompting, multiple prompts, missing assignment, "%" "\n" "\t" no longer supported in messages...
 * [#14399](http://bugzilla.scilab.org/show_bug.cgi?id=14399): Whereami : wrong information (line numbers).
 * [#14424](http://bugzilla.scilab.org/show_bug.cgi?id=14424): New problem with the input function.
+* [#14573](http://bugzilla.scilab.org/show_bug.cgi?id=14573): Management of varargout when is not alone.
 * [#14598](http://bugzilla.scilab.org/show_bug.cgi?id=14598): `fort` wasn't properly removed.
+* [#14623](http://bugzilla.scilab.org/show_bug.cgi?id=14623): Bad lhs in MList extraction overload.
 * [#14629](http://bugzilla.scilab.org/show_bug.cgi?id=14629): In the Xcos EXPRESSION block, `<` could truncate the rendering of the expression in the icon.
 * [#14636](http://bugzilla.scilab.org/show_bug.cgi?id=14636): Xcos model with modelica electrical blocks (created in 5.5.2) crashed Scilab 6.
 * [#14637](http://bugzilla.scilab.org/show_bug.cgi?id=14367): Some Scilab 5.5.2 diagrams didn't simulate properly in Xcos.
index 01e2f81..dea0cb3 100644 (file)
@@ -269,11 +269,10 @@ Callable::ReturnValue Macro::call(typed_list &in, optional_list &opt, int _iRetC
 
     // varargout management
     //rules :
-    // varargout must be alone
     // varargout is a list
     // varargout can containt more items than caller need
     // varargout must containt at leat caller needs
-    if (m_outputArgs->size() == 1 && m_outputArgs->back()->getSymbol().getName() == L"varargout")
+    if (m_outputArgs->size() >= 1 && m_outputArgs->back()->getSymbol().getName() == L"varargout")
     {
         bVarargout = true;
         List* pL = new List();
@@ -329,7 +328,45 @@ Callable::ReturnValue Macro::call(typed_list &in, optional_list &opt, int _iRetC
         cleanCall(pContext, oldVal);
         throw ia;
     }
-    // Normally, seqexp throws only SM so no need to catch SErr
+
+    //nb excepted output without varargout
+    int iRet = std::min((int)m_outputArgs->size() - (bVarargout ? 1 : 0), _iRetCount);
+
+    //normal output management
+    //for (std::list<symbol::Variable*>::iterator i = m_outputArgs->begin(); i != m_outputArgs->end() && _iRetCount; ++i, --_iRetCount)
+    for (auto arg : *m_outputArgs)
+    {
+        iRet--;
+        if (iRet < 0)
+        {
+            break;
+        }
+
+        InternalType * pIT = pContext->get(arg);
+        if (pIT)
+        {
+            out.push_back(pIT);
+            pIT->IncreaseRef();
+        }
+        else
+        {
+            const int size = (const int)out.size();
+            for (int j = 0; j < size; ++j)
+            {
+                out[j]->DecreaseRef();
+                out[j]->killMe();
+            }
+            out.clear();
+            cleanCall(pContext, oldVal);
+
+            char* pstArgName = wide_string_to_UTF8(arg->getSymbol().getName().c_str());
+            char* pstMacroName = wide_string_to_UTF8(getName().c_str());
+            Scierror(999, _("Undefined variable '%s' in function '%s'.\n"), pstArgName, pstMacroName);
+            FREE(pstArgName);
+            FREE(pstMacroName);
+            return Callable::Error;
+        }
+    }
 
     //varargout management
     if (bVarargout)
@@ -372,37 +409,6 @@ Callable::ReturnValue Macro::call(typed_list &in, optional_list &opt, int _iRetC
             out.push_back(pIT);
         }
     }
-    else
-    {
-        //normal output management
-        for (std::list<symbol::Variable*>::iterator i = m_outputArgs->begin(); i != m_outputArgs->end() && _iRetCount; ++i, --_iRetCount)
-        {
-            InternalType * pIT = pContext->get(*i);
-            if (pIT)
-            {
-                out.push_back(pIT);
-                pIT->IncreaseRef();
-            }
-            else
-            {
-                const int size = (const int)out.size();
-                for (int j = 0; j < size; ++j)
-                {
-                    out[j]->DecreaseRef();
-                    out[j]->killMe();
-                }
-                out.clear();
-                cleanCall(pContext, oldVal);
-
-                char* pstArgName = wide_string_to_UTF8((*i)->getSymbol().getName().c_str());
-                char* pstMacroName = wide_string_to_UTF8(getName().c_str());
-                Scierror(999, _("Undefined variable '%s' in function '%s'.\n"), pstArgName, pstMacroName);
-                FREE(pstArgName);
-                FREE(pstMacroName);
-                return Callable::Error;
-            }
-        }
-    }
 
     //close the current scope
     cleanCall(pContext, oldVal);
@@ -432,7 +438,7 @@ int Macro::getNbInputArgument(void)
 
 int Macro::getNbOutputArgument(void)
 {
-    if (m_outputArgs->size() == 1 && m_outputArgs->back()->getSymbol().getName() == L"varargout")
+    if (m_outputArgs->size() >= 1 && m_outputArgs->back()->getSymbol().getName() == L"varargout")
     {
         return -1;
     }
index 6dee900..3496558 100644 (file)
@@ -26,7 +26,7 @@
 
 namespace types
 {
-bool MList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, const ast::Exp & e)
+bool MList::invoke(typed_list & in, optional_list & /*opt*/, int _iRetCount, typed_list & out, const ast::Exp & e)
 {
     if (in.size() == 0)
     {
@@ -71,11 +71,11 @@ bool MList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/,
 
     try
     {
-        ret = Overload::call(L"%" + getShortTypeStr() + L"_e", in, 1, out);
+        ret = Overload::call(L"%" + getShortTypeStr() + L"_e", in, _iRetCount, out);
     }
     catch (ast::InternalError & /*se*/)
     {
-        ret = Overload::call(L"%l_e", in, 1, out);
+        ret = Overload::call(L"%l_e", in, _iRetCount, out);
     }
 
     // Remove this from "in" for keep "in" unchanged.
index 2d9bc34..6677245 100644 (file)
@@ -180,7 +180,7 @@ bool TList::invoke(typed_list & in, optional_list & /*opt*/, int _iRetCount, typ
             if (stType.size() > 8)
             {
                 std::wcout << (L"%" + stType.substr(0, 8) + L"_e") << std::endl;
-                ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out);
+                ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, _iRetCount, out);
             }
             else
             {
@@ -189,7 +189,7 @@ bool TList::invoke(typed_list & in, optional_list & /*opt*/, int _iRetCount, typ
         }
         catch (ast::InternalError & /*se*/)
         {
-            ret = Overload::call(L"%l_e", in, 1, out);
+            ret = Overload::call(L"%l_e", in, _iRetCount, out);
         }
     }
 
diff --git a/scilab/modules/ast/tests/nonreg_tests/bug_14573.tst b/scilab/modules/ast/tests/nonreg_tests/bug_14573.tst
new file mode 100644 (file)
index 0000000..24c6e57
--- /dev/null
@@ -0,0 +1,101 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - ESI - Antoine ELIAS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+// <-- Non-regression test for bug 14573 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=14573
+//
+// <-- Short Description -->
+// varargout error when it is not alone
+
+//varargout alone
+function [varargout]=foo0(varargin)
+    for i=1:argn(2)
+        varargout(i)=varargin(i);
+    end
+endfunction
+
+[a,b]=foo0(1,2,3,4,5);
+assert_checkequal(a, 1);
+assert_checkequal(b, 2);
+
+[a,b,c]=foo0(1,2,3,4,5);
+assert_checkequal(a, 1);
+assert_checkequal(b, 2);
+assert_checkequal(c, 3);
+
+[a,b,c,d]=foo0(1,2,3,4,5);
+assert_checkequal(a, 1);
+assert_checkequal(b, 2);
+assert_checkequal(c, 3);
+assert_checkequal(d, 4);
+
+[a,b,c,d,e]=foo0(1,2,3,4,5);
+assert_checkequal(a, 1);
+assert_checkequal(b, 2);
+assert_checkequal(c, 3);
+assert_checkequal(d, 4);
+assert_checkequal(e, 5);
+
+//1 output var + varargout
+function [aa, varargout]=foo1(varargin)
+    aa = argn(2);
+    for i=1:aa
+        varargout(i)=varargin(i);
+    end
+endfunction
+
+[a,b]=foo1(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 1);
+
+[a,b,c]=foo1(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 1);
+assert_checkequal(c, 2);
+
+[a,b,c,d]=foo1(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 1);
+assert_checkequal(c, 2);
+assert_checkequal(d, 3);
+
+//2 output vars + varargin
+function [aa, bb, varargout]=foo2(varargin)
+    aa = argn(2);
+    bb = argn(1);
+    for i=1:aa
+        varargout(i)=varargin(i);
+    end
+endfunction
+
+[a,b]=foo2(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 2);
+
+[a,b,c]=foo2(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 3);
+assert_checkequal(c, 1);
+
+[a,b,c,d]=foo2(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 4);
+assert_checkequal(c, 1);
+assert_checkequal(d, 2);
+
+[a,b,c,d,e]=foo2(1,2,3);
+assert_checkequal(a, 3);
+assert_checkequal(b, 5);
+assert_checkequal(c, 1);
+assert_checkequal(d, 2);
+assert_checkequal(e, 3);
+
diff --git a/scilab/modules/ast/tests/nonreg_tests/bug_14623.tst b/scilab/modules/ast/tests/nonreg_tests/bug_14623.tst
new file mode 100644 (file)
index 0000000..6dad3ba
--- /dev/null
@@ -0,0 +1,51 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - ESI - Antoine ELIAS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+// <-- Non-regression test for bug 14623 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=14623
+//
+// <-- Short Description -->
+// wrong arng(1) in MList extration overload
+
+//wrong argn(1) in MList overload
+function varargout = %mymlist_e(varargin)
+    varargout(1) = argn(1);
+    varargout(2) = argn(2);
+    for i = 3:argn(1)
+        varargout(i) = i;
+    end
+endfunction
+
+m = mlist("mymlist");
+
+
+[res1, res2] = m(1);
+assert_checkequal(res1, 2);
+assert_checkequal(res2, 2);
+
+[res1, res2, res3] = m(1);
+assert_checkequal(res1, 3);
+assert_checkequal(res2, 2);
+assert_checkequal(res3, 3);
+
+[res1, res2, res3, res4] = m(1);
+assert_checkequal(res1, 4);
+assert_checkequal(res2, 2);
+assert_checkequal(res3, 3);
+assert_checkequal(res4, 4);
+
+[res1, res2, res3, res4, res5] = m(1);
+assert_checkequal(res1, 5);
+assert_checkequal(res2, 2);
+assert_checkequal(res3, 3);
+assert_checkequal(res4, 4);
+assert_checkequal(res5, 5);