error stack management and displaying 91/16691/6
Cedric Delamarre [Mon, 15 Jun 2015 12:45:47 +0000 (14:45 +0200)]
  * print of error in Scierror and catches removed
  * print done only in the catch of runner
  * new call stack displaying
  * file name stored in types::Macro

Change-Id: I89c26ff915bf0fb3bb2cf038475e236b36c5b61d

19 files changed:
scilab/modules/ast/fileio_Import.def
scilab/modules/ast/includes/system_env/configvariable.hxx
scilab/modules/ast/includes/types/macro.hxx
scilab/modules/ast/src/cpp/ast/run_CallExp.hpp
scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/ast/src/cpp/system_env/configvariable.cpp
scilab/modules/ast/src/cpp/types/callable.cpp
scilab/modules/ast/src/cpp/types/macro.cpp
scilab/modules/ast/src/cpp/types/macrofile.cpp
scilab/modules/ast/src/cpp/types/overload.cpp
scilab/modules/core/sci_gateway/cpp/sci_error.cpp
scilab/modules/core/src/cpp/runner.cpp
scilab/modules/functions/sci_gateway/cpp/sci_exec.cpp
scilab/modules/functions/sci_gateway/cpp/sci_execstr.cpp
scilab/modules/functions/tests/nonreg_tests/bug_2551.dia.ref
scilab/modules/functions/tests/nonreg_tests/bug_2551.tst
scilab/modules/functions/tests/nonreg_tests/bug_2553.dia.ref
scilab/modules/functions/tests/nonreg_tests/bug_2553.tst
scilab/modules/output_stream/src/c/Scierror.c

index a867520..864acab 100644 (file)
@@ -4,3 +4,4 @@ LIBRARY    fileio.dll
 EXPORTS
 removedir
 getshortpathname
+FileExistW
\ No newline at end of file
index 5d8d6dd..864a378 100644 (file)
@@ -384,18 +384,26 @@ public :
     {
         int m_line;
         int m_absolute_line;
+        int m_macro_first_line;
         std::wstring m_name;
-        WhereEntry(int line, int absolute_line, const std::wstring& name) : m_line(line), m_absolute_line(absolute_line), m_name(name) {}
+        std::wstring m_file_name;
+        WhereEntry(int line, int absolute_line, const std::wstring& name, int first_line, const std::wstring& file_name) :
+            m_line(line), m_absolute_line(absolute_line), m_name(name), m_macro_first_line(first_line), m_file_name(file_name) {}
     };
-    static void where_begin(int _iLineNum, int _iLineLocation, const std::wstring& _wstName);
+    static void where_begin(int _iLineNum, int _iLineLocation, types::Callable* _pCall);
     static void where_end();
     static const std::vector<WhereEntry>& getWhere();
+    static void fillWhereError(int _iErrorLine);
+    static void resetWhereError();
 
     static void macroFirstLine_begin(int _iLine);
     static void macroFirstLine_end();
     static int getMacroFirstLines();
+    static void setFileNameToLastWhere(const std::wstring& _fileName);
+    static void whereErrorToString(std::wostringstream &ostr);
 private :
     static std::vector<WhereEntry> m_Where;
+    static std::list<WhereEntry> m_WhereError;
     static std::vector<int> m_FirstMacroLine;
 
     //module called with variable by reference
index 92b8744..ceea1d6 100644 (file)
@@ -74,6 +74,16 @@ public :
         return L"function";
     }
 
+    const std::wstring&         getFileName()
+    {
+        return m_stPath;
+    }
+
+    void                        setFileName(const std::wstring& _fileName)
+    {
+        m_stPath = _fileName;
+    }
+
     std::list<symbol::Variable*>*   inputs_get();
     std::list<symbol::Variable*>*   outputs_get();
 
@@ -96,6 +106,7 @@ private :
     Double*                         m_pDblArgIn;
     Double*                         m_pDblArgOut;
     std::map<symbol::Variable*, Macro*> m_submacro;
+    std::wstring                    m_stPath;
 };
 }
 
index 4592940..fd5b519 100644 (file)
@@ -269,13 +269,6 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                 {
                     ConfigVariable::setLastErrorFunction(pCall->getName());
                 }
-
-                if (pCall->isMacro() || pCall->isMacroFile())
-                {
-                    wchar_t szError[bsiz];
-                    os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
-                    throw ScilabMessage(szError);
-                }
             }
 
             throw sm;
