From 70974277af271eba0a3773feddba43199a509ba9 Mon Sep 17 00:00:00 2001 From: linkmauve Date: Wed, 1 Dec 2021 08:14:07 +0100 Subject: [PATCH] debugger: Use libreadline for the prompt (#11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * debugger: Use libreadline for the prompt This fixes the issue where ^D would put the debugger into an infinite loop, and adds support for persistent history, with familiar keybindings. I originally tried to make this new dependency optional, but your usage of make doesn’t really tend itself to this, feel free to tell me if you prefer another option. Co-authored-by: Yannik Marchand --- Makefile | 6 +++--- src/debugger/debugger.cpp | 17 +++++++++++++---- src/history.cpp | 33 +++++++++++++++++++++++++++++++++ src/history.h | 9 +++++++++ src/main.cpp | 4 +++- 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 src/history.cpp create mode 100644 src/history.h diff --git a/Makefile b/Makefile index 49fcab7..8ce5d22 100644 --- a/Makefile +++ b/Makefile @@ -11,12 +11,12 @@ SRC += $(shell find src/ -type f -name "*.c") OBJS = $(patsubst src/%,build/%.o,$(SRC)) main: $(OBJS) - $(CXX) -o $@ $(LDFLAGS) $(OBJS) -lcrypto + $(CXX) -o $@ $(LDFLAGS) $(OBJS) -lreadline -lhistory -lcrypto build/%.o: src/% - mkdir -p $(dir $@) + @mkdir -p $(dir $@) $(CXX) $(SRCFLAGS) -c -o $@ $< - + clean: rm -rf build rm -f main diff --git a/src/debugger/debugger.cpp b/src/debugger/debugger.cpp index bb54584..bdb4581 100644 --- a/src/debugger/debugger.cpp +++ b/src/debugger/debugger.cpp @@ -3,10 +3,12 @@ #include "debugger/expression.h" #include "debugger/common.h" #include "emulator.h" +#include "history.h" #include "common/sys.h" #include "common/buffer.h" +#include #include @@ -159,14 +161,21 @@ void Debugger::show(int core) { DebugInterface *debugger = getInterface(); std::string format = StringUtils::format("%%s:%s> ", debugger->format()); - Sys::out->write(format, debugger->name(), debugger->pc()); + std::string prompt = StringUtils::format(format, debugger->name(), debugger->pc()); - std::string line = Sys::in->readline(); - std::vector args; + char *line = readline(prompt.c_str()); + if (!line) { + ArgParser parser(debugger->getContext(), args); + quit(&parser); + return; + } + + History::append(line); + std::string current; - for (char c : line) { + for (char c : std::string(line)) { if (c == ' ') { if (!current.empty()) { args.push_back(current); diff --git a/src/history.cpp b/src/history.cpp new file mode 100644 index 0000000..cd11c16 --- /dev/null +++ b/src/history.cpp @@ -0,0 +1,33 @@ + +#include "history.h" + +#include +#include +#include + + +namespace History { + std::string filename; + + void init() { + using_history(); + + char *home = getenv("HOME"); + char *xdg_data = getenv("XDG_DATA_HOME"); + + std::string directory; + if (xdg_data && xdg_data[0] == '/') + directory = std::string(xdg_data) + "/wiiu-firmware-emulator"; + else + directory = std::string(home) + "/.local/share/wiiu-firmware-emulator"; + + mkdir(directory.c_str(), 0755); + filename = directory + "/history"; + read_history(filename.c_str()); + } + + void append(char *line) { + add_history(line); + write_history(filename.c_str()); + } +} diff --git a/src/history.h b/src/history.h new file mode 100644 index 0000000..1da4611 --- /dev/null +++ b/src/history.h @@ -0,0 +1,9 @@ + +#pragma once + +#include + +namespace History { + void init(); + void append(char *line); +} diff --git a/src/main.cpp b/src/main.cpp index a7f63ce..665c037 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,12 @@ #include "emulator.h" +#include "history.h" #include "common/logger.h" int main(int argc, const char *argv[]) { Logger::init(Logger::DEBUG); - + History::init(); + Emulator *emulator = new Emulator(); emulator->run(); delete emulator;