GPL + CeCILL Header change
[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  * === LICENSE_END ===
14  *
15  */
16
17 #ifndef __DEBUGGER_MANAGER_HXX__
18 #define __DEBUGGER_MANAGER_HXX__
19
20 #include <memory>
21
22 #include "abstractdebugger.hxx"
23 #include "breakpoint.hxx"
24 #include "dynlib_ast.h"
25
26 namespace debugger
27 {
28 class EXTERN_AST DebuggerMagager
29 {
30 public :
31     enum DebugAction
32     {
33         Continue,
34         StepNext,
35         StepIn,
36         StepOut
37     };
38
39 private:
40     static std::unique_ptr<DebuggerMagager> me;
41     DebuggerMagager() :
42         breakpoints(),
43         debuggers(), pExp(nullptr), interrupted(false), currentBreakPoint(-1), action(Continue), level(0) {}
44
45     Debuggers debuggers;
46     Breakpoints breakpoints;
47
48     ast::Exp* pExp;
49     bool interrupted;
50     int currentBreakPoint;
51     DebugAction action;
52     int level;
53
54     void internal_stop();
55 public:
56     ~DebuggerMagager()
57     {
58         for (auto d : debuggers)
59         {
60             delete d;
61         }
62         for (auto b : breakpoints)
63         {
64             delete b;
65         }
66     }
67
68     static DebuggerMagager* getInstance();
69
70     //debuggers functions
71     void addDebugger(AbstractDebugger* _debug);
72     void removeDebugger(int _iDebugger);
73     AbstractDebugger* getDebugger(int _iDebugger);
74     int getDebuggerCount();
75     Debuggers& getAllDebugger();
76
77     void setExp(const ast::Exp* _pExp)
78     {
79         pExp = const_cast<ast::Exp*>(_pExp);
80     }
81     void clearExp()
82     {
83         pExp = NULL;
84     }
85     ast::Exp* getExp()
86     {
87         return pExp;
88     }
89
90     bool isInterrupted()
91     {
92         return interrupted;
93     }
94
95     Breakpoint* getCurrentBreakPoint()
96     {
97         if (currentBreakPoint != -1)
98         {
99             return getBreakPoint(currentBreakPoint);
100         }
101
102         return nullptr;
103     }
104     //send information to debuggers
105     void sendStop(int index);
106     void sendResume();
107     void sendAbort();
108     void sendErrorInFile(const std::wstring& filename) const;
109     void sendErrorInScript(const std::wstring& funcname) const;
110     void sendQuit();
111     void sendUpdate() const;
112
113     void stop(const ast::Exp* pExp, int index);
114     void errorInFile(const std::wstring filename, const ast::Exp* pExp);
115     void errorInScript(const std::wstring funcname, const ast::Exp* pExp);
116     //breakpoints functions
117     void addBreakPoint(Breakpoint* bp);
118     void removeBreakPoint(int _iBreakPoint);
119     void removeAllBreakPoints();
120     void disableAllBreakPoints();
121     void disableBreakPoint(int _iBreakPoint);
122     void enableAllBreakPoints();
123     void enableBreakPoint(int _iBreakPoint);
124     bool isEnableBreakPoint(int _iBreakPoint);
125     Breakpoint* getBreakPoint(int _iBreakPoint);
126     int getBreakPointCount();
127     Breakpoints& getAllBreakPoint();
128
129
130     //actions called by debuggers
131     inline void setStepIn() //enter macro
132     {
133         action = StepIn;
134         level = symbol::Context::getInstance()->getScopeLevel();
135     }
136     inline bool isStepIn()
137     {
138         int l = symbol::Context::getInstance()->getScopeLevel();
139         //if stepIn failed ( not a macro ), stepIn become a stepNext
140         return action == StepIn && l >= level;
141     }
142     inline void resetStepIn()
143     {
144         if (isStepIn())
145         {
146             action = Continue;
147         }
148     }
149
150     inline void setStepOut() //exit macro
151     {
152         action = StepOut;
153         level = symbol::Context::getInstance()->getScopeLevel();
154     }
155     inline bool isStepOut()
156     {
157         int l = symbol::Context::getInstance()->getScopeLevel();
158         return action == StepOut && l < level;
159     }
160     inline void resetStepOut()
161     {
162         if (isStepOut())
163         {
164             action = Continue;
165         }
166     }
167
168     inline void setStepNext() //next statement
169     {
170         action = StepNext;
171         level = symbol::Context::getInstance()->getScopeLevel();
172     }
173     inline bool isStepNext()
174     {
175         int l = symbol::Context::getInstance()->getScopeLevel();
176         //if stepNext failed ( end of macro ), stepNext become a stepOut
177         return action == StepNext && l <= level;
178     }
179     inline void resetStepNext()
180     {
181         if (isStepNext())
182         {
183             action = Continue;
184         }
185     }
186
187     inline void resetStep()
188     {
189         if (isInterrupted() == false)
190         {
191             action = Continue;
192         }
193     }
194     void resume(); //resume execution
195     void abort(); //abort execution
196 };
197
198 }
199 #endif /* !__DEBUGGER_MANAGER_HXX__ */