exec : management of macro and macrofile. 55/11555/8
Cedric Delamarre [Wed, 22 May 2013 07:52:57 +0000 (09:52 +0200)]
Change-Id: Ia440a19553312f9a658dd0f2d2992abc971fb492

scilab/modules/ast/src/cpp/system_env/configvariable.cpp
scilab/modules/core/sci_gateway/cpp/sci_argn.cpp
scilab/modules/core/tests/unit_tests/compiled_functions.dia.ref [deleted file]
scilab/modules/core/tests/unit_tests/compiled_functions.tst [deleted file]
scilab/modules/core/tests/unit_tests/not_compiled_functions.dia.ref [deleted file]
scilab/modules/core/tests/unit_tests/not_compiled_functions.tst [deleted file]
scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp
scilab/modules/functions/tests/unit_tests/exec.dia.ref
scilab/modules/functions/tests/unit_tests/exec.tst

index 853ef01..51fe27a 100644 (file)
@@ -29,7 +29,6 @@ std::list<std::wstring> ConfigVariable::m_ModuleList;
 void ConfigVariable::setModuleList(std::list<std::wstring>& _pModule_list)
 {
     m_ModuleList = _pModule_list;
-
 }
 
 std::list<std::wstring> ConfigVariable::getModuleList()
index dd8e569..cf0a91d 100644 (file)
@@ -91,6 +91,10 @@ types::Function::ReturnValue sci_argn(types::typed_list &in, int _iRetCount, typ
     {
         Double* pD = new Double(0);
         out.push_back(pD);
+        if (_iRetCount == 2)
+        {
+            out.push_back(pD);
+        }
     }
     else
     {
diff --git a/scilab/modules/core/tests/unit_tests/compiled_functions.dia.ref b/scilab/modules/core/tests/unit_tests/compiled_functions.dia.ref
deleted file mode 100644 (file)
index 64be1f0..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// compiled functions
-deff('y=foo(a)','x=a+1000,stacksize(x),y=stacksize();y=y(1)')
-a = stacksize();
-a = a(1);
-y = foo(a);
-if y<>a+1000 then bugmes();quit;end
-a=y;
-deff('y=toto()','a=stacksize();a=a(1);y=foo(a)')
-y=toto();
-if y<>a+1000 then bugmes();quit;end
-a=y;
-exec(toto)
- y  =
-    10003000.  
-if y<>a+1000 then bugmes();quit;end
-a=y;
-//in a loop
-for k=1:3,
-  y=toto();
-  if y<>a+1000 then bugmes();quit;end
-  a=y;
-end
diff --git a/scilab/modules/core/tests/unit_tests/compiled_functions.tst b/scilab/modules/core/tests/unit_tests/compiled_functions.tst
deleted file mode 100644 (file)
index 478c73c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-
-// compiled functions
-
-deff('y=foo(a)','x=a+1000,stacksize(x),y=stacksize();y=y(1)')
-
-a = stacksize();
-a = a(1);
-y = foo(a);
-
-if y<>a+1000 then pause,end
-a=y;
-deff('y=toto()','a=stacksize();a=a(1);y=foo(a)')
-y=toto();
-if y<>a+1000 then pause,end
-a=y;
-exec(toto)
-if y<>a+1000 then pause,end
-a=y;
-
-//in a loop
-for k=1:3,
-  y=toto();
-  if y<>a+1000 then pause,end
-  a=y;
-end
diff --git a/scilab/modules/core/tests/unit_tests/not_compiled_functions.dia.ref b/scilab/modules/core/tests/unit_tests/not_compiled_functions.dia.ref
deleted file mode 100644 (file)
index 1411cee..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-//non compiled functions
-deff("y=foo(a)","x=a+1000,stacksize(x),y=stacksize();y=y(1)","n");
-a = stacksize();
-a = a(1);
-y = foo(a);
-if y<>a+1000 then bugmes();quit;end
-a = y;
-deff("y=toto()","a=stacksize();a=a(1);y=foo(a)","n");
-y = toto();
-if y<>a+1000 then bugmes();quit;end
-a=y;
-exec(toto);
- y  =
-    10003000.  
-if y<>a+1000 then bugmes();quit;end
-a=y;
diff --git a/scilab/modules/core/tests/unit_tests/not_compiled_functions.tst b/scilab/modules/core/tests/unit_tests/not_compiled_functions.tst
deleted file mode 100644 (file)
index 23bc5cd..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2008 - INRIA
-//
-//  This file is distributed under the same license as the Scilab package.
-// =============================================================================
-
-//non compiled functions
-
-deff("y=foo(a)","x=a+1000,stacksize(x),y=stacksize();y=y(1)","n");
-
-a = stacksize();
-a = a(1);
-y = foo(a);
-
-if y<>a+1000 then pause,end
-
-a = y;
-deff("y=toto()","a=stacksize();a=a(1);y=foo(a)","n");
-y = toto();
-
-if y<>a+1000 then pause,end
-a=y;
-exec(toto);
-if y<>a+1000 then pause,end
-a=y;
index bfe1b36..e908174 100644 (file)
@@ -60,6 +60,12 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
     int iID             = 0;
     Parser parser;
 
+    wchar_t* pwstFile = NULL;
+    char* pstFile = NULL;
+
+    std::string stFile;
+    std::ifstream* file = NULL;
+
     if (ConfigVariable::getStartProcessing() == false)
     {
         if (ConfigVariable::getVerbose())
@@ -78,73 +84,29 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         return Function::Error;
     }
 
-    if (in.size() > 1)
-    {
-        //errcatch or mode
-        if (in[1]->isString() && in[1]->getAs<types::String>()->isScalar())
-        {
-            //errcatch
-            String* pS = in[1]->getAs<types::String>();
-            if (os_wcsicmp(pS->get(0), L"errcatch") == 0)
-            {
-                bErrCatch = true;
-            }
-            else
-            {
-                Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "exec", 2);
-                return Function::Error;
-            }
-
-            if (in.size() > 2)
-            {
-                if (in[2]->isDouble() == false || in[2]->getAs<Double>()->isScalar() == false)
-                {
-                    //mode
-                    Scierror(999, _("%s: Wrong type for input argument #%d: A integer expected.\n"), "exec", 3);
-                    return Function::Error;
-                }
-
-                promptMode = (int)in[2]->getAs<Double>()->getReal()[0];
-                bPromptMode = true;
-            }
-        }
-        else if (in[1]->isDouble() && in[1]->getAs<Double>()->isScalar())
-        {
-            //mode
-            promptMode = (int)in[1]->getAs<Double>()->getReal()[0];
-            bPromptMode = true;
-        }
-        else
-        {
-            //not managed
-            Scierror(999, _("%s: Wrong type for input argument #%d: A integer or string expected.\n"), "exec", 2);
-            return Function::Error;
-        }
-    }
-
     if (in[0]->isString() && in[0]->getAs<types::String>()->isScalar())
     {
         //1st argument is a path, parse file and execute it
-        int iParsePathLen              = 0;
+        int iParsePathLen = 0;
         String* pS = in[0]->getAs<types::String>();
 
-        wchar_t* pstFile = pS->get(0);
-        wchar_t *expandedPath = expandPathVariableW(pstFile);
+        pwstFile = expandPathVariableW(pS->get(0));
+        pstFile = wide_string_to_UTF8(pwstFile);
+        stFile = std::string(pstFile);
+        file = new std::ifstream(pstFile);
+
         wchar_t* pwstTemp = (wchar_t*)MALLOC(sizeof(wchar_t) * (PATH_MAX * 2));
-        get_full_pathW(pwstTemp, (const wchar_t*)expandedPath, PATH_MAX * 2);
+        get_full_pathW(pwstTemp, (const wchar_t*)pwstFile, PATH_MAX * 2);
 
         /*fake call to mopen to show file within file()*/
         if (mopen(pwstTemp, L"r", 0, &iID) != MOPEN_NO_ERROR)
         {
             FREE(pwstTemp);
-            char* pstPath = wide_string_to_UTF8(expandedPath);
-            Scierror(999, _("%s: Cannot open file %s.\n"), "exec", pstPath);
-            FREE(pstPath);
+            Scierror(999, _("%s: Cannot open file %s.\n"), "exec", pstFile);
             return Function::Error;
         }
 
         parser.parseFile(pwstTemp, L"exec");
-        FREE(expandedPath);
         FREE(pwstTemp);
         if (parser.getExitStatus() !=  Parser::Succeded)
         {
@@ -173,23 +135,42 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
             pExp = parser.getTree();
         }
     }
-    else if (in[0]->isMacro())
+    else if (in[0]->isMacro() || in[0]->isMacroFile())
     {
-        //1st argument is a macro name, execute it in the current environnement
-        pExp = in[0]->getAs<Macro>()->getBody();
-    }
-    else if (in[0]->isMacroFile())
-    {
-        //1st argument is a macro name, parse and execute it in the current environnement
-        if (in[0]->getAs<MacroFile>()->parse() == false)
+        types::Macro* pMacro = NULL;
+        typed_list input;
+        optional_list optional;
+        typed_list output;
+        ast::ExecVisitor execFunc;
+
+        if (in[0]->isMacroFile())
         {
-            char* pstMacro = wide_string_to_UTF8(in[0]->getAs<MacroFile>()->getName().c_str());
-            Scierror(999, _("%s: Unable to parse macro '%s'"), "exec", pstMacro);
-            FREE(pstMacro);
-            mclose(iID);
+            //1st argument is a macro name, parse and execute it in the current environnement
+            if (in[0]->getAs<MacroFile>()->parse() == false)
+            {
+                char* pstMacro = wide_string_to_UTF8(in[0]->getAs<MacroFile>()->getName().c_str());
+                Scierror(999, _("%s: Unable to parse macro '%s'"), "exec", pstMacro);
+                FREE(pstMacro);
+                return Function::Error;
+            }
+
+            pMacro = in[0]->getAs<MacroFile>()->getMacro();
+
+        }
+        else //1st argument is a macro name, execute it in the current environnement
+        {
+            pMacro = in[0]->getAs<Macro>();
+        }
+
+        // We dont care about the input and output argument
+        if (pMacro->outputs_get()->empty() == false || pMacro->inputs_get()->empty() == false)
+        {
+            Scierror(999, _("%s: Wrong type for input argument #%d: A macro without input and output argument expected.\n"), "exec", 1);
             return Function::Error;
         }
-        pExp = in[0]->getAs<MacroFile>()->getMacro()->getBody();
+
+        promptMode = 3;
+        pExp = pMacro->getBody();
     }
     else
     {
@@ -197,18 +178,57 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         return Function::Error;
     }
 
+    // get mode and errcatch
+    if (in.size() > 1)
+    {
+        //errcatch or mode
+        if (in[1]->isString() && in[1]->getAs<types::String>()->isScalar())
+        {
+            //errcatch
+            String* pS = in[1]->getAs<types::String>();
+            if (os_wcsicmp(pS->get(0), L"errcatch") == 0)
+            {
+                bErrCatch = true;
+            }
+            else
+            {
+                Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "exec", 2);
+                return Function::Error;
+            }
+
+            if (in.size() > 2)
+            {
+                if (in[2]->isDouble() == false || in[2]->getAs<Double>()->isScalar() == false)
+                {
+                    //mode
+                    Scierror(999, _("%s: Wrong type for input argument #%d: A integer expected.\n"), "exec", 3);
+                    return Function::Error;
+                }
+
+                promptMode = (int)in[2]->getAs<Double>()->getReal()[0];
+                bPromptMode = true;
+            }
+        }
+        else if (in[1]->isDouble() && in[1]->getAs<Double>()->isScalar())
+        {
+            //mode
+            promptMode = (int)in[1]->getAs<Double>()->getReal()[0];
+            bPromptMode = true;
+        }
+        else
+        {
+            //not managed
+            Scierror(999, _("%s: Wrong type for input argument #%d: A integer or string expected.\n"), "exec", 2);
+            return Function::Error;
+        }
+    }
+
     ast::exps_t LExp = pExp->getAs<SeqExp>()->getExps();
 
     char pstPrompt[64];
     //get prompt
     GetCurrentPrompt(pstPrompt);
     std::string stPrompt(pstPrompt);
