openMSX
BreakPointBase.hh
Go to the documentation of this file.
1#ifndef BREAKPOINTBASE_HH
2#define BREAKPOINTBASE_HH
3
4#include "CommandException.hh"
5#include "GlobalCliComm.hh"
6#include "TclObject.hh"
7
8#include "ScopedAssign.hh"
9#include "strCat.hh"
10
11namespace openmsx {
12
13class Interpreter;
14
17template<typename Derived>
19{
20public:
21 [[nodiscard]] unsigned getId() const { return id; }
22 [[nodiscard]] std::string getIdStr() const { return strCat(Derived::prefix, id); }
23
24 [[nodiscard]] TclObject getCondition() const { return condition; }
25 [[nodiscard]] TclObject getCommand() const { return command; }
26 [[nodiscard]] bool isEnabled() const { return enabled; }
27 [[nodiscard]] bool onlyOnce() const { return once; }
28
29 void setCondition(const TclObject& c) { condition = c; }
30 void setCommand(const TclObject& c) { command = c; }
31 void setEnabled(Interpreter& interp, const TclObject& e) {
32 setEnabled(e.getBoolean(interp)); // may throw
33 }
34 void setEnabled(bool e) { enabled = e; }
35 void setOnce(Interpreter& interp, const TclObject& o) {
36 setOnce(o.getBoolean(interp)); // may throw
37 }
38 void setOnce(bool o) { once = o; }
39
40 bool checkAndExecute(GlobalCliComm& cliComm, Interpreter& interp) {
41 if (!enabled) return false;
42 if (executing) {
43 // no recursive execution
44 return false;
45 }
46 ScopedAssign sa(executing, true);
47 if (isTrue(cliComm, interp)) {
48 try {
49 command.executeCommand(interp, true); // compile command
50 } catch (CommandException& e) {
51 cliComm.printWarning(e.getMessage());
52 }
53 return onlyOnce();
54 }
55 return false;
56 }
57
58protected:
59 BreakPointBase() : id(++lastId) {}
60 unsigned id;
61
62private:
63 // Note: we require GlobalCliComm here because breakpoint objects can
64 // be transferred to different MSX machines, and so the MSXCliComm
65 // object won't remain valid.
66 [[nodiscard]] bool isTrue(GlobalCliComm& cliComm, Interpreter& interp) const {
67 if (condition.getString().empty()) {
68 // unconditional bp
69 return true;
70 }
71 try {
72 return condition.evalBool(interp);
73 } catch (CommandException& e) {
74 cliComm.printWarning(e.getMessage());
75 return false;
76 }
77 }
78
79private:
80 TclObject command{"debug break"};
81 TclObject condition;
82 bool enabled = true;
83 bool once = false;
84 bool executing = false;
85
86 static inline unsigned lastId = 0;
87};
88
89} // namespace openmsx
90
91#endif
Assign new value to some variable and restore the original value when this object goes out of scope.
CRTP base class for CPU break and watch points.
void setEnabled(Interpreter &interp, const TclObject &e)
void setOnce(Interpreter &interp, const TclObject &o)
std::string getIdStr() const
TclObject getCommand() const
void setCondition(const TclObject &c)
TclObject getCondition() const
void setCommand(const TclObject &c)
bool checkAndExecute(GlobalCliComm &cliComm, Interpreter &interp)
void printWarning(std::string_view message)
Definition CliComm.cc:12
bool getBoolean(Interpreter &interp) const
Definition TclObject.cc:88
TclObject executeCommand(Interpreter &interp, bool compile=false)
Interpret this TclObject as a command and execute it.
Definition TclObject.cc:248
bool evalBool(Interpreter &interp) const
Definition TclObject.cc:228
zstring_view getString() const
Definition TclObject.cc:141
constexpr auto empty() const
This file implemented 3 utility functions:
Definition Autofire.cc:11
std::string strCat()
Definition strCat.hh:703