Files

131 lines
2.5 KiB
C

#include "command.h"
#include "context.h"
#include "line-ed/line-ed.h"
#include <fx/collections/array.h>
#include <fx/string.h>
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);
}