index 143e9aa..c623805 100644 (file)
@@ -958,26 +958,12 @@ void RunVisitorT<T>::visitprivate(const SeqExp  &e)
                     }
                     catch (ScilabMessage& sm)
                     {
-                        wostringstream os;
-                        PrintVisitor printMe(os);
-                        exp->accept(printMe);
-                        //os << std::endl << std::endl;
                         if (ConfigVariable::getLastErrorFunction() == L"")
                         {
                             ConfigVariable::setLastErrorFunction(pCall->getName());
                         }
 
-                        if (pCall->isMacro() || pCall->isMacroFile())
-                        {
-                            wchar_t szError[bsiz];
-                            os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
-                            throw ScilabMessage(szError + os.str());
-                        }
-                        else
-                        {
-                            sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
-                            throw sm;
-                        }
+                        throw sm;
                     }
                     catch (ast::ScilabError & se)
                     {
@@ -985,19 +971,9 @@ void RunVisitorT<T>::visitprivate(const SeqExp  &e)
                         {
                             ConfigVariable::setLastErrorFunction(pCall->getName());
                             ConfigVariable::setLastErrorLine(e.getLocation().first_line);
-                            throw ScilabError();
                         }
 
-                        if (pCall->isMacro() || pCall->isMacroFile())
-                        {
-                            wchar_t szError[bsiz];
-                            os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), exp->getLocation().first_line, pCall->getName().c_str());
-                            throw ScilabMessage(szError);
-                        }
-                        else
-                        {
-                            throw ScilabMessage();
-                        }
+                        throw se;
                     }
                 }
 
@@ -1041,30 +1017,10 @@ void RunVisitorT<T>::visitprivate(const SeqExp  &e)
                 break;
             }
         }
-        catch (const ScilabMessage& sm)
+        catch (ScilabMessage& sm)
         {
-            scilabErrorW(sm.GetErrorMessage().c_str());
-
-            CallExp* pCall = dynamic_cast<CallExp*>(exp);
-            if (pCall != NULL)
-            {
-                //to print call expression only of it is a macro
-                pCall->getName().accept(*this);
-
-                if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
-                {
-                    wostringstream os;
-                    PrintVisitor printMe(os);
-                    pCall->accept(printMe);
-                    //os << std::endl << std::endl;
-                    if (ConfigVariable::getLastErrorFunction() == L"")
-                    {
-                        ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
-                    }
-                    throw ScilabMessage(os.str(), 0, exp->getLocation());
-                }
-            }
-            throw ScilabMessage(exp->getLocation());
+            ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
+            throw sm;
         }
         catch (const ScilabError& se)
         {
@@ -1077,33 +1033,8 @@ void RunVisitorT<T>::visitprivate(const SeqExp  &e)
                 ConfigVariable::setLastErrorFunction(wstring(L""));
             }
 
-            CallExp* pCall = dynamic_cast<CallExp*>(exp);
-            if (pCall != NULL)
-            {
-                //to print call expression only of it is a macro
-                try
-                {
-                    pCall->getName().accept(*this);
-                    if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
-                    {
-                        wostringstream os;
-                        PrintVisitor printMe(os);
-                        pCall->accept(printMe);
-                        //os << std::endl << std::endl;
-                        ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
-                        scilabErrorW(se.GetErrorMessage().c_str());
-                        throw ScilabMessage(os.str(), 999, exp->getLocation());
-                    }
-                }
-                catch (ScilabError& se2)
-                {
-                    //just to catch exception, do nothing
-                }
-            }
-
-            scilabErrorW(se.GetErrorMessage().c_str());
-            scilabErrorW(L"\n");
-            throw ScilabMessage(exp->getLocation());
+            ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
+            throw ScilabMessage(se.GetErrorMessage(), se.GetErrorNumber(), se.GetErrorLocation());
         }
 
         // If something other than NULL is given to setResult, then that would imply
@@ -1447,7 +1378,7 @@ void RunVisitorT<T>::visitprivate(const MemfillExp &e)
 {
     e.getOriginal()->accept(*this);
 }
