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-2021 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 #include "Device.hxx"
31 
32 class DebuggerParser
33 {
34   public:
35     DebuggerParser(Debugger& debugger, Settings& settings);
36 
37     /** Run the given command, and return the result */
38     string run(const string& command);
39 
40     /** Execute parser commands given in 'file' */
41     string exec(const FilesystemNode& file, StringList* history = nullptr);
42 
43     /** Given a substring, determine matching substrings from the list
44         of available commands.  Used in the debugger prompt for tab-completion */
45     void getCompletions(const char* in, StringList& list) const;
46 
47     /** Evaluate the given expression using operators, current base, etc */
48     int decipher_arg(const string& str);
49 
50     /** String representation of all watches currently defined */
51     string showWatches();
52 
red(const string & msg="")53     static inline string red(const string& msg = "")
54     {
55       return char(kDbgColorRed & 0xff) + msg;
56     }
inverse(const string & msg="")57     static inline string inverse(const string& msg = "")
58     {
59       // ASCII DEL char, decimal 127
60       return "\177" + msg;
61     }
62 
63   private:
64     bool getArgs(const string& command, string& verb);
65     bool validateArgs(int cmd);
66     string eval();
67     string saveScriptFile(string file);
68     void saveDump(const FilesystemNode& node, const stringstream& out,
69                   ostringstream& result);
70     const string& cartName() const;
71 
72   private:
73     // Constants for argument processing
74     enum class ParseState {
75       IN_COMMAND,
76       IN_SPACE,
77       IN_BRACE,
78       IN_ARG
79     };
80 
81     enum class Parameters {
82       ARG_WORD,        // single 16-bit value
83       ARG_DWORD,       // single 32-bit value
84       ARG_MULTI_WORD,  // multiple 16-bit values (must occur last)
85       ARG_BYTE,        // single 8-bit value
86       ARG_MULTI_BYTE,  // multiple 8-bit values (must occur last)
87       ARG_BOOL,        // 0 or 1 only
88       ARG_LABEL,       // label (need not be defined, treated as string)
89       ARG_FILE,        // filename
90       ARG_BASE_SPCL,   // base specifier: 2, 10, or 16 (or "bin" "dec" "hex")
91       ARG_END_ARGS     // sentinel, occurs at end of list
92     };
93 
94     // List of commands available
95     struct Command {
96       string cmdString;
97       string description;
98       string extendedDesc;
99       bool parmsRequired{false};
100       bool refreshRequired{false};
101       std::array<Parameters, 10> parms;
102       std::function<void (DebuggerParser*)> executor;
103     };
104     using CommandArray = std::array<Command, 103>;
105     static CommandArray commands;
106 
107     struct Trap
108     {
109       bool read{false};
110       bool write{false};
111       uInt32 begin{0};
112       uInt32 end{0};
113       string condition;
114 
TrapDebuggerParser::Trap115       Trap(bool r, bool w, uInt32 b, uInt32 e, const string& c)
116         : read(r), write(w), begin(b), end(e), condition(c) {}
117     };
118 
119     // Reference to our debugger object
120     Debugger& debugger;
121 
122     // Reference to settings object (required for saving certain options)
123     Settings& settings;
124 
125     // The results of the currently running command
126     ostringstream commandResult;
127 
128     // currently execute command id
129     int myCommand{0};
130     // Arguments in 'int' and 'string' format for the currently running command
131     IntArray args;
132     StringList argStrings;
133     uInt32 argCount{0};
134 
135     uInt32 execDepth{0};
136     string execPrefix;
137 
138     StringList myWatches;
139 
140     // Keep track of traps (read and/or write)
141     vector<unique_ptr<Trap>> myTraps;
142     void listTraps(bool listCond);
143     string trapStatus(const Trap& trap);
144 
145     // output the error with the example provided for the command
146     void outputCommandError(const string& errorMsg, int command);
147 
148     void executeDirective(Device::AccessType type);
149 
150     // List of available command methods
151     void executeA();
152     void executeAud();
153     void executeAutoSave();
154     void executeBase();
155     void executeBCol();
156     void executeBreak();
157     void executeBreakIf();
158     void executeBreakLabel();
159     void executeC();
160     void executeCheat();
161     void executeClearBreaks();
162     void executeClearConfig();
163     void executeClearHistory();
164     void executeClearSaveStateIfs();
165     void executeClearTraps();
166     void executeClearWatches();
167     void executeCls();
168     void executeCode();
169     void executeCol();
170     void executeColorTest();
171     void executeD();
172     void executeData();
173     void executeDebugColors();
174     void executeDefine();
175     void executeDelBreakIf();
176     void executeDelFunction();
177     void executeDelSaveStateIf();
178     void executeDelTrap();
179     void executeDelWatch();
180     void executeDisAsm();
181     void executeDump();
182     void executeExec();
183     void executeExitRom();
184     void executeFrame();
185     void executeFunction();
186     void executeGfx();
187     void executeHelp();
188     void executeJoy0Up();
189     void executeJoy0Down();
190     void executeJoy0Left();
191     void executeJoy0Right();
192     void executeJoy0Fire();
193     void executeJoy1Up();
194     void executeJoy1Down();
195     void executeJoy1Left();
196     void executeJoy1Right();
197     void executeJoy1Fire();
198     void executeJump();
199     void executeListBreaks();
200     void executeListConfig();
201     void executeListFunctions();
202     void executeListSaveStateIfs();
203     void executeListTraps();
204     void executeLoadAllStates();
205     void executeLoadConfig();
206     void executeLoadState();
207     void executeLogBreaks();
208     void executeN();
209     void executePalette();
210     void executePc();
211     void executePCol();
212     void executePGfx();
213     void executePrint();
214     void executeRam();
215     void executeReset();
216     void executeRewind();
217     void executeRiot();
218     void executeRom();
219     void executeRow();
220     void executeRun();
221     void executeRunTo();
222     void executeRunToPc();
223     void executeS();
224     void executeSave();
225     void executeSaveAccess();
226     void executeSaveAllStates();
227     void executeSaveConfig();
228     void executeSaveDisassembly();
229     void executeSaveRom();
230     void executeSaveSes();
231     void executeSaveSnap();
232     void executeSaveState();
233     void executeSaveStateIf();
234     void executeScanLine();
235     void executeStep();
236     void executeStepWhile();
237     void executeTia();
238     void executeTrace();
239     void executeTrap();
240     void executeTrapIf();
241     void executeTrapRead();
242     void executeTrapReadIf();
243     void executeTrapWrite();
244     void executeTrapWriteIf();
245     void executeTraps(bool read, bool write, const string& command, bool cond = false);
246     void executeTrapRW(uInt32 addr, bool read, bool write, bool add = true);  // not exposed by debugger
247     void executeType();
248     void executeUHex();
249     void executeUndef();
250     void executeUnwind();
251     void executeV();
252     void executeWatch();
253     void executeWinds(bool unwind);
254     void executeX();
255     void executeY();
256     void executeZ();
257 
258   private:
259     // Following constructors and assignment operators not supported
260     DebuggerParser() = delete;
261     DebuggerParser(const DebuggerParser&) = delete;
262     DebuggerParser(DebuggerParser&&) = delete;
263     DebuggerParser& operator=(const DebuggerParser&) = delete;
264     DebuggerParser& operator=(DebuggerParser&&) = delete;
265 };
266 
267 #endif
268