The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
debugger.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2017 by Yurii Chernyi <terraninfo@terraninfo.net>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Formula debugger - implementation
18  * */
19 
20 
21 #include "formula/debugger.hpp"
22 #include "formula/formula.hpp"
23 #include "formula/function.hpp"
24 #include "game_display.hpp"
25 #include "log.hpp"
26 #include "resources.hpp"
28 #include "gui/widgets/settings.hpp"
29 
30 static lg::log_domain log_formula_debugger("scripting/formula/debug");
31 #define DBG_FDB LOG_STREAM(debug, log_formula_debugger)
32 #define LOG_FDB LOG_STREAM(info, log_formula_debugger)
33 #define WRN_FDB LOG_STREAM(warn, log_formula_debugger)
34 #define ERR_FDB LOG_STREAM(err, log_formula_debugger)
35 
36 namespace wfl {
37 
38 
39 debug_info::debug_info(int arg_number, int counter, int level, const std::string &name, const std::string &str, const variant &value, bool evaluated)
40  : arg_number_(arg_number), counter_(counter), level_(level), name_(name), str_(str), value_(value), evaluated_(evaluated)
41 {
42 }
43 
44 
46 {
47 }
48 
49 
50 int debug_info::level() const
51 {
52  return level_;
53 }
54 
56 {
57  return name_;
58 }
59 
60 
62 {
63  return counter_;
64 }
65 
66 
67 const variant& debug_info::value() const
68 {
69  return value_;
70 }
71 
72 
73 void debug_info::set_value(const variant &value)
74 {
75  value_ = value;
76 }
77 
78 
80 {
81  return evaluated_;
82 }
83 
84 
85 void debug_info::set_evaluated(bool evaluated)
86 {
88 }
89 
90 
92 {
93  return str_;
94 }
95 
96 
98  : call_stack_(), counter_(0), current_breakpoint_(), breakpoints_(), execution_trace_(),arg_number_extra_debug_info(-1), f_name_extra_debug_info("")
99 {
102 }
103 
104 
106 {
107 }
108 
109 
110 static void msg(const char *act, debug_info &i, const char *to="", const char *result = "")
111 {
112  DBG_FDB << "#" << i.counter() << act << std::endl <<" \""<< i.name() << "\"='" << i.str() << "' " << to << result << std::endl;
113 }
114 
115 
116 void formula_debugger::add_debug_info(int arg_number, const std::string& f_name)
117 {
118  arg_number_extra_debug_info = arg_number;
119  f_name_extra_debug_info = f_name;
120 }
121 
122 
123 const std::list<debug_info>& formula_debugger::get_call_stack() const
124 {
125  return call_stack_;
126 }
127 
128 
130 {
131  return current_breakpoint_;
132 }
133 
134 const std::list<debug_info>& formula_debugger::get_execution_trace() const
135 {
136  return execution_trace_;
137 }
138 
140 {
141  for(std::list<breakpoint_ptr>::iterator b = breakpoints_.begin(); b != breakpoints_.end(); ++b) {
142  if ((*b)->is_break_now()){
143  current_breakpoint_ = (*b);
144  show_gui();
146  if ((*b)->is_one_time_only()) {
147  b = breakpoints_.erase(b);
148  }
149  break;
150  }
151  }
152 }
153 
155 {
156  if (resources::screen == nullptr) {
157  WRN_FDB << "do not showing debug window due to nullptr gui" << std::endl;
158  return;
159  }
160  if (game_config::debug) {
161  gui2::dialogs::formula_debugger debug_dialog(*this);
162  debug_dialog.show(resources::screen->video());
163  } else {
164  WRN_FDB << "do not showing debug window due to disabled --new-widgets"<< std::endl;
165  }
166 }
167 
169 {
173  execution_trace_.push_back(call_stack_.back());
174 }
175 
176 
178 {
179  execution_trace_.push_back(call_stack_.back());
180  call_stack_.pop_back();
181 }
182 
183 
185 {
186  call_stack_.back().set_evaluated(evaluated);
187 }
188 
190 {
191  call_stack_.back().set_value(v);
192 }
193 
195 {
196  call_stack_push(expression.str());
198  msg(" evaluating expression: ",call_stack_.back());
199  variant v = expression.execute(variables,this);
202  msg(" evaluated expression: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
204  call_stack_pop();
205  return v;
206 }
207 
208 
210 {
211  call_stack_push(f.str());
213  msg(" evaluating formula: ",call_stack_.back());
214  variant v = f.execute(variables,this);
217  msg(" evaluated formula: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
219  call_stack_pop();
220  return v;
221 }
222 
223 
225 {
226  call_stack_push(f.str());
228  msg(" evaluating formula without variables: ",call_stack_.back());
229  variant v = f.execute(this);
232  msg(" evaluated formula without variables: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
234  call_stack_pop();
235  return v;
236 }
237 
238 
240  : fdb_(fdb), name_(name), one_time_only_(one_time_only)
241 {
242 
243 }
244 
245 
247 {
248 }
249 
250 
252 {
253  return one_time_only_;
254 }
255 
256 
258 {
259  return name_;
260 }
261 
263 public:
265  : base_breakpoint(fdb,"End", true)
266  {
267  }
268 
269  virtual ~end_breakpoint()
270  {
271  }
272 
273  virtual bool is_break_now() const
274  {
275  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
276  if ((call_stack.size() == 1) && (call_stack.front().evaluated()) ) {
277  return true;
278  }
279  return false;
280  }
281 };
282 
283 
285 public:
287  : base_breakpoint(fdb,"Step",true)
288  {
289  }
290 
292  {
293  }
294 
295  virtual bool is_break_now() const
296  {
297  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
298  if (call_stack.empty() || call_stack.back().evaluated()) {
299  return false;
300  }
301 
302  return true;
303  }
304 };
305 
306 
308 public:
310  : base_breakpoint(fdb,"Step out",true), level_(fdb.get_call_stack().size()-1)
311  {
312  }
313 
315  {
316  }
317 
318  virtual bool is_break_now() const
319  {
320  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
321  if (call_stack.empty() || call_stack.back().evaluated()) {
322  return false;
323  }
324 
325  if (call_stack.size() == level_) {
326  return true;
327  }
328  return false;
329  }
330 private:
331  size_t level_;
332 };
333 
334 
336 public:
338  : base_breakpoint(fdb,"Next",true), level_(fdb.get_call_stack().size())
339  {
340  }
341 
343  {
344  }
345 
346  virtual bool is_break_now() const
347  {
348  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
349  if (call_stack.empty() || call_stack.back().evaluated()) {
350  return false;
351  }
352  if (call_stack.size() == level_) {
353  return true;
354  }
355  return false;
356  }
357 private:
358  size_t level_;
359 };
360 
361 
363 {
364  breakpoints_.emplace_back(new end_breakpoint(*this));
365  LOG_FDB << "added 'end' breakpoint"<< std::endl;
366 }
367 
368 
370 {
371  breakpoints_.emplace_back(new step_in_breakpoint(*this));
372  LOG_FDB << "added 'step into' breakpoint"<< std::endl;
373 }
374 
375 
377 {
378  breakpoints_.emplace_back(new step_out_breakpoint(*this));
379  LOG_FDB << "added 'step out' breakpoint"<< std::endl;
380 }
381 
382 
384 {
385  breakpoints_.emplace_back(new next_breakpoint(*this));
386  LOG_FDB << "added 'next' breakpoint"<< std::endl;
387 }
388 
389 
390 } // end of namespace wfl
virtual ~next_breakpoint()
Definition: debugger.cpp:342
virtual ~step_in_breakpoint()
Definition: debugger.cpp:291
std::vector< char_t > string
virtual std::string str() const =0
void add_debug_info(int arg_number, const std::string &f_name)
Definition: debugger.cpp:116
void add_breakpoint_step_out()
Definition: debugger.cpp:376
Formula AI debugger.
void call_stack_push(const std::string &str)
Definition: debugger.cpp:168
game_display * screen
Definition: resources.cpp:27
std::list< debug_info > call_stack_
Definition: debugger.hpp:144
debug_info(int arg_number, int counter, int level, const std::string &name, const std::string &str, const variant &value, bool evaluated)
Definition: debugger.cpp:39
const std::string & str() const
Definition: formula.hpp:72
variant value_
Definition: debugger.hpp:53
std::list< breakpoint_ptr > breakpoints_
Definition: debugger.hpp:147
void set_evaluated(bool evaluated)
Definition: debugger.cpp:85
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
formula_debugger & fdb_
Definition: debugger.hpp:66
const std::string & name() const
Definition: debugger.cpp:55
std::shared_ptr< base_breakpoint > breakpoint_ptr
#define b
breakpoint_ptr current_breakpoint_
Definition: debugger.hpp:146
const std::list< debug_info > & get_call_stack() const
Definition: debugger.cpp:123
virtual ~base_breakpoint()
Definition: debugger.cpp:246
variant evaluate_arg_callback(const formula_expression &expression, const formula_callable &variables)
Definition: debugger.cpp:194
int level() const
Definition: debugger.cpp:50
This file contains the settings handling of the widget library.
std::string f_name_extra_debug_info
Definition: debugger.hpp:150
#define WRN_FDB
Definition: debugger.cpp:33
step_in_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:286
virtual ~end_breakpoint()
Definition: debugger.cpp:269
virtual ~step_out_breakpoint()
Definition: debugger.cpp:314
void set_value(const variant &value)
Definition: debugger.cpp:73
virtual ~debug_info()
Definition: debugger.cpp:45
static lg::log_domain log_formula_debugger("scripting/formula/debug")
std::list< debug_info > execution_trace_
Definition: debugger.hpp:148
virtual bool is_break_now() const
Definition: debugger.cpp:295
std::string str_
Definition: debugger.hpp:52
std::string name_
Definition: debugger.hpp:51
variant evaluate_formula_callback(const formula &f, const formula_callable &variables)
Definition: debugger.cpp:209
variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const
Definition: formula.cpp:231
std::string name_
Definition: debugger.hpp:67
size_t size(const utf8::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
virtual bool is_break_now() const
Definition: debugger.cpp:318
virtual bool is_break_now() const
Definition: debugger.cpp:273
next_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:337
const std::string & str() const
Definition: debugger.cpp:91
#define LOG_FDB
Definition: debugger.cpp:32
void call_stack_set_value(const variant &v)
Definition: debugger.cpp:189
#define i
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
#define DBG_FDB
Definition: debugger.cpp:31
int counter() const
Definition: debugger.cpp:61
virtual ~formula_debugger()
Definition: debugger.cpp:105
const variant & value() const
Definition: debugger.cpp:67
void add_breakpoint_continue_to_end()
Definition: debugger.cpp:362
#define f
Definition: contexts.hpp:42
const breakpoint_ptr get_current_breakpoint() const
Definition: debugger.cpp:129
Standard logging facilities (interface).
base_breakpoint(formula_debugger &fdb, const std::string &name, bool one_time_only)
Definition: debugger.cpp:239
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
bool evaluated() const
Definition: debugger.cpp:79
virtual bool is_break_now() const
Definition: debugger.cpp:346
void add_breakpoint_step_into()
Definition: debugger.cpp:369
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
static std::deque< std::string > call_stack
Definition: function.cpp:38
step_out_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:309
bool is_one_time_only() const
Definition: debugger.cpp:251
void call_stack_set_evaluated(bool evaluated)
Definition: debugger.cpp:184
const std::list< debug_info > & get_execution_trace() const
Definition: debugger.cpp:134
virtual variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const =0
end_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:264
const std::string & name() const
Definition: debugger.cpp:257