-    
+
 template <class T>
 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
 {
index a794670..f9bbdd7 100644 (file)
@@ -12,8 +12,9 @@
 
 #include <vector>
 #include <list>
-#include "configvariable.hxx"
 #include "context.hxx"
+#include "configvariable.hxx"
+#include "macrofile.hxx"
 
 extern "C"
 {
@@ -21,6 +22,7 @@ extern "C"
 #include "os_string.h"
 #include "sci_malloc.h"
 #include "elem_common.h"
+#include "FileExist.h"
 }
 
 /*
@@ -1097,10 +1099,25 @@ int ConfigVariable::getFuncprot()
 */
 
 std::vector<ConfigVariable::WhereEntry> ConfigVariable::m_Where;
+std::list<ConfigVariable::WhereEntry> ConfigVariable::m_WhereError;
 std::vector<int> ConfigVariable::m_FirstMacroLine;
-void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, const std::wstring& _wstName)
+void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, types::Callable* _pCall)
 {
-    m_Where.emplace_back(_iLineNum, _iLineLocation, _wstName);
+    std::wstring wstrFileName = L"";
+    types::Callable* pCall = _pCall;
+    if (pCall->isMacroFile())
+    {
+        types::Macro* pM = pCall->getAs<types::MacroFile>()->getMacro();
+        wstrFileName = pM->getFileName();
+        pCall = pM;
+    }
+    else if (pCall->isMacro())
+    {
+        types::Macro* pM = pCall->getAs<types::Macro>();
+        wstrFileName = pM->getFileName();
+    }
+
+    m_Where.emplace_back(_iLineNum, _iLineLocation, pCall->getName(), pCall->getFirstLine(), wstrFileName);
 }
 
 void ConfigVariable::where_end()
@@ -1132,6 +1149,133 @@ int ConfigVariable::getMacroFirstLines()
 
     return m_FirstMacroLine.back();
 }
