The Battle for Wesnoth  1.15.0-dev
debugger.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Yurii Chernyi <terraninfo@terraninfo.net>
3  Part of the Battle for Wesnoth Project https://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"
27 #include "gui/widgets/settings.hpp"
28 
29 static lg::log_domain log_formula_debugger("scripting/formula/debug");
30 #define DBG_FDB LOG_STREAM(debug, log_formula_debugger)
31 #define LOG_FDB LOG_STREAM(info, log_formula_debugger)
32 #define WRN_FDB LOG_STREAM(warn, log_formula_debugger)
33 #define ERR_FDB LOG_STREAM(err, log_formula_debugger)
34 
35 namespace wfl {
36 
37 
38 debug_info::debug_info(int arg_number, int counter, int level, const std::string &name, const std::string &str, const variant &value, bool evaluated)
39  : arg_number_(arg_number), counter_(counter), level_(level), name_(name), str_(str), value_(value), evaluated_(evaluated)
40 {
41 }
42 
43 
45 {
46 }
47 
48 
49 int debug_info::level() const
50 {
51  return level_;
52 }
53 
54 const std::string& debug_info::name() const
55 {
56  return name_;
57 }
58 
59 
61 {
62  return counter_;
63 }
64 
65 
66 const variant& debug_info::value() const
67 {
68  return value_;
69 }
70 
71 
73 {
74  value_ = value;
75 }
76 
77 
79 {
80  return evaluated_;
81 }
82 
83 
85 {
87 }
88 
89 
90 const std::string& debug_info::str() const
91 {
92  return str_;
93 }
94 
95 
97  : call_stack_(), counter_(0), current_breakpoint_(), breakpoints_(), execution_trace_(),arg_number_extra_debug_info(-1), f_name_extra_debug_info("")
98 {
101 }
102 
103 
105 {
106 }
107 
108 
109 static void msg(const char *act, debug_info &i, const char *to="", const char *result = "")
110 {
111  DBG_FDB << "#" << i.counter() << act << std::endl <<" \""<< i.name() << "\"='" << i.str() << "' " << to << result << std::endl;
112 }
113 
114 
115 void formula_debugger::add_debug_info(int arg_number, const std::string& f_name)
116 {
117  arg_number_extra_debug_info = arg_number;
118  f_name_extra_debug_info = f_name;
119 }
120 
121 
122 const std::list<debug_info>& formula_debugger::get_call_stack() const
123 {
124  return call_stack_;
125 }
126 
127 
129 {
130  return current_breakpoint_;
131 }
132 
133 const std::list<debug_info>& formula_debugger::get_execution_trace() const
134 {
135  return execution_trace_;
136 }
137 
139 {
140  for(std::list<breakpoint_ptr>::iterator b = breakpoints_.begin(); b != breakpoints_.end(); ++b) {
141  if ((*b)->is_break_now()){
142  current_breakpoint_ = (*b);
143  show_gui();
145  if ((*b)->is_one_time_only()) {
146  b = breakpoints_.erase(b);
147  }
148  break;
149  }
150  }
151 }
152 
154 {
155  if (game_display::get_singleton() == nullptr) {
156  WRN_FDB << "do not showing debug window due to nullptr gui" << std::endl;
157  return;
158  }
159  if (game_config::debug) {
160  gui2::dialogs::formula_debugger debug_dialog(*this);
161  debug_dialog.show();
162  } else {
163  WRN_FDB << "do not showing debug window due to disabled --new-widgets"<< std::endl;
164  }
165 }
166 
167 void formula_debugger::call_stack_push(const std::string &str)
168 {
172  execution_trace_.push_back(call_stack_.back());
173 }
174 
175 
177 {
178  execution_trace_.push_back(call_stack_.back());
179  call_stack_.pop_back();
180 }
181 
182 
184 {
185  call_stack_.back().set_evaluated(evaluated);
186 }
187 
189 {
190  call_stack_.back().set_value(v);
191 }
192 
194 {
195  call_stack_push(expression.str());
197  msg(" evaluating expression: ",call_stack_.back());
198  variant v = expression.execute(variables,this);
201  msg(" evaluated expression: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
203  call_stack_pop();
204  return v;
205 }
206 
207 
209 {
210  call_stack_push(f.str());
212  msg(" evaluating formula: ",call_stack_.back());
213  variant v = f.execute(variables,this);
216  msg(" evaluated formula: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
218  call_stack_pop();
219  return v;
220 }
221 
222 
224 {
225  call_stack_push(f.str());
227  msg(" evaluating formula without variables: ",call_stack_.back());
228  variant v = f.execute(this);
231  msg(" evaluated formula without variables: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
233  call_stack_pop();
234  return v;
235 }
236 
237 
238 base_breakpoint::base_breakpoint(formula_debugger &fdb, const std::string &name, bool one_time_only)
239  : fdb_(fdb), name_(name), one_time_only_(one_time_only)
240 {
241 
242 }
243 
244 
246 {
247 }
248 
249 
251 {
252  return one_time_only_;
253 }
254 
255 
256 const std::string& base_breakpoint::name() const
257 {
258  return name_;
259 }
260 
262 public:
264  : base_breakpoint(fdb,"End", true)
265  {
266  }
267 
268  virtual ~end_breakpoint()
269  {
270  }
271 
272  virtual bool is_break_now() const
273  {
274  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
275  if ((call_stack.size() == 1) && (call_stack.front().evaluated()) ) {
276  return true;
277  }
278  return false;
279  }
280 };
281 
282 
284 public:
286  : base_breakpoint(fdb,"Step",true)
287  {
288  }
289 
291  {
292  }
293 
294  virtual bool is_break_now() const
295  {
296  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
297  if (call_stack.empty() || call_stack.back().evaluated()) {
298  return false;
299  }
300 
301  return true;
302  }
303 };
304 
305 
307 public:
309  : base_breakpoint(fdb,"Step out",true), level_(fdb.get_call_stack().size()-1)
310  {
311  }
312 
314  {
315  }
316 
317  virtual bool is_break_now() const
318  {
319  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
320  if (call_stack.empty() || call_stack.back().evaluated()) {
321  return false;
322  }
323 
324  if (call_stack.size() == level_) {
325  return true;
326  }
327  return false;
328  }
329 private:
330  std::size_t level_;
331 };
332 
333 
335 public:
337  : base_breakpoint(fdb,"Next",true), level_(fdb.get_call_stack().size())
338  {
339  }
340 
342  {
343  }
344 
345  virtual bool is_break_now() const
346  {
347  const std::list<debug_info> &call_stack = fdb_.get_call_stack();
348  if (call_stack.empty() || call_stack.back().evaluated()) {
349  return false;
350  }
351  if (call_stack.size() == level_) {
352  return true;
353  }
354  return false;
355  }
356 private:
357  std::size_t level_;
358 };
359 
360 
362 {
363  breakpoints_.emplace_back(new end_breakpoint(*this));
364  LOG_FDB << "added 'end' breakpoint"<< std::endl;
365 }
366 
367 
369 {
370  breakpoints_.emplace_back(new step_in_breakpoint(*this));
371  LOG_FDB << "added 'step into' breakpoint"<< std::endl;
372 }
373 
374 
376 {
377  breakpoints_.emplace_back(new step_out_breakpoint(*this));
378  LOG_FDB << "added 'step out' breakpoint"<< std::endl;
379 }
380 
381 
383 {
384  breakpoints_.emplace_back(new next_breakpoint(*this));
385  LOG_FDB << "added 'next' breakpoint"<< std::endl;
386 }
387 
388 
389 } // end of namespace wfl
int level() const
Definition: debugger.cpp:49
virtual ~next_breakpoint()
Definition: debugger.cpp:341
virtual ~step_in_breakpoint()
Definition: debugger.cpp:290
virtual bool is_break_now() const
Definition: debugger.cpp:317
virtual std::string str() const =0
void add_debug_info(int arg_number, const std::string &f_name)
Definition: debugger.cpp:115
void add_breakpoint_step_out()
Definition: debugger.cpp:375
Formula AI debugger.
void call_stack_push(const std::string &str)
Definition: debugger.cpp:167
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:38
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:84
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
std::size_t level_
Definition: debugger.cpp:357
formula_debugger & fdb_
Definition: debugger.hpp:66
bool show(const unsigned auto_close_time=0)
Shows the window.
const std::string & name() const
Definition: debugger.cpp:256
std::shared_ptr< base_breakpoint > breakpoint_ptr
#define b
breakpoint_ptr current_breakpoint_
Definition: debugger.hpp:146
const breakpoint_ptr get_current_breakpoint() const
Definition: debugger.cpp:128
static const char * name(const std::vector< SDL_Joystick *> &joysticks, const std::size_t index)
Definition: joystick.cpp:48
virtual ~base_breakpoint()
Definition: debugger.cpp:245
variant evaluate_arg_callback(const formula_expression &expression, const formula_callable &variables)
Definition: debugger.cpp:193
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:86
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:32
step_in_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:285
virtual ~end_breakpoint()
Definition: debugger.cpp:268
virtual ~step_out_breakpoint()
Definition: debugger.cpp:313
void set_value(const variant &value)
Definition: debugger.cpp:72
virtual ~debug_info()
Definition: debugger.cpp:44
const variant & value() const
Definition: debugger.cpp:66
static lg::log_domain log_formula_debugger("scripting/formula/debug")
int counter() const
Definition: debugger.cpp:60
std::list< debug_info > execution_trace_
Definition: debugger.hpp:148
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:208
std::string name_
Definition: debugger.hpp:67
std::size_t i
Definition: function.cpp:933
virtual bool is_break_now() const
Definition: debugger.cpp:272
virtual bool is_break_now() const
Definition: debugger.cpp:294
next_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:336
#define LOG_FDB
Definition: debugger.cpp:31
void call_stack_set_value(const variant &v)
Definition: debugger.cpp:188
bool evaluated() const
Definition: debugger.cpp:78
#define DBG_FDB
Definition: debugger.cpp:30
const bool & debug
bool is_one_time_only() const
Definition: debugger.cpp:250
virtual ~formula_debugger()
Definition: debugger.cpp:104
void add_breakpoint_continue_to_end()
Definition: debugger.cpp:361
const std::list< debug_info > & get_call_stack() const
Definition: debugger.cpp:122
#define f
Definition: contexts.hpp:42
const std::string & str() const
Definition: debugger.cpp:90
const std::string & name() const
Definition: debugger.cpp:54
Standard logging facilities (interface).
base_breakpoint(formula_debugger &fdb, const std::string &name, bool one_time_only)
Definition: debugger.cpp:238
variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const
Definition: formula.cpp:262
void add_breakpoint_step_into()
Definition: debugger.cpp:368
virtual bool is_break_now() const
Definition: debugger.cpp:345
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
static std::deque< std::string > call_stack
Definition: function.cpp:39
step_out_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:308
void call_stack_set_evaluated(bool evaluated)
Definition: debugger.cpp:183
const std::list< debug_info > & get_execution_trace() const
Definition: debugger.cpp:133
virtual variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const =0
static game_display * get_singleton()
end_breakpoint(formula_debugger &fdb)
Definition: debugger.cpp:263