-    //    MessageBoxA(NULL, stPrompt, "", 0);
-
-    wchar_t* pwstFile =  expandPathVariableW(in[0]->getAs<types::String>()->get(0));
-    char* pstFile = wide_string_to_UTF8(pwstFile);
-    std::string stFile(pstFile);
-    std::ifstream file(pstFile);
 
     std::string str;
     int iCurrentLine = -1; //no data in str
@@ -225,12 +245,12 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         {
             ast::exps_t::iterator k = j;
             //mode == 0, print new variable but not command
-            if (ConfigVariable::getPromptMode() != 0 && ConfigVariable::getPromptMode() != 2)
+            if (file && ConfigVariable::getPromptMode() != 0 && ConfigVariable::getPromptMode() != 2)
             {
                 int iLastLine = (*j)->getLocation().last_line;
                 do
                 {
-                    str = printExp(file, *k, stPrompt, &iCurrentLine, &iCurrentCol, str);
+                    str = printExp(*file, *k, stPrompt, &iCurrentLine, &iCurrentCol, str);
                     iLastLine = (*k)->getLocation().last_line;
                     k++;
                 }
@@ -398,15 +418,22 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
                         ConfigVariable::setLastErrorFunction(execFunc.getResult()->getAs<Callable>()->getName());
                     }
 
+                    if (file)
+                    {
+                        mclose(iID);
+                    }
 
-                    mclose(iID);
                     //restore previous prompt mode
                     ConfigVariable::setPromptMode(oldVal);
                     throw ast::ScilabMessage(os.str(), 0, (*j)->getLocation());
                 }
             }
 
