exec and execstr fixed and updated 42/16742/2
Cedric Delamarre [Mon, 29 Jun 2015 13:42:22 +0000 (15:42 +0200)]
* line number fixed when error occured in string executed by execstr.
execstr(["a=1;";"a(3)"])

* exec and execstr uses a seqexp to execute scripts.
test_run functions exec
test_run functions execstr

Change-Id: Ib55f1b5c1ef3e66385033c676445b459c0c1e46b

scilab/modules/ast/includes/system_env/configvariable.hxx
scilab/modules/ast/includes/types/file.hxx
scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/ast/src/cpp/system_env/configvariable.cpp
scilab/modules/ast/src/cpp/types/file.cpp
scilab/modules/core/src/cpp/InitScilab.cpp
scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp
scilab/modules/functions/sci_gateway/cpp/sci_execstr.cpp

index 864a378..8315210 100644 (file)
@@ -403,7 +403,7 @@ public :
     static void whereErrorToString(std::wostringstream &ostr);
 private :
     static std::vector<WhereEntry> m_Where;
-    static std::list<WhereEntry> m_WhereError;
+    static std::vector<WhereEntry> m_WhereError;
     static std::vector<int> m_FirstMacroLine;
 
     //module called with variable by reference
@@ -436,6 +436,14 @@ private:
 public:
     static void setMexFunctionName(const std::string& name);
     static std::string& getMexFunctionName();
+
+    // executed file with exec
+private:
+    static int m_iFileID;
+public:
+    static void setExecutedFileID(int _iFileID);
+    static int getExecutedFileID();
+
 };
 
 #endif /* !__CONFIGVARIABLE_HXX__ */
index 993c743..a1c0adf 100644 (file)
@@ -41,7 +41,7 @@ public :
     std::wstring                getFileTypeAsString();
 
     void                        setFilename(std::wstring _stFilename);
-    std::wstring                getFilename();
+    std::wstring&               getFilename();
 
     int                         getCountLines();
 
index c623805..6951ec6 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "macrofile.hxx"
 #include "macro.hxx"
+#include "filemanager.hxx"
 
 #include "runner.hxx"
 #include "threadmanagement.hxx"
@@ -926,6 +927,24 @@ void RunVisitorT<T>::visitprivate(const SeqExp  &e)
             setExpectedSize(iExpectedSize);
             InternalType * pIT = getResult();
 
