d2b5300cb1dcdacb8c9af1f0be3cb468515eef53
[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_execution_released();
76     void internal_stop();
77     bool callstackAddFile(StackRow* _row, const std::wstring& _fileName);
78
79 public:
80     ~DebuggerManager()
81     {
82         for (auto d : debuggers)
83         {
84             delete d.second;
85         }
86
87         for (auto b : breakpoints)
88         {
89             delete b;
90         }
91
92         clearCallStack();
93     }
94
95     static DebuggerManager* getInstance();
96
97     //debuggers functions
98     void addDebugger(const std::string& _name, AbstractDebugger* _debug);
99     void removeDebugger(const std::string& _name);
100     AbstractDebugger* getDebugger(const std::string& _name);
101     int getDebuggerCount();
102     Debuggers& getAllDebugger();
103
104     void setExp(const ast::Exp* _pExp)
105     {
106         pExp = const_cast<ast::Exp*>(_pExp);
107     }
108     void clearExp()
109     {
110         pExp = NULL;
111     }
112     ast::Exp* getExp()
113     {
114         return pExp;
115     }
116
117     bool isInterrupted()
118     {
119         return interrupted;
120     }
121
122     Breakpoint* getCurrentBreakPoint()
123     {
124         if (currentBreakPoint != -1)
125         {
126             return getBreakPoint(currentBreakPoint);
127         }
128
129         return nullptr;
130     }
131
132     void generateCallStack();
133     inline void clearCallStack()
134     {
135         callstack.exp.clear();
136         callstack.stack.clear();
137     }
138
139     CallStack& getCallStack()
140     {
141         return callstack;
142     }
143
144     //send information to debuggers
145     void sendStop(int index);
146     void sendExecution();
147     void sendExecutionReleased();
148     void sendPrint(const std::string& variable);
149     void sendShow(int bp);
150     void sendResume();
151     void sendAbort();
152     void sendErrorInFile(const std::wstring& filename) const;
153     void sendErrorInScript(const std::wstring& funcname) const;
154     void sendQuit();
155     void sendUpdate() const;
156
157     void stop(const ast::Exp* pExp, int index);
158     void errorInFile(const std::wstring filename, const ast::Exp* pExp);
159     void errorInScript(const std::wstring funcname, const ast::Exp* pExp);
160
161     //breakpoints functions
162     bool addBreakPoint(Breakpoint* bp);
163     bool updateBreakPoint(Breakpoint* bp);
164     bool removeBreakPoint(Breakpoint* bp);
165     Breakpoints::iterator findBreakPoint(Breakpoint* bp);
166     void removeBreakPoint(int _iBreakPoint);
167     void setAllBreakPoints(Breakpoints& _bps);
168     void removeAllBreakPoints();
169     void disableAllBreakPoints();
170     void disableBreakPoint(int _iBreakPoint);
171     void enableAllBreakPoints();
172     void enableBreakPoint(int _iBreakPoint);
173     bool isEnableBreakPoint(int _iBreakPoint);
174     Breakpoint* getBreakPoint(int _iBreakPoint);
175     int getBreakPointCount();
176     Breakpoints& getAllBreakPoint();
177
178     //actions called by debuggers
179     inline void setStepIn() //enter macro
180     {
181         action = StepIn;
182         level = symbol::Context::getInstance()->getScopeLevel();
183     }
184
185     inline bool isStepIn()
186     {
187         int l = symbol::Context::getInstance()->getScopeLevel();
188         //if stepIn failed ( not a macro ), stepIn become a stepNext
189         if(action != StepIn)
190         {
191             return false;
192         }
193
194         if(l < level)
195         {
196             action = StepNext;
197             return false;
198         }
199
200         return true;
201     }
202
203     inline void resetStepIn()
204     {
205         if (isStepIn())
206         {
207             action = Continue;
208         }
209     }
210
211     inline void setStepOut() //exit macro
212     {
213         action = StepOut;
214         level = ConfigVariable::getWhere().size();
215     }
216
217     inline bool isStepOut()
218     {
219         int l = ConfigVariable::getWhere().size();
220         return action == StepOut && l < level;
221     }
222
223     inline void resetStepOut()
224     {
225         if (isStepOut())
226         {
227             action = Continue;
228         }
229     }
230
231     inline void setAborted() //next statement
232     {
233         action = Aborted;
234     }
235
236     inline bool isAborted()
237     {
238         return action == Aborted;
239     }
240
241     inline void resetAborted()
242     {
243         if (isAborted())
244         {
245             action = Continue;
246         }
247     }
248
249     inline void setStepNext() //next statement
250     {
251         action = StepNext;
252         level = symbol::Context::getInstance()->getScopeLevel();
253     }
254
255     inline bool isStepNext()
256     {
257         int l = symbol::Context::getInstance()->getScopeLevel();
258         //if stepNext failed ( end of macro ), stepNext become a stepOut
259         return action == StepNext && l <= level;
260     }
261
262     inline void resetStepNext()
263     {
264         if (isStepNext())
265         {
266             action = Continue;
267         }
268     }
269
270     inline void resetStep()
271     {
272         if (isInterrupted() == false)
273         {
274             action = Continue;
275         }
276     }
277
278     char* execute(const std::string& command); //execute a command
279     void print(const std::string& variable); //print a variable
280     void show(int bp); //print the breakpoint bp or all breakpoints (bp = -1)
281     void resume(); //resume execution
282     void abort(); //abort execution
283     void requestPause(); //pause execution
284     bool isPauseRequested(); //get pause request status
285     void resetPauseRequest(); //reset pause request status
286 };
287
288 }
289 #endif /* !__DEBUGGER_MANAGER_HXX__ */