diff --git a/include/shell.h b/include/shell.h index 54ff439..3ed875a 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,16 +1,25 @@ #pragma once -size_t count_args(char *line); -char **parse_args(char *line, size_t *argc); - struct cmd { - const char *key; - void (* exec)(const char *line); + const char *cmd; + const char *desc; + void (* exec)(FILE *out, const char **argv, size_t argc); +}; + +struct shell { + char line[128]; + struct cmd *cmds; + const char *prompt; + struct usart_console *con; + FILE *fp; }; -void do_flash_cmd(const char *line); -void do_ftl_cmd(const char *line); -void do_mufs_cmd(const char *line); +size_t count_args(const char *line); +char **parse_args(const char *line, size_t *argc); + +void cmd_exec(struct cmd *cmds, FILE *out, const char **argv, size_t argc); +void cmd_parse(struct cmd *cmds, FILE *out, const char *line); -void cmd_exec(struct cmd *cmds, const char *line); -void cmd_loop(const char *s); +int shell_init(struct shell *shell, struct cmd *cmds, + struct usart_console *con, const char *prompt); +int shell_parse(struct shell *shell); diff --git a/source/main.c b/source/main.c index 2bc2795..f28e757 100644 --- a/source/main.c +++ b/source/main.c @@ -10,51 +10,43 @@ #include struct usart_console *user_con, *admin_con; -FILE *user_io, *admin_io; -char user_line[128]; -char admin_line[128]; +struct shell user_shell, admin_shell; + +static void do_echo(FILE *out, const char **argv, size_t argc) +{ + if (argc < 1) + return; + + fprintf(out, "%s\n", argv[0]); +} + +struct cmd cmds[] = { + { "echo", "", do_echo }, + { NULL, NULL, NULL }, +}; int main(void) { - char **argv; - size_t argc, i; + FILE *fp; rcc_init(); gpio_init(); + user_con = console_init(0); admin_con = console_init(1); - user_io = console_to_fp(user_con); - admin_io = console_to_fp(admin_con); - fprintf(user_io, "TBM-dev (built on " __DATE__ ")\n"); - fprintf(admin_io, "TBM-dev (built on " __DATE__ ")\n"); - fprintf(admin_io, "Welcome to the administrative interface.\n"); - fprintf(user_io, "tbm # "); + fp = console_to_fp(user_con); + fprintf(fp, "TBM-dev (built on " __DATE__ ")\n"); - while (1) { - if (console_getline(user_con, user_line, 128) == 0) { - argv = parse_args(user_line, &argc); - - for (i = 0; i < argc; ++i) { - fprintf(user_io, "user: %s\n", argv[i]); - fprintf(admin_io, "user: %s\n", argv[i]); - } - - free(argv); - *user_line = '\0'; - } + fp = console_to_fp(admin_con); + fprintf(fp, "TBM-dev (built on " __DATE__ ")\n"); - if (console_getline(admin_con, admin_line, 128) == 0) { - argv = parse_args(admin_line, &argc); + shell_init(&user_shell, cmds, user_con, "tbm $"); + shell_init(&admin_shell, cmds, admin_con, "tbm #"); - for (i = 0; i < argc; ++i) { - fprintf(admin_io, "admin: %s\n", argv[i]); - fprintf(user_io, "admin: %s\n", argv[i]); - } - - free(argv); - *admin_line = '\0'; - } + while (1) { + shell_parse(&user_shell); + shell_parse(&admin_shell); } return 0; diff --git a/source/shell/args.c b/source/shell/args.c index 6fc08bb..66ae3e6 100644 --- a/source/shell/args.c +++ b/source/shell/args.c @@ -4,9 +4,9 @@ #include -size_t count_args(char *line) +size_t count_args(const char *line) { - char *p = line; + const char *p = line; size_t n = 0; while (*p != '\0') { @@ -29,11 +29,11 @@ size_t count_args(char *line) return n; } -char **parse_args(char *line, size_t *argc) +char **parse_args(const char *line, size_t *argc) { char **argv; char **arg; - char *p = line; + const char *p = line; char *s; size_t n; diff --git a/source/shell/cmd.c b/source/shell/cmd.c index 1f59d98..27d5760 100644 --- a/source/shell/cmd.c +++ b/source/shell/cmd.c @@ -2,78 +2,67 @@ #include #include +#include #include -static int should_exit = 0; -static char buf[128]; -static void do_exit(const char *s); - -struct cmd main_cmds[] = { - { "exit", do_exit }, - { "quit", do_exit }, - { "flash", do_flash_cmd }, - { "ftl", do_ftl_cmd }, - { "mufs", do_mufs_cmd }, - { NULL, NULL }, -}; - -static void do_exit(const char *s) +void cmd_exec(struct cmd *cmds, FILE *out, const char **argv, size_t argc) { - (void)s; + struct cmd *cmd; - should_exit = 1; + if (argc < 1) + return; + + for (cmd = cmds; cmd->cmd; ++cmd) { + if (strcmp(cmd->cmd, argv[0]) == 0) { + cmd->exec(out, argv + 1, argc - 1); + break; + } + } } -static char *prompt(const char *prefix) +void cmd_parse(struct cmd *cmds, FILE *out, const char *line) { - size_t len; - - printf(prefix); - - if (!fgets(buf, 128, stdin)) - return NULL; - - len = strlen(buf); + char **argv; + size_t argc; - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = '\0'; + if (!(argv = parse_args(line, &argc))) + return; - putchar('\n'); - - return buf; + cmd_exec(cmds, out, (const char **)argv, argc); + free(argv); } -void cmd_exec(struct cmd *cmds, const char *line) +int shell_init(struct shell *shell, struct cmd *cmds, + struct usart_console *con, const char *prompt) { - struct cmd *cmd; - const char *args; - char *key; - size_t n; + if (!shell || !con) + return -1; - n = strcspn(line, " \n"); - key = strndup(line, n); + memset(shell->line, '\0', sizeof shell->line); + shell->cmds = cmds; + shell->con = con; + shell->fp = console_to_fp(con); + shell->prompt = prompt; - args = line + n; - args += strspn(args, " \n"); + fprintf(shell->fp, "%s ", prompt ? prompt : "#"); - for (cmd = cmds; cmd->key; ++cmd) { - if (strcmp(cmd->key, key) == 0) { - cmd->exec(args); - break; - } - } - - free(key); + return 0; } -void cmd_loop(const char *show) +int shell_parse(struct shell *shell) { - char *line; + int ret; - should_exit = 0; + if (!shell) + return -1; - while (!should_exit) { - line = prompt(show); - cmd_exec(main_cmds, line); - } + if ((ret = console_getline(shell->con, shell->line, sizeof shell->line)) < + 0) + return ret; + + cmd_parse(shell->cmds, shell->fp, shell->line); + fprintf(shell->fp, "%s ", shell->prompt ? shell->prompt : "#"); + *shell->line = '\0'; + + return 0; }