Scilab debugger updates 05/21005/14
Cedric Delamarre [Tue, 11 Jun 2019 16:06:59 +0000 (18:06 +0200)]
Change-Id: I6c50133a304daa406908c1419ac9a9c00174ca2a

33 files changed:
scilab/modules/ast/core_Import.def
scilab/modules/ast/fileio_Import.def
scilab/modules/ast/includes/ast/abstractdebugger.hxx
scilab/modules/ast/includes/ast/breakpoint.hxx
scilab/modules/ast/includes/ast/consoledebugger.hxx
scilab/modules/ast/includes/ast/debugmanager.hxx
scilab/modules/ast/includes/system_env/configvariable.hxx
scilab/modules/ast/includes/system_env/threadmanagement.hxx
scilab/modules/ast/src/cpp/ast/consoledebugger.cpp
scilab/modules/ast/src/cpp/ast/debuggervisitor.cpp
scilab/modules/ast/src/cpp/ast/debugmanager.cpp
scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/ast/src/cpp/system_env/configvariable.cpp
scilab/modules/ast/src/cpp/system_env/configvariable_interface.cpp
scilab/modules/ast/src/cpp/system_env/threadmanagement.cpp
scilab/modules/core/Makefile.am
scilab/modules/core/Makefile.in
scilab/modules/core/includes/parsecommand.h [new file with mode: 0644]
scilab/modules/core/includes/pause.h [new file with mode: 0644]
scilab/modules/core/includes/runner.hxx
scilab/modules/core/includes/storeCommand.h
scilab/modules/core/includes/tasks.hxx
scilab/modules/core/sci_gateway/cpp/sci_debug.cpp
scilab/modules/core/sci_gateway/cpp/sci_pause.cpp
scilab/modules/core/src/c/core.vcxproj
scilab/modules/core/src/c/core.vcxproj.filters
scilab/modules/core/src/cpp/InitScilab.cpp
scilab/modules/core/src/cpp/parsecommand.cpp [new file with mode: 0644]
scilab/modules/core/src/cpp/pause.cpp [new file with mode: 0644]
scilab/modules/core/src/cpp/runner.cpp
scilab/modules/core/src/cpp/storeCommand.cpp
scilab/modules/core/src/cpp/tasks.cpp
scilab/modules/output_stream/sci_gateway/cpp/sci_mprintf.cpp

index 0501c00..f6528ec 100644 (file)
@@ -10,4 +10,9 @@ StaticRunner_isInterruptibleCommand
 StaticRunner_setInterruptibleCommand
 StoreConsoleCommand
 StorePrioritaryCommand
-parseCommand
\ No newline at end of file
+StoreDebuggerCommand
+parseCommand
+checkCommand
+parseFile
+checkFile
+pause
index e5b157f..0b92368 100644 (file)
@@ -6,6 +6,7 @@ removedir
 getshortpathname
 getlongpathname
 FileExistW
+FileExist
 getfile_filename
 get_full_pathW
 isdir
index 6a780f1..75a0af2 100644 (file)
@@ -17,7 +17,7 @@
 #define __ABSTRACT_DEBUGGER_HXX__
 
 #include <string>
-#include <vector>
+#include <map>
 
 extern "C"
 {
@@ -35,6 +35,10 @@ public:
 
     //interface
     virtual void onStop(int index) = 0; //when a bp is trigger
+    virtual void onExecution() = 0;//when an execution is started
+    virtual void onExecutionReleased() = 0;//when the wait for execution is release (stop on bp or execution end)
+    virtual void onPrint(const std::string& variable) = 0;//when print a variable is asked
+    virtual void onShow(int bp) = 0;//when print a breakpoint
     virtual void onResume() = 0;//when "play" is trigger
     virtual void onAbort() = 0;//when execution is abort
     virtual void onErrorInFile(const std::wstring& filemane) = 0;//when an error is trigger in a file
@@ -45,6 +49,8 @@ public:
 
 };
 
-typedef std::vector<AbstractDebugger*> Debuggers;
+typedef std::map<std::string, AbstractDebugger*> Debuggers;
+typedef std::map<std::string, std::string> Watches;
+
 }
 #endif /* !__ABSTRACT_DEBUGGER_HXX__ */
index 2741de7..1628ee4 100644 (file)
 #include <string>
 #include "macro.hxx"
 #include "exp.hxx"
-#include "tasks.hxx"
+
+extern "C"
+{
+#include "parsecommand.h"
+}
 
 namespace debugger
 {
 struct Breakpoint
 {
-    Breakpoint(const std::wstring& functionName, int iLine = -1, const std::wstring& condition = L"")
-        : _pFunctionName(functionName), _iMacroLine(iLine), _file(L""), _iFileLine(0), _condition(condition), _conditionExp(NULL), enable(true) {}
-
+    Breakpoint() :  _pFunctionName(""),
+                    _iMacroLine(0),
+                    _pFileName(""),
+                    _iFileLine(0),
+                    _iFirstColumn(0),
+                    _condition(""),
+                    _conditionExp(NULL),
+                    _enable(true) {}
     ~Breakpoint()
     {
         if (_conditionExp)
@@ -36,20 +45,20 @@ struct Breakpoint
         }
     };
 
-    void setFile(std::wstring& file)
+    void setFileName(const std::string& name)
     {
-        _file = file;
+        _pFileName = name;
     }
-    const std::wstring& getFile() const
+    const std::string& getFileName() const
     {
-        return _file;
+        return _pFileName;
     }
 
-    void setFunctionName(std::wstring& functionName)
+    void setFunctionName(const std::string& functionName)
     {
         _pFunctionName = functionName;
     }
-    const std::wstring& getFunctioName() const
+    const std::string& getFunctioName() const
     {
         return _pFunctionName;
     }
@@ -63,6 +72,15 @@ struct Breakpoint
         return _iMacroLine;
     }
 
+    void setBeginLine(int column)
+    {
+        _iFirstColumn = column;
+    }
+    int getBeginLine() const
+    {
+        return _iFirstColumn;
+    }
+
     void setFileLine(int line)
     {
         _iFileLine = line;
@@ -72,53 +90,59 @@ struct Breakpoint
         return _iFileLine;
     }
 
-    bool isMacro() const
+    bool hasMacro() const
     {
-        return _pFunctionName.empty() == false;
+        return _pFunctionName.empty() == false && _iMacroLine >= 0;
     }
 
-    bool isFile() const
+    bool hasFile() const
     {
-        return isMacro() == false;
+        return _pFileName.empty() == false && _iFileLine >= 0;
     }
 
     void setEnable()
     {
-        enable = true;
+        _enable = true;
     }
     void setDisable()
     {
-        enable = false;
+        _enable = false;
     }
     bool isEnable() const
     {
-        return enable;
+        return _enable;
     }
 
-    const std::wstring& getCondition() const
+    char* setCondition(const std::string& condition)
+    {
+        char* error = parseCommand(condition.data(), (void**)(&_conditionExp));
+        if(error)
+        {
+            return error;
+        }
+        _condition = condition;
+        return nullptr;
+    }
+
+    const std::string& getCondition() const
     {
         return _condition;
     }
 
     ast::Exp* getConditionExp()
     {
-        if (_conditionExp)
-        {
-            return _conditionExp;
-        }
-
-        _conditionExp = parseCommand(_condition);
         return _conditionExp;
     }
 
 private:
-    std::wstring _pFunctionName;
+    std::string _pFunctionName;
     int _iMacroLine;
-    std::wstring _file;
+    int _iFirstColumn;
+    std::string _pFileName;
     int _iFileLine;
-    std::wstring _condition;
+    std::string _condition;
     ast::Exp* _conditionExp;
-    bool enable;
+    bool _enable;
 };
 
 typedef std::vector<Breakpoint*> Breakpoints;
index 8dbf2f0..c16728b 100644 (file)
@@ -17,6 +17,7 @@
 #define __CONSOLE_DEBUGGER_HXX__
 
 #include "abstractdebugger.hxx"
+#include "breakpoint.hxx"
 
 extern "C"
 {
@@ -29,14 +30,21 @@ namespace debugger
 {
 class EXTERN_AST ConsoleDebugger : public AbstractDebugger
 {
+private:
 
     void printExp();
+    void printBreakPoints(debugger::Breakpoints& bps);
+
 public:
 
     ConsoleDebugger() {}
     virtual ~ConsoleDebugger() {}
 
     virtual void onStop(int index);
+    virtual void onExecution();
+    virtual void onExecutionReleased();
+    virtual void onPrint(const std::string& variable);
+    virtual void onShow(int bp);
     virtual void onResume();
     virtual void onAbort();
     virtual void onErrorInFile(const std::wstring& filemane);
index 820b8e0..7b95732 100644 (file)
 #include <memory>
 
 #include "abstractdebugger.hxx"
+#include "configvariable.hxx"
 #include "breakpoint.hxx"
 #include "dynlib_ast.h"
 
 namespace debugger
 {
-class EXTERN_AST DebuggerMagager
+class EXTERN_AST DebuggerManager
 {
-public :
+public:
     enum DebugAction
     {
         Continue,
+        Aborted,
         StepNext,
         StepIn,
         StepOut
     };
 
+    struct StackRow
+    {
+        std::string functionName;
+        std::string fileName;
+        int functionLine;
+        int fileLine;
+        int scope;
+        bool hasFile = false;
+    };
+
+    typedef std::vector<StackRow> Stack;
+    struct CallStack
+    {
+        std::string exp;
+        Stack stack;
+    };
+
 private:
-    static std::unique_ptr<DebuggerMagager> me;
-    DebuggerMagager() :
+    static std::unique_ptr<DebuggerManager> me;
+    DebuggerManager() :
         breakpoints(),
-        debuggers(), pExp(nullptr), interrupted(false), currentBreakPoint(-1), action(Continue), level(0) {}
+        debuggers(),
+        callstack(), pExp(nullptr), interrupted(false), currentBreakPoint(-1), action(Continue), level(0) {}
 
     Breakpoints breakpoints;
+    Watches watches;
+    CallStack callstack;
     Debuggers debuggers;
 
     ast::Exp* pExp;
@@ -50,26 +72,31 @@ private:
     DebugAction action;
     int level;
 
+    void internal_execution_released();
     void internal_stop();
+    bool callstackAddFile(StackRow* _row, const std::wstring& _fileName);
+
 public:
-    ~DebuggerMagager()
+    ~DebuggerManager()
     {
         for (auto d : debuggers)
         {
-            delete d;
+            delete d.second;
         }
         for (auto b : breakpoints)
         {
             delete b;
         }
+
+        clearCallStack();
     }
 
-    static DebuggerMagager* getInstance();
+    static DebuggerManager* getInstance();
 
     //debuggers functions
-    void addDebugger(AbstractDebugger* _debug);
-    void removeDebugger(int _iDebugger);
-    AbstractDebugger* getDebugger(int _iDebugger);
+    void addDebugger(const std::string& _name, AbstractDebugger* _debug);
+    void removeDebugger(const std::string& _name);
+    AbstractDebugger* getDebugger(const std::string& _name);
     int getDebuggerCount();
     Debuggers& getAllDebugger();
 
@@ -100,8 +127,25 @@ public:
 
         return nullptr;
     }
+
+    void generateCallStack();
+    inline void clearCallStack()
+    {
+        callstack.exp.clear();
+        callstack.stack.clear();
+    }
+
+    CallStack getCallStack()
+    {
+        return callstack;
+    }
+
     //send information to debuggers
     void sendStop(int index);
+    void sendExecution();
+    void sendExecutionReleased();
+    void sendPrint(const std::string& variable);
+    void sendShow(int bp);
     void sendResume();
     void sendAbort();
     void sendErrorInFile(const std::wstring& filename) const;
@@ -112,9 +156,11 @@ public:
     void stop(const ast::Exp* pExp, int index);
     void errorInFile(const std::wstring filename, const ast::Exp* pExp);
     void errorInScript(const std::wstring funcname, const ast::Exp* pExp);
+
     //breakpoints functions
     void addBreakPoint(Breakpoint* bp);
     void removeBreakPoint(int _iBreakPoint);
+    void setAllBreakPoints(Breakpoints& _bps);
     void removeAllBreakPoints();
     void disableAllBreakPoints();
     void disableBreakPoint(int _iBreakPoint);
@@ -125,6 +171,11 @@ public:
     int getBreakPointCount();
     Breakpoints& getAllBreakPoint();
 
+    //watches functions
+    void setWatches(Watches _w);
+    void removeWatches();
+    void updateWatches(int _iScopeLvl = -1);
+    Watches& getWatches();
 
     //actions called by debuggers
     inline void setStepIn() //enter macro
@@ -136,7 +187,18 @@ public:
     {
         int l = symbol::Context::getInstance()->getScopeLevel();
         //if stepIn failed ( not a macro ), stepIn become a stepNext
-        return action == StepIn && l >= level;
+        if(action != StepIn)
+        {
+            return false;
+        }
+
+        if(l < level)
+        {
+            action = StepNext;
+            return false;
+        }
+
+        return true;
     }
     inline void resetStepIn()
     {
@@ -149,11 +211,11 @@ public:
     inline void setStepOut() //exit macro
     {
         action = StepOut;
-        level = symbol::Context::getInstance()->getScopeLevel();
+        level = ConfigVariable::getWhere().size();
     }
     inline bool isStepOut()
     {
-        int l = symbol::Context::getInstance()->getScopeLevel();
+        int l = ConfigVariable::getWhere().size();
         return action == StepOut && l < level;
     }
     inline void resetStepOut()
@@ -164,6 +226,22 @@ public:
         }
     }
 
+    inline void setAborted() //next statement
+    {
+        action = Aborted;
+    }
+    inline bool isAborted()
+    {
+        return action == Aborted;
+    }
+    inline void resetAborted()
+    {
+        if (isAborted())
+        {
+            action = Continue;
+        }
+    }
+
     inline void setStepNext() //next statement
     {
         action = StepNext;
@@ -190,6 +268,10 @@ public:
             action = Continue;
         }
     }
+
+    char* execute(const std::string& command); //execute a command
+    void print(const std::string& variable); //print a variable
+    void show(int bp); //print the breakpoint bp or all breakpoints (bp = -1)
     void resume(); //resume execution
     void abort(); //abort execution
 };
index d358225..5c47f93 100644 (file)
@@ -417,10 +417,11 @@ public :
     {
         int m_line;
         int m_absolute_line;
+        int m_scope_lvl;
         types::Callable* call;
         std::wstring m_file_name;
-        WhereEntry(int line, int absolute_line, types::Callable* pCall, const std::wstring& file_name) :
-            m_line(line), m_absolute_line(absolute_line), call(pCall), m_file_name(file_name) {}
+        WhereEntry(int line, int absolute_line, int scope_lvl, types::Callable* pCall, const std::wstring& file_name) :
+            m_line(line), m_absolute_line(absolute_line), m_scope_lvl(scope_lvl), call(pCall), m_file_name(file_name) {}
     };
 
     typedef std::vector<WhereEntry> WhereVector;
index dd2f5bb..4a10e73 100644 (file)
@@ -23,7 +23,7 @@ extern "C"
 #include "dynlib_ast.h"
 }
 
