1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef DEBUGGER_PARSER_HXX |
19 | #define DEBUGGER_PARSER_HXX |
20 | |
21 | #include <functional> |
22 | #include <set> |
23 | |
24 | class Debugger; |
25 | class Settings; |
26 | class FilesystemNode; |
27 | struct Command; |
28 | |
29 | #include "bspf.hxx" |
30 | |
31 | class DebuggerParser |
32 | { |
33 | public: |
34 | DebuggerParser(Debugger& debugger, Settings& settings); |
35 | |
36 | /** Run the given command, and return the result */ |
37 | string run(const string& command); |
38 | |
39 | /** Execute parser commands given in 'file' */ |
40 | string exec(const FilesystemNode& file, StringList* history = nullptr); |
41 | |
42 | /** Given a substring, determine matching substrings from the list |
43 | of available commands. Used in the debugger prompt for tab-completion */ |
44 | void getCompletions(const char* in, StringList& list) const; |
45 | |
46 | /** Evaluate the given expression using operators, current base, etc */ |
47 | int decipher_arg(const string& str); |
48 | |
49 | /** String representation of all watches currently defined */ |
50 | string showWatches(); |
51 | |
52 | static inline string red(const string& msg = "" ) |
53 | { |
54 | return char(kDbgColorRed & 0xff) + msg; |
55 | } |
56 | static inline string inverse(const string& msg = "" ) |
57 | { |
58 | // ASCII DEL char, decimal 127 |
59 | return "\177" + msg; |
60 | } |
61 | |
62 | private: |
63 | bool getArgs(const string& command, string& verb); |
64 | bool validateArgs(int cmd); |
65 | string eval(); |
66 | string saveScriptFile(string file); |
67 | |
68 | private: |
69 | // Constants for argument processing |
70 | enum class ParseState { |
71 | IN_COMMAND, |
72 | IN_SPACE, |
73 | IN_BRACE, |
74 | IN_ARG |
75 | }; |
76 | |
77 | enum class Parameters { |
78 | ARG_WORD, // single 16-bit value |
79 | ARG_DWORD, // single 32-bit value |
80 | ARG_MULTI_WORD, // multiple 16-bit values (must occur last) |
81 | ARG_BYTE, // single 8-bit value |
82 | ARG_MULTI_BYTE, // multiple 8-bit values (must occur last) |
83 | ARG_BOOL, // 0 or 1 only |
84 | ARG_LABEL, // label (need not be defined, treated as string) |
85 | ARG_FILE, // filename |
86 | ARG_BASE_SPCL, // base specifier: 2, 10, or 16 (or "bin" "dec" "hex") |
87 | ARG_END_ARGS // sentinel, occurs at end of list |
88 | }; |
89 | |
90 | // List of commands available |
91 | struct Command { |
92 | string cmdString; |
93 | string description; |
94 | string extendedDesc; |
95 | bool parmsRequired; |
96 | bool refreshRequired; |
97 | Parameters parms[10]; |
98 | std::function<void (DebuggerParser*)> executor; |
99 | }; |
100 | static std::array<Command, 95> commands; |
101 | |
102 | struct Trap |
103 | { |
104 | bool read; |
105 | bool write; |
106 | uInt32 begin; |
107 | uInt32 end; |
108 | string condition; |
109 | }; |
110 | |
111 | // Reference to our debugger object |
112 | Debugger& debugger; |
113 | |
114 | // Reference to settings object (required for saving certain options) |
115 | Settings& settings; |
116 | |
117 | // The results of the currently running command |
118 | ostringstream commandResult; |
119 | |
120 | // currently execute command id |
121 | int myCommand; |
122 | // Arguments in 'int' and 'string' format for the currently running command |
123 | IntArray args; |
124 | StringList argStrings; |
125 | uInt32 argCount; |
126 | |
127 | uInt32 execDepth; |
128 | string execPrefix; |
129 | |
130 | StringList myWatches; |
131 | |
132 | // Keep track of traps (read and/or write) |
133 | vector<unique_ptr<Trap>> myTraps; |
134 | void listTraps(bool listCond); |
135 | string trapStatus(const Trap& trap); |
136 | |
137 | // output the error with the example provided for the command |
138 | void outputCommandError(const string& errorMsg, int command); |
139 | |
140 | // List of available command methods |
141 | void executeA(); |
142 | void executeBase(); |
143 | void executeBreak(); |
144 | void executeBreakif(); |
145 | void executeBreaklabel(); |
146 | void executeC(); |
147 | void executeCheat(); |
148 | void executeClearbreaks(); |
149 | void executeClearconfig(); |
150 | void executeClearsavestateifs(); |
151 | void executeCleartraps(); |
152 | void executeClearwatches(); |
153 | void executeCls(); |
154 | void executeCode(); |
155 | void executeColortest(); |
156 | void executeD(); |
157 | void executeData(); |
158 | void executeDebugColors(); |
159 | void executeDefine(); |
160 | void executeDelbreakif(); |
161 | void executeDelfunction(); |
162 | void executeDelsavestateif(); |
163 | void executeDeltrap(); |
164 | void executeDelwatch(); |
165 | void executeDisasm(); |
166 | void executeDump(); |
167 | void executeExec(); |
168 | void executeExitRom(); |
169 | void executeFrame(); |
170 | void executeFunction(); |
171 | void executeGfx(); |
172 | void executeHelp(); |
173 | void executeJoy0Up(); |
174 | void executeJoy0Down(); |
175 | void executeJoy0Left(); |
176 | void executeJoy0Right(); |
177 | void executeJoy0Fire(); |
178 | void executeJoy1Up(); |
179 | void executeJoy1Down(); |
180 | void executeJoy1Left(); |
181 | void executeJoy1Right(); |
182 | void executeJoy1Fire(); |
183 | void executeJump(); |
184 | void executeListbreaks(); |
185 | void executeListconfig(); |
186 | void executeListfunctions(); |
187 | void executeListsavestateifs(); |
188 | void executeListtraps(); |
189 | void executeLoadallstates(); |
190 | void executeLoadconfig(); |
191 | void executeLoadstate(); |
192 | void executeN(); |
193 | void executePalette(); |
194 | void executePc(); |
195 | void executePGfx(); |
196 | void executePrint(); |
197 | void executeRam(); |
198 | void executeReset(); |
199 | void executeRewind(); |
200 | void executeRiot(); |
201 | void executeRom(); |
202 | void executeRow(); |
203 | void executeRun(); |
204 | void executeRunTo(); |
205 | void executeRunToPc(); |
206 | void executeS(); |
207 | void executeSave(); |
208 | void executeSaveallstates(); |
209 | void executeSaveconfig(); |
210 | void executeSavedisassembly(); |
211 | void executeSaverom(); |
212 | void executeSaveses(); |
213 | void executeSavesnap(); |
214 | void executeSavestate(); |
215 | void executeSavestateif(); |
216 | void executeScanline(); |
217 | void executeStep(); |
218 | void executeStepwhile(); |
219 | void executeTia(); |
220 | void executeTrace(); |
221 | void executeTrap(); |
222 | void executeTrapif(); |
223 | void executeTrapread(); |
224 | void executeTrapreadif(); |
225 | void executeTrapwrite(); |
226 | void executeTrapwriteif(); |
227 | void executeTraps(bool read, bool write, const string& command, bool cond = false); |
228 | void executeTrapRW(uInt32 addr, bool read, bool write, bool add = true); // not exposed by debugger |
229 | void executeType(); |
230 | void executeUHex(); |
231 | void executeUndef(); |
232 | void executeUnwind(); |
233 | void executeV(); |
234 | void executeWatch(); |
235 | void executeWinds(bool unwind); |
236 | void executeX(); |
237 | void executeY(); |
238 | void executeZ(); |
239 | |
240 | private: |
241 | // Following constructors and assignment operators not supported |
242 | DebuggerParser() = delete; |
243 | DebuggerParser(const DebuggerParser&) = delete; |
244 | DebuggerParser(DebuggerParser&&) = delete; |
245 | DebuggerParser& operator=(const DebuggerParser&) = delete; |
246 | DebuggerParser& operator=(DebuggerParser&&) = delete; |
247 | }; |
248 | |
249 | #endif |
250 | |