+            // In case of exec file, set the file name in the Macro to store where it is defined.
+            int iFileID = ConfigVariable::getExecutedFileID();
+            if (iFileID && exp->isFunctionDec())
+            {
+                InternalType* pITMacro = symbol::Context::getInstance()->get(exp->getAs<FunctionDec>()->getSymbol());
+                if (pITMacro)
+                {
+                    types::Macro* pMacro = pITMacro->getAs<types::Macro>();
+                    types::File* pFile = FileManager::getFile(iFileID);
+                    // scilab.quit is not open with mopen
+                    // in this case pFile is NULL because FileManager have not been filled.
+                    if (pFile)
+                    {
+                        pMacro->setFileName(pFile->getFilename());
+                    }
+                }
+            }
+
             if (pIT != NULL)
             {
                 bool bImplicitCall = false;
index f9bbdd7..44e3303 100644 (file)
@@ -1099,7 +1099,7 @@ int ConfigVariable::getFuncprot()
 */
 
 std::vector<ConfigVariable::WhereEntry> ConfigVariable::m_Where;
-std::list<ConfigVariable::WhereEntry> ConfigVariable::m_WhereError;
+std::vector<ConfigVariable::WhereEntry> ConfigVariable::m_WhereError;
 std::vector<int> ConfigVariable::m_FirstMacroLine;
 void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, types::Callable* _pCall)
 {
@@ -1264,6 +1264,7 @@ void ConfigVariable::fillWhereError(int _iErrorLine)
     {
         // +1 because the first line of the funtionDec "function func()" is the line 1.
         int iTmp = _iErrorLine - getMacroFirstLines() + 1;
+        m_WhereError.reserve(m_Where.size());
         for (auto where = m_Where.rbegin(); where != m_Where.rend(); ++where)
         {
             m_WhereError.emplace_back(iTmp, (*where).m_absolute_line, (*where).m_name, (*where).m_macro_first_line, (*where).m_file_name);
@@ -1377,3 +1378,18 @@ std::string& ConfigVariable::getMexFunctionName()
 {
     return mexFunctionName;
 }
+
+/*
+** \}
+*/
+// executed file with exec
+int ConfigVariable::m_iFileID = 0;
+void ConfigVariable::setExecutedFileID(int _iFileID)
+{
+    m_iFileID = _iFileID;
+}
+
+int ConfigVariable::getExecutedFileID()
+{
+    return m_iFileID;
+}
index 0d6f9de..7334a54 100644 (file)
@@ -170,7 +170,7 @@ void File::setFilename(std::wstring _stFilename)
     m_stFilename = _stFilename;
 }
 
-std::wstring File::getFilename()
+std::wstring& File::getFilename()
 {
     return m_stFilename;
 }
index 4608529..c04fdd2 100644 (file)
@@ -293,7 +293,6 @@ int StartScilabEngine(ScilabEngineInfo* _pSEI)
         else if (_pSEI->pstFile)
         {
             //-f option execute exec('%s',-1)
-            Parser parser;
             char *pstCommand = (char *)MALLOC(sizeof(char) * (strlen("exec(\"\",-1)") + strlen(_pSEI->pstFile) + 1));
             sprintf(pstCommand, "exec(\"%s\",-1)", _pSEI->pstFile);
 
index 2344422..7c3cbf3 100644 (file)
@@ -102,16 +102,6 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
             }
             else
             {
-                if (file)
-                {
-                    delete pExp;
-                    mclose(iID);
-                    file->close();
-                    delete file;
-                    FREE(pstFile);
-                    FREE(pwstFile);
-                }
-
                 Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "exec", 2);
                 return Function::Error;
             }
@@ -121,16 +111,6 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
 
                 if (in[2]->isDouble() == false || in[2]->getAs<Double>()->isScalar() == false)
                 {
-                    if (file)
-                    {
-                        delete pExp;
-                        mclose(iID);
-                        file->close();
-                        delete file;
-                        FREE(pstFile);
-                        FREE(pwstFile);
-                    }
-
                     //mode
                     Scierror(999, _("%s: Wrong type for input argument #%d: A integer expected.\n"), "exec", 3);
                     return Function::Error;
@@ -144,16 +124,6 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         {
             if (in.size() > 2)
             {
-                if (file)
-                {
-                    delete pExp;
-                    mclose(iID);
-                    file->close();
-                    delete file;
-                    FREE(pstFile);
-                    FREE(pwstFile);
-                }
-
                 Scierror(999, _("%s: Wrong value for input argument #%d: 'errcatch' expected.\n"), "exec", 2);
                 return Function::Error;
             }
@@ -163,16 +133,6 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         }
         else
         {
-            if (file)
-            {
-                delete pExp;
-                mclose(iID);
-                file->close();
-                delete file;
-                FREE(pstFile);
-                FREE(pwstFile);
-            }
-
             //not managed
             Scierror(999, _("%s: Wrong type for input argument #%d: A integer or string expected.\n"), "exec", 2);
             return Function::Error;
@@ -247,6 +207,8 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
 
         // update where to set the name of the executed file.
         ConfigVariable::setFileNameToLastWhere(pwstFile);
+
+        ConfigVariable::setExecutedFileID(iID);
     }
     else if (in[0]->isMacro() || in[0]->isMacroFile())
     {
@@ -304,246 +266,180 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         ConfigVariable::macroFirstLine_begin(pMacro->getFirstLine());
     }
 
-    ast::exps_t& LExp = pExp->getAs<SeqExp>()->getExps();
-
-    char pstPrompt[64];
-    //get prompt
-    GetCurrentPrompt(pstPrompt);
-    std::string stPrompt(pstPrompt);
-
-    std::string str;
-    int iCurrentLine = -1; //no data in str
-    int iCurrentCol = 0; //no data in str
-
     //save current prompt mode
     int oldVal = ConfigVariable::getPromptMode();
-
     ConfigVariable::setPromptMode(promptMode);
 
-    types::ThreadId* pThreadMe = ConfigVariable::getThread(__GetCurrentThreadKey());
-
-    for (ast::exps_t::iterator j = LExp.begin(), itEnd = LExp.end() ; j != itEnd ; ++j)
+    // if not exp displaying, just execute the seqexp
+    if (file == NULL || promptMode == 0 || promptMode == 2)
     {
+        ast::SeqExp* pSeqExp = pExp->getAs<SeqExp>();
+
         try
         {
-            if (pThreadMe && pThreadMe->getInterrupt())
+            ExecVisitor execExps;
+            pSeqExp->accept(execExps);
+        }
+        catch (ast::ScilabMessage sm)
+        {
+            if (bErrCatch == false)
             {
-                ThreadManagement::SendAstPendingSignal();
-                pThreadMe->suspend();
+                ConfigVariable::setPromptMode(oldVal);
+                ConfigVariable::setExecutedFileID(0);
+                throw sm;
             }
 
+            ConfigVariable::resetWhereError();
+            iErr = ConfigVariable::getLastErrorNumber();
+        }
+    }
+    else
+    {
+        ast::exps_t& LExp = pExp->getAs<SeqExp>()->getExps();
+
+        char pstPrompt[64];
+        //get prompt
+        GetCurrentPrompt(pstPrompt);
+        std::string stPrompt(pstPrompt);
+
+        std::string str;
+        int iCurrentLine = -1; //no data in str
+        int iCurrentCol = 0; //no data in str
+
+        for (ast::exps_t::iterator j = LExp.begin(), itEnd = LExp.end() ; j != itEnd; ++j)
+        {
+            // printf some exp
             ast::exps_t::iterator k = j;
-            //mode == 0, print new variable but not command
-            if (file && ConfigVariable::getPromptMode() != 0 && ConfigVariable::getPromptMode() != 2)
+            int iLastLine = (*j)->getLocation().last_line;
+            do
             {
-                int iLastLine = (*j)->getLocation().last_line;
-                do
-                {
-                    str = printExp(*file, *k, stPrompt, &iCurrentLine, &iCurrentCol, str);
-                    iLastLine = (*k)->getLocation().last_line;
-                    k++;
-                }
-                while (k != LExp.end() && (*k)->getLocation().first_line == iLastLine);
-
-                // In case where the line ends by spaces, iCurrentCol is not reset
-                // by printExp because we don't know if that's the end of the expression
-                // before go out of the loop. So we have to reset column count
-                // and print a new line before manage the next line.
-                if (iCurrentCol != 0)
-                {
-                    iCurrentCol = 0;
-                    printLine("", "", true);
-                }
+                str = printExp(*file, *k, stPrompt, &iCurrentLine, &iCurrentCol, str);
+                iLastLine = (*k)->getLocation().last_line;
+                k++;
             }
-            else
+            while (k != LExp.end() && (*k)->getLocation().first_line == iLastLine);
+
+            // In case where the line ends by spaces, iCurrentCol is not reset
+            // by printExp because we don't know if that's the end of the expression
+            // before go out of the loop. So we have to reset column count
+            // and print a new line before manage the next line.
+            if (iCurrentCol != 0)
             {
-                k++;
+                iCurrentCol = 0;
+                printLine("", "", true);
             }
 
+            // create a seqexp with printed exp
+            ast::exps_t* someExps = new ast::exps_t();
+            someExps->assign(j, k);
+            k--;
+            SeqExp seqExp(Location((*j)->getLocation().first_line,      (*k)->getLocation().last_line,
+                                   (*j)->getLocation().first_column,    (*k)->getLocation().last_column),
+                          *someExps);
 
-            ast::exps_t::iterator p = j;
-            for (; p != k; p++)
+            j = k;
+
+            try
             {
-                bool bImplicitCall = false;
-                j = p;
-                //excecute script
-                //force -1 to prevent recursive call to exec to write in console
-                //ConfigVariable::setPromptMode(-1);
-                ExecVisitor execMe;
-                (*j)->accept(execMe);
-                //ConfigVariable::setPromptMode(promptMode);
-
-                if (pwstFile && (*j)->isFunctionDec())
+                // execute printed exp
+                ExecVisitor execExps;
+                seqExp.accept(execExps);
+            }
+            catch (ast::ScilabMessage sm)
+            {
+                ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
+
+                if (file)
                 {
-                    InternalType* pIT = symbol::Context::getInstance()->get((*j)->getAs<FunctionDec>()->getSymbol());
-                    if (pIT)
-                    {
-                        types::Macro* pMacro = pIT->getAs<types::Macro>();
-                        pMacro->setFileName(pwstFile);
-                    }
+                    delete pExp;
+                    mclose(iID);
+                    file->close();
+                    delete file;
+                    FREE(pstFile);
+                    FREE(pwstFile);
                 }
 
-                //to manage call without ()
-                if (execMe.getResult() != NULL && execMe.getResult()->isCallable())
+                if (pMacro)
                 {
-                    Callable *pCall = execMe.getResult()->getAs<Callable>();
-                    types::typed_list out;
-                    types::typed_list in;
-                    types::optional_list opt;
-
-                    try
-                    {
-                        //in this case of calling, we can return only one values
-                        ExecVisitor execCall;
-                        execCall.setExpectedSize(1);
-                        pCall->invoke(in, opt, 1, out, execCall, *(*j));
-
-                        if (out.size() == 0)
-                        {
-                            execMe.setResult(NULL);
-                        }
-                        else if (out.size() == 1)
-                        {
-                            out[0]->DecreaseRef();
-                            execMe.setResult(out[0]);
-                            bImplicitCall = true;
-                        }
-                        else
-                        {
-                            for (int i = 0 ; i < static_cast<int>(out.size()) ; i++)
-                            {
-                                out[i]->DecreaseRef();
-                                execMe.setResult(i, out[i]);
-                            }
-                        }
-                    }
-                    catch (ScilabMessage sm)
-                    {
-                        if (ConfigVariable::getLastErrorFunction() == L"")
-                        {
-                            ConfigVariable::setLastErrorFunction(pCall->getName());
-                        }
-
-                        throw sm;
-                    }
+                    // reset last first line of macro called
+                    ConfigVariable::macroFirstLine_end();
                 }
 
-                //update ans variable
-                SimpleVar* pVar = dynamic_cast<SimpleVar*>(*j);
-                //don't output Simplevar and empty result
-                if (execMe.getResult() != NULL && (pVar == NULL || bImplicitCall))
+                if (bErrCatch == false)
                 {
-                    InternalType* pITAns = execMe.getResult();
-                    symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), pITAns);
-                    if ( (*j)->isVerbose() && bErrCatch == false)
+                    ConfigVariable::setPromptMode(oldVal);
+                    ConfigVariable::setExecutedFileID(0);
+
+                    // avoid double delete on exps when "seqExp" is destryed and "LExp" too
+                    ast::exps_t& protectExp = seqExp.getExps();
+                    for (int i = 0; i < protectExp.size(); ++i)
                     {
-                        //TODO manage multiple returns
-                        scilabWriteW(L" ans  =\n\n");
-                        std::wostringstream ostrName;
-                        ostrName << SPACES_LIST << L"ans";
-                        VariableToString(pITAns, ostrName.str().c_str());
+                        protectExp[i] = NULL;
                     }
-                }
-            }
-        }
-        catch (const ast::InternalAbort& ia)
-        {
-            if (file)
-            {
-                delete pExp;
-                mclose(iID);
-                file->close();
-                delete file;
-                FREE(pstFile);
-                FREE(pwstFile);
-            }
 
-            //restore previous prompt mode
-            ConfigVariable::setPromptMode(oldVal);
-
-            throw ia;
-        }
-        catch (ast::ScilabMessage& sm)
-        {
-            ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
+                    throw sm;
+                }
 
-            if (pMacro)
+                ConfigVariable::resetWhereError();
+                iErr = ConfigVariable::getLastErrorNumber();
+            }
+            catch (ast::ScilabError& se)
             {
-                if (ConfigVariable::getLastErrorFunction() == L"")
+                ConfigVariable::setExecutedFileID(0);
+                ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
+                if (ConfigVariable::getLastErrorNumber() == 0)
                 {
-                    ConfigVariable::setLastErrorFunction(pMacro->getName());
+                    ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
+                    ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
+                    ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
+                    ConfigVariable::setLastErrorFunction(wstring(L""));
                 }
 
-                //restore previous prompt mode
-                ConfigVariable::setPromptMode(oldVal);
-
-                // reset last first line of macro called
-                ConfigVariable::macroFirstLine_end();
-            }
-
-            // get location of exp before delete it in "file" case.
-            Location loc = (*j)->getLocation();
-
-            if (file)
-            {
-                delete pExp;
-                mclose(iID);
-                file->close();
-                delete file;
-                FREE(pstFile);
-                FREE(pwstFile);
-            }
+                //store message
+                iErr = ConfigVariable::getLastErrorNumber();
+                if (bErrCatch == false)
+                {
+                    if (file)
+                    {
+                        delete pExp;
+                        mclose(iID);
+                        file->close();
+                        delete file;
+                        FREE(pstFile);
+                        FREE(pwstFile);
+                    }
 
+                    //restore previous prompt mode
+                    ConfigVariable::setPromptMode(oldVal);
 
-            if (bErrCatch == false)
-            {
-                sm.SetErrorLocation(loc);
-                throw sm;
-            }
+                    // avoid double delete on exps when "seqExp" is destryed and "LExp" too
+                    ast::exps_t& protectExp = seqExp.getExps();
+                    for (int i = 0; i < protectExp.size(); ++i)
+                    {
+                        protectExp[i] = NULL;
+                    }
 
-            ConfigVariable::resetWhereError();
-            iErr = ConfigVariable::getLastErrorNumber();
-            break;
-        }
-        catch (ast::ScilabError& se)
-        {
-            ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
-            if (ConfigVariable::getLastErrorNumber() == 0)
-            {
-                ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
-                ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
-                ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
-                ConfigVariable::setLastErrorFunction(wstring(L""));
-            }
+                    throw se;
+                }
 
