debugger: deadlock in the java EDT due to the debug mode fixed
[scilab.git] / scilab / modules / ast / includes / ast / debugmanager.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #ifndef __DEBUGGER_MANAGER_HXX__
17 #define __DEBUGGER_MANAGER_HXX__
18
19 #include <memory>
20
21 #include "abstractdebugger.hxx"
22 #include "configvariable.hxx"
23 #include "breakpoint.hxx"
24 #include "dynlib_ast.h"
25
26 namespace debugger
27 {
28 class EXTERN_AST DebuggerManager
29 {
30 public:
31     enum DebugAction
32     {
33         Continue,
34         Aborted,
35         StepNext,
36         StepIn,
37         StepOut
38     };
39
40     struct StackRow
41     {
42         std::string functionName;
43         std::string fileName;
44         int functionLine;
45         int fileLine;
46         int scope;
47         bool hasFile = false;
48     };
49
50     typedef std::vector<StackRow> Stack;
51     struct CallStack
52     {
53         std::string exp;
54         Stack stack;
55     };
56
57 private:
58     static std::unique_ptr<DebuggerManager> me;
59     DebuggerManager() :
60         breakpoints(),
61         debuggers(),
62         callstack(), pExp(nullptr), interrupted(false), currentBreakPoint(-1), action(Continue), level(0) {}
63
64     Breakpoints breakpoints;
65     CallStack callstack;
66     Debuggers debuggers;
67
68     ast::Exp* pExp;
69     bool interrupted;
70     bool request_pause;
71     int currentBreakPoint;
72     DebugAction action;
73     int level;
74
75     void internal_stop();
76     bool callstackAddFile(StackRow* _row, const std::wstring& _fileName);
77
78 public:
79     ~DebuggerManager()
80     {
81         for (auto d : debuggers)
82         {
83             delete d.second;
84         }
85
86         for (auto b : breakpoints)
87         {
88             delete b;
89         }
90
91         clearCallStack();
92     }
93
94     static DebuggerManager* getInstance();
95
96     //debuggers functions
97     void addDebugger(const std::string& _name, AbstractDebugger* _debug);
98     void removeDebugger(const std::string& _name);
99     AbstractDebugger* getDebugger(const std::string& _name);
100     int getDebuggerCount();
101     Debuggers& getAllDebugger();
102
103     void setExp(const ast::Exp* _pExp)
104     {
105         pExp = const_cast<ast::Exp*>(_pExp);
106     }
107     void clearExp()
108     {
109         pExp = NULL;
110     }
111     ast::Exp* getExp()
112     {
113         return pExp;
114     }
115
116     bool isInterrupted()
117     {
118         return interrupted;
119     }
120
121     Breakpoint* getCurrentBreakPoint()
122     {
123         if (currentBreakPoint != -1)
124         {
125             return getBreakPoint(currentBreakPoint);
126         }
127
128         return nullptr;
129     }
130
131     void generateCallStack();
132     inline void clearCallStack()
133     {
134         callstack.exp.clear();
135         callstack.stack.clear();
136     }
137
138     CallStack& getCallStack()
139     {
140         return callstack;
141     }
142
143     //send information to debuggers
144     void sendStop(int index);
145     void sendExecution();
146     void sendExecutionReleased();
147     void sendPrint(const std::string& variable);
148     void sendShow(int bp);
149     void sendResume();
150     void sendAbort();
151     void sendErrorInFile(const std::wstring& filename) const;
152     void sendErrorInScript(const std::wstring& funcname) const;
153     void sendQuit();
154     void sendUpdate() const;
155
156     void stop(const ast::Exp* pExp, int index);
157     void errorInFile(const std::wstring filename, const ast::Exp* pExp);
158     void errorInScript(const std::wstring funcname, const ast::Exp* pExp);
159
160     //breakpoints functions
161     bool addBreakPoint(Breakpoint* bp);
162     bool updateBreakPoint(Breakpoint* bp);
163     bool removeBreakPoint(Breakpoint* bp);
164     Breakpoints::iterator findBreakPoint(Breakpoint* bp);
165     void removeBreakPoint(int _iBreakPoint);
166     void setAllBreakPoints(Breakpoints& _bps);
167     void removeAllBreakPoints();
168     void disableAllBreakPoints();
169     void disableBreakPoint(int _iBreakPoint);
170     void enableAllBreakPoints();
171     void enableBreakPoint(int _iBreakPoint);
172     bool isEnableBreakPoint(int _iBreakPoint);
173     Breakpoint* getBreakPoint(int _iBreakPoint);
174     int getBreakPointCount();
175     Breakpoints& getAllBreakPoint();
176
177     //actions called by debuggers
178     inline void setStepIn() //enter macro
179     {
180         action = StepIn;
181         level = symbol::Context::getInstance()->getScopeLevel();
182     }
183
184     inline bool isStepIn()
185     {
186         int l = symbol::Context::getInstance()->getScopeLevel();
187         //if stepIn failed ( not a macro ), stepIn become a stepNext
188         if(action != StepIn)
189         {
190             return false;
191         }
192
193         if(l < level)
194         {
195             action = StepNext;
196             return false;
197         }
198
199         return true;
200     }
201
202     inline void resetStepIn()
203     {
204         if (isStepIn())
205         {
206             action = Continue;
207         }
208     }
209
210     inline void setStepOut() //exit macro
211     {
212         action = StepOut;
213         level = ConfigVariable::getWhere().size();
214     }
215
216     inline bool isStepOut()
217     {
218         int l = ConfigVariable::getWhere().size();
219         return action == StepOut && l < level;
220     }
221
222     inline void resetStepOut()
223     {
224         if (isStepOut())
225         {
226             action = Continue;
227         }
228     }
229
230     inline void setAborted() //next statement
231     {
232         action = Aborted;
233     }
234
235     inline bool isAborted()
236     {
237         return action == Aborted;
238     }
239
240     inline void resetAborted()
241     {
242         if (isAborted())
243         {
244             action = Continue;
245         }
246     }
247
248     inline void setStepNext() //next statement
249     {
250         action = StepNext;
251         level = symbol::Context::getInstance()->getScopeLevel();
252     }
253
254     inline bool isStepNext()
255     {
256         int l = symbol::Context::getInstance()->getScopeLevel();
257         //if stepNext failed ( end of macro ), stepNext become a stepOut
258         return action == StepNext && l <= level;
259     }
260
261     inline void resetStepNext()
262     {
263         if (isStepNext())
264         {
265             action = Continue;
266         }
267     }
268
269     inline void resetStep()
270     {
271         if (isInterrupted() == false)
272         {
273             action = Continue;
274         }
275     }
276
277     char* execute(const std::string& command, int iWaitForIt = 1); //execute a command
278     void print(const std::string& variable); //print a variable
279     void show(int bp); //print the breakpoint bp or all breakpoints (bp = -1)
280     void resume(); //resume execution
281     void abort(); //abort execution
282     void requestPause(); //pause execution
283     bool isPauseRequested(); //get pause request status
284     void resetPauseRequest(); //reset pause request status
285 };
286
287 }
288 #endif /* !__DEBUGGER_MANAGER_HXX__ */