#include "command.h" #include "context.h" #include "line-ed/line-ed.h" #include #include static struct line_ed *ed = NULL; extern struct command cmd_quit; extern struct command cmd_info; extern struct command cmd_memory; extern struct command cmd_breakpoint; extern struct command cmd_attach; extern struct command cmd_continue; static const struct command *commands[] = { &cmd_quit, &cmd_info, &cmd_memory, &cmd_breakpoint, &cmd_attach, &cmd_continue, }; static const size_t nr_commands = sizeof commands / sizeof commands[0]; static int tokenise_command(const char *s, int *out_argc, char ***out_argv) { fx_array *args = fx_array_create(); if (!args) { return -1; } fx_string *str = fx_string_create_from_cstr(s); if (!str) { fx_array_unref(args); return -1; } const char *delim = " "; const fx_iterator *it = fx_string_tokenise(str, &delim, 1, FX_STRING_TOK_F_NORMAL); fx_foreach(tok, it) { const char *tok_cstr = NULL; fx_value_get_cstr(tok, &tok_cstr); fx_string *tok_str = fx_string_create_from_cstr(tok_cstr); fx_array_push_back(args, FX_VALUE_OBJECT(tok_str)); fx_string_unref(tok_str); } fx_string_unref(str); int argc = fx_array_get_size(args); char **argv = calloc(argc, sizeof *argv); if (!argv) { fx_array_unref(args); return -1; } for (int i = 0; i < argc; i++) { const fx_value *arg_value = fx_array_get_ref(args, i); const char *arg_cstr = NULL; fx_value_get_cstr(arg_value, &arg_cstr); char *arg_cstr_owned = fx_strdup(arg_cstr); argv[i] = arg_cstr_owned; } fx_array_unref(args); *out_argc = argc; *out_argv = argv; return 0; } int repl(struct debug_context *ctx) { ed = line_ed_create(); if (!ed) { return -1; } int ret = 0; line_ed_set_flags(ed, LINE_ED_NO_TRAILING_LINEFEED); fx_stringstream *line = fx_stringstream_create(); while (!ctx->ctx_quit && line_ed_readline(ed, line) != LINE_ED_EOF) { const char *cmd_cstr = fx_stringstream_ptr(line); int argc; char **argv = NULL; if (tokenise_command(cmd_cstr, &argc, &argv) != 0) { ret = -1; break; } if (argc == 0) { goto skip; } const struct command *cmd = command_find(commands, nr_commands, argv[0]); if (cmd) { command_execute( cmd, ctx, argc - 1, (const char **)argv + 1, NULL); } skip: fx_stringstream_reset(line); } fx_stringstream_unref(line); line_ed_destroy(ed); ed = NULL; return ret; } int repl_suspend(void) { return line_ed_suspend(ed); } int repl_resume(void) { return line_ed_resume(ed); }