-            //store message
-            iErr = ConfigVariable::getLastErrorNumber();
-            if (bErrCatch == false)
-            {
-                if (file)
+                if (pMacro)
                 {
-                    delete pExp;
-                    mclose(iID);
-                    file->close();
-                    delete file;
-                    FREE(pstFile);
-                    FREE(pwstFile);
+                    // reset last first line of macro called
+                    ConfigVariable::macroFirstLine_end();
                 }
 
-                //restore previous prompt mode
-                ConfigVariable::setPromptMode(oldVal);
-
-                throw se;
+                ConfigVariable::resetWhereError();
+                break;
             }
 
-            if (pMacro)
+            ConfigVariable::setExecutedFileID(0);
+
+            // avoid double delete on exps when "seqExp" is destryed and "LExp" too
+            ast::exps_t& protectExp = seqExp.getExps();
+            for (int i = 0; i < protectExp.size(); ++i)
             {
-                // reset last first line of macro called
-                ConfigVariable::macroFirstLine_end();
+                protectExp[i] = NULL;
             }
-
-            ConfigVariable::resetWhereError();
-            break;
         }
     }
 
index d41e576..9884a64 100644 (file)
@@ -22,9 +22,6 @@
 #include "scilabWrite.hxx"
 #include "scilabexception.hxx"
 #include "configvariable.hxx"
