8b9290df70d65f971b8ad0822449f1ea809ca4f0
[scilab.git] / scilab / modules / ast / src / cpp / ast / debugmanager.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "debugmanager.hxx"
14 #include "configvariable.hxx"
15 #include "threadmanagement.hxx"
16 #include "runner.hxx"
17
18 #include "threadId.hxx"
19
20 extern "C"
21 {
22 #include "Thread_Wrapper.h"
23 }
24
25 namespace debugger
26 {
27 DebuggerMagager* DebuggerMagager::me = NULL;
28
29 //singleton
30 DebuggerMagager* DebuggerMagager::getInstance()
31 {
32     if (me == NULL)
33     {
34         me = new DebuggerMagager();
35     }
36
37     return me;
38 }
39
40 void DebuggerMagager::addDebugger(AbstractDebugger* _debug)
41 {
42     debuggers.push_back(_debug);
43 }
44
45 void DebuggerMagager::removeDebugger(int _iDebugger)
46 {
47     if (_iDebugger >= 0 && _iDebugger <= debuggers.size())
48     {
49         debuggers.erase(debuggers.begin() + _iDebugger);
50     }
51 }
52
53 AbstractDebugger* DebuggerMagager::getDebugger(int _iDebugger)
54 {
55     if (_iDebugger >= 0 && _iDebugger <= debuggers.size())
56     {
57         return debuggers[_iDebugger];
58     }
59
60     return NULL;
61 }
62
63 int DebuggerMagager::getDebuggerCount()
64 {
65     return (int)debuggers.size();
66 }
67
68 Debuggers& DebuggerMagager::getAllDebugger()
69 {
70     return debuggers;
71 }
72
73 void DebuggerMagager::sendStop(int index)
74 {
75     currentBreakPoint = index;
76     for (const auto& it : debuggers)
77     {
78         it->onStop(index);
79     }
80 }
81
82 void DebuggerMagager::sendResume()
83 {
84     currentBreakPoint = -1;
85     for (const auto& it : debuggers)
86     {
87         it->onResume();
88     }
89 }
90
91 void DebuggerMagager::sendAbort()
92 {
93     currentBreakPoint = -1;
94     for (const auto& it : debuggers)
95     {
96         it->onAbort();
97     }
98 }
99
100 void DebuggerMagager::sendErrorInFile(const std::wstring& filename) const
101 {
102     for (const auto& it : debuggers)
103     {
104         it->onErrorInFile(filename);
105     }
106 }
107
108 void DebuggerMagager::sendErrorInScript(const std::wstring& funcname) const
109 {
110     for (const auto& it : debuggers)
111     {
112         it->onErrorInScript(funcname);
113     }
114 }
115
116 void DebuggerMagager::sendQuit()
117 {
118     currentBreakPoint = -1;
119     for (const auto& it : debuggers)
120     {
121         it->onQuit();
122     }
123 }
124
125 void DebuggerMagager::sendUpdate() const
126 {
127     for (const auto& it : debuggers)
128     {
129         it->updateBreakpoints();
130     }
131 }
132
133 void DebuggerMagager::addBreakPoint(Breakpoint* bp)
134 {
135     breakpoints.push_back(bp);
136     sendUpdate();
137 }
138
139 void DebuggerMagager::removeBreakPoint(int _iBreakPoint)
140 {
141     if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
142     {
143         Breakpoints::iterator it = breakpoints.begin() + _iBreakPoint;
144         delete *it;
145         breakpoints.erase(it);
146         sendUpdate();
147     }
148 }
149
150 void DebuggerMagager::removeAllBreakPoints()
151 {
152     Breakpoints::iterator it = breakpoints.begin();
153     for (; it != breakpoints.end(); ++it)
154     {
155         delete *it;
156     }
157
158     breakpoints.clear();
159     sendUpdate();
160 }
161
162 void DebuggerMagager::disableBreakPoint(int _iBreakPoint)
163 {
164     if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
165     {
166         breakpoints[_iBreakPoint]->setDisable();
167         sendUpdate();
168     }
169 }
170
171 void DebuggerMagager::disableAllBreakPoints()
172 {
173     for (const auto& it : breakpoints)
174     {
175         it->setDisable();
176     }
177
178     sendUpdate();
179 }
180
181 void DebuggerMagager::enableBreakPoint(int _iBreakPoint)
182 {
183     if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
184     {
185         breakpoints[_iBreakPoint]->setEnable();
186     }
187 }
188
189 void DebuggerMagager::enableAllBreakPoints()
190 {
191     for (const auto& it : breakpoints)
192     {
193         it->setEnable();
194     }
195
196     sendUpdate();
197 }
198
199 bool DebuggerMagager::isEnableBreakPoint(int _iBreakPoint)
200 {
201     if (_iBreakPoint >= 0 && _iBreakPoint <= breakpoints.size())
202     {
203         return breakpoints[_iBreakPoint]->isEnable();
204     }
205
206     return false;
207 }
208
209 Breakpoint* DebuggerMagager::getBreakPoint(int _iBreakPoint)
210 {
211     if (_iBreakPoint >= 0 && _iBreakPoint < breakpoints.size())
212     {
213         return breakpoints[_iBreakPoint];
214     }
215
216     return NULL;
217 }
218
219 int DebuggerMagager::getBreakPointCount()
220 {
221     return (int)breakpoints.size();
222 }
223
224 Breakpoints& DebuggerMagager::getAllBreakPoint()
225 {
226     return breakpoints;
227 }
228
229 void DebuggerMagager::resume() //resume execution
230 {
231     if (ConfigVariable::getPauseLevel() != 0)
232     {
233         ConfigVariable::DecreasePauseLevel();
234         //inform debuggers
235         sendResume();
236     }
237
238 }
239
240 void DebuggerMagager::abort() //abort execution
241 {
242     if (ConfigVariable::getPauseLevel() != 0)
243     {
244         //inform debuggers
245         sendAbort();
246
247         throw ast::InternalAbort();
248     }
249 }
250
251 void DebuggerMagager::internal_stop()
252 {
253     interrupted = true;
254
255     ConfigVariable::IncreasePauseLevel();
256
257     // unlock console thread to display prompt again
258     ThreadManagement::SendConsoleExecDoneSignal();
259
260     //return to console so change mode to 2
261     int iOldMode = ConfigVariable::getPromptMode();
262     ConfigVariable::setPromptMode(2);
263
264     int iPauseLevel = ConfigVariable::getPauseLevel();
265     while (ConfigVariable::getPauseLevel() == iPauseLevel)
266     {
267         ThreadManagement::SendAwakeRunnerSignal();
268         ThreadManagement::WaitForRunMeSignal();
269         try
270         {
271             StaticRunner_launch();
272         }
273         catch (const ast::InternalError& ie)
274         {
275             //return from console so change mode to initial
276             ConfigVariable::setPromptMode(iOldMode);
277             //clean current seqexp
278             clearExp();
279             interrupted = false;
280
281             throw ie;
282         }
283         catch (const ast::InternalAbort& ia)
284         {
285             //return from console so change mode to initial
286             ConfigVariable::setPromptMode(iOldMode);
287             //clean current seqexp
288             clearExp();
289             interrupted = false;
290
291             throw ia;
292         }
293     }
294
295     //return from console so change mode to initial
296     ConfigVariable::setPromptMode(iOldMode);
297     //clean current seqexp
298     interrupted = false;
299 }
300
301 void DebuggerMagager::stop(const ast::Exp* pExp, int index)
302 {
303     //send stop information to all debuggers
304     setExp(pExp);
305     sendStop(index);
306     internal_stop();
307     clearExp();
308 }
309 void DebuggerMagager::errorInFile(const std::wstring filename, const ast::Exp* pExp)
310 {
311     setExp(pExp);
312     sendErrorInFile(filename);
313     internal_stop();
314     clearExp();
315 }
316 void DebuggerMagager::errorInScript(const std::wstring funcname, const ast::Exp* pExp)
317 {
318     setExp(pExp);
319     sendErrorInScript(funcname);
320     internal_stop();
321     clearExp();
322 }
323
324 }