-            mclose(iID);
+            if (file)
+            {
+                mclose(iID);
+            }
+
             throw ast::ScilabMessage((*j)->getLocation());
         }
         catch (const ast::ScilabError& se)
@@ -423,10 +450,13 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
             iErr = ConfigVariable::getLastErrorNumber();
             if (bErrCatch == false)
             {
-                file.close();
-                //print failed command
-                scilabError(getExpression(stFile, *j).c_str());
-                scilabErrorW(L"\n");
+                if (file)
+                {
+                    file->close();
+                    //print failed command
+                    scilabError(getExpression(stFile, *j).c_str());
+                    scilabErrorW(L"\n");
+                }
 
                 //write error
                 scilabErrorW(se.GetErrorMessage().c_str());
@@ -435,7 +465,11 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
                 wchar_t szError[bsiz];
                 os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->getLocation().first_line);
                 scilabErrorW(szError);
-                mclose(iID);
+                if (file)
+                {
+                    mclose(iID);
+                }
+
                 //restore previous prompt mode
                 ConfigVariable::setPromptMode(oldVal);
                 //throw ast::ScilabMessage(szError, 1, (*j)->getLocation());
@@ -456,11 +490,16 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         ConfigVariable::setLastErrorCall();
     }
 
-    delete pExp;
-    mclose(iID);
-    file.close();
-    FREE(pstFile);
-    FREE(pwstFile);
+    if (file)
+    {
+        delete pExp;
+        mclose(iID);
+        file->close();
+        delete file;
+        FREE(pstFile);
+        FREE(pwstFile);
+    }
+
     return Function::OK;
 }
 
