From 08228a8e5890bbe325e79ea5905e0cb3dc072818 Mon Sep 17 00:00:00 2001 From: Cedric Delamarre Date: Wed, 22 May 2013 09:52:57 +0200 Subject: [PATCH] exec : management of macro and macrofile. Change-Id: Ia440a19553312f9a658dd0f2d2992abc971fb492 --- .../ast/src/cpp/system_env/configvariable.cpp | 1 - scilab/modules/core/sci_gateway/cpp/sci_argn.cpp | 4 + .../tests/unit_tests/compiled_functions.dia.ref | 32 --- .../core/tests/unit_tests/compiled_functions.tst | 31 --- .../unit_tests/not_compiled_functions.dia.ref | 23 --- .../tests/unit_tests/not_compiled_functions.tst | 26 --- .../modules/functions/sci_gateway/cpp/sci_exec.cpp | 209 ++++++++++++-------- .../functions/tests/unit_tests/exec.dia.ref | 84 ++++---- scilab/modules/functions/tests/unit_tests/exec.tst | 55 +++--- 9 files changed, 194 insertions(+), 271 deletions(-) delete mode 100644 scilab/modules/core/tests/unit_tests/compiled_functions.dia.ref delete mode 100644 scilab/modules/core/tests/unit_tests/compiled_functions.tst delete mode 100644 scilab/modules/core/tests/unit_tests/not_compiled_functions.dia.ref delete mode 100644 scilab/modules/core/tests/unit_tests/not_compiled_functions.tst diff --git a/scilab/modules/ast/src/cpp/system_env/configvariable.cpp b/scilab/modules/ast/src/cpp/system_env/configvariable.cpp index 853ef01..51fe27a 100644 --- a/scilab/modules/ast/src/cpp/system_env/configvariable.cpp +++ b/scilab/modules/ast/src/cpp/system_env/configvariable.cpp @@ -29,7 +29,6 @@ std::list ConfigVariable::m_ModuleList; void ConfigVariable::setModuleList(std::list& _pModule_list) { m_ModuleList = _pModule_list; - } std::list ConfigVariable::getModuleList() diff --git a/scilab/modules/core/sci_gateway/cpp/sci_argn.cpp b/scilab/modules/core/sci_gateway/cpp/sci_argn.cpp index dd8e569..cf0a91d 100644 --- a/scilab/modules/core/sci_gateway/cpp/sci_argn.cpp +++ b/scilab/modules/core/sci_gateway/cpp/sci_argn.cpp @@ -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 index 64be1f0..0000000 --- a/scilab/modules/core/tests/unit_tests/compiled_functions.dia.ref +++ /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 index 478c73c..0000000 --- a/scilab/modules/core/tests/unit_tests/compiled_functions.tst +++ /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 index 1411cee..0000000 --- a/scilab/modules/core/tests/unit_tests/not_compiled_functions.dia.ref +++ /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 index 23bc5cd..0000000 --- a/scilab/modules/core/tests/unit_tests/not_compiled_functions.tst +++ /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; diff --git a/scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp b/scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp index bfe1b36..e908174 100644 --- a/scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp +++ b/scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp @@ -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()->isScalar()) - { - //errcatch - String* pS = in[1]->getAs(); - 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()->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()->getReal()[0]; - bPromptMode = true; - } - } - else if (in[1]->isDouble() && in[1]->getAs()->isScalar()) - { - //mode - promptMode = (int)in[1]->getAs()->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()->isScalar()) { //1st argument is a path, parse file and execute it - int iParsePathLen = 0; + int iParsePathLen = 0; String* pS = in[0]->getAs(); - 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()->getBody(); - } - else if (in[0]->isMacroFile()) - { - //1st argument is a macro name, parse and execute it in the current environnement - if (in[0]->getAs()->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()->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()->parse() == false) + { + char* pstMacro = wide_string_to_UTF8(in[0]->getAs()->getName().c_str()); + Scierror(999, _("%s: Unable to parse macro '%s'"), "exec", pstMacro); + FREE(pstMacro); + return Function::Error; + } + + pMacro = in[0]->getAs()->getMacro(); + + } + else //1st argument is a macro name, execute it in the current environnement + { + pMacro = in[0]->getAs(); + } + + // 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()->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()->isScalar()) + { + //errcatch + String* pS = in[1]->getAs(); + 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()->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()->getReal()[0]; + bPromptMode = true; + } + } + else if (in[1]->isDouble() && in[1]->getAs()->isScalar()) + { + //mode + promptMode = (int)in[1]->getAs()->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()->getExps(); char pstPrompt[64]; //get prompt GetCurrentPrompt(pstPrompt); std::string stPrompt(pstPrompt); - // MessageBoxA(NULL, stPrompt, "", 0); - - wchar_t* pwstFile = expandPathVariableW(in[0]->getAs()->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()->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; } diff --git a/scilab/modules/functions/tests/unit_tests/exec.dia.ref b/scilab/modules/functions/tests/unit_tests/exec.dia.ref index c137701..7201e1c 100644 --- a/scilab/modules/functions/tests/unit_tests/exec.dia.ref +++ b/scilab/modules/functions/tests/unit_tests/exec.dia.ref @@ -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); diff --git a/scilab/modules/functions/tests/unit_tests/exec.tst b/scilab/modules/functions/tests/unit_tests/exec.tst index 37676c0..45caeeb 100644 --- a/scilab/modules/functions/tests/unit_tests/exec.tst +++ b/scilab/modules/functions/tests/unit_tests/exec.tst @@ -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); -- 1.7.9.5