-//#define DEBUG_THREAD
+// #define DEBUG_THREAD
 
 class EXTERN_AST ThreadManagement
 {
@@ -37,6 +37,9 @@ private :
     static __threadSignal m_ConsoleExecDone;
     static __threadSignalLock m_ConsoleExecDoneLock;
 
+    static __threadSignal m_DebuggerExecDone;
+    static __threadSignalLock m_DebuggerExecDoneLock;
+
     static __threadSignal m_AwakeRunner;
     static __threadSignalLock m_AwakeRunnerLock;
 
@@ -58,6 +61,7 @@ private :
     // used to avoid "Spurious Wakeups"
     static bool m_AvailableRunnerWasSignalled;
     static bool m_ConsoleExecDoneWasSignalled;
+    static bool m_DebuggerExecDoneWasSignalled;
     static bool m_AwakeRunnerWasSignalled;
     static bool m_StartPendingWasSignalled;
     static bool m_CommandStoredWasSignalled;
@@ -86,6 +90,8 @@ public :
     static void WaitForAvailableRunnerSignal(void);
     static void SendConsoleExecDoneSignal(void);
     static void WaitForConsoleExecDoneSignal(void);
+    static void SendDebuggerExecDoneSignal(void);
+    static void WaitForDebuggerExecDoneSignal(bool bResume);
     static void SendAwakeRunnerSignal(void);
     static void WaitForAwakeRunnerSignal(void);
     static void SendStartPendingSignal(void);
index f68ffa2..74f45fe 100644 (file)
 #include "consoledebugger.hxx"
 #include "debugmanager.hxx"
 #include "printvisitor.hxx"
+#include "configvariable.hxx"
 
 extern "C"
 {
 #include "sciprint.h"
 #include "prompt.h"
+#include "storeCommand.h"
 }
 
 namespace debugger
@@ -29,20 +31,68 @@ void ConsoleDebugger::onStop(int index)
 {
     if (index >= 0)
     {
-        debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
+        debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
         debugger::Breakpoint* bp = manager->getBreakPoint(index);
         if (bp)
         {
-            sciprint(_("debugger stop on breakpoint(%d) in function %ls line %d\n"), index, bp->getFunctioName().data(), bp->getMacroLine());
+            if(bp->hasMacro())
+            {
+                sciprint(_("debugger stop on breakpoint(%d) in function %s at line %d\n"), index, bp->getFunctioName().data(), bp->getMacroLine());
+            }
+            else
+            {
+                sciprint(_("debugger stop on breakpoint(%d) in file %s at line %d\n"), index, bp->getFileName().data(), bp->getFileLine());
+            }
         }
     }
-
     printExp();
 }
 
+void ConsoleDebugger::onExecution()
+{
+    // sciprint("ConsoleDebugger::onExecution.\n");
+}
+
+void ConsoleDebugger::onExecutionReleased()
+{
+    // sciprint("ConsoleDebugger::onExecutionReleased.\n");
+    // debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    // if(manager->getCurrentBreakPoint())
+    // {
+    //     sciprint("execution stopped on breakpoint.\n");
+    // }
+    // else
+    // {
+    //     sciprint("execution finished.\n");
+    // }
+}
+
+void ConsoleDebugger::onPrint(const std::string& variable)
+{
+    // sciprint("ConsoleDebugger::onPrint.\n");
+    StoreDebuggerCommand(std::string("disp("+variable+")").data());
+}
+
+void ConsoleDebugger::onShow(int bp)
+{
+    // sciprint("ConsoleDebugger::onShow.\n");
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    if(bp == -1)
+    {
+        debugger::Breakpoints& bps = manager->getAllBreakPoint();
+        printBreakPoints(bps);
+    }
+    else
+    {
+        debugger::Breakpoints bps;
+        bps.push_back(manager->getBreakPoint(bp));
+        printBreakPoints(bps);
+    }
+}
+
 void ConsoleDebugger::onResume()
 {
-    //sciprint("ConsoleDebugger::onResume.\n");
+    // sciprint("ConsoleDebugger::onResume.\n");
 }
 
 void ConsoleDebugger::onAbort()
@@ -52,7 +102,7 @@ void ConsoleDebugger::onAbort()
 
 void ConsoleDebugger::onErrorInFile(const std::wstring& filename)
 {
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
     ast::Exp* exp = manager->getExp();
     sciprint(_("debugger stop on error in file %ls line %d\n"), filename.data(), exp->getLocation().first_line);
     printExp();
@@ -60,7 +110,7 @@ void ConsoleDebugger::onErrorInFile(const std::wstring& filename)
 
 void ConsoleDebugger::onErrorInScript(const std::wstring& funcname)
 {
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
     ast::Exp* exp = manager->getExp();
     sciprint(_("debugger stop on error in function %ls line %d\n"), funcname.data(), exp->getLocation().first_line);
     printExp();
@@ -73,37 +123,41 @@ void ConsoleDebugger::onQuit()
 
 void ConsoleDebugger::updateBreakpoints()
 {
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
-    debugger::Breakpoints& brks = manager->getAllBreakPoint();
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    debugger::Breakpoints& bps = manager->getAllBreakPoint();
+    printBreakPoints(bps);
+}
 
-    if (brks.size() == 0)
+void ConsoleDebugger::printExp()
+{
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    std::wostringstream ostr;
+    ast::PrintVisitor pp(ostr, true, true, true);
+    manager->getExp()->accept(pp);
+    sciprint("%s%ls\n", SCIPROMPT_PAUSE, ostr.str().data());
+}
+
+void ConsoleDebugger::printBreakPoints(debugger::Breakpoints& bps)
+{
+    if (bps.size() == 0)
     {
         sciprint("No breakpoint\n");
         return;
     }
 
-    sciprint("% 3ls % 7ls %24ls % 5ls %ls\n\n", L"num", L"enable", L"function", L"line", L"condition");
+    sciprint("% 3s % 7s % 24s % 24s  %s\n\n", "num", "enable", "function", "file", "condition");
     int i = 0;
-    for (const auto& b : brks)
+    for (const auto& b : bps)
     {
-        if (b->isMacro())
-        {
-            std::wstring condition = b->getCondition();
-            sciprint("% 3d % 7s %24ls % 5d %ls\n", i, b->isEnable() ? "true" : "false", b->getFunctioName().c_str(), b->getMacroLine(),
-                     condition.size() < 30 ? condition.c_str() :
-                     (std::wstring(condition.begin(), condition.begin() + 27) + L"...").c_str());
-        }
+        std::string condition = b->getCondition();
+        std::string macro = b->hasMacro() ? b->getFunctioName() + ":" + std::to_string(b->getMacroLine()) : "";
+        std::string file  = b->hasFile()  ? b->getFileName() +    ":" + std::to_string(b->getFileLine())  : "";
 
+        sciprint("% 3d % 7s % 24s % 24s  %s\n",
+                i, b->isEnable() ? "true" : "false", macro.data(), file.data(),
+                condition.size() < 30 ? condition.c_str() :
+                    (std::string(condition.begin(), condition.begin() + 27) + "...").c_str());
         ++i;
     }
 }
-
-void ConsoleDebugger::printExp()
-{
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
-    std::wostringstream ostr;
-    ast::PrintVisitor pp(ostr, true, true, true);
-    manager->getExp()->accept(pp);
-    sciprint("%s%ls\n", SCIPROMPT_PAUSE, ostr.str().data());
-}
 }
index 2f40e73..97029a2 100644 (file)
 extern "C"
 {
 #include "filemanager_interface.h"
+#include "FileExist.h"
 }
 
 namespace ast
 {
 void DebuggerVisitor::visit(const SeqExp  &e)
 {
-    RunVisitor* exec = NULL;
     std::list<Exp *>::const_iterator itExp;
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
-
-    if (ConfigVariable::getEnableDebug() == false)
-    {
-        //enable debugger for next execution
-        ConfigVariable::setEnableDebug(true);
-
-        ExecVisitor exec;
-        e.accept(exec);
-        return;
-    }
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    manager->resetAborted();
 
     for (const auto & exp : e.getExps())
     {
@@ -62,34 +53,28 @@ void DebuggerVisitor::visit(const SeqExp  &e)
         }
 
         //debugger check !
+        int iBreakPoint = -1;
         if (ConfigVariable::getEnableDebug())
         {
-            std::vector<ConfigVariable::WhereEntry> lWhereAmI = ConfigVariable::getWhere();
-            int iLine = (exp->getLocation().first_line - ConfigVariable::getMacroFirstLines()) + 1;
-
-            //manage step next
-            if (manager->isStepNext())
-            {
-                manager->resetStepNext();
-                manager->stop(exp, -1);
-            }
-            else if (manager->isStepIn())
+            bool stopExecution = false;
+            if (manager->isStepIn())
             {
                 manager->resetStepIn();
-                manager->stop(exp, -1);
+                stopExecution = true;
             }
-            else if (manager->isStepOut())
+            else if (manager->isStepNext())
             {
-                manager->resetStepOut();
-                manager->stop(exp, -1);
+                manager->resetStepNext();
+                stopExecution = true;
             }
             else
             {
+                std::vector<ConfigVariable::WhereEntry> lWhereAmI = ConfigVariable::getWhere();
                 //set information from debugger commands
                 if (lWhereAmI.size() != 0 && manager->getBreakPointCount() != 0)
                 {
                     debugger::Breakpoints bps = manager->getAllBreakPoint();
-                    std::wstring functionName = lWhereAmI.back().call->getName();
+
                     int i = -1;
                     for (const auto & bp : bps)
                     {
@@ -99,68 +84,126 @@ void DebuggerVisitor::visit(const SeqExp  &e)
                             continue;
                         }
 
-                        if (functionName == bp->getFunctioName())
+                        // look for a breakpoint on this line and update breakpoint information when possible
+                        char* functionName = wide_string_to_UTF8(lWhereAmI.back().call->getName().data());
+                        std::wstring pstrFileName = lWhereAmI.back().m_file_name;
+                        char* fileName = wide_string_to_UTF8(pstrFileName.data());
+
+                        int iLine = exp->getLocation().first_line - ConfigVariable::getMacroFirstLines();
+                        if (bp->hasMacro() &&
+                            bp->getFunctioName().compare(functionName) == 0)
                         {
-                            if (bp->getMacroLine() == -1)
+                            if (bp->getMacroLine() == 0)
                             {
                                 //first pass in macro.
                                 //update first line with real value
                                 bp->setMacroLine(iLine);
                             }
 
-                            if (bp->getMacroLine() == iLine)
+                            stopExecution = bp->getMacroLine() == iLine;
+                        }
+                        else if(bp->hasFile() &&
+                                bp->getFileLine() == exp->getLocation().first_line)
+                        {
+                            if(pstrFileName.rfind(L".bin") != std::string::npos)
                             {
-                                //check condition
-                                if (bp->getConditionExp() != NULL)
+                                pstrFileName.replace(pstrFileName.size() - 4, 4, L".sci");
+                                // stop on bp only if the file exist
+                                if (FileExistW(pstrFileName.data()))
                                 {
-                                    //do not use debuggervisitor !
-                                    symbol::Context* pCtx = symbol::Context::getInstance();
-                                    try
-                                    {
-                                        ExecVisitor execCond;
-                                        //protect current env during condition execution
-                                        pCtx->scope_begin();
-                                        bp->getConditionExp()->accept(execCond);
-                                        types::InternalType* pIT = pCtx->getCurrentLevel(symbol::Symbol(L"ans"));
-                                        if (pIT == NULL ||
-                                                pIT->isBool() == false ||
-                                                ((types::Bool*)pIT)->isScalar() == false ||
-                                                ((types::Bool*)pIT)->get(0) == 0)
-                                        {
-                                            pCtx->scope_end();
-                                            //not a boolean, not scalar or false
-                                            continue;
-                                        }
-
-                                        pCtx->scope_end();
-                                        //ok condition is valid and true
-                                    }
-                                    catch (ast::ScilabException &/*e*/)
-                                    {
-                                        pCtx->scope_end();
-                                        //not work !
-                                        //invalid breakpoint
-                                        continue;
-                                    }
+                                    FREE(fileName);
+                                    fileName = wide_string_to_UTF8(pstrFileName.data());
                                 }
+                            }
+
+                            if(bp->getFileName().compare(fileName) == 0)
+                            {
+                                stopExecution = true;
+                                // set function information
+                                if(lWhereAmI.back().call->getFirstLine())
+                                {
+                                    bp->setFunctionName(functionName);
+                                    bp->setMacroLine(iLine);
+                                }
+                            }
+                        }
+
+                        FREE(functionName);
+                        FREE(fileName);
+
+                        if(stopExecution == false)
+                        {
+                            // no breakpoint for this line
+                            continue;
+                        }
+
+                        // Set the begin of line if not yet done
+                        if(bp->getBeginLine() == 0)
+                        {
+                            bp->setBeginLine(exp->getLocation().first_column);
+                        }
+                        // check if this exp is at the begin of the breakpoint line
+                        else if(bp->getBeginLine() != exp->getLocation().first_column)
+                        {
+                            // stop only if we are at the line begins
+                            stopExecution = false;
+                            continue;
+                        }
 
-                                //we have a breakpoint !
-                                //stop execution and wait signal from debugger to restart
-                                manager->stop(exp, i);
+                        //check condition
+                        if (bp->getConditionExp() != NULL)
+                        {
+                            //do not use debuggervisitor !
+                            symbol::Context* pCtx = symbol::Context::getInstance();
+                            try
+                            {
+                                ExecVisitor execCond;
+                                //protect current env during condition execution
+                                pCtx->scope_begin();
+                                bp->getConditionExp()->accept(execCond);
+                                types::InternalType* pIT = pCtx->getCurrentLevel(symbol::Symbol(L"ans"));
+                                if (pIT == NULL ||
+                                        pIT->isBool() == false ||
+                                        ((types::Bool*)pIT)->isScalar() == false ||
+                                        ((types::Bool*)pIT)->get(0) == 0)
+                                {
+                                    pCtx->scope_end();
+                                    //not a boolean, not scalar or false
+                                    stopExecution = false;
+                                    continue;
+                                }
 
-                                //only one breakpoint can be "call" on same exp
-                                break;
+                                pCtx->scope_end();
+                                //ok condition is valid and true
+                            }
+                            catch (ast::ScilabException &/*e*/)
+                            {
+                                pCtx->scope_end();
+                                stopExecution = false;
+                                //not work !
+                                //invalid breakpoint
+                                continue;
                             }
                         }
+
+                        //we have a breakpoint !
+                        //stop execution and wait signal from debugger to restart
+                        iBreakPoint = i;
+
+                        //only one breakpoint can be "call" on same exp
+                        break;
                     }
                 }
             }
-            exec = this;
-        }
-        else
-        {
-            //change visitor to execvitor instead of debuggervisitor
-            exec = new ExecVisitor();
+
+            if(stopExecution)
+            {
+                manager->stop(exp, iBreakPoint);
+                if (manager->isAborted())
+                {
+                    throw ast::InternalAbort();
+                }
+            }
         }
 
         //copy from runvisitor::seqexp
@@ -170,7 +213,7 @@ void DebuggerVisitor::visit(const SeqExp  &e)
             setResult(NULL);
             int iExpectedSize = getExpectedSize();
             setExpectedSize(-1);
-            exp->accept(*exec);
+            exp->accept(*this);
             setExpectedSize(iExpectedSize);
             types::InternalType * pIT = getResult();
 
@@ -273,6 +316,21 @@ void DebuggerVisitor::visit(const SeqExp  &e)
                 exp->resetReturn();
                 break;
             }
+
+            // Stop execution at the end of the seqexp of the caller
+            // Do it at the end of the seqexp will make the debugger stop
+            // even if the caller is at the last line
+            // ie: the caller is followed by endfunction
+            if(manager->isStepOut())
+            {
+                manager->resetStepOut();
+                manager->stop(exp, iBreakPoint);
+                if (manager->isAborted())
+                {
+                    throw ast::InternalAbort();
+                }
+            }
+
         }
         catch (const InternalError& ie)
         {
@@ -295,6 +353,12 @@ void DebuggerVisitor::visit(const SeqExp  &e)
                 {
                     manager->errorInFile(filename, exp);
                 }
+
+                // Debugger just restart after been stopped on an error.
+                if (manager->isAborted())
+                {
+                    throw ast::InternalAbort();
+                }
             }
 
             throw ie;
@@ -305,10 +369,5 @@ void DebuggerVisitor::visit(const SeqExp  &e)
         setResult(NULL);
 
     }
