From a6fc606a2d2a5471c1998bde0c4d39a380e2709b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 21 Dec 2019 13:52:16 -0800 Subject: [PATCH] Debugger: Separate aliases from main commands --- CHANGES | 1 + include/mgba/internal/debugger/cli-debugger.h | 7 + src/arm/debugger/cli-debugger.c | 17 ++- src/debugger/cli-debugger.c | 140 ++++++++++++------ src/gb/debugger/cli.c | 1 + src/gba/debugger/cli.c | 1 + src/lr35902/debugger/cli-debugger.c | 1 + 7 files changed, 114 insertions(+), 54 deletions(-) diff --git a/CHANGES b/CHANGES index f7643fbd0..c53357c3d 100644 --- a/CHANGES +++ b/CHANGES @@ -108,6 +108,7 @@ Other fixes: Misc: - GB Memory: Support manual SRAM editing (fixes mgba.io/i/1580) - SDL: Use controller GUID instead of name + - Debugger: Separate aliases from main commands 0.8 beta 1: (2019-10-20) - Initial beta for 0.8 diff --git a/include/mgba/internal/debugger/cli-debugger.h b/include/mgba/internal/debugger/cli-debugger.h index 35a1a936a..367b7bf64 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -42,6 +42,11 @@ struct CLIDebuggerCommandSummary { const char* summary; }; +struct CLIDebuggerCommandAlias { + const char* name; + const char* original; +}; + struct CLIDebuggerSystem { struct CLIDebugger* p; @@ -53,8 +58,10 @@ struct CLIDebuggerSystem { void (*printStatus)(struct CLIDebuggerSystem*); struct CLIDebuggerCommandSummary* commands; + struct CLIDebuggerCommandAlias* commandAliases; const char* name; struct CLIDebuggerCommandSummary* platformCommands; + struct CLIDebuggerCommandAlias* platformCommandAliases; const char* platformName; }; diff --git a/src/arm/debugger/cli-debugger.c b/src/arm/debugger/cli-debugger.c index d458ad4aa..3dc87c4fc 100644 --- a/src/arm/debugger/cli-debugger.c +++ b/src/arm/debugger/cli-debugger.c @@ -22,19 +22,23 @@ static void _disassembleMode(struct CLIDebugger*, struct CLIDebugVector*, enum E static uint32_t _printLine(struct CLIDebugger* debugger, uint32_t address, enum ExecutionMode mode); static struct CLIDebuggerCommandSummary _armCommands[] = { - { "b/a", _setBreakpointARM, "I", "Set a software breakpoint as ARM" }, - { "b/t", _setBreakpointThumb, "I", "Set a software breakpoint as Thumb" }, { "break/a", _setBreakpointARM, "I", "Set a software breakpoint as ARM" }, { "break/t", _setBreakpointThumb, "I", "Set a software breakpoint as Thumb" }, - { "dis/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" }, - { "dis/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" }, - { "disasm/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" }, - { "disasm/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" }, { "disassemble/a", _disassembleArm, "Ii", "Disassemble instructions as ARM" }, { "disassemble/t", _disassembleThumb, "Ii", "Disassemble instructions as Thumb" }, { 0, 0, 0, 0 } }; +static struct CLIDebuggerCommandAlias _armCommandAliases[] = { + { "b/a", "break/a" }, + { "b/t", "break/t" }, + { "dis/a", "disassemble/a" }, + { "dis/t", "disassemble/t" }, + { "disasm/a", "disassemble/a" }, + { "disasm/t", "disassemble/t" }, + { 0, 0 } +}; + static inline void _printPSR(struct CLIDebuggerBackend* be, union PSR psr) { be->printf(be, "%08X [%c%c%c%c%c%c%c]\n", psr.packed, psr.n ? 'N' : '-', @@ -175,4 +179,5 @@ void ARMCLIDebuggerCreate(struct CLIDebuggerSystem* debugger) { debugger->disassemble = _disassemble; debugger->platformName = "ARM"; debugger->platformCommands = _armCommands; + debugger->platformCommandAliases = _armCommandAliases; } diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 64d431297..f1cc1f0e3 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -71,32 +71,17 @@ static void _source(struct CLIDebugger*, struct CLIDebugVector*); #endif static struct CLIDebuggerCommandSummary _debuggerCommands[] = { - { "b", _setBreakpoint, "Is", "Set a breakpoint" }, { "break", _setBreakpoint, "Is", "Set a breakpoint" }, - { "c", _continue, "", "Continue execution" }, { "continue", _continue, "", "Continue execution" }, - { "d", _clearBreakpoint, "I", "Delete a breakpoint or watchpoint" }, { "delete", _clearBreakpoint, "I", "Delete a breakpoint or watchpoint" }, - { "dis", _disassemble, "Ii", "Disassemble instructions" }, - { "disasm", _disassemble, "Ii", "Disassemble instructions" }, { "disassemble", _disassemble, "Ii", "Disassemble instructions" }, - { "h", _printHelp, "S", "Print help" }, { "help", _printHelp, "S", "Print help" }, - { "i", _printStatus, "", "Print the current status" }, - { "info", _printStatus, "", "Print the current status" }, - { "lb", _listBreakpoints, "", "List breakpoints" }, { "listb", _listBreakpoints, "", "List breakpoints" }, - { "lw", _listWatchpoints, "", "List watchpoints" }, { "listw", _listWatchpoints, "", "List watchpoints" }, - { "n", _next, "", "Execute next instruction" }, { "next", _next, "", "Execute next instruction" }, - { "p", _print, "S+", "Print a value" }, - { "p/t", _printBin, "S+", "Print a value as binary" }, - { "p/x", _printHex, "S+", "Print a value as hexadecimal" }, { "print", _print, "S+", "Print a value" }, { "print/t", _printBin, "S+", "Print a value as binary" }, { "print/x", _printHex, "S+", "Print a value as hexadecimal" }, - { "q", _quit, "", "Quit the emulator" }, { "quit", _quit, "", "Quit the emulator" }, { "reset", _reset, "", "Reset the emulation" }, { "r/1", _readByte, "I", "Read a byte from a specified offset" }, @@ -104,7 +89,6 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "r/4", _readWord, "I", "Read a word from a specified offset" }, { "status", _printStatus, "", "Print the current status" }, { "trace", _trace, "Is", "Trace a number of instructions" }, - { "w", _setReadWriteWatchpoint, "Is", "Set a watchpoint" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, { "w/r", _writeRegister, "SI", "Write a register" }, @@ -125,6 +109,26 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { 0, 0, 0, 0 } }; +static struct CLIDebuggerCommandAlias _debuggerCommandAliases[] = { + { "b", "break" }, + { "c", "continue" }, + { "d", "delete" }, + { "dis", "disassemble" }, + { "disasm", "disassemble" }, + { "h", "help" }, + { "i", "status" }, + { "info", "status" }, + { "lb", "listb" }, + { "lw", "listw" }, + { "n", "next" }, + { "p", "print" }, + { "p/t", "print/t" }, + { "p/x", "print/x" }, + { "q", "quit" }, + { "w", "watch" }, + { 0, 0 } +}; + #if !defined(NDEBUG) && !defined(_WIN32) static void _handleDeath(int sig) { UNUSED(sig); @@ -232,42 +236,71 @@ static void _printHex(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { debugger->backend->printf(debugger->backend, " 0x%08X\n", intValue); } +static void _printCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandSummary* commands, struct CLIDebuggerCommandAlias* aliases) { + int i; + for (i = 0; commands[i].name; ++i) { + debugger->backend->printf(debugger->backend, "%-15s %s\n", commands[i].name, commands[i].summary); + if (aliases) { + bool printedAlias = false; + int j; + for (j = 0; aliases[j].name; ++j) { + if (strcmp(aliases[j].original, commands[i].name) == 0) { + if (!printedAlias) { + debugger->backend->printf(debugger->backend, " Aliases:"); + printedAlias = true; + } + debugger->backend->printf(debugger->backend, " %s", aliases[j].name); + } + } + if (printedAlias) { + debugger->backend->printf(debugger->backend, "\n"); + } + } + } +} + +static void _printCommandSummary(struct CLIDebugger* debugger, const char* name, struct CLIDebuggerCommandSummary* commands, struct CLIDebuggerCommandAlias* aliases) { + int i; + for (i = 0; commands[i].name; ++i) { + if (strcmp(commands[i].name, name) == 0) { + debugger->backend->printf(debugger->backend, " %s\n", commands[i].summary); + if (aliases) { + bool printedAlias = false; + int j; + for (j = 0; aliases[j].name; ++j) { + if (strcmp(aliases[j].original, commands[i].name) == 0) { + if (!printedAlias) { + debugger->backend->printf(debugger->backend, " Aliases:"); + printedAlias = true; + } + debugger->backend->printf(debugger->backend, " %s", aliases[j].name); + } + } + if (printedAlias) { + debugger->backend->printf(debugger->backend, "\n"); + } + } + return; + } + } +} + static void _printHelp(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { UNUSED(dv); if (!dv) { debugger->backend->printf(debugger->backend, "Generic commands:\n"); - int i; - for (i = 0; _debuggerCommands[i].name; ++i) { - debugger->backend->printf(debugger->backend, "%-10s %s\n", _debuggerCommands[i].name, _debuggerCommands[i].summary); - } + _printCommands(debugger, _debuggerCommands, _debuggerCommandAliases); if (debugger->system) { - debugger->backend->printf(debugger->backend, "%s commands:\n", debugger->system->platformName); - for (i = 0; debugger->system->platformCommands[i].name; ++i) { - debugger->backend->printf(debugger->backend, "%-10s %s\n", debugger->system->platformCommands[i].name, debugger->system->platformCommands[i].summary); - } - debugger->backend->printf(debugger->backend, "%s commands:\n", debugger->system->name); - for (i = 0; debugger->system->commands[i].name; ++i) { - debugger->backend->printf(debugger->backend, "%-10s %s\n", debugger->system->commands[i].name, debugger->system->commands[i].summary); - } + debugger->backend->printf(debugger->backend, "\n%s commands:\n", debugger->system->platformName); + _printCommands(debugger, debugger->system->platformCommands, debugger->system->platformCommandAliases); + debugger->backend->printf(debugger->backend, "\n%s commands:\n", debugger->system->name); + _printCommands(debugger, debugger->system->commands, debugger->system->commandAliases); } } else { - int i; - for (i = 0; _debuggerCommands[i].name; ++i) { - if (strcmp(_debuggerCommands[i].name, dv->charValue) == 0) { - debugger->backend->printf(debugger->backend, " %s\n", _debuggerCommands[i].summary); - } - } + _printCommandSummary(debugger, dv->charValue, _debuggerCommands, _debuggerCommandAliases); if (debugger->system) { - for (i = 0; debugger->system->platformCommands[i].name; ++i) { - if (strcmp(debugger->system->platformCommands[i].name, dv->charValue) == 0) { - debugger->backend->printf(debugger->backend, " %s\n", debugger->system->platformCommands[i].summary); - } - } - for (i = 0; debugger->system->commands[i].name; ++i) { - if (strcmp(debugger->system->commands[i].name, dv->charValue) == 0) { - debugger->backend->printf(debugger->backend, " %s\n", debugger->system->commands[i].summary); - } - } + _printCommandSummary(debugger, dv->charValue, debugger->system->platformCommands, debugger->system->platformCommandAliases); + _printCommandSummary(debugger, dv->charValue, debugger->system->commands, debugger->system->commandAliases); } } } @@ -784,11 +817,22 @@ static struct CLIDebugVector* _parseArg(struct CLIDebugger* debugger, const char return dv; } -static int _tryCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandSummary* commands, const char* command, size_t commandLen, const char* args, size_t argsLen) { +static int _tryCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandSummary* commands, struct CLIDebuggerCommandAlias* aliases, const char* command, size_t commandLen, const char* args, size_t argsLen) { struct CLIDebugVector* dv = NULL; struct CLIDebugVector* dvLast = NULL; int i; const char* name; + if (aliases) { + for (i = 0; (name = aliases[i].name); ++i) { + if (strlen(name) != commandLen) { + continue; + } + if (strncasecmp(name, command, commandLen) == 0) { + command = aliases[i].original; + commandLen = strlen(aliases[i].original); + } + } + } for (i = 0; (name = commands[i].name); ++i) { if (strlen(name) != commandLen) { continue; @@ -885,11 +929,11 @@ static bool _parse(struct CLIDebugger* debugger, const char* line, size_t count) if (firstSpace) { args = firstSpace + 1; } - int result = _tryCommands(debugger, _debuggerCommands, line, cmdLength, args, count - cmdLength - 1); + int result = _tryCommands(debugger, _debuggerCommands, _debuggerCommandAliases, line, cmdLength, args, count - cmdLength - 1); if (result < 0 && debugger->system) { - result = _tryCommands(debugger, debugger->system->commands, line, cmdLength, args, count - cmdLength - 1); + result = _tryCommands(debugger, debugger->system->commands, debugger->system->commandAliases, line, cmdLength, args, count - cmdLength - 1); if (result < 0) { - result = _tryCommands(debugger, debugger->system->platformCommands, line, cmdLength, args, count - cmdLength - 1); + result = _tryCommands(debugger, debugger->system->platformCommands, debugger->system->platformCommandAliases, line, cmdLength, args, count - cmdLength - 1); } } if (result < 0) { diff --git a/src/gb/debugger/cli.c b/src/gb/debugger/cli.c index 2d86b12ec..2554acb1b 100644 --- a/src/gb/debugger/cli.c +++ b/src/gb/debugger/cli.c @@ -36,6 +36,7 @@ struct CLIDebuggerSystem* GBCLIDebuggerCreate(struct mCore* core) { debugger->d.name = "Game Boy"; debugger->d.commands = _GBCLIDebuggerCommands; + debugger->d.commandAliases = NULL; debugger->core = core; diff --git a/src/gba/debugger/cli.c b/src/gba/debugger/cli.c index c9f8bf2b7..5e0ba6ec2 100644 --- a/src/gba/debugger/cli.c +++ b/src/gba/debugger/cli.c @@ -35,6 +35,7 @@ struct GBACLIDebugger* GBACLIDebuggerCreate(struct mCore* core) { debugger->d.name = "Game Boy Advance"; debugger->d.commands = _GBACLIDebuggerCommands; + debugger->d.commandAliases = NULL; debugger->core = core; diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index 300a3dd8f..1e52303e5 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -108,4 +108,5 @@ void LR35902CLIDebuggerCreate(struct CLIDebuggerSystem* debugger) { debugger->disassemble = _disassemble; debugger->platformName = "GB-Z80"; debugger->platformCommands = _lr35902Commands; + debugger->platformCommandAliases = NULL; }