index c137701..7201e1c 100644 (file)
@@ -11,58 +11,48 @@ tab_ref = [
 "เฮลโลเวิลด์",
 "حريات وحقوق",
 "תוכנית"];
-str_exec = 'disp(''OK'');';
-for i = 1 : size(tab_ref,'*')
-  mkdir(TMPDIR + filesep() + tab_ref(i));
-  fd = mopen(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + '.sce','wt');
-  mputl(str_exec,fd);
-  mclose(fd);
-  exec(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + '.sce');
-  mdelete(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + '.sce');
-  rmdir(TMPDIR + filesep() + tab_ref(i));
-end  
- OK   
- OK   
- OK   
- OK   
- OK   
- OK   
+str_exec = "disp(''OK'');";
+for i = 1 : size(tab_ref,"*")
+    mkdir(TMPDIR + filesep() + tab_ref(i));
+    fd = mopen(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + ".sce","wt");
+    mputl(str_exec,fd);
+    mclose(fd);
+    exec(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + ".sce");
+    mdelete(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + ".sce");
+    rmdir(TMPDIR + filesep() + tab_ref(i));
+end
+ OK
+ OK
+ OK
+ OK
+ OK
+ OK
 // create a script file
-mputl('a=1;b=2',TMPDIR+'/myscript')
- ans  =
-  T  
+mputl("a=1;b=2",TMPDIR+"/myscript");
 // execute it
