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