+void ConfigVariable::setFileNameToLastWhere(const std::wstring& _fileName)
+{
+    m_Where.back().m_file_name = _fileName;
+}
+
+void ConfigVariable::whereErrorToString(std::wostringstream &ostr)
+{
+    int iLenName = 1;
+    bool isExecstr = false;
+    bool isExecfile = false;
+
+    // get max length of functions name and check if exec or execstr have been called.
+    for (auto & where : m_WhereError)
+    {
+        if (isExecstr == false && where.m_name == L"execstr")
+        {
+            isExecstr = true;
+            continue;
+        }
+        else if (isExecfile == false && where.m_name == L"exec")
+        {
+            isExecfile = true;
+            continue;
+        }
+
+        iLenName = (std::max)((int)where.m_name.length(), iLenName);
+
+        // in case of bin file, the file path and line is displayed only if the associated .sci file exists
+        if (where.m_file_name != L"" && where.m_file_name.find(L".bin") != std::wstring::npos)
+        {
+            std::size_t pos = where.m_file_name.find_last_of(L".");
+            where.m_file_name.replace(pos, pos + 4, L".sci");
+            if (FileExistW(const_cast<wchar_t*>(where.m_file_name.c_str())) == false)
+            {
+                where.m_file_name = L"";
+            }
+        }
+    }
+
+    // add margin
+    iLenName++;
+
+    // initialize localized strings
+    std::wstring wstrBuiltin(_W("in builtin "));
+    std::wstring wstrAtLine(_W("at line % 5d of function "));
+    std::wstring wstrExecStr(_W("at line % 5d of executed string "));
+    std::wstring wstrExecFile(_W("at line % 5d of executed file "));
+
+    // compute max size between "at line xxx of function" and "in builtin "
+    // +1 : line number is pad to 5. length of "% 5d" + 1 == 5
+    int iMaxLen = (std::max)(wstrAtLine.length() + 1, wstrBuiltin.length());
+    if (isExecstr)
+    {
+        iMaxLen = (std::max)(((int)wstrExecStr.length()) + 1, iMaxLen);
+    }
+
+    if (isExecstr)
+    {
+        iMaxLen = (std::max)(((int)wstrExecFile.length()) + 1, iMaxLen);
+    }
+
+    // print call stack
+    ostr << std::left;
+    ostr.fill(L' ');
+    for (auto & where : m_WhereError)
+    {
+        ostr.width(iMaxLen);
+        if (where.m_line == 0)
+        {
+            ostr << wstrBuiltin;
+        }
+        else
+        {
+            if (where.m_name == L"execstr")
+            {
+                isExecstr = true;
+                wchar_t wcsTmp[bsiz];
+                os_swprintf(wcsTmp, bsiz, wstrExecStr.c_str(), where.m_line);
+                ostr << wcsTmp << std::endl;
+                continue;
+            }
+            else if (where.m_name == L"exec")
+            {
+                wchar_t wcsTmp[bsiz];
+                os_swprintf(wcsTmp, bsiz, wstrExecFile.c_str(), where.m_line);
+                ostr << wcsTmp << where.m_file_name << std::endl;
+                continue;
+            }
+            else
+            {
+                wchar_t wcsTmp[bsiz];
+                os_swprintf(wcsTmp, bsiz, wstrAtLine.c_str(), where.m_line);
+                ostr << wcsTmp;
+            }
+        }
+
+        ostr.width(iLenName);
+        ostr << where.m_name;
+
+        if (where.m_file_name != L"")
+        {
+            // -1 because the first line of a function dec is : "function myfunc()"
+            ostr << L"( " << where.m_file_name << L" " << _W("line") << L" " << where.m_macro_first_line + where.m_line - 1 << L" )";
+        }
+
+        ostr << std::endl;
+    }
+}
+
+void ConfigVariable::fillWhereError(int _iErrorLine)
+{
+    if (m_WhereError.empty())
+    {
+        // +1 because the first line of the funtionDec "function func()" is the line 1.
+        int iTmp = _iErrorLine - getMacroFirstLines() + 1;
+        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);
+            iTmp = (*where).m_line;
+        }
+    }
+}
+
+void ConfigVariable::resetWhereError()
+{
+    m_WhereError.clear();
+}
 
 /*
 ** \}
index 6dc2159..b18e640 100644 (file)
@@ -27,7 +27,8 @@ bool Callable::invoke(typed_list & in, optional_list & opt, int _iRetCount, type
     //update verbose";" flag
     ConfigVariable::setVerbose(e.isVerbose());
     // add line and function name in where
-    ConfigVariable::where_begin(e.getLocation().first_line + 1 - ConfigVariable::getMacroFirstLines(), e.getLocation().first_line, getName());
+    int iFirstLine = e.getLocation().first_line;
+    ConfigVariable::where_begin(iFirstLine + 1 - ConfigVariable::getMacroFirstLines(), iFirstLine, this);
     Callable::ReturnValue Ret;
 
     try
@@ -61,7 +62,7 @@ bool Callable::invoke(typed_list & in, optional_list & opt, int _iRetCount, type
     {
         ConfigVariable::setLastErrorFunction(getName());
         ConfigVariable::setLastErrorLine(e.getLocation().first_line);
-        throw ast::ScilabError();
+        throw ast::ScilabError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
     }
 
     return true;
index 3dfaba0..3bf66a9 100644 (file)
@@ -51,6 +51,7 @@ Macro::Macro(const std::wstring& _stName, std::list<symbol::Variable*>& _inputAr
     m_pDblArgOut->IncreaseRef(); //never delete
 
     m_body->setReturnable();
+    m_stPath = L"";
 }
 
 Macro::~Macro()
index 4b214b4..97c079a 100644 (file)
@@ -134,6 +134,7 @@ bool MacroFile::parse(void)
             const symbol::Symbol & sym = pFD->getSymbol();
             Macro* macro = new Macro(sym.getName(), *pVarList, *pRetList, (ast::SeqExp&)pFD->getBody(), m_wstModule);
             macro->setFirstLine(pFD->getLocation().first_line);
+            macro->setFileName(m_stPath);
 
             if (m_pMacro == nullptr && sym.getName() == getName())
             {
index 01228e6..39e6ca5 100644 (file)
@@ -110,7 +110,7 @@ types::Function::ReturnValue Overload::call(std::wstring _stOverloadingFunctionN
         types::optional_list opt;
 
         // add line and function name in where
-        ConfigVariable::where_begin(0, 0, _stOverloadingFunctionName);
+        ConfigVariable::where_begin(0, 0, pCall);
 
         types::Function::ReturnValue ret = pCall->call(in, opt, _iRetCount, out, _execMe);
 
@@ -123,17 +123,7 @@ types::Function::ReturnValue Overload::call(std::wstring _stOverloadingFunctionN
     {
         // remove function name in where
         ConfigVariable::where_end();
-
-        if (pCall->isMacro() || pCall->isMacroFile())
-        {
-            wchar_t szError[bsiz];
-            os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
-            throw ast::ScilabMessage(szError);
-        }
-        else
-        {
-            throw sm;
-        }
+        throw sm;
     }
 }
 
index bbeea70..dd7359c 100644 (file)
@@ -134,7 +134,7 @@ Function::ReturnValue sci_error(types::typed_list &in, int _iRetCount, types::ty
         }
 
         char* pst = wide_string_to_UTF8(pStr->get(0));
-        Scierror((int)pDbl->get(0), "%s", pst);
+        Scierror((int)pDbl->get(0), "%s\n", pst);
         FREE(pst);
     }
 
index 386a99e..4a52ab5 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "runner.hxx"
 #include "threadmanagement.hxx"
+#include "configvariable.hxx"
 
 using namespace ast;
 
@@ -37,6 +38,11 @@ void *Runner::launch(void *args)
     catch (const ast::ScilabException& se)
     {
         scilabErrorW(se.GetErrorMessage().c_str());
+        scilabErrorW(L"\n");
+        std::wostringstream ostr;
+        ConfigVariable::whereErrorToString(ostr);
+        scilabErrorW(ostr.str().c_str());
+        ConfigVariable::resetWhereError();
     }
 
     // reset error state when new prompt occurs
index 36a39b0..2344422 100644 (file)
@@ -61,6 +61,7 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
     bool bErrCatch      = false;
     Exp* pExp           = NULL;
     int iID             = 0;
+    types::Macro* pMacro = NULL;
     Parser parser;
 
     wchar_t* pwstFile = NULL;
@@ -219,6 +220,7 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
             char* pst = wide_string_to_UTF8(parser.getErrorMessage());
             Scierror(999, "%s", pst);
             FREE(pst);
+
             delete parser.getTree();
             mclose(iID);
             return Function::Error;
@@ -242,10 +244,12 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         {
             pExp = parser.getTree();
         }
+
+        // update where to set the name of the executed file.
+        ConfigVariable::setFileNameToLastWhere(pwstFile);
     }
     else if (in[0]->isMacro() || in[0]->isMacroFile())
     {
-        types::Macro* pMacro = NULL;
         typed_list input;
         optional_list optional;
         typed_list output;
@@ -261,9 +265,7 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
                 FREE(pstMacro);
                 return Function::Error;
             }
-
             pMacro = in[0]->getAs<MacroFile>()->getMacro();
-
         }
         else //1st argument is a macro name, execute it in the current environnement
         {
@@ -282,6 +284,13 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
 
         promptMode = 3;
         pExp = pMacro->getBody();
+
+        // update where to set the name of the executed macro instead of "exec"
+        ConfigVariable::WhereEntry lastWhere = ConfigVariable::getWhere().back();
+        int iLine = lastWhere.m_line;
+        int iAbsLine = lastWhere.m_absolute_line;
+        ConfigVariable::where_end();
+        ConfigVariable::where_begin(iLine, iAbsLine, pMacro);
     }
     else
     {
@@ -289,6 +298,12 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
         return Function::Error;
     }
 
+    if (pMacro)
+    {
+        //store the line number where is stored this macro in file.
+        ConfigVariable::macroFirstLine_begin(pMacro->getFirstLine());
+    }
+
     ast::exps_t& LExp = pExp->getAs<SeqExp>()->getExps();
 
     char pstPrompt[64];
@@ -358,6 +373,15 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
                 (*j)->accept(execMe);
                 //ConfigVariable::setPromptMode(promptMode);
 
+                if (pwstFile && (*j)->isFunctionDec())
+                {
+                    InternalType* pIT = symbol::Context::getInstance()->get((*j)->getAs<FunctionDec>()->getSymbol());
+                    if (pIT)
+                    {
+                        types::Macro* pMacro = pIT->getAs<types::Macro>();
+                        pMacro->setFileName(pwstFile);
+                    }
+                }
 
                 //to manage call without ()
                 if (execMe.getResult() != NULL && execMe.getResult()->isCallable())
@@ -372,74 +396,35 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
                         //in this case of calling, we can return only one values
                         ExecVisitor execCall;
                         execCall.setExpectedSize(1);
-                        Function::ReturnValue Ret = pCall->call(in, opt, 1, out, &execCall);
+                        pCall->invoke(in, opt, 1, out, execCall, *(*j));
 
-                        if (Ret == Callable::OK)
+                        if (out.size() == 0)
                         {
-                            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]);
-                                }
-                            }
+                            execMe.setResult(NULL);
                         }
-                        else if (Ret == Callable::Error)
+                        else if (out.size() == 1)
                         {
-                            if (ConfigVariable::getLastErrorFunction() == L"")
-                            {
-                                ConfigVariable::setLastErrorFunction(pCall->getName());
-                            }
-
-                            if (pCall->isMacro() || pCall->isMacroFile())
-                            {
-                                wchar_t szError[bsiz];
-                                os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*j)->getLocation().first_line, pCall->getName().c_str());
-                                throw ast::ScilabMessage(szError);
-                            }
-                            else
+                            out[0]->DecreaseRef();
+                            execMe.setResult(out[0]);
+                            bImplicitCall = true;
+                        }
+                        else
+                        {
+                            for (int i = 0 ; i < static_cast<int>(out.size()) ; i++)
                             {
-                                throw ast::ScilabMessage();
+                                out[i]->DecreaseRef();
+                                execMe.setResult(i, out[i]);
                             }
                         }
                     }
                     catch (ScilabMessage sm)
                     {
-                        wostringstream os;
-                        PrintVisitor printMe(os);
-                        (*j)->accept(printMe);
-                        os << std::endl << std::endl;
                         if (ConfigVariable::getLastErrorFunction() == L"")
                         {
                             ConfigVariable::setLastErrorFunction(pCall->getName());
                         }
 
-                        if (pCall->isMacro() || pCall->isMacroFile())
-                        {
-                            wstring szAllError;
-                            wchar_t szError[bsiz];
-                            os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
-                            szAllError = szError + os.str();
-                            os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->getLocation().first_line);
-                            szAllError += szError;
-                            throw ast::ScilabMessage(szAllError);
-                        }
-                        else
-                        {
-                            sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
-                            throw sm;
-                        }
+                        throw sm;
                     }
                 }
 
@@ -478,55 +463,27 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
 
             throw ia;
         }
-        catch (const ScilabMessage& sm)
+        catch (ast::ScilabMessage& sm)
         {
-            scilabErrorW(sm.GetErrorMessage().c_str());
+            ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
 
-            CallExp* pCall = dynamic_cast<CallExp*>(*j);
-            if (pCall != NULL)
+            if (pMacro)
             {
-                //to print call expression only of it is a macro
-                ExecVisitor execFunc;
-                pCall->getName().accept(execFunc);
-
-                if (execFunc.getResult() != NULL &&
-                        (execFunc.getResult()->isMacro() || execFunc.getResult()->isMacroFile()))
+                if (ConfigVariable::getLastErrorFunction() == L"")
                 {
-                    wostringstream os;
-
-                    //add function failed
-                    PrintVisitor printMe(os);
-                    pCall->accept(printMe);
-                    os << std::endl;
-
-                    //add info on file failed
-                    wchar_t szError[bsiz];
-                    os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->getLocation().first_line);
-                    os << szError;
-
-                    if (ConfigVariable::getLastErrorFunction() == L"")
-                    {
-                        ConfigVariable::setLastErrorFunction(execFunc.getResult()->getAs<Callable>()->getName());
-                    }
+                    ConfigVariable::setLastErrorFunction(pMacro->getName());
+                }
 
-                    Location location = (*j)->getLocation();
-                    if (file)
-                    {
-                        delete pExp;
-                        mclose(iID);
-                        file->close();
-                        delete file;
-                        FREE(pstFile);
-                        FREE(pwstFile);
-                    }
+                //restore previous prompt mode
+                ConfigVariable::setPromptMode(oldVal);
 
-                    //restore previous prompt mode
-                    ConfigVariable::setPromptMode(oldVal);
-                    throw ast::ScilabMessage(os.str(), 0, location);
-                }
+                // reset last first line of macro called
+                ConfigVariable::macroFirstLine_end();
             }
 
-            Location location = (*j)->getLocation();
+            // get location of exp before delete it in "file" case.
+            Location loc = (*j)->getLocation();
+
             if (file)
             {
                 delete pExp;
@@ -537,10 +494,20 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
                 FREE(pwstFile);
             }
 
-            throw ast::ScilabMessage(location);
+
+            if (bErrCatch == false)
+            {
+                sm.SetErrorLocation(loc);
+                throw sm;
+            }
+
+            ConfigVariable::resetWhereError();
+            iErr = ConfigVariable::getLastErrorNumber();
+            break;
         }
-        catch (const ast::ScilabError& se)
+        catch (ast::ScilabError& se)
         {
+            ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
             if (ConfigVariable::getLastErrorNumber() == 0)
             {
                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
@@ -555,20 +522,6 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
             {
                 if (file)
                 {
-                    //print failed command
-                    scilabError(getExpression(stFile, *j).c_str());
-                    scilabErrorW(L"\n");
-                }
-
-                //write error
-                scilabErrorW(se.GetErrorMessage().c_str());
-
-                //write position
-                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);
-                if (file)
-                {
                     delete pExp;
                     mclose(iID);
                     file->close();
@@ -579,17 +532,23 @@ types::Function::ReturnValue sci_exec(types::typed_list &in, int _iRetCount, typ
 
                 //restore previous prompt mode
                 ConfigVariable::setPromptMode(oldVal);
-                //throw ast::ScilabMessage(szError, 1, (*j)->getLocation());
-                //print already done, so just foward exception but with message
-                throw ast::ScilabError();
+
+                throw se;
+            }
+
+            if (pMacro)
+            {
+                // reset last first line of macro called
+                ConfigVariable::macroFirstLine_end();
             }
+
+            ConfigVariable::resetWhereError();
             break;
         }
     }
 
     //restore previous prompt mode
     ConfigVariable::setPromptMode(oldVal);
-
     if (bErrCatch)
     {
         out.push_back(new Double(iErr));
index 67830c8..d41e576 100644 (file)
@@ -57,7 +57,6 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
     wchar_t *pstCommand = NULL;
     Parser parser;
 
-    int iOldSilentError = ConfigVariable::getSilentError();
     if (in.size() < 1 || in.size() > 3)
     {
         Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "execstr" , 1, 3);
@@ -193,11 +192,6 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
     int oldVal = ConfigVariable::getPromptMode();
     ConfigVariable::setPromptMode(-1);
 
-    if (bErrCatch)
-    {
-        ConfigVariable::setSilentError(1);
-    }
-
     if (ConfigVariable::getAnalyzerOptions() == 1)
     {
         analysis::AnalysisVisitor analysis;
@@ -220,6 +214,11 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
                 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);
@@ -259,51 +258,17 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
                     }
                     else if (Ret == Callable::Error)
                     {
-                        ConfigVariable::setSilentError(iOldSilentError);
-                        if (ConfigVariable::getLastErrorFunction() == L"")
-                        {
-                            ConfigVariable::setLastErrorFunction(pCall->getName());
-                        }
-
-                        if (pCall->isMacro() || pCall->isMacroFile())
-                        {
-                            wchar_t szError[bsiz];
-                            os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*j)->getLocation().first_line, pCall->getName().c_str());
-                            throw ast::ScilabMessage(szError);
-                        }
-                        else
-                        {
-                            throw ast::ScilabMessage();
-                        }
+                        throw ast::ScilabMessage(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), (*j)->getLocation());
                     }
                 }
-                catch (ScilabMessage sm)
+                catch (ast::ScilabMessage sm)
                 {
-                    ConfigVariable::setSilentError(iOldSilentError);
-                    wostringstream os;
-                    PrintVisitor printMe(os);
-                    (*j)->accept(printMe);
-                    os << std::endl << std::endl;
                     if (ConfigVariable::getLastErrorFunction() == L"")
                     {
                         ConfigVariable::setLastErrorFunction(pCall->getName());
                     }
 
-                    if (pCall->isMacro() || pCall->isMacroFile())
-                    {
-                        wstring szAllError;
-                        wchar_t szError[bsiz];
-                        os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
-                        szAllError = szError + os.str();
-                        os_swprintf(szError, bsiz, _W("in  execstr instruction    called by :\n").c_str());
-                        szAllError += szError;
-                        throw ast::ScilabMessage(szAllError);
-                    }
-                    else
-                    {
-                        sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
-                        throw sm;
-                    }
+                    throw sm;
                 }
             }
 
@@ -322,63 +287,23 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
                     scilabWriteW(ostr.str().c_str());
                 }
             }
-
-            //if( !checkPrompt(iMode, EXEC_MODE_MUTE) &&
-            //             bErrCatch == false)
-            //{
-            // scilabWriteW(L"\n");
-            //}
         }
-        catch (ScilabMessage sm)
+        catch (ast::ScilabMessage sm)
         {
-            ConfigVariable::setSilentError(iOldSilentError);
+            ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
             if (bErrCatch == false && bMute == false)
             {
-                scilabErrorW(sm.GetErrorMessage().c_str());
-
-                CallExp* pCall = dynamic_cast<CallExp*>(*j);
-                if (pCall != NULL)
-                {
-                    //to print call expression only of it is a macro
-                    ExecVisitor execFunc;
-                    pCall->getName().accept(execFunc);
-
-                    if (execFunc.getResult() != NULL &&
-                            (execFunc.getResult()->isMacro() || execFunc.getResult()->isMacroFile()))
-                    {
-                        wostringstream os;
-
-                        //add function failed
-                        PrintVisitor printMe(os);
-                        pCall->accept(printMe);
-                        os << std::endl;
-
-                        //add info on file failed
-                        wchar_t szError[bsiz];
-                        os_swprintf(szError, bsiz, _W("at line % 5d of exec file called by :\n").c_str(), (*j)->getLocation().first_line);
-                        os << szError;
-
-                        if (ConfigVariable::getLastErrorFunction() == L"")
-                        {
-                            ConfigVariable::setLastErrorFunction(execFunc.getResult()->getAs<Callable>()->getName());
-                        }
-
-                        //restore previous prompt mode
-                        ConfigVariable::setPromptMode(oldVal);
-                        throw ast::ScilabMessage(os.str(), 0, (*j)->getLocation());
-                    }
-                }
-                throw ast::ScilabMessage((*j)->getLocation());
-            }
-            else
-            {
-                iErr = ConfigVariable::getLastErrorNumber();
-                break;
+                sm.SetErrorLocation((*j)->getLocation());
+                throw sm;
             }
+
+            ConfigVariable::resetWhereError();
+            iErr = ConfigVariable::getLastErrorNumber();
+            break;
         }
         catch (ast::ScilabError se)
         {
-            ConfigVariable::setSilentError(iOldSilentError);
+            ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
             // check on error number because error message can be empty.
             if (ConfigVariable::getLastErrorNumber() == 0)
             {
@@ -392,27 +317,19 @@ Function::ReturnValue sci_execstr(types::typed_list &in, int _iRetCount, types::
             iErr = ConfigVariable::getLastErrorNumber();
             if (bErrCatch == false)
             {
-                //in case of error, change mode to 2 ( prompt )
-                ConfigVariable::setPromptMode(2);
-                //write error
-                scilabErrorW(se.GetErrorMessage().c_str());
-
-                //write positino
-                // sciprint(_("in  execstr instruction    called by :\n"));
                 //restore previous prompt mode
                 ConfigVariable::setPromptMode(oldVal);
-                //throw ast::ScilabMessage(szError, 1, (*j)->getLocation());
-                //print already done, so just foward exception but with message
-                //throw ast::ScilabError();
-                return Function::Error;
+                se.SetErrorLocation((*j)->getLocation());
+                throw se;
             }
+
+            ConfigVariable::resetWhereError();
             break;
         }
     }
 
     //restore previous prompt mode and silent mode
     ConfigVariable::setPromptMode(oldVal);
-    ConfigVariable::setSilentError(iOldSilentError);
 
     if (bErrCatch)
     {
index f72f5c3..657dd91 100644 (file)
@@ -17,8 +17,5 @@
 // 6 feb 2008
 function f();  x=1;y=x(3);endfunction
 function g();exec(f);endfunction
-ierr=exec(g,'errcatch',-1)             
- ierr  =
-    21.  
-if ierr<>21 then bugmes();quit;end
+ierr=exec(g,"errcatch",-1);
+assert_checkequal(ierr, 999);
index e1897bd..09b2851 100644 (file)
@@ -23,5 +23,5 @@
 function f();  x=1;y=x(3);endfunction
 function g();exec(f);endfunction
 
-ierr=exec(g,'errcatch',-1)             
-if ierr<>21 then pause,end
+ierr=exec(g,"errcatch",-1);
+assert_checkequal(ierr, 999);
index 72c3c1d..70ff8b5 100644 (file)
 // <-- Short Description -->
 //   error recovery problem
 function toto();x=1;y=x(3)+1;endfunction
-function titi();execstr('toto();disp ok');endfunction
-ierr=exec(titi,'errcatch',-1)          
- ierr  =
-    21.  
-               
-if ierr<>21 then bugmes();quit;end
+function titi();execstr("toto();disp ok");endfunction
+ierr=exec(titi,"errcatch",-1);
+if ierr<>999 then bugmes();quit;end
index 43c58c6..a8fc0d5 100644 (file)
@@ -16,7 +16,7 @@
 //   error recovery problem
 
 function toto();x=1;y=x(3)+1;endfunction
-function titi();execstr('toto();disp ok');endfunction
-ierr=exec(titi,'errcatch',-1)          
-               
-if ierr<>21 then pause,end
+function titi();execstr("toto();disp ok");endfunction
+ierr=exec(titi,"errcatch",-1);
+
+if ierr<>999 then pause,end
index 46f4124..7dde7a9 100644 (file)
@@ -51,8 +51,6 @@ int  Scierror(int iv, const char *fmt, ...)
     pwstError = to_wide_string(s_buf);
     setLastError(iv, pwstError, 0, NULL);
 
-    scilabErrorW(pwstError);
-    scilabErrorW(L"\n");
     FREE(pwstError);
     return retval;
 }