The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
debugger.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
3 by Yurii Chernyi <terraninfo@terraninfo.net>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16/**
17 * @file
18 * Formula debugger - implementation
19 * */
20
21
22#include "formula/debugger.hpp"
23#include "formula/formula.hpp"
24#include "formula/function.hpp"
25#include "game_display.hpp"
26#include "log.hpp"
28
29static 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
35namespace wfl {
36
37
38debug_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
47
48
50{
51 return level_;
52}
53
54const std::string& debug_info::name() const
55{
56 return name_;
57}
58
59
61{
62 return counter_;
63}
64
65
67{
68 return value_;
69}
70
71
73{
74 value_ = value;
75}
76
77
79{
80 return evaluated_;
81}
82
83
84void debug_info::set_evaluated(bool evaluated)
85{
87}
88
89
90const 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
107
108
109static 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;
112}
113
114
115void formula_debugger::add_debug_info(int arg_number, const std::string& f_name)
116{
117 arg_number_extra_debug_info = arg_number;
119}
120
121
122const std::list<debug_info>& formula_debugger::get_call_stack() const
123{
124 return call_stack_;
125}
126
127
132
133const 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 << "skipping WFL debug window due to nullptr gui";
157 return;
158 }
159 if (game_config::debug) {
160 gui2::dialogs::formula_debugger::display(*this);
161 } else {
162 WRN_FDB << "skipping WFL debug window because :debug is not enabled";
163 }
164}
165
173
174
176{
177 execution_trace_.push_back(call_stack_.back());
178 call_stack_.pop_back();
179}
180
181
183{
184 call_stack_.back().set_evaluated(evaluated);
185}
186
188{
189 call_stack_.back().set_value(v);
190}
191
193{
194 call_stack_push(expression.str());
196 msg(" evaluating expression: ",call_stack_.back());
197 variant v = expression.execute(variables,this);
200 msg(" evaluated expression: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
203 return v;
204}
205
206
208{
209 call_stack_push(f.str());
211 msg(" evaluating formula: ",call_stack_.back());
212 variant v = f.execute(variables,this);
215 msg(" evaluated formula: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
218 return v;
219}
220
221
223{
224 call_stack_push(f.str());
226 msg(" evaluating formula without variables: ",call_stack_.back());
227 variant v = f.execute(this);
230 msg(" evaluated formula without variables: ",call_stack_.back()," to ",v.to_debug_string(true).c_str());
233 return v;
234}
235
236
237base_breakpoint::base_breakpoint(formula_debugger &fdb, const std::string &name, bool one_time_only)
238 : fdb_(fdb), name_(name), one_time_only_(one_time_only)
239{
240
241}
242
243
247
248
250{
251 return one_time_only_;
252}
253
254
255const std::string& base_breakpoint::name() const
256{
257 return name_;
258}
259
261public:
263 : base_breakpoint(fdb,"End", true)
264 {
265 }
266
268 {
269 }
270
271 virtual bool is_break_now() const
272 {
273 const std::list<debug_info> &call_stack = fdb_.get_call_stack();
274 if ((call_stack.size() == 1) && (call_stack.front().evaluated()) ) {
275 return true;
276 }
277 return false;
278 }
279};
280
281
283public:
285 : base_breakpoint(fdb,"Step",true)
286 {
287 }
288
290 {
291 }
292
293 virtual bool is_break_now() const
294 {
295 const std::list<debug_info> &call_stack = fdb_.get_call_stack();
296 if (call_stack.empty() || call_stack.back().evaluated()) {
297 return false;
298 }
299
300 return true;
301 }
302};
303
304
306public:
308 : base_breakpoint(fdb,"Step out",true), level_(fdb.get_call_stack().size()-1)
309 {
310 }
311
313 {
314 }
315
316 virtual bool is_break_now() const
317 {
318 const std::list<debug_info> &call_stack = fdb_.get_call_stack();
319 if (call_stack.empty() || call_stack.back().evaluated()) {
320 return false;
321 }
322
323 if (call_stack.size() == level_) {
324 return true;
325 }
326 return false;
327 }
328private:
329 std::size_t level_;
330};
331
332
334public:
336 : base_breakpoint(fdb,"Next",true), level_(fdb.get_call_stack().size())
337 {
338 }
339
341 {
342 }
343
344 virtual bool is_break_now() const
345 {
346 const std::list<debug_info> &call_stack = fdb_.get_call_stack();
347 if (call_stack.empty() || call_stack.back().evaluated()) {
348 return false;
349 }
350 if (call_stack.size() == level_) {
351 return true;
352 }
353 return false;
354 }
355private:
356 std::size_t level_;
357};
358
359
361{
362 breakpoints_.emplace_back(new end_breakpoint(*this));
363 LOG_FDB << "added 'end' breakpoint";
364}
365
366
368{
369 breakpoints_.emplace_back(new step_in_breakpoint(*this));
370 LOG_FDB << "added 'step into' breakpoint";
371}
372
373
375{
376 breakpoints_.emplace_back(new step_out_breakpoint(*this));
377 LOG_FDB << "added 'step out' breakpoint";
378}
379
380
382{
383 breakpoints_.emplace_back(new next_breakpoint(*this));
384 LOG_FDB << "added 'next' breakpoint";
385}
386
387
388} // end of namespace wfl
std::unique_ptr< PangoAttribute, void(*)(PangoAttribute *)> value_
static game_display * get_singleton()
std::string name_
Definition debugger.hpp:68
formula_debugger & fdb_
Definition debugger.hpp:67
virtual ~base_breakpoint()
Definition debugger.cpp:244
const std::string & name() const
Definition debugger.cpp:255
base_breakpoint(formula_debugger &fdb, const std::string &name, bool one_time_only)
Definition debugger.cpp:237
bool is_one_time_only() const
Definition debugger.cpp:249
bool evaluated() const
Definition debugger.cpp:78
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 variant & value() const
Definition debugger.cpp:66
virtual ~debug_info()
Definition debugger.cpp:44
std::string name_
Definition debugger.hpp:52
int level() const
Definition debugger.cpp:49
void set_evaluated(bool evaluated)
Definition debugger.cpp:84
const std::string & name() const
Definition debugger.cpp:54
std::string str_
Definition debugger.hpp:53
const std::string & str() const
Definition debugger.cpp:90
void set_value(const variant &value)
Definition debugger.cpp:72
int counter() const
Definition debugger.cpp:60
end_breakpoint(formula_debugger &fdb)
Definition debugger.cpp:262
virtual ~end_breakpoint()
Definition debugger.cpp:267
virtual bool is_break_now() const
Definition debugger.cpp:271
const std::list< debug_info > & get_execution_trace() const
Definition debugger.cpp:133
void add_debug_info(int arg_number, const std::string &f_name)
Definition debugger.cpp:115
std::list< debug_info > call_stack_
Definition debugger.hpp:145
std::string f_name_extra_debug_info
Definition debugger.hpp:151
void add_breakpoint_step_into()
Definition debugger.cpp:367
virtual ~formula_debugger()
Definition debugger.cpp:104
breakpoint_ptr current_breakpoint_
Definition debugger.hpp:147
std::list< debug_info > execution_trace_
Definition debugger.hpp:149
void call_stack_push(const std::string &str)
Definition debugger.cpp:166
variant evaluate_formula_callback(const formula &f, const formula_callable &variables)
Definition debugger.cpp:207
void add_breakpoint_continue_to_end()
Definition debugger.cpp:360
variant evaluate_arg_callback(const formula_expression &expression, const formula_callable &variables)
Definition debugger.cpp:192
void call_stack_set_value(const variant &v)
Definition debugger.cpp:187
const std::list< debug_info > & get_call_stack() const
Definition debugger.cpp:122
void call_stack_set_evaluated(bool evaluated)
Definition debugger.cpp:182
std::list< breakpoint_ptr > breakpoints_
Definition debugger.hpp:148
const breakpoint_ptr get_current_breakpoint() const
Definition debugger.cpp:128
virtual std::string str() const =0
virtual variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const =0
virtual ~next_breakpoint()
Definition debugger.cpp:340
virtual bool is_break_now() const
Definition debugger.cpp:344
next_breakpoint(formula_debugger &fdb)
Definition debugger.cpp:335
virtual ~step_in_breakpoint()
Definition debugger.cpp:289
virtual bool is_break_now() const
Definition debugger.cpp:293
step_in_breakpoint(formula_debugger &fdb)
Definition debugger.cpp:284
step_out_breakpoint(formula_debugger &fdb)
Definition debugger.cpp:307
virtual bool is_break_now() const
Definition debugger.cpp:316
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
Definition variant.cpp:686
#define LOG_FDB
Definition debugger.cpp:31
static lg::log_domain log_formula_debugger("scripting/formula/debug")
#define WRN_FDB
Definition debugger.cpp:32
#define DBG_FDB
Definition debugger.cpp:30
Formula AI debugger.
Standard logging facilities (interface).
const bool & debug
std::shared_ptr< base_breakpoint > breakpoint_ptr
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition debugger.cpp:109
static thread_local std::deque< std::string > call_stack
For printing error messages when WFL parsing or evaluation fails, this contains the names of the WFL ...
Definition function.cpp:51
std::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
Definition sound.cpp:139
#define i
#define f
#define b