-#include "context.hxx"
-#include "runner.hxx"
-#include "threadmanagement.hxx"
 
 #include <iostream>
 #include <fstream>
@@ -189,7 +186,7 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
     }
 
     //save current prompt mode
-    int oldVal = ConfigVariable::getPromptMode();
+    int iPromptMode = ConfigVariable::getPromptMode();
     ConfigVariable::setPromptMode(-1);
 
     if (ConfigVariable::getAnalyzerOptions() == 1)
@@ -200,137 +197,30 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
         //pExp->accept(debugMe);
     }
 
-    ast::exps_t LExp = pExp->getAs<SeqExp>()->getExps();
+    ast::SeqExp* pSeqExp = pExp->getAs<SeqExp>();
 
-    types::ThreadId* pThreadMe = ConfigVariable::getThread(__GetCurrentThreadKey());
+    // add execstr in list of macro called
+    // to manage line displayed when error occured.
+    ConfigVariable::macroFirstLine_begin(1);
 
-    for (ast::exps_t::iterator j = LExp.begin(), itEnd = LExp.end(); j != itEnd; ++j)
+    try
     {
-        try
-        {
-            if (pThreadMe && pThreadMe->getInterrupt())
-            {
-                ThreadManagement::SendAstPendingSignal();
-                pThreadMe->suspend();
-            }
-
-            // Set the real location of this exp contained in the string of the input of execstr
-            // in case where execstr is called in a file.
-            (*j)->getLocation().first_line = ConfigVariable::getMacroFirstLines();
-            (*j)->getLocation().last_line += (ConfigVariable::getMacroFirstLines() - 1);
-
-            //excecute script
-            ExecVisitor execMe;
-            (*j)->accept(execMe);
-
-            //to manage call without ()
-            if (execMe.getResult() != NULL && execMe.getResult()->isCallable())
-            {
-                Callable *pCall = execMe.getResult()->getAs<Callable>();
-                types::typed_list out;
-                types::typed_list in;
-                types::optional_list opt;
-
-                try
-                {
-                    ExecVisitor execCall;
-                    Function::ReturnValue Ret = pCall->call(in, opt, 1, out, &execCall);
-
-                    if (Ret == Callable::OK)
-                    {
-                        if (out.size() == 0)
-                        {
-                            execMe.setResult(NULL);
-                        }
-                        else if (out.size() == 1)
-                        {
-                            out[0]->DecreaseRef();
-                            execMe.setResult(out[0]);
-                        }
-                        else
-                        {
-                            for (int i = 0; i < static_cast<int>(out.size()); i++)
-                            {
-                                out[i]->DecreaseRef();
-                                execMe.setResult(i, out[i]);
-                            }
-                        }
-                    }
-                    else if (Ret == Callable::Error)
-                    {
-                        throw ast::ScilabMessage(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), (*j)->getLocation());
-                    }
-                }
-                catch (ast::ScilabMessage sm)
-                {
-                    if (ConfigVariable::getLastErrorFunction() == L"")
-                    {
-                        ConfigVariable::setLastErrorFunction(pCall->getName());
-                    }
-
-                    throw sm;
-                }
-            }
-
-            //update ans variable.
-            if (execMe.getResult() != NULL && execMe.getResult()->isDeletable())
-            {
-                InternalType* pITAns = execMe.getResult();
-                symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), pITAns);
-                if ((*j)->isVerbose() && bErrCatch == false)
-                {
-                    std::wostringstream ostr;
-                    ostr << L" ans  =" << std::endl;
-                    ostr << std::endl;
-                    pITAns->toString(ostr);
-                    ostr << std::endl;
-                    scilabWriteW(ostr.str().c_str());
-                }
-            }
-        }
-        catch (ast::ScilabMessage sm)
+        ExecVisitor execExps;
+        pSeqExp->accept(execExps);
+    }
+    catch (ast::ScilabMessage sm)
+    {
+        if (bErrCatch == false && bMute == false)
         {
-            ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
-            if (bErrCatch == false && bMute == false)
-            {
-                sm.SetErrorLocation((*j)->getLocation());
-                throw sm;
-            }
-
-            ConfigVariable::resetWhereError();
-            iErr = ConfigVariable::getLastErrorNumber();
-            break;
+            ConfigVariable::macroFirstLine_end();
+            ConfigVariable::setPromptMode(iPromptMode);
+            throw sm;
         }
-        catch (ast::ScilabError se)
-        {
-            ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
-            // check on error number because error message can be empty.
-            if (ConfigVariable::getLastErrorNumber() == 0)
-            {
-                ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
-                ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
-                ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
-                ConfigVariable::setLastErrorFunction(wstring(L""));
-            }
 
-            //store message
-            iErr = ConfigVariable::getLastErrorNumber();
-            if (bErrCatch == false)
-            {
-                //restore previous prompt mode
-                ConfigVariable::setPromptMode(oldVal);
-                se.SetErrorLocation((*j)->getLocation());
-                throw se;
-            }
-
-            ConfigVariable::resetWhereError();
-            break;
-        }
+        ConfigVariable::resetWhereError();
+        iErr = ConfigVariable::getLastErrorNumber();
     }
 
-    //restore previous prompt mode and silent mode
-    ConfigVariable::setPromptMode(oldVal);
-
     if (bErrCatch)
     {
         out.push_back(new Double(iErr));
@@ -340,6 +230,9 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
         ConfigVariable::resetError();
     }
 
+    ConfigVariable::macroFirstLine_end();
+    ConfigVariable::setPromptMode(iPromptMode);
+
     delete pExp;
     return Function::OK;
 }