-exec(TMPDIR+'/myscript')
+exec(TMPDIR+"/myscript")
 a=1;b=2
- b  =
-    2.  
-if isdef('a')<> %t then bugmes();quit;end
-if isdef('b')<> %t then bugmes();quit;end
-if a <> 1 then bugmes();quit;end
-if b <> 2 then bugmes();quit;end
+b  = 
+    2.
+if isdef("a")<> %t then bugmes();quit;end
+if isdef("b")<> %t then bugmes();quit;end
+assert_checkequal(a, 1);
+assert_checkequal(b, 2);
 // create a function
-deff('y=foo(x)','a=x+1;y=a^2');
+deff("y=foo(x)","a=x+1;y=a^2");
 clear a b
 // call the function
 k = foo(1);
-if isdef('k')<> %t then bugmes();quit;end
-if isdef('a')<> %f then bugmes();quit;end
-if k <> 4 then bugmes();quit;end
-x=4; //create x to make it known by the script foo
+if isdef("k")<> %t then bugmes();quit;end
+if isdef("a")<> %f then bugmes();quit;end
+assert_checkequal(k, 4);
 clear k y
-exec(foo);
- y  =
-    25.  
-if isdef('y')<> %t then bugmes();quit;end
-if y <> 25 then bugmes();quit;end
+// create a function and call this body as a script
+deff("script()","a=x+1;y=a^2");
+x=4; //create x to make it known by script
+exec(script);
+y  = 
+    25.
+if isdef("y")<> %t then bugmes();quit;end
+if isdef("a")<> %t then bugmes();quit;end
+assert_checkequal(y, 25);
index 37676c0..45caeeb 100644 (file)
@@ -13,40 +13,43 @@ tab_ref = [
 "حريات وحقوق",
 "תוכנית"];
 
-str_exec = 'disp(''OK'');';
-
-for i = 1 : size(tab_ref,'*')
-  mkdir(TMPDIR + filesep() + tab_ref(i));
-  fd = mopen(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + '.sce','wt');
-  mputl(str_exec,fd);
-  mclose(fd);
-  exec(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + '.sce');
-  mdelete(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + '.sce');
-  rmdir(TMPDIR + filesep() + tab_ref(i));
-end  
+str_exec = "disp(''OK'');";
+
+for i = 1 : size(tab_ref,"*")
+    mkdir(TMPDIR + filesep() + tab_ref(i));
+    fd = mopen(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + ".sce","wt");
+    mputl(str_exec,fd);
+    mclose(fd);
+    exec(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + ".sce");
+    mdelete(TMPDIR + filesep() + tab_ref(i) + filesep() + tab_ref(i) + ".sce");
+    rmdir(TMPDIR + filesep() + tab_ref(i));
+end
 
 // create a script file
-mputl('a=1;b=2',TMPDIR+'/myscript')
+mputl("a=1;b=2",TMPDIR+"/myscript");
 // execute it
-exec(TMPDIR+'/myscript')
-if isdef('a')<> %t then pause,end
-if isdef('b')<> %t then pause,end
-if a <> 1 then pause,end
-if b <> 2 then pause,end
+exec(TMPDIR+"/myscript")
+if isdef("a")<> %t then pause,end
+if isdef("b")<> %t then pause,end
+assert_checkequal(a, 1);
+assert_checkequal(b, 2);
 
 
 // create a function
-deff('y=foo(x)','a=x+1;y=a^2');
+deff("y=foo(x)","a=x+1;y=a^2");
 clear a b
 // call the function
 k = foo(1);
-if isdef('k')<> %t then pause,end
-if isdef('a')<> %f then pause,end
-if k <> 4 then pause,end
-
-x=4; //create x to make it known by the script foo
+if isdef("k")<> %t then pause,end
+if isdef("a")<> %f then pause,end
+assert_checkequal(k, 4);
 clear k y
-exec(foo);
-if isdef('y')<> %t then pause,end
-if y <> 25 then pause,end
+
+// create a function and call this body as a script
+deff("script()","a=x+1;y=a^2");
+x=4; //create x to make it known by script
+exec(script);
+if isdef("y")<> %t then pause,end
+if isdef("a")<> %t then pause,end
+assert_checkequal(y, 25);