-
-    //propagate StepNext to parent SeqExp
-    if (ConfigVariable::getEnableDebug())
-    {
-    }
 }
 }
index e94b1f7..a3e0b67 100644 (file)
 #include <memory>
 
 #include "debugmanager.hxx"
-#include "configvariable.hxx"
 #include "threadmanagement.hxx"
-#include "runner.hxx"
+#include "execvisitor.hxx"
+#include "printvisitor.hxx"
+#include "UTF8.hxx"
 
 #include "threadId.hxx"
 
 extern "C"
 {
 #include "Thread_Wrapper.h"
+#include "storeCommand.h"
+#include "pause.h"
+#include "FileExist.h"
 }
 
 namespace debugger
 {
-std::unique_ptr<DebuggerMagager> DebuggerMagager::me(nullptr);
+std::unique_ptr<DebuggerManager> DebuggerManager::me(nullptr);
 
 //singleton
-DebuggerMagager* DebuggerMagager::getInstance()
+DebuggerManager* DebuggerManager::getInstance()
 {
     if (me.get() == nullptr)
     {
-        me.reset(new DebuggerMagager());
+        me.reset(new DebuggerManager());
     }
 
     return me.get();
 }
 
-void DebuggerMagager::addDebugger(AbstractDebugger* _debug)
+void DebuggerManager::addDebugger(const std::string& _name, AbstractDebugger* _debug)
 {
-    debuggers.push_back(_debug);
+    debuggers[_name] = _debug;
 }
 
-void DebuggerMagager::removeDebugger(int _iDebugger)
+void DebuggerManager::removeDebugger(const std::string& _name)
 {
-    if (_iDebugger >= 0 && _iDebugger <= debuggers.size())
+    if(getDebugger(_name))
     {
-        debuggers.erase(debuggers.begin() + _iDebugger);
+        debuggers.erase(_name);
     }
 }
 
-AbstractDebugger* DebuggerMagager::getDebugger(int _iDebugger)
+AbstractDebugger* DebuggerManager::getDebugger(const std::string& _name)
 {
-    if (_iDebugger >= 0 && _iDebugger <= debuggers.size())
+    const auto& d = debuggers.find(_name);
+    if(d != debuggers.end())
     {
-        return debuggers[_iDebugger];
+        return debuggers[_name];
     }
 
     return NULL;
 }
 
-int DebuggerMagager::getDebuggerCount()
+int DebuggerManager::getDebuggerCount()
 {
     return (int)debuggers.size();
 }
 
-Debuggers& DebuggerMagager::getAllDebugger()
+Debuggers& DebuggerManager::getAllDebugger()
 {
     return debuggers;
 }
 
-void DebuggerMagager::sendStop(int index)
+void DebuggerManager::sendStop(int index)
 {
     currentBreakPoint = index;
     for (const auto& it : debuggers)
     {
-        it->onStop(index);
+        it.second->onStop(index);
     }
 }
 
-void DebuggerMagager::sendResume()
+void DebuggerManager::sendExecution()
+{
+    for (const auto& it : debuggers)
+    {
+        it.second->onExecution();
+    }
+}
+
+void DebuggerManager::sendExecutionReleased()
+{
+    for (const auto& it : debuggers)
+    {
+        it.second->onExecutionReleased();
+    }
+}
+
+void DebuggerManager::sendPrint(const std::string& variable)
+{
+    for (const auto& it : debuggers)
+    {
+        it.second->onPrint(variable);
+    }
+}
+
+void DebuggerManager::sendShow(int bp)
+{
+    for (const auto& it : debuggers)
+    {
+        it.second->onShow(bp);
+    }
+}
+
+void DebuggerManager::sendResume()
 {
     currentBreakPoint = -1;
     for (const auto& it : debuggers)
     {
-        it->onResume();
+        it.second->onResume();
     }
 }
 
-void DebuggerMagager::sendAbort()
+void DebuggerManager::sendAbort()
 {
     currentBreakPoint = -1;
     for (const auto& it : debuggers)
     {
-        it->onAbort();
+        it.second->onAbort();
     }
 }
 
-void DebuggerMagager::sendErrorInFile(const std::wstring& filename) const
+void DebuggerManager::sendErrorInFile(const std::wstring& filename) const
 {
     for (const auto& it : debuggers)
     {
-        it->onErrorInFile(filename);
+        it.second->onErrorInFile(filename);
     }
 }
 
-void DebuggerMagager::sendErrorInScript(const std::wstring& funcname) const
+void DebuggerManager::sendErrorInScript(const std::wstring& funcname) const
 {
     for (const auto& it : debuggers)
     {
-        it->onErrorInScript(funcname);
+        it.second->onErrorInScript(funcname);
     }
 }
 
-void DebuggerMagager::sendQuit()
+void DebuggerManager::sendQuit()
 {
     currentBreakPoint = -1;
     for (const auto& it : debuggers)
     {
-        it->onQuit();
+        it.second->onQuit();
     }
 }
 
-void DebuggerMagager::sendUpdate() const
+void DebuggerManager::sendUpdate() const
 {
     for (const auto& it : debuggers)
     {
-        it->updateBreakpoints();
+        it.second->updateBreakpoints();
     }
 }
 
-void DebuggerMagager::addBreakPoint(Breakpoint* bp)
+void DebuggerManager::addBreakPoint(Breakpoint* bp)
 {
     //check if breakpoint does not exist
-
-    bool add = true;
     for (const auto b : breakpoints)
     {
-        if (b->getFunctioName() != bp->getFunctioName())
-        {
-            continue;
-        }
-
-        if (b->getMacroLine() != bp->getMacroLine())
+        bool isMacro = b->getFunctioName() == bp->getFunctioName() &&
+                       b->getMacroLine() != bp->getMacroLine();
+        bool isFile  = b->getFileName() == bp->getFileName() &&
+                       b->getFileLine() != bp->getFileLine();
+        bool equalCondition = b->getCondition() != bp->getCondition();
+        if ((isMacro || isFile) && equalCondition)
         {
-            continue;
+            //same breakpoint, cancel add
+            return;
         }
-
-        if (b->getCondition() != bp->getCondition())
-        {
-            continue;
-        }
-
-        //same breakpoint, cancel add
-        add = false;
     }
 
-    if (add)
+    breakpoints.push_back(bp);
+    sendUpdate();
+}
+
+void DebuggerManager::setAllBreakPoints(Breakpoints& _bps)
+{
+    // remove existing breakpoints
+    for (auto bp : breakpoints)
     {
-        breakpoints.push_back(bp);
-        sendUpdate();
+        delete bp;
     }
+    breakpoints.clear();
+
+    // set new breakpoints
+    breakpoints.swap(_bps);
+    sendUpdate();
 }
 
-void DebuggerMagager::removeBreakPoint(int _iBreakPoint)
+void DebuggerManager::removeBreakPoint(int _iBreakPoint)
 {
-    if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
+    if (_iBreakPoint >= 0 && _iBreakPoint <= (int)breakpoints.size())
     {
         Breakpoints::iterator it = breakpoints.begin() + _iBreakPoint;
         delete *it;
@@ -179,7 +218,7 @@ void DebuggerMagager::removeBreakPoint(int _iBreakPoint)
     }
 }
 
-void DebuggerMagager::removeAllBreakPoints()
+void DebuggerManager::removeAllBreakPoints()
 {
     Breakpoints::iterator it = breakpoints.begin();
     for (; it != breakpoints.end(); ++it)
@@ -191,16 +230,16 @@ void DebuggerMagager::removeAllBreakPoints()
     sendUpdate();
 }
 
-void DebuggerMagager::disableBreakPoint(int _iBreakPoint)
+void DebuggerManager::disableBreakPoint(int _iBreakPoint)
 {
-    if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
+    if (_iBreakPoint >= 0 && _iBreakPoint <= (int)breakpoints.size())
     {
         breakpoints[_iBreakPoint]->setDisable();
         sendUpdate();
     }
 }
 
-void DebuggerMagager::disableAllBreakPoints()
+void DebuggerManager::disableAllBreakPoints()
 {
     for (const auto& it : breakpoints)
     {
@@ -210,15 +249,16 @@ void DebuggerMagager::disableAllBreakPoints()
     sendUpdate();
 }
 
-void DebuggerMagager::enableBreakPoint(int _iBreakPoint)
+void DebuggerManager::enableBreakPoint(int _iBreakPoint)
 {
-    if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
+    if (_iBreakPoint >= 0 && _iBreakPoint <= (int)breakpoints.size())
     {
         breakpoints[_iBreakPoint]->setEnable();
+        sendUpdate();
     }
 }
 
-void DebuggerMagager::enableAllBreakPoints()
+void DebuggerManager::enableAllBreakPoints()
 {
     for (const auto& it : breakpoints)
     {
@@ -228,9 +268,9 @@ void DebuggerMagager::enableAllBreakPoints()
     sendUpdate();
 }
 
-bool DebuggerMagager::isEnableBreakPoint(int _iBreakPoint)
+bool DebuggerManager::isEnableBreakPoint(int _iBreakPoint)
 {
-    if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
+    if (_iBreakPoint >= 0 && _iBreakPoint <= (int)breakpoints.size())
     {
         return breakpoints[_iBreakPoint]->isEnable();
     }
@@ -238,9 +278,9 @@ bool DebuggerMagager::isEnableBreakPoint(int _iBreakPoint)
     return false;
 }
 
-Breakpoint* DebuggerMagager::getBreakPoint(int _iBreakPoint)
+Breakpoint* DebuggerManager::getBreakPoint(int _iBreakPoint)
 {
-    if (_iBreakPoint >= 0 && _iBreakPoint < breakpoints.size())
+    if (_iBreakPoint >= 0 && _iBreakPoint < (int)breakpoints.size())
     {
         return breakpoints[_iBreakPoint];
     }
@@ -248,104 +288,259 @@ Breakpoint* DebuggerMagager::getBreakPoint(int _iBreakPoint)
     return NULL;
 }
 
-int DebuggerMagager::getBreakPointCount()
+int DebuggerManager::getBreakPointCount()
 {
     return (int)breakpoints.size();
 }
 
-Breakpoints& DebuggerMagager::getAllBreakPoint()
+Breakpoints& DebuggerManager::getAllBreakPoint()
 {
     return breakpoints;
 }
 
-void DebuggerMagager::resume() //resume execution
+void DebuggerManager::setWatches(Watches _w)
 {
-    if (ConfigVariable::getPauseLevel() != 0)
-    {
-        ConfigVariable::DecreasePauseLevel();
-        //inform debuggers
-        sendResume();
-    }
+    watches.clear();
+    watches = _w;
+}
 
+void DebuggerManager::removeWatches()
+{
+    watches.clear();
 }
 
-void DebuggerMagager::abort() //abort execution
+void DebuggerManager::updateWatches(int _iScopeLvl)
 {
-    if (ConfigVariable::getPauseLevel() != 0)
+    symbol::Context* pCtx = symbol::Context::getInstance();
+
+    if(_iScopeLvl < 0)
     {
-        //inform debuggers
-        sendAbort();
+        // get current scope lvl
+        _iScopeLvl = pCtx->getScopeLevel();
+    }
 
-        throw ast::InternalAbort();
+    for(auto& w : watches)
+    {
+        types::InternalType* pIT = pCtx->getAtLevel(symbol::Symbol(scilab::UTF8::toWide(w.first)), _iScopeLvl);
+        if(pIT)
+        {
+            std::wostringstream os;
+            pIT->toString(os);
+            w.second = scilab::UTF8::toUTF8(os.str());
+        }
+        else
+        {
+            w.second.clear();
+        }
     }
 }
 
-void DebuggerMagager::internal_stop()
+Watches& DebuggerManager::getWatches()
 {
-    interrupted = true;
+    return watches;
+}
+
+
+
+void DebuggerManager::generateCallStack()
+{
+    clearCallStack();
+
+    std::wostringstream ostr;
+    ast::PrintVisitor pp(ostr, true, true, true);
+    getExp()->accept(pp);
+    char* tmp = wide_string_to_UTF8(ostr.str().data());
+    callstack.exp = tmp;
+    FREE(tmp);
+
+    //where
+    ConfigVariable::WhereVector where = ConfigVariable::getWhere();
+    auto it_name = where.rbegin();
+
+    // first row
+    Stack cs;
+    StackRow row;
+    tmp = wide_string_to_UTF8(it_name->call->getName().data());
+    row.functionName = tmp;
+    FREE(tmp);
 
-    ConfigVariable::IncreasePauseLevel();
+    row.functionLine = -1;
+    if(it_name->call->getFirstLine())
+    {
+        row.functionLine = getExp()->getLocation().first_line - it_name->call->getFirstLine();
+    }
+
+    if(callstackAddFile(&row, it_name->m_file_name))
+    {
+        row.fileLine = getExp()->getLocation().first_line;
+    }
 
-    // unlock console thread to display prompt again
-    ThreadManagement::SendConsoleExecDoneSignal();
+    row.scope = symbol::Context::getInstance()->getScopeLevel();
 
-    //return to console so change mode to 2
-    int iOldMode = ConfigVariable::getPromptMode();
-    ConfigVariable::setPromptMode(2);
+    cs.push_back(row);
+    ++it_name;
 
-    int iPauseLevel = ConfigVariable::getPauseLevel();
-    while (ConfigVariable::getPauseLevel() == iPauseLevel)
+    // next rows
+    for (auto it_line = where.rbegin(); it_name != where.rend(); it_name++, it_line++)
     {
-        ThreadManagement::SendAwakeRunnerSignal();
-        ThreadManagement::WaitForRunMeSignal();
-        try
+        StackRow row;
+        tmp = wide_string_to_UTF8(it_name->call->getName().data());
+        row.functionName = tmp;
+        FREE(tmp);
+        row.functionLine = it_line->m_line - 1;
+        if(callstackAddFile(&row, it_name->m_file_name))
         {
-            StaticRunner_launch();
+            row.fileLine = it_line->m_line;
+            row.functionLine = -1;
+            if(it_name->call->getFirstLine())
+            {
+                row.fileLine = it_name->call->getFirstLine() + it_line->m_line - 1;
+                row.functionLine = it_line->m_line - 1;
+            }
         }
-        catch (const ast::InternalError& ie)
-        {
-            //return from console so change mode to initial
-            ConfigVariable::setPromptMode(iOldMode);
-            //clean current seqexp
-            clearExp();
-            interrupted = false;
 
-            throw ie;
-        }
-        catch (const ast::InternalAbort& ia)
+        row.scope = it_line->m_scope_lvl;
+        cs.push_back(row);
+    }
+
+    callstack.stack = cs;
+}
+
+bool DebuggerManager::callstackAddFile(StackRow* _row, const std::wstring& _fileName)
+{
+    _row->hasFile = false;
+    if(_fileName.length())
+    {
+        std::string pstrFileName = scilab::UTF8::toUTF8(_fileName);
+        _row->hasFile = true;
+        // replace .bin by .sci
+        size_t pos = pstrFileName.rfind(".bin");
+        if(pos != std::string::npos)
         {
-            //return from console so change mode to initial
-            ConfigVariable::setPromptMode(iOldMode);
-            //clean current seqexp
-            clearExp();
-            interrupted = false;
+            pstrFileName.replace(pos, 4, ".sci");
+            // do not add the file in the callstack if the associeted .sci is not available
+            if (FileExist(pstrFileName.data()) == false)
+            {
+                _row->hasFile = false;
+            }
+        }
 
-            throw ia;
+        if(_row->hasFile)
+        {
+            _row->fileName = pstrFileName;
         }
     }
 
-    //return from console so change mode to initial
-    ConfigVariable::setPromptMode(iOldMode);
+    return _row->hasFile;
+}
+
+void DebuggerManager::print(const std::string& variable)
+{
+    //inform debuggers
+    sendPrint(variable);
+}
+
+void DebuggerManager::show(int bp)
+{
+    //inform debuggers
+    sendShow(bp);
+}
+
+char* DebuggerManager::execute(const std::string& command)
+{
+    char* error = checkCommand(command.data());
+    if(error)
+    {
+        return error;
+    }
+
+    //inform debuggers
+    sendExecution();
+    // execute command and wait
+    StoreDebuggerCommand(command.data());
+    // send execution finished and update debugger informations
+    internal_execution_released();
+
+    return nullptr;
+}
+
+void DebuggerManager::resume() //resume execution
+{
+    if (ConfigVariable::getPauseLevel() != 0)
+    {
+        //inform debuggers
+        sendResume();
+
+        ConfigVariable::DecreasePauseLevel();
+        // reset callstack
+        clearCallStack();
+
+        // send "SendRunMeSignal" to unlock execution then wait
+        ThreadManagement::WaitForDebuggerExecDoneSignal(true);
+
+        // send execution finished and update debugger informations
+        internal_execution_released();
+    }
+}
+
+void DebuggerManager::abort() //abort execution
+{
+    if (ConfigVariable::getPauseLevel() != 0)
+    {
+        //inform debuggers
+        sendAbort();
+
+        // this state is check by the debuggerVisitor to do abort in the main thread
+        setAborted();
+        ConfigVariable::DecreasePauseLevel();
+        // reset lasterror
+        ConfigVariable::clearLastError();
+        // reset callstack
+        clearCallStack();
+
+        ThreadManagement::WaitForDebuggerExecDoneSignal(true);
+
+        internal_execution_released();
+    }
+}
+
+void DebuggerManager::internal_execution_released()
+{
+    // update watches at each execution released
+    updateWatches();
+    // send execution finished
+    sendExecutionReleased();
+}
+
+void DebuggerManager::internal_stop()
+{
+    interrupted = true;
+    generateCallStack();
+    updateWatches();
+    pause();
     //clean current seqexp
     interrupted = false;
 }
 
-void DebuggerMagager::stop(const ast::Exp* pExp, int index)
+void DebuggerManager::stop(const ast::Exp* pExp, int index)
 {
     //send stop information to all debuggers
     setExp(pExp);
     sendStop(index);
+    // because stop is used only in the debuggervisitor the pause
+    // will be executed in the main thread (where is executed the command)
     internal_stop();
     clearExp();
 }
-void DebuggerMagager::errorInFile(const std::wstring filename, const ast::Exp* pExp)
+
+void DebuggerManager::errorInFile(const std::wstring filename, const ast::Exp* pExp)
 {
     setExp(pExp);
     sendErrorInFile(filename);
     internal_stop();
     clearExp();
 }
-void DebuggerMagager::errorInScript(const std::wstring funcname, const ast::Exp* pExp)
+void DebuggerManager::errorInScript(const std::wstring funcname, const ast::Exp* pExp)
 {
     setExp(pExp);
     sendErrorInScript(funcname);
index 44cb87c..24ec1f7 100644 (file)
@@ -902,13 +902,6 @@ void RunVisitorT<T>::visitprivate(const ReturnExp &e)
     {
         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
         {
-            if (ConfigVariable::getEnableDebug() == true)
-            {
-                sciprint(_("%s: function is disabled in debug mode.\n"), "resume");
-                CoverageInstance::stopChrono((void*)&e);
-                return;
-            }
-
             //return or resume
             ConfigVariable::DecreasePauseLevel();
             ConfigVariable::macroFirstLine_end();
index 25b9723..6930e20 100644 (file)
@@ -1185,7 +1185,7 @@ void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, types::Calla
         wstrFileName = pM->getFileName();
     }
 
-    m_Where.emplace_back(_iLineNum, _iLineLocation, pCall, wstrFileName);
+    m_Where.emplace_back(_iLineNum, _iLineLocation, symbol::Context::getInstance()->getScopeLevel(), pCall, wstrFileName);
 }
 
 void ConfigVariable::where_end()
@@ -1342,7 +1342,7 @@ void ConfigVariable::fillWhereError(int _iErrorLine)
         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).call, (*where).m_file_name);
+            m_WhereError.emplace_back(iTmp, (*where).m_absolute_line, 0, (*where).call, (*where).m_file_name);
             iTmp = (*where).m_line;
         }
     }
index 2791af9..41da8f0 100644 (file)
@@ -243,7 +243,7 @@ int isEnableDebug()
 
 int isDebugInterrupted()
 {
-    return debugger::DebuggerMagager::getInstance()->isInterrupted() ? 1 : 0;
+    return debugger::DebuggerManager::getInstance()->isInterrupted() ? 1 : 0;
 }
 
 int isExecutionBreak()
index 74e2a48..fdd10b4 100644 (file)
@@ -35,6 +35,9 @@ __threadLock ThreadManagement::m_ScilabReadLock;
 __threadSignal ThreadManagement::m_ConsoleExecDone;
 __threadSignalLock ThreadManagement::m_ConsoleExecDoneLock;
 
+__threadSignal ThreadManagement::m_DebuggerExecDone;
+__threadSignalLock ThreadManagement::m_DebuggerExecDoneLock;
+
 __threadSignal ThreadManagement::m_AwakeRunner;
 __threadSignalLock ThreadManagement::m_AwakeRunnerLock;
 
@@ -52,6 +55,7 @@ __threadSignalLock ThreadManagement::m_RunMeLock;
 
 bool ThreadManagement::m_AvailableRunnerWasSignalled    = false;
 bool ThreadManagement::m_ConsoleExecDoneWasSignalled    = false;
+bool ThreadManagement::m_DebuggerExecDoneWasSignalled   = false;
 bool ThreadManagement::m_AwakeRunnerWasSignalled        = false;
 bool ThreadManagement::m_StartPendingWasSignalled       = false;
 bool ThreadManagement::m_CommandStoredWasSignalled      = false;
@@ -70,6 +74,9 @@ void ThreadManagement::initialize()
     __InitSignal(&m_ConsoleExecDone);
     __InitSignalLock(&m_ConsoleExecDoneLock);
 
+    __InitSignal(&m_DebuggerExecDone);
+    __InitSignalLock(&m_DebuggerExecDoneLock);
+
     __InitSignal(&m_AvailableRunner);
     __InitSignalLock(&m_AvailableRunnerLock);
 
@@ -242,6 +249,58 @@ void ThreadManagement::WaitForConsoleExecDoneSignal(void)
 }
 
 /***
+    [DebuggerExecDone Signal]
+
+    Send : A debugger command is excuted.
+    Wait : Wait for its execution.
+
+    This signal can be sent without any threads are waiting for,
+    so we have to perform the Wait for each call to WaitForDebuggerExecDoneSignal.
+    (in case of "pause", we send this signal in sci_pause and in Runner::launch)
+
+    The loop while is used to avoid spurious wakeup of __Wait.
+***/
+void ThreadManagement::SendDebuggerExecDoneSignal(void)
+{
+#ifdef DEBUG_THREAD
+    PrintDebug("SendDebuggerExecDoneSignal");
+#endif // DEBUG_THREAD
+    __LockSignal(&m_DebuggerExecDoneLock);
+    m_DebuggerExecDoneWasSignalled = true;
+    __Signal(&m_DebuggerExecDone);
+    __UnLockSignal(&m_DebuggerExecDoneLock);
+}
+
+// bResume: resume execution before wait for its end
+void ThreadManagement::WaitForDebuggerExecDoneSignal(bool bResume)
+{
+# ifdef __DEBUG_SIGNAL
+    std::cout << "WaitForDebuggerExecDoneSignal" << std::endl;
+# endif // __DEBUG_SIGNAL
+    __LockSignal(&m_DebuggerExecDoneLock);
+    if(bResume)
+    {
+        // release execution there in case of pause
+        // because a released execution can be finished
+        // before we are waiting for.
+        // we avoid this by the lock of "m_DebuggerExecDoneLock"
+        // This signal is sent only in pause case because a runner already exists
+        ThreadManagement::SendRunMeSignal();
+    }
+
+    ThreadManagement::UnlockStoreCommand();
+    m_DebuggerExecDoneWasSignalled = false;
+    while (m_DebuggerExecDoneWasSignalled == false)
+    {
+#ifdef DEBUG_THREAD
+        PrintDebug("WaitForDebuggerExecDoneSignal");
+#endif // DEBUG_THREAD
+        __Wait(&m_DebuggerExecDone, &m_DebuggerExecDoneLock);
+    }
+    __UnLockSignal(&m_DebuggerExecDoneLock);
+}
+
+/***
     [AwakeRunner Signal]
 
     Send : Wakeup the runner when:
index 119e8b7..c9bb432 100644 (file)
@@ -54,6 +54,8 @@ CORE_CPP_SOURCES = \
     src/cpp/getmacrosname.cpp \
     src/cpp/getfunctionsname.cpp \
     src/cpp/InitScilab.cpp \
+    src/cpp/parsecommand.cpp \
+    src/cpp/pause.cpp \
     src/cpp/setformat.cpp
 
 CORE_FORTRAN_SOURCES = \
index 00628d9..c2e5e0e 100644 (file)
@@ -239,6 +239,8 @@ am__objects_2 = src/cpp/libscicore_algo_la-demangle.lo \
        src/cpp/libscicore_algo_la-getmacrosname.lo \
        src/cpp/libscicore_algo_la-getfunctionsname.lo \
        src/cpp/libscicore_algo_la-InitScilab.lo \
+       src/cpp/libscicore_algo_la-parsecommand.lo \
+       src/cpp/libscicore_algo_la-pause.lo \
        src/cpp/libscicore_algo_la-setformat.lo
 am__objects_3 = src/fortran/clunit.lo src/fortran/folhp.lo \
        src/fortran/xerbla.lo src/fortran/expsum.lo \
@@ -810,6 +812,8 @@ CORE_CPP_SOURCES = \
     src/cpp/getmacrosname.cpp \
     src/cpp/getfunctionsname.cpp \
     src/cpp/InitScilab.cpp \
+    src/cpp/parsecommand.cpp \
+    src/cpp/pause.cpp \
     src/cpp/setformat.cpp
 
 CORE_FORTRAN_SOURCES = \
@@ -1209,6 +1213,10 @@ src/cpp/libscicore_algo_la-getfunctionsname.lo:  \
        src/cpp/$(am__dirstamp) src/cpp/$(DEPDIR)/$(am__dirstamp)
 src/cpp/libscicore_algo_la-InitScilab.lo: src/cpp/$(am__dirstamp) \
        src/cpp/$(DEPDIR)/$(am__dirstamp)
+src/cpp/libscicore_algo_la-parsecommand.lo: src/cpp/$(am__dirstamp) \
+       src/cpp/$(DEPDIR)/$(am__dirstamp)
+src/cpp/libscicore_algo_la-pause.lo: src/cpp/$(am__dirstamp) \
+       src/cpp/$(DEPDIR)/$(am__dirstamp)
 src/cpp/libscicore_algo_la-setformat.lo: src/cpp/$(am__dirstamp) \
        src/cpp/$(DEPDIR)/$(am__dirstamp)
 src/fortran/$(am__dirstamp):
@@ -1560,6 +1568,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-getfunctionsname.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-getmacrosname.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-getvariablesname.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-parsecommand.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-pause.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-runner.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-setformat.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicore_algo_la-storeCommand.Plo@am__quote@
@@ -1901,6 +1911,20 @@ src/cpp/libscicore_algo_la-InitScilab.lo: src/cpp/InitScilab.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/libscicore_algo_la-InitScilab.lo `test -f 'src/cpp/InitScilab.cpp' || echo '$(srcdir)/'`src/cpp/InitScilab.cpp
 
+src/cpp/libscicore_algo_la-parsecommand.lo: src/cpp/parsecommand.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/libscicore_algo_la-parsecommand.lo -MD -MP -MF src/cpp/$(DEPDIR)/libscicore_algo_la-parsecommand.Tpo -c -o src/cpp/libscicore_algo_la-parsecommand.lo `test -f 'src/cpp/parsecommand.cpp' || echo '$(srcdir)/'`src/cpp/parsecommand.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/$(DEPDIR)/libscicore_algo_la-parsecommand.Tpo src/cpp/$(DEPDIR)/libscicore_algo_la-parsecommand.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/parsecommand.cpp' object='src/cpp/libscicore_algo_la-parsecommand.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/libscicore_algo_la-parsecommand.lo `test -f 'src/cpp/parsecommand.cpp' || echo '$(srcdir)/'`src/cpp/parsecommand.cpp
+
+src/cpp/libscicore_algo_la-pause.lo: src/cpp/pause.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/libscicore_algo_la-pause.lo -MD -MP -MF src/cpp/$(DEPDIR)/libscicore_algo_la-pause.Tpo -c -o src/cpp/libscicore_algo_la-pause.lo `test -f 'src/cpp/pause.cpp' || echo '$(srcdir)/'`src/cpp/pause.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/$(DEPDIR)/libscicore_algo_la-pause.Tpo src/cpp/$(DEPDIR)/libscicore_algo_la-pause.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/pause.cpp' object='src/cpp/libscicore_algo_la-pause.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/libscicore_algo_la-pause.lo `test -f 'src/cpp/pause.cpp' || echo '$(srcdir)/'`src/cpp/pause.cpp
+
 src/cpp/libscicore_algo_la-setformat.lo: src/cpp/setformat.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_algo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/libscicore_algo_la-setformat.lo -MD -MP -MF src/cpp/$(DEPDIR)/libscicore_algo_la-setformat.Tpo -c -o src/cpp/libscicore_algo_la-setformat.lo `test -f 'src/cpp/setformat.cpp' || echo '$(srcdir)/'`src/cpp/setformat.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/$(DEPDIR)/libscicore_algo_la-setformat.Tpo src/cpp/$(DEPDIR)/libscicore_algo_la-setformat.Plo
diff --git a/scilab/modules/core/includes/parsecommand.h b/scilab/modules/core/includes/parsecommand.h
new file mode 100644 (file)
index 0000000..7f58c63
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2019-2019 - ESI Group - Cedric Delamarre
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#ifndef __PARSECOMMAND_HXX__
+#define __PARSECOMMAND_HXX__
+#include <string>
+
+#include "exp.hxx"
+
+#include "dynlib_core.h"
+
+/*** Parse a command
+ * command: input, string to parse
+ * tree: output, the tree generated by the scilab parser if no error else nullptr
+ *
+ * return the error message or nullptr
+ * the message MUST be delete by the caller
+ *
+ ***/
+CORE_IMPEXP char* parseCommand(const char* command,  void** tree);
+CORE_IMPEXP char* checkCommand(const char* command);
+
+/*** Parse a file
+ * file: input, file name
+ * program: input, program name (ie: exec)
+ * tree: output, the tree generated by the scilab parser if no error else nullptr
+ *
+ * return the error message or nullptr
+ * the message MUST be delete by the caller
+ *
+ ***/
+CORE_IMPEXP char* parseFile(const char* file, const char* program, void** tree);
+CORE_IMPEXP char* checkFile(const char* file, const char* program);
+
+
+
+#endif /* !__PARSECOMMAND_HXX__ */
diff --git a/scilab/modules/core/includes/pause.h b/scilab/modules/core/includes/pause.h
new file mode 100644 (file)
index 0000000..22020d4
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2019-2019 - ESI Group - Cedric Delamarre
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#ifndef __PAUSE_H__
+#define __PAUSE_H__
+
+#include "dynlib_core.h"
+CORE_IMPEXP void pause(void);
+
+#endif /* !__PAUSE_H__ */
index 1ef85f3..95cfc19 100644 (file)
@@ -76,7 +76,9 @@ class StaticRunner
 public:
     static int launch(void);
     static void setRunner(Runner* _RunMe);
+    static void setCurrentRunner(Runner* _RunMe);
     static Runner* getRunner(void);
+    static Runner* getCurrentRunner(void);
     static bool isRunnerAvailable(void);
     static bool isInterruptibleCommand(void);
     static void setInterruptibleCommand(bool _isInterruptible);
@@ -84,9 +86,11 @@ public:
     static void execAndWait(ast::Exp* _theProgram, ast::RunVisitor *_visitor,
                             bool _isInterruptible, bool _isPrioritary, command_origin_t _iCommandOrigin);
     static bool exec(ast::Exp* _theProgram, ast::RunVisitor *_visitor);
+    static void sendExecDoneSignal();
 
 private:
     static std::atomic<Runner*> m_RunMe;
+    static std::atomic<Runner*> m_CurrentRunner;
     static std::atomic<bool> m_bInterruptibleCommand;
 };
 
index 556cddb..9c849f9 100644 (file)
@@ -20,8 +20,9 @@
 enum command_origin_t
 {
     NONE,
-    CONSOLE, // command from console
-    TCLSCI   // command from tclsci using ScilabEval interpreter
+    CONSOLE,  // command from console
+    TCLSCI,   // command from tclsci using ScilabEval interpreter
+    DEBUGGER  // command from debugger
 };
 
 /**
@@ -47,10 +48,19 @@ int StoreCommand(const char *command);
  * Store a prioritary and interruptible command
  *
  * @param command : the command
+ * @param iWaitFor : wait for the command execution end before return
  * @return <ReturnValue>
  */
-
 int StoreConsoleCommand(const char *command, int iWaitFor);
+
+/**
+ * Store a prioritary and interruptible command and wait for it's execution
+ *
+ * @param command : the command
+  * @return <ReturnValue>
+ */
+int StoreDebuggerCommand(const char *command);
+
 /**
  * Store a prioritary and non-interruptible command
  *
index 1254d7e..a509693 100644 (file)
@@ -80,12 +80,4 @@ void dumpStackTask(bool timed);
 int execScilabStartTask(bool _bSerialize);
 int execScilabQuitTask(bool _bSerialize);
 
-#ifdef __cplusplus
-extern "C"
-{
-ast::Exp* parseCommand(std::wstring _command);
-}
-#endif
-
-
 #endif /* !__TASKS_HXX__ */
index 5488014..f9f76d4 100644 (file)
 
 #include "core_gw.hxx"
 #include "function.hxx"
-#include "string.hxx"
-#include "printvisitor.hxx"
-#include "execvisitor.hxx"
 #include "debuggervisitor.hxx"
 #include "configvariable.hxx"
 #include "debugmanager.hxx"
-#include "threadId.hxx"
+#include "consoledebugger.hxx"
 
 extern "C"
 {
 #include "Scierror.h"
 #include "sciprint.h"
-#include "Thread_Wrapper.h"
 }
 
-enum EnumCommand
-{
-    AbortCommand,
-    BreakCommand,
-    ContinueCommand,
-    DisableCommand,
-    DeleteCommand,
-    EnableCommand,
-    HelpCommand,
-    HelpShortCommand,
-    ListCommand,
-    NextCommand,
-    QuitCommand,
-    ShowCommand,
-    StepInCommand,
-    StepOutCommand,
-    UnknowCommand,
-    WhereCommand
-};
-
 const char fname[] = "debug";
-const std::string HELP_DEBUG_COMMAND("help debug");
-
-void print_help();
-EnumCommand getCommand(const std::wstring& command);
-
 types::Function::ReturnValue sci_debug(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
-    if (in.size() == 0)
+    if (in.size() > 0)
     {
-        //debugger already active
-        if (ConfigVariable::getEnableDebug())
-        {
-            return types::Function::OK;
-        }
-
-        //debugger can be lauch only on console scope level
-        if (symbol::Context::getInstance()->getScopeLevel() != SCOPE_CONSOLE)
-        {
-            Scierror(999, _("%s: Debugger can be activated only at console scope level\n"), fname);
-            return types::Function::Error;
-        }
+        Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), fname, 0);
+        return types::Function::Error;
+    }
 
-        ConfigVariable::setEnableDebug(true);
-        ConfigVariable::setDefaultVisitor(new ast::DebuggerVisitor());
+    //debugger already active
+    if (ConfigVariable::getEnableDebug())
+    {
         return types::Function::OK;
     }
 
-    if (ConfigVariable::getEnableDebug() == false)
+    //debugger cannot be launch inside a pause
+    if (ConfigVariable::getPauseLevel())
     {
-        Scierror(999, _("%s: Debugger is not running. Call \"%s\" without parameter first.\n"), fname, fname);
+        Scierror(999, _("%s: Debugger cannot be activated in pause\n"), fname);
         return types::Function::Error;
     }
 
-    int iRhs = (int)in.size();
-    for (int i = 0; i < iRhs; i++)
+    //debugger can be lauch only on console scope level
+    if (symbol::Context::getInstance()->getScopeLevel() != SCOPE_CONSOLE)
     {
-        if (in[i]->isString() == false || ((types::String*)in[i])->isScalar() == false)
-        {
-            Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, i + 1);
-            return types::Function::Error;
-        }
+        Scierror(999, _("%s: Debugger can be activated only at console scope level\n"), fname);
+        return types::Function::Error;
     }
 
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
-
-    std::wstring command(((types::String*)in[0])->get(0));
-    switch (getCommand(command))
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    if(manager->getDebugger("console") == NULL)
     {
-        case AbortCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "abort", 0);
-                return types::Function::Error;
-            }
-
-            //abort
-            if (manager->isInterrupted())
-            {
-                manager->abort();
-            }
-            else
-            {
-                sciprint("debugger is not paused\n");
-            }
-
-            return types::Function::OK;
-        }
-        case BreakCommand:
-        {
-            if (iRhs < 2 || iRhs > 4)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "breakpoint", 1, 3);
-                return types::Function::Error;
-            }
-
-            //breakpoint
-            wchar_t* pwstFunctionName = NULL;
-            int iLine = -1;
-            wchar_t* pwstCondition = NULL;
-            debugger::Breakpoint* bp = NULL;
-            //function name
-            if (iRhs > 1)
-            {
-                //do not check name
-                //we can set breakpoint before function declaration
-                //for embedded function for example
-                pwstFunctionName = ((types::String*)in[1])->get(0);
-            }
-
-            if (iRhs > 2)
-            {
-                wchar_t* pwstLineNumber = ((types::String*)in[2])->get(0);
-                wchar_t* pwstEnd = NULL;
-                iLine = wcstol(pwstLineNumber, &pwstEnd, 10);
-                if (pwstEnd == NULL || *pwstEnd != 0)
-                {
-                    Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "breakpoint", 2);
-                    return types::Function::Error;
-                }
-            }
-
-            if (iRhs > 3)
-            {
-                pwstCondition = ((types::String*)in[3])->get(0);
-                bp = new debugger::Breakpoint(pwstFunctionName, iLine, pwstCondition);
-            }
-            else
-            {
-                bp = new debugger::Breakpoint(pwstFunctionName, iLine);
-            }
-
-            manager->addBreakPoint(bp);
-            return types::Function::OK;
-        }
-        case ContinueCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "continue", 0);
-                return types::Function::Error;
-            }
-
-            //continue
-            if (manager->isInterrupted())
-            {
-                manager->resume();
-            }
-            else
-            {
-                sciprint("debugger is not paused\n");
-            }
-
-            return types::Function::OK;
-        }
-        case DisableCommand:
-        {
-            if (iRhs > 2)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "disable", 0, 1);
-                return types::Function::Error;
-            }
-
-            //disable
-            if (iRhs == 2)
-            {
-                wchar_t* pEnd = NULL;
-                int iBp = (int)wcstol(((types::String*)in[1])->get(0), &pEnd, 10);
-                if (pEnd == NULL || *pEnd != 0)
-                {
-                    Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "disable", 1);
-                    return types::Function::Error;
-                }
-
-                if (manager->getBreakPoint(iBp) == NULL)
-                {
-                    Scierror(999, _("%s: Unable to retrieve information about breakpoint %d.\n"), "disable", iBp);
-                    return types::Function::Error;
-                }
-
-                manager->disableBreakPoint(iBp);
-            }
-            else
-            {
-                manager->disableAllBreakPoints();
-            }
-
-            return types::Function::OK;
-        }
-        case DeleteCommand :
-        {
-            if (iRhs > 2)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "delete", 0, 1);
-                return types::Function::Error;
-            }
-
-            //delete
-            if (iRhs == 2)
-            {
-                wchar_t* pEnd = NULL;
-                int iBp = (int)wcstol(((types::String*)in[1])->get(0), &pEnd, 10);
-                if (pEnd == NULL || *pEnd != 0)
-                {
-                    Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "disable", 1);
-                    return types::Function::Error;
-                }
-
-                if (manager->getBreakPoint(iBp) == NULL)
-                {
-                    Scierror(999, _("%s: Unable to retrieve information about breakpoint %d.\n"), "delete", iBp);
-                    return types::Function::Error;
-                }
-
-                manager->removeBreakPoint(iBp);
-            }
-            else
-            {
-                manager->removeAllBreakPoints();
-            }
-
-            return types::Function::OK;
-        }
-        case EnableCommand:
-        {
-            if (iRhs > 2)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "enable", 0, 1);
-                return types::Function::Error;
-            }
-
-            //enable
-            if (iRhs == 2)
-            {
-                wchar_t* pEnd = NULL;
-                int iBp = (int)wcstol(((types::String*)in[1])->get(0), &pEnd, 10);
-                if (pEnd == NULL || *pEnd != 0)
-                {
-                    Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "enable", 1);
-                    return types::Function::Error;
-                }
-
-                if (manager->getBreakPoint(iBp) == NULL)
-                {
-                    Scierror(999, _("%s: Unable to retrieve information about breakpoint %d.\n"), "enable", iBp);
-                    return types::Function::Error;
-                }
-
-                manager->enableBreakPoint(iBp);
-            }
-            else
-            {
-                manager->enableAllBreakPoints();
-            }
-
-            return types::Function::OK;
-        }
-        case HelpCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "help", 0);
-                return types::Function::Error;
-            }
-
-            if (ConfigVariable::getScilabMode() == SCILAB_NW || ConfigVariable::getScilabMode() == SCILAB_STD)
-            {
-                StorePrioritaryCommand(HELP_DEBUG_COMMAND.data());
-                return types::Function::OK;
-            }
-
-            //continue tp HelpShortCommand
-        }
-        case HelpShortCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "help", 0);
-                return types::Function::Error;
-            }
-
-            //help
-            print_help();
-            return types::Function::OK;
-        }
-        case ListCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "list", 0);
-                return types::Function::Error;
-            }
-
-            if (manager->isInterrupted())
-            {
-                std::wostringstream ostr;
-                ast::PrintVisitor pp(ostr, true, true, true);
-                manager->getExp()->accept(pp);
-                sciprint(_("%ls"), ostr.str().data());
-            }
-            else
-            {
-                sciprint("debugger is not paused\n");
-            }
-            return types::Function::OK;
-        }
-        case StepInCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "stepin", 0);
-                return types::Function::Error;
-            }
-
-            if (manager->isInterrupted())
-            {
-                manager->setStepIn();
-                manager->resume();
-            }
-            return types::Function::OK;
-        }
-        case NextCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "next", 0);
-                return types::Function::Error;
-            }
-
-            if (manager->isInterrupted())
-            {
-                manager->setStepNext();
-                manager->resume();
-            }
-            else
-            {
-                sciprint("debugger is not paused\n");
-            }
-            return types::Function::OK;
-        }
-        case StepOutCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "stepout", 0);
-                return types::Function::Error;
-            }
-
-            //need to level to go stepout
-            if (manager->isInterrupted())
-            {
-                manager->setStepOut();
-                manager->resume();
-            }
-            else
-            {
-                sciprint("debugger is not paused\n");
-            }
-            return types::Function::OK;
-        }
-        case QuitCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "quit", 0);
-                return types::Function::Error;
-            }
-
-            //quit : disable debugger + abort + quit
-            ConfigVariable::setEnableDebug(false);
-            ConfigVariable::setDefaultVisitor(new ast::ExecVisitor());
-            manager->abort();
-            manager->sendQuit();
-            return types::Function::OK;
-        }
-        case ShowCommand:
-        {
-            if (iRhs > 2)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d to %d expected.\n"), "show", 0, 1);
-                return types::Function::Error;
-            }
-
-            sciprint("% 3ls % 7ls %24ls % 5ls %ls\n\n", L"num", L"enable", L"function name", L"line", L"condition");
-
-            if (iRhs > 1)
-            {
-                wchar_t* pEnd = NULL;
-                int iBp = (int)wcstol(((types::String*)in[1])->get(0), &pEnd, 10);
-                if (pEnd == NULL || *pEnd != 0)
-                {
-                    Scierror(999, _("%s: Wrong value for input argument #%d: Scalar positive integer expected.\n"), "disable", 1);
-                    return types::Function::Error;
-                }
-
-                debugger::Breakpoint* bp = manager->getBreakPoint(iBp);
-                if (bp == NULL)
-                {
-                    Scierror(999, _("%s: Unable to retrieve information about breakpoint %d.\n"), "showbreakpoint", iBp);
-                    return types::Function::Error;
-                }
-
-                if (bp->isMacro())
-                {
-                    std::wstring condition = bp->getCondition();
-                    sciprint("% 3d % 7s %24ls % 5d %ls\n", iBp, bp->isEnable() ? "true" : "false", bp->getFunctioName().c_str(), bp->getMacroLine(),
-                             condition.size() < 30 ? condition.c_str() :
-                             (std::wstring(condition.begin(), condition.begin() + 27) + L"...").c_str());
-                }
-            }
-            else
-            {
-                debugger::Breakpoints bps = manager->getAllBreakPoint();
-                debugger::Breakpoints::iterator it = bps.begin();
-                for (int i = 0; it != bps.end(); ++it, ++i)
-                {
-                    debugger::Breakpoint* bp = *it;
-                    if (bp->isMacro())
-                    {
-                        std::wstring condition = bp->getCondition();
-                        sciprint("% 3d % 7s %24ls % 5d %ls\n", i, bp->isEnable() ? "true" : "false", bp->getFunctioName().c_str(), bp->getMacroLine(),
-                                 condition.size() < 30 ? condition.c_str() :
-                                 (std::wstring(condition.begin(), condition.begin() + 27) + L"...").c_str());
-                    }
-                }
-            }
-
-            return types::Function::OK;
-        }
-        case WhereCommand:
-        {
-            if (iRhs > 1)
-            {
-                Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "where", 0);
-                return types::Function::Error;
-            }
-
-            if (manager->isInterrupted() == false)
-            {
-                sciprint("debugger is not paused\n");
-                return types::Function::OK;
-            }
-
-            int curLine = (manager->getExp()->getLocation().first_line - ConfigVariable::getMacroFirstLines()) + 1;
-
-            //where
-            int i = 0;
-            sciprint("%s\n", _("callstack:"));
-
-            std::wostringstream ostr;
-            ast::PrintVisitor pp(ostr, true, true, true);
-            manager->getExp()->accept(pp);
-#define BT_PRINT "#%-5d%ls (line %d)\n"
-            sciprint("#%-5d%ls\n", 0, ostr.str().data());
-
-            ConfigVariable::WhereVector where = ConfigVariable::getWhere();
-            auto it1 = where.rbegin();
-            auto it2 = ++where.rbegin();
-
-            sciprint(_(BT_PRINT), 1, it2->call->getName().data(), curLine);
-            ++it1;
-            ++it2;
-            for (int j = 2; it2 != where.rend(); it1++, it2++, j++)
-            {
-                sciprint(_(BT_PRINT), j, it2->call->getName().data(), it1->m_line);
-            }
-
-            return types::Function::OK;
-        }
-
-        case UnknowCommand:
-        default :
-            break;
+        //register console debugger as debugger
+        manager->addDebugger("console", new debugger::ConsoleDebugger());
     }
 
-    sciprint("Unknown command \"%ls\".\n\n", command.c_str());
-    sciprint("use 'h' for more information\n\n");
+    ConfigVariable::setEnableDebug(true);
+    ConfigVariable::setDefaultVisitor(new ast::DebuggerVisitor());
     return types::Function::OK;
 }
-
-void print_help()
-{
-    //a,b,c,d,h,i,n,o,q,s,w
-
-    sciprint(_("debug commands : \n"));
-    sciprint("  h                            : %s.\n", _("show this help"));
-    sciprint("  help                         : %s.\n", _("open debug documentation page"));
-    sciprint("\n");
-    sciprint("  (q)uit                       : %s.\n", _("stop debugging"));
-    sciprint("  (w)here or bt                : %s.\n", _("show callstack"));
-    sciprint("\n");
-    sciprint("  (e)xec cmd                   : %s.\n", _("execute cmd"));
-    sciprint("  (r)un cmd                    : %s.\n", _("execute cmd"));
-    sciprint("\n");
-    sciprint("  (d)isp var                   : %s.\n", _("display variable"));
-    sciprint("  (p)rint var                  : %s.\n", _("display variable"));
-    sciprint("\n");
-    sciprint("  (c)ontinue                   : %s.\n", _("continue execution"));
-    sciprint("  (a)bort                      : %s.\n", _("abort execution"));
-    sciprint("  step(n)ext or next           : %s.\n", _("continue to next statement"));
-    sciprint("  step(i)n or in               : %s.\n", _("step into function"));
-    sciprint("  step(o)ut or out             : %s.\n", _("step outside function"));
-    sciprint("\n");
-    sciprint("  (b)reakpoint or break\n     func [line [\"condition\"]] : %s.\n", _("add a breakpoint"));
-    sciprint("  (del)ete                     : %s.\n", _("delete all breakpoints"));
-    sciprint("  (del)ete n                   : %s.\n", _("delete a specific breakpoint"));
-    sciprint("  enable                       : %s.\n", _("enable all breakpoints"));
-    sciprint("  enable n                     : %s.\n", _("enable a specific breakpoint"));
-    sciprint("  disable                      : %s.\n", _("disable all breakpoints"));
-    sciprint("  disable n                    : %s.\n", _("disable a specific breakpoint"));
-    sciprint("  (s)how                       : %s.\n", _("show all breakpoints"));
-    sciprint("  (s)how n                     : %s.\n", _("show a specific breakpoint"));
-    sciprint("\n");
-    sciprint(_("  for more details, show help page.\n"));
-}
-
-EnumCommand getCommand(const std::wstring& command)
-{
-    wchar_t c = command[0];
-
-    switch (c)
-    {
-        case L'a':
-        {
-            if (command.size() == 1 || command == L"abort")
-            {
-                return AbortCommand;
-            }
-            break;
-        }
-        case 'b':
-        {
-            if (command.size() == 1 || command == L"break" || command == L"breakpoint")
-            {
-                return BreakCommand;
-            }
-
-            if (command == L"bt")
-            {
-                return WhereCommand;
-            }
-            break;
-        }
-        case L'c':
-        {
-            if (command.size() == 1 || command == L"continue")
-            {
-                return ContinueCommand;
-            }
-            break;
-        }
-        case L'd':
-        {
-            if (command == L"disable")
-            {
-                return DisableCommand;
-            }
-
-            if (command == L"del" || command == L"delete")
-            {
-                return DeleteCommand;
-            }
-            break;
-        }
-        case L'e':
-        {
-            if (command == L"enable")
-            {
-                return EnableCommand;
-            }
-            break;
-        }
-        case L'h':
-        {
-            if (command.size() == 1)
-            {
-                return HelpShortCommand;
-            }
-
-            if (command == L"help")
-            {
-                return HelpCommand;
-            }
-
-            break;
-        }
-        case L'l':
-        {
-            if (command.size() == 1 || command == L"list")
-            {
-                return ListCommand;
-            }
-            break;
-        }
-        case L'i':
-        {
-            if (command.size() == 1 || command == L"in")
-            {
-                return StepInCommand;
-            }
-            break;
-        }
-        case L'n':
-        {
-            if (command.size() == 1 || command == L"next")
-            {
-                return NextCommand;
-            }
-            break;
-        }
-        case L'o':
-        {
-            if (command.size() == 1 || command == L"out")
-            {
-                return StepOutCommand;
-            }
-            break;
-        }
-        case L'q':
-        {
-            if (command.size() == 1 || command == L"quit")
-            {
-                return QuitCommand;
-            }
-            break;
-        }
-        case L's':
-        {
-            if (command.size() == 1 || command == L"show")
-            {
-                return ShowCommand;
-            }
-            if (command == L"stepnext")
-            {
-                return NextCommand;
-            }
-            if (command == L"stepin")
-            {
-                return StepInCommand;
-            }
-            if (command == L"stepout")
-            {
-                return StepOutCommand;
-            }
-            break;
-        }
-        case L'w':
-        {
-            if (command.size() == 1 || command == L"where")
-            {
-                return WhereCommand;
-            }
-            break;
-        }
-    }
-
-    return UnknowCommand;
-}
index 269f3ed..8b60291 100644 (file)
@@ -16,9 +16,7 @@
 
 #include "core_gw.hxx"
 #include "function.hxx"
-#include "threadmanagement.hxx"
 #include "configvariable.hxx"
-#include "runner.hxx"
 
 extern "C"
 {
@@ -26,6 +24,7 @@ extern "C"
 #include "localization.h"
 #include "Scierror.h"
 #include "sciprint.h"
+#include "pause.h"
 }
 
 types::Function::ReturnValue sci_pause(types::typed_list &in, int _iRetCount, types::typed_list &out)
@@ -36,36 +35,19 @@ types::Function::ReturnValue sci_pause(types::typed_list &in, int _iRetCount, ty
         return types::Function::OK;
     }
 
-
     if (in.size() != 0)
     {
         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "pause", 0);
         return types::Function::Error;
     }
 
-    ConfigVariable::IncreasePauseLevel();
-
     // add pause in list of macro called
     // to manage line displayed when error occured
     // or when the "where()" function is called.
     ConfigVariable::macroFirstLine_begin(2);
 
-    // unlock console thread to display prompt again
-    ThreadManagement::SendConsoleExecDoneSignal();
-
-    //return to console so change mode to 2
-    int iOldMode = ConfigVariable::getPromptMode();
-    ConfigVariable::setPromptMode(2);
-
-    int iPauseLevel = ConfigVariable::getPauseLevel();
-    while (ConfigVariable::getPauseLevel() == iPauseLevel)
-    {
-        ThreadManagement::SendAwakeRunnerSignal();
-        ThreadManagement::WaitForRunMeSignal();
-        StaticRunner_launch();
-    }
+    // do pause
+    pause();
 
-    //return from console so change mode to initial
-    ConfigVariable::setPromptMode(iOldMode);
     return types::Function::OK;
 }
index 3273855..86eb6d9 100644 (file)
@@ -248,6 +248,8 @@ cd ..
     <ClCompile Include="..\cpp\getmacrosname.cpp" />
     <ClCompile Include="..\cpp\getvariablesname.cpp" />
     <ClCompile Include="..\cpp\InitScilab.cpp" />
+    <ClCompile Include="..\cpp\parsecommand.cpp" />
+    <ClCompile Include="..\cpp\pause.cpp" />
     <ClCompile Include="..\cpp\runner.cpp" />
     <ClCompile Include="..\cpp\setformat.cpp" />
     <ClCompile Include="..\cpp\setlines.cpp" />
@@ -336,6 +338,8 @@ cd ..
     <ClInclude Include="..\..\includes\loadversion.h" />
     <ClInclude Include="..\..\includes\machine.h" />
     <ClInclude Include="..\..\includes\md5.h" />
+    <ClInclude Include="..\..\includes\parsecommand.h" />
+    <ClInclude Include="..\..\includes\pause.h" />
     <ClInclude Include="..\..\includes\sci_malloc.h" />
     <ClInclude Include="..\..\includes\PARAMS.h" />
     <ClInclude Include="..\..\includes\PATH_MAX.h" />
index 8dc8f71..e6e7577 100644 (file)
     <ClCompile Include="..\cpp\setlines.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\cpp\parsecommand.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\cpp\pause.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\core.iss" />
     <ClInclude Include="..\..\includes\md5.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\includes\pause.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\includes\parsecommand.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\core.iss" />
index 7bec998..ee8001b 100644 (file)
@@ -36,6 +36,7 @@
 #include "numericconstants.hxx"
 #include "expandPathVariable.h"
 #include "execvisitor.hxx"
+#include "printvisitor.hxx"
 #include "debugmanager.hxx"
 #include "consoledebugger.hxx"
 
@@ -120,6 +121,10 @@ static int interactiveMain(ScilabEngineInfo* _pSEI);
 static void processCommand(ScilabEngineInfo* _pSEI);
 static void stateShow(Parser::ControlStatus status);
 
+static void executeDebuggerCommand(std::string cmd);
+static void splitOnSpaces(const std::string& command, std::vector<std::string>& vCommand, std::vector<size_t>& vPos);
+static void printDebuggerHelp();
+
 using namespace ast;
 
 ScilabEngineInfo* InitScilabEngineInfo()
@@ -419,13 +424,8 @@ int StartScilabEngine(ScilabEngineInfo* _pSEI)
     }
 
     ConfigVariable::setPromptMode(2);
-
     InitializePreferences(iScript);
 
-
-    //register console debugger as debugger
-    debugger::DebuggerMagager::getInstance()->addDebugger(new debugger::ConsoleDebugger());
-
     return iMainRet;
 }
 
@@ -779,87 +779,10 @@ void* scilabReadAndStore(void* param)
 
             if (ConfigVariable::getEnableDebug())
             {
-                bool disableDebug = false;
-                char* tmpCommand = NULL;
-                int commandsize = static_cast<int>(strlen(command));
-
-                //all commands must be prefixed by debug except e(xec) (r)un or p(rint) "something" that become "something" or disp("something")
-                if (strncmp(command, "e ", 2) == 0 || strncmp(command, "r ", 2) == 0)
-                {
-                    tmpCommand = os_strdup(command + 2);
-                }
-                else if (commandsize >= 5 && strncmp(command, "exec ", 5) == 0)
-                {
-                    tmpCommand = os_strdup(command + 5);
-                }
-                else if (commandsize >= 4 && strncmp(command, "run ", 4) == 0)
-                {
-                    tmpCommand = os_strdup(command + 5);
-                }
-
-                if (tmpCommand)
-                {
-                    if (debugger::DebuggerMagager::getInstance()->isInterrupted())
-                    {
-                        sciprint(_("Debugger is on a breakpoint\n"));
-                        sciprint(_("(c)ontinue or (a)bort current execution before execute a new command\n"));
-                        FREE(tmpCommand);
-                        continue;
-                    }
-                }
-                else if (commandsize > 1 && command[0] == 'd' && command[1] == ' ')
-                {
-                    std::string s("disp(");
-                    s += command + 2;
-                    s += ")";
-                    tmpCommand = os_strdup(s.data());
-                    disableDebug = true;
-                }
-                else if (commandsize > 5 && strncmp(command, "disp ", 5) == 0)
-                {
-                    std::string s("disp(");
-                    s += command + 5;
-                    s += ")";
-                    tmpCommand = os_strdup(s.data());
-                    disableDebug = true;
-                }
-                else if (commandsize > 1 && command[0] == 'p' && command[1] == ' ')
-                {
-                    std::string s("disp(");
-                    s += command + 2;
-                    s += ")";
-                    tmpCommand = os_strdup(s.data());
-                    disableDebug = true;
-                }
-                else if (commandsize > 6 && strncmp(command, "print ", 6) == 0)
-                {
-                    std::string s("disp(");
-                    s += command + 6;
-                    s += ")";
-                    tmpCommand = os_strdup(s.data());
-                    disableDebug = true;
-                }
-                else
-                {
-                    int iLen = (int)strlen(command) + (int)strlen("debug ") + 1;
-                    tmpCommand = (char*)MALLOC(sizeof(char) * iLen);
-#ifdef _MSC_VER
-                    os_sprintf(tmpCommand, iLen, "%s %s", "debug", command);
-#else
-                    os_sprintf(tmpCommand, "%s %s", "debug", command);
-#endif
-                    disableDebug = true;
-                }
-
-                if (disableDebug)
-                {
-                    //disable debugger time to exec debug command
-                    //it will be enable in debuggervisitor, after execution
-                    ConfigVariable::setEnableDebug(false);
-                }
-
+                executeDebuggerCommand(command);
                 FREE(command);
-                command = tmpCommand;
+                command = NULL;
+                continue;
             }
 
             ThreadManagement::LockParser();
@@ -1221,3 +1144,438 @@ static void Add_String_Constant(const std::wstring& _szName, const char *_pstStr
     types::String * ps = new types::String(_pstString);
     symbol::Context::getInstance()->put(symbol::Symbol(_szName), ps);
 }
+
+// manage debugger commands
+static void executeDebuggerCommand(std::string _command)
+{
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
+    std::vector<std::string> vCommand;
+    std::vector<size_t> vPos;
+    splitOnSpaces(_command, vCommand, vPos);
+
+    std::string cmd = vCommand[0];
+    int iSize = vCommand.size();
+
+    // check prefix
+    if (cmd.compare("e")    == 0 ||
+        cmd.compare("exec") == 0 ||
+        cmd.compare("r")    == 0 ||
+        cmd.compare("run")  == 0)
+    {
+        if (manager->isInterrupted())
+        {
+            // try to execute a command when execution is stopped on a breakpoint
+            sciprint(_("Debugger is on a breakpoint\n"));
+            sciprint(_("(c)ontinue or (a)bort current execution before execute a new command\n"));
+            vCommand.clear();
+            return;
+        }
+
+        if(iSize == 1)
+        {
+            sciprint(_("%s: Command missing.\n"), "run");
+            sciprint("use 'h' for more information\n\n");
+            vCommand.clear();
+            return;
+        }
+
+        // execute a command
+        char* error = manager->execute(_command.erase(0, _command.find(" ")).data());
+        if(error)
+        {
+            sciprint("Debugger execution failed\n\n%s\n", error);
+            vCommand.clear();
+            return;
+        }
+    }
+    else if(cmd.compare("d")     == 0 ||
+            cmd.compare("disp")  == 0 ||
+            cmd.compare("p")     == 0 ||
+            cmd.compare("print") == 0)
+    {
+        if(iSize < 2)
+        {
+            sciprint(_("%s: Wrong number of input arguments: %d expected.\n"), "print", 2);
+            sciprint("use 'h' for more information\n\n");
+            vCommand.clear();
+            return;
+        }
+
+        manager->print(vCommand[1]);
+    }
+    else if(cmd.compare("a")      == 0 ||
+            cmd.compare("abort")  == 0)
+    {
+        manager->abort();
+    }
+    else if(cmd.compare("c")         == 0 ||
+            cmd.compare("continue")  == 0 ||
+            cmd.compare("resume")    == 0)
+    {
+        if (manager->isInterrupted() == false)
+        {
+            // cannot execute this comment if the execution is not stopped
+            sciprint("debugger is not on a breakpoint\n");
+            vCommand.clear();
+            return;
+        }
+
+        manager->resume();
+    }
+    else if(cmd.compare("b")           == 0 ||
+            cmd.compare("break")       == 0 ||
+            cmd.compare("breakpoint")  == 0)
+    {
+        if(iSize < 2)
+        {
+            sciprint(_("%s: Wrong number of input arguments: %d to %d expected.\n"), "breakpoint", 1, 3);
+            sciprint("use 'h' for more information\n\n");
+            vCommand.clear();
+            return;
+        }
+
+        debugger::Breakpoint* bp = new debugger::Breakpoint();
+
+        // set file or function name
+        bool isFile = vCommand[1].find_first_of("\\./") != std::string::npos;
+        isFile ? bp->setFileName(vCommand[1]) : bp->setFunctionName(vCommand[1]);
+
+        // set file or function line
+        if(iSize > 2)
+        {
+            try
+            {
+                int iFileFuncLine = std::stoi(vCommand[2].data());
+                isFile ? bp->setFileLine(iFileFuncLine) : bp->setMacroLine(iFileFuncLine);
+            }
+            catch(std::invalid_argument e) // std::stoi
+            {
+                sciprint(_("%s: Wrong type for input argument #%d: Integer expected.\n"), "breakpoint", 2);
+                sciprint("use 'h' for more information\n\n");
+                vCommand.clear();
+                return;
+            }
+        }
+
+        // set condition
+        if(iSize > 3)
+        {
+            char* error = bp->setCondition(_command.substr(vPos[3], _command.length() - vPos[3]));
+            if(error)
+            {
+                delete bp;
+                bp = nullptr;
+                sciprint("parsing condition failed\n\n%s\n", error);
+                FREE(error);
+                vCommand.clear();
+                return;
+            }
+        }
+
+        manager->addBreakPoint(bp);
+    }
+    else if(cmd.compare("w")     == 0 ||
+            cmd.compare("bt")    == 0 ||
+            cmd.compare("where") == 0)
+    {
+        if (manager->isInterrupted() == false)
+        {
+            // cannot execute this comment if the execution is not stopped
+            sciprint("debugger is not on a breakpoint\n");
+            vCommand.clear();
+            return;
+        }
+
+        sciprint("%s\n", _("callstack:"));
+        debugger::DebuggerManager::CallStack callstack = manager->getCallStack();
+        int i = 0;
+        sciprint("#%-5d%s\n", i++, callstack.exp.data());
+        for (auto row : callstack.stack)
+        {
+            if(row.functionLine < 0)
+            {
+                sciprint(_("#%-5d%s"), i++, row.functionName.data());
+            }
+            else
+            {
+                sciprint(_("#%-5d%s (line %d)"), i++, row.functionName.data(), row.functionLine);
+            }
+
+            if(row.hasFile)
+            {
+                sciprint("  %s:%d", row.fileName.data(), row.fileLine);
+            }
+
+            sciprint("\n");
+        }
+    }
+    else if(cmd.compare("disable") == 0)
+    {
+        if(iSize == 1)
+        {
+            manager->disableAllBreakPoints();
+        }
+        else
+        {
+            try
+            {
+                int bp = std::stoi(vCommand[1].data());
+                if (manager->getBreakPoint(bp) == NULL)
+                {
+                    sciprint(_("%s: Unable to retrieve information about breakpoint %d.\n"), "disable", bp);
+                    sciprint("use 'h' for more information\n\n");
+                    vCommand.clear();
+                    return;
+                }
+                manager->disableBreakPoint(bp);
+            }
+            catch(std::invalid_argument e) // std::stoi
+            {
+                sciprint(_("%s: Wrong type for input argument #%d: Integer expected.\n"), "disable", 1);
+                sciprint("use 'h' for more information\n\n");
+                vCommand.clear();
+                return;
+            }
+        }
+    }
+    else if(cmd.compare("enable") == 0)
+    {
+        if(iSize == 1)
+        {
+            manager->enableAllBreakPoints();
+        }
+        else
+        {
+            try
+            {
+                int bp = std::stoi(vCommand[1].data());
+                if (manager->getBreakPoint(bp) == NULL)
+                {
+                    sciprint(_("%s: Unable to retrieve information about breakpoint %d.\n"), "enable", bp);
+                    sciprint("use 'h' for more information\n\n");
+                    vCommand.clear();
+                    return;
+                }
+                manager->enableBreakPoint(bp);
+            }
+            catch(std::invalid_argument e) // std::stoi
+            {
+                sciprint(_("%s: Wrong type for input argument #%d: Integer expected.\n"), "enable", 1);
+                sciprint("use 'h' for more information\n\n");
+                vCommand.clear();
+                return;
+            }
+        }
+    }
+    else if(cmd.compare("del")   == 0 ||
+            cmd.compare("delete") == 0)
+    {
+        if(iSize == 1)
+        {
+            manager->removeAllBreakPoints();
+        }
+        else
+        {
+            try
+            {
+                int bp = std::stoi(vCommand[1].data());
+                if (manager->getBreakPoint(bp) == NULL)
+                {
+                    sciprint(_("%s: Unable to retrieve information about breakpoint %d.\n"), "delete", bp);
+                    sciprint("use 'h' for more information\n\n");
+                    vCommand.clear();
+                    return;
+                }
+                manager->removeBreakPoint(bp);
+            }
+            catch(std::invalid_argument e) // std::stoi
+            {
+                sciprint(_("%s: Wrong type for input argument #%d: Integer expected.\n"), "delete", 1);
+                sciprint("use 'h' for more information\n\n");
+                vCommand.clear();
+                return;
+            }
+        }
+    }
+    else if(cmd.compare("h")     == 0 ||
+            cmd.compare("help")  == 0)
+    {
+        if(cmd.compare("help") == 0 &&
+          (ConfigVariable::getScilabMode() == SCILAB_NW || ConfigVariable::getScilabMode() == SCILAB_STD))
+        {
+            StorePrioritaryCommand("help debug");
+            vCommand.clear();
+            return;
+        }
+
+        printDebuggerHelp();
+    }
+    else if(cmd.compare("l")     == 0 ||
+            cmd.compare("list")  == 0)
+    {
+        if (manager->isInterrupted() == false)
+        {
+            // cannot execute this comment if the execution is not stopped
+            sciprint("debugger is not on a breakpoint\n");
+            vCommand.clear();
+            return;
+        }
+
+        std::wostringstream ostr;
+        ast::PrintVisitor pp(ostr, true, true, true);
+        manager->getExp()->accept(pp);
+        sciprint(_("%ls"), ostr.str().data());
+    }
+    else if(cmd.compare("i")      == 0 ||
+            cmd.compare("in")     == 0 ||
+            cmd.compare("stepin") == 0)
+    {
+        if (manager->isInterrupted() == false)
+        {
+            // cannot execute this comment if the execution is not stopped
+            sciprint("debugger is not on a breakpoint\n");
+            vCommand.clear();
+            return;
+        }
+
+        manager->setStepIn();
+        manager->resume();
+    }
+    else if(cmd.compare("o")         == 0 ||
+            cmd.compare("out")       == 0 ||
+            cmd.compare("stepout")   == 0)
+    {
+        if (manager->isInterrupted() == false)
+        {
+            // cannot execute this comment if the execution is not stopped
+            sciprint("debugger is not on a breakpoint\n");
+            vCommand.clear();
+            return;
+        }
+
+        manager->setStepOut();
+        manager->resume();
+    }
+    else if(cmd.compare("n")         == 0 ||
+            cmd.compare("next")      == 0 ||
+            cmd.compare("stepnext")  == 0)
+    {
+        if (manager->isInterrupted() == false)
+        {
+            // cannot execute this comment if the execution is not stopped
+            sciprint("debugger is not on a breakpoint\n");
+            vCommand.clear();
+            return;
+        }
+
+        manager->setStepNext();
+        manager->resume();
+    }
+    else if(cmd.compare("q")     == 0 ||
+            cmd.compare("exit")  == 0 ||
+            cmd.compare("quit")  == 0)
+    {
+        // quit debugger
+        manager->sendQuit();
+        ConfigVariable::setEnableDebug(false);
+        ConfigVariable::setDefaultVisitor(new ast::ExecVisitor());
+        StoreConsoleCommand("abort", 1);
+        manager->removeDebugger("console");
+    }
+    else if(cmd.compare("s")     == 0 ||
+            cmd.compare("show")  == 0)
+    {
+        if(iSize == 1)
+        {
+            manager->show(-1);
+        }
+        else
+        {
+            try
+            {
+                int bp = std::stoi(vCommand[1].data());
+                if (manager->getBreakPoint(bp) == NULL)
+                {
+                    sciprint(_("%s: Unable to retrieve information about breakpoint %d.\n"), "show", bp);
+                    sciprint("use 'h' for more information\n\n");
+                    vCommand.clear();
+                    return;
+                }
+                manager->show(bp);
+            }
+            catch(std::invalid_argument e) // std::stoi
+            {
+                sciprint(_("%s: Wrong type for input argument #%d: Integer expected.\n"), "show", 1);
+                sciprint("use 'h' for more information\n\n");
+                vCommand.clear();
+                return;
+            }
+        }
+    }
+    else
+    {
+        // not a debugger command
+        sciprint("Unknown command \"%s\".\n\n", _command.data());
+        sciprint("use 'h' for more information\n\n");
+    }
+
+    vCommand.clear();
+}
+
+static void splitOnSpaces(const std::string& command, std::vector<std::string>& vCommand, std::vector<size_t>& vPos)
+{
+    size_t pos = command.find(' ');
+    size_t lastPos = 0;
+
+    while(pos != std::string::npos)
+    {
+        if(pos - lastPos)
+        {
+            vCommand.push_back(command.substr(lastPos, pos - lastPos));
+            vPos.push_back(lastPos);
+        }
+
+        lastPos = pos + 1;
+        pos = command.find(' ', lastPos);
+    }
+
+    if(lastPos != command.length())
+    {
+        vCommand.push_back(command.substr(lastPos, std::min(pos, command.size()) - lastPos + 1 ) );
+        vPos.push_back(lastPos);
+    }
+}
+
+static void printDebuggerHelp()
+{
+    sciprint(_("debug commands : \n"));
+    sciprint("  h                            : %s.\n", _("show this help"));
+    sciprint("  help                         : %s.\n", _("open debug documentation page"));
+    sciprint("\n");
+    sciprint("  (q)uit                       : %s.\n", _("stop debugging"));
+    sciprint("  (w)here or bt                : %s.\n", _("show callstack"));
+    sciprint("\n");
+    sciprint("  (e)xec cmd                   : %s.\n", _("execute cmd"));
+    sciprint("  (r)un cmd                    : %s.\n", _("execute cmd"));
+    sciprint("\n");
+    sciprint("  (d)isp var                   : %s.\n", _("display variable"));
+    sciprint("  (p)rint var                  : %s.\n", _("display variable"));
+    sciprint("\n");
+    sciprint("  (c)ontinue                   : %s.\n", _("continue execution"));
+    sciprint("  (a)bort                      : %s.\n", _("abort execution"));
+    sciprint("  step(n)ext or next           : %s.\n", _("continue to next statement"));
+    sciprint("  step(i)n or in               : %s.\n", _("step into function"));
+    sciprint("  step(o)ut or out             : %s.\n", _("step outside function"));
+    sciprint("\n");
+    sciprint("  (b)reakpoint or break\n     func [line [\"condition\"]] : %s.\n", _("add a breakpoint"));
+    sciprint("  (del)ete                     : %s.\n", _("delete all breakpoints"));
+    sciprint("  (del)ete n                   : %s.\n", _("delete a specific breakpoint"));
+    sciprint("  enable                       : %s.\n", _("enable all breakpoints"));
+    sciprint("  enable n                     : %s.\n", _("enable a specific breakpoint"));
+    sciprint("  disable                      : %s.\n", _("disable all breakpoints"));
+    sciprint("  disable n                    : %s.\n", _("disable a specific breakpoint"));
+    sciprint("  (s)how                       : %s.\n", _("show all breakpoints"));
+    sciprint("  (s)how n                     : %s.\n", _("show a specific breakpoint"));
+    sciprint("\n");
+    sciprint(_("  for more details, show help page.\n"));
+}
diff --git a/scilab/modules/core/src/cpp/parsecommand.cpp b/scilab/modules/core/src/cpp/parsecommand.cpp
new file mode 100644 (file)
index 0000000..f1618bd
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2019-2019 - ESI Group - Cedric Delamarre
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#include "threadmanagement.hxx"
+#include "parser.hxx"
+
+extern "C"
+{
+#include "parsecommand.h"
+}
+
+static char* doParseCommand(const std::string& command, ast::Exp** tree, bool bDeleteTree)
+{
+    *tree = nullptr;
+    ThreadManagement::LockParser();
+    Parser parse;
+    parse.parse(command.data());
+    if (parse.getExitStatus() != Parser::Succeded)
+    {
+        char* msg = wide_string_to_UTF8(parse.getErrorMessage());
+        ThreadManagement::UnlockParser();
+        return msg;
+    }
+    ThreadManagement::UnlockParser();
+    *tree = parse.getTree();
+    if(bDeleteTree && *tree)
+    {
+        delete *tree;
+        parse.setTree(nullptr);
+    }
+
+    return nullptr;
+}
+
+char* parseCommand(const char* command, void** tree)
+{
+    return doParseCommand(command, (ast::Exp**)tree, false);
+}
+
+char* checkCommand(const char* command)
+{
+    ast::Exp* pExp = nullptr;
+    return doParseCommand(command, &pExp, true);
+}
+
+static wchar_t* doParseFileW(const std::wstring& file, const std::wstring& program, ast::Exp** tree, bool bDeleteTree)
+{
+    *tree = nullptr;
+    ThreadManagement::LockParser();
+    Parser parse;
+    parse.parseFile(file.data(), program.data());
+    if (parse.getExitStatus() != Parser::Succeded)
+    {
+        wchar_t* msg = os_wcsdup(parse.getErrorMessage());
+        ThreadManagement::UnlockParser();
+        return msg;
+    }
+    ThreadManagement::UnlockParser();
+    *tree = parse.getTree();
+    if(bDeleteTree && tree)
+    {
+        delete *tree;
+        parse.setTree(nullptr);
+    }
+
+    return nullptr;
+}
+
+static char* doParseFile(const std::string& file, const std::string& program, ast::Exp** tree, bool bDeleteTree)
+{
+    char* pcError = nullptr;
+    wchar_t* wcsFile = to_wide_string(file.data());
+    wchar_t* wcsProgram = to_wide_string(program.data());
+    wchar_t* wcsError = doParseFileW(wcsFile, wcsProgram, tree, bDeleteTree);
+    FREE(wcsFile);
+    FREE(wcsProgram);
+    if (wcsError)
+    {
+        pcError = wide_string_to_UTF8(wcsError);
+        FREE(wcsError);
+    }
+
+    return pcError;
+}
+
+char* parseFile(const char* file, const char* program, void** tree)
+{
+    return doParseFile(file, program, (ast::Exp**)tree, false);
+}
+
+char* checkFile(const char* file, const char* program)
+{
+    ast::Exp* pExp = nullptr;
+    return doParseFile(file, program, &pExp, true);
+}
diff --git a/scilab/modules/core/src/cpp/pause.cpp b/scilab/modules/core/src/cpp/pause.cpp
new file mode 100644 (file)
index 0000000..3c2df7e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2019-2019 - ESI Group - Cedric Delamarre
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#include "configvariable.hxx"
+#include "threadmanagement.hxx"
+#include "runner.hxx"
+
+extern "C" {
+#include "pause.h"
+}
+
+void pause(void)
+{
+    ConfigVariable::IncreasePauseLevel();
+
+    //return to console so change mode to 2
+    int iOldMode = ConfigVariable::getPromptMode();
+    ConfigVariable::setPromptMode(2);
+
+    // save current runner
+    Runner* rCurrent = StaticRunner::getCurrentRunner();
+
+    // send the good signal to unlock wait
+    // ie: unlock console thread to display prompt again
+    StaticRunner::sendExecDoneSignal();
+
+    int iPauseLevel = ConfigVariable::getPauseLevel();
+    while (ConfigVariable::getPauseLevel() == iPauseLevel)
+    {
+        ThreadManagement::SendAwakeRunnerSignal();
+        ThreadManagement::WaitForRunMeSignal();
+        if(StaticRunner::isRunnerAvailable())
+        {
+            StaticRunner::launch();
+        }
+    }
+
+    // set back the runner to know wich "execution done" signal send
+    // StaticRunner::sendExecDoneSignal
+    StaticRunner::setCurrentRunner(rCurrent);
+
+    //return from console so change mode to initial
+    ConfigVariable::setPromptMode(iOldMode);
+}
\ No newline at end of file
index cd0687d..7d0d728 100644 (file)
@@ -30,19 +30,25 @@ extern "C"
 }
 
 std::atomic<Runner*> StaticRunner::m_RunMe(nullptr);
+std::atomic<Runner*> StaticRunner::m_CurrentRunner(nullptr);
 std::atomic<bool> StaticRunner::m_bInterruptibleCommand(true);
 
 static bool initialJavaHooks = false;
 
-static void sendExecDoneSignal(Runner* _pRunner)
+void StaticRunner::sendExecDoneSignal()
 {
-    switch (_pRunner->getCommandOrigin())
+    switch (getCurrentRunner()->getCommandOrigin())
     {
         case CONSOLE :
         {
             ThreadManagement::SendConsoleExecDoneSignal();
             break;
         }
+        case DEBUGGER :
+        {
+            ThreadManagement::SendDebuggerExecDoneSignal();
+            break;
+        }
         case TCLSCI :
         case NONE :
         default :
@@ -63,9 +69,9 @@ int StaticRunner::launch()
     int iRet = 0;
     // get the runner to execute
     std::unique_ptr<Runner> runMe(getRunner());
-    // set if the current comment is interruptible
+    // set if the current command is interruptible
     setInterruptibleCommand(runMe->isInterruptible());
-    debugger::DebuggerMagager* manager = debugger::DebuggerMagager::getInstance();
+    debugger::DebuggerManager* manager = debugger::DebuggerManager::getInstance();
 
     ConfigVariable::resetExecutionBreak();
 
@@ -155,10 +161,10 @@ int StaticRunner::launch()
         }
 
         // send the good signal about the end of execution
-        sendExecDoneSignal(runMe.get());
+        sendExecDoneSignal();
 
-        //clean debugger step flag if debugger is not interrupted ( end of debug )
-        manager->resetStep();
+        // debugger leave with abort state
+        manager->setAborted();
         throw ia;
     }
 
@@ -186,7 +192,7 @@ int StaticRunner::launch()
     ConfigVariable::resetError();
 
     // send the good signal about the end of execution
-    sendExecDoneSignal(runMe.get());
+    sendExecDoneSignal();
 
     //clean debugger step flag if debugger is not interrupted ( end of debug )
     manager->resetStep();
@@ -198,13 +204,24 @@ void StaticRunner::setRunner(Runner* _RunMe)
     m_RunMe = _RunMe;
 }
 
+void StaticRunner::setCurrentRunner(Runner* _RunMe)
+{
+    m_CurrentRunner = _RunMe;
+}
+
 Runner* StaticRunner::getRunner(void)
 {
     Runner* tmp = m_RunMe.exchange(nullptr);
+    setCurrentRunner(tmp);
     ThreadManagement::SendAvailableRunnerSignal();
     return tmp;
 }
 
+Runner* StaticRunner::getCurrentRunner(void)
+{
+    return m_CurrentRunner;
+}
+
 // return true if a Runner is already set in m_RunMe.
 bool StaticRunner::isRunnerAvailable(void)
 {
index f70bef8..8644208 100644 (file)
@@ -116,6 +116,27 @@ int StoreConsoleCommand(const char *command, int iWaitFor)
     return 0;
 }
 
+int StoreDebuggerCommand(const char *command)
+{
+    ThreadManagement::LockStoreCommand();
+    commandQueuePrioritary.emplace_back(os_strdup(command),
+                                        /*is prioritary*/ 1,
+                                        /* is interruptible*/ 1,
+                                        /* cmd origin */ DEBUGGER);
+
+    // Awake Scilab to execute a new command
+    ThreadManagement::SendCommandStoredSignal();
+    // Awake Runner to execute this prioritary command
+    ThreadManagement::SendAwakeRunnerSignal();
+
+    // make this wait before unlock the Store Command will prevent
+    // dead lock in case where another thread get this command
+    // and execute it before this thread is waiting for.
+    ThreadManagement::WaitForDebuggerExecDoneSignal(false);
+
+    return 0;
+}
+
 int StorePrioritaryCommand(const char *command)
 {
     ThreadManagement::LockStoreCommand();
index 0f24ac9..99027b1 100644 (file)
@@ -300,21 +300,3 @@ int execScilabQuitTask(bool _bSerialize)
 
     return StaticRunner::exec(newTree, new ast::ExecVisitor()) ? 0 : 1;
 }
-
-
-ast::Exp* parseCommand(std::wstring _command)
-{
-    if (_command.empty())
-    {
-        return NULL;
-    }
-
-    Parser parse;
-    parse.parse((wchar_t*)_command.c_str());
-    if (parse.getExitStatus() != Parser::Succeded)
-    {
-        return NULL;
-    }
-
-    return parse.getTree();
-}
index c8c3835..da7c950 100644 (file)
@@ -78,7 +78,7 @@ types::Callable::ReturnValue sci_mprintf(types::typed_list &in, int _iRetCount,
 
         scilabForcedWriteW(pwstOutput[i]);
 
-        fflush(NULL);
+        // fflush(NULL);
         FREE(pwstOutput[i]);
     }