From 9f8a3860c18cd9b05394707987428a1a0252e239 Mon Sep 17 00:00:00 2001 From: whowechina Date: Sat, 27 Apr 2024 14:41:19 +0800 Subject: [PATCH] Ignore '\0' input in CLI --- firmware/src/cli.c | 391 +++++++++++++++++++++++---------------------- 1 file changed, 197 insertions(+), 194 deletions(-) diff --git a/firmware/src/cli.c b/firmware/src/cli.c index 535694a..5e5a42b 100644 --- a/firmware/src/cli.c +++ b/firmware/src/cli.c @@ -1,194 +1,197 @@ -#include -#include -#include -#include -#include - -#include "pico/stdio.h" -#include "pico/stdlib.h" -#include "pico/bootrom.h" -#include "cli.h" -#include "save.h" - -#define MAX_COMMANDS 32 -#define MAX_PARAMETERS 6 -#define MAX_PARAMETER_LENGTH 20 - -const char *cli_prompt = "cli>"; -const char *cli_logo = "CLI"; - -static const char *commands[MAX_COMMANDS]; -static const char *helps[MAX_COMMANDS]; -static cmd_handler_t handlers[MAX_COMMANDS]; -static int max_cmd_len = 0; - -static int num_commands = 0; - -void cli_register(const char *cmd, cmd_handler_t handler, const char *help) -{ - if (num_commands < MAX_COMMANDS) { - commands[num_commands] = cmd; - handlers[num_commands] = handler; - helps[num_commands] = help; - num_commands++; - if (strlen(cmd) > max_cmd_len) { - max_cmd_len = strlen(cmd); - } - } -} - -// return -1 if not matched, return -2 if ambiguous -int cli_match_prefix(const char *str[], int num, const char *prefix) -{ - int match = -1; - bool found = false; - - for (int i = 0; (i < num) && str[i]; i++) { - if (strncasecmp(str[i], prefix, strlen(prefix)) == 0) { - if (found) { - return -2; - } - found = true; - match = i; - } - } - - return match; -} - -static void handle_help(int argc, char *argv[]) -{ - printf("%s", cli_logo); - printf("\tSN: %016llx\n\n", board_id_64()); - printf("Available commands:\n"); - for (int i = 0; i < num_commands; i++) { - printf("%*s: %s\n", max_cmd_len + 2, commands[i], helps[i]); - } -} - -static int fps[2]; -void cli_fps_count(int core) -{ - static uint32_t last[2] = {0}; - static int counter[2] = {0}; - - counter[core]++; - - uint32_t now = time_us_32(); - if (now - last[core] < 1000000) { - return; - } - last[core] = now; - fps[core] = counter[core]; - counter[core] = 0; -} - -static void handle_fps(int argc, char *argv[]) -{ - printf("FPS: core 0: %d, core 1: %d\n", fps[0], fps[1]); -} - -static void handle_update(int argc, char *argv[]) -{ - printf("Boot into update mode.\n"); - fflush(stdout); - sleep_ms(100); - reset_usb_boot(0, 2); -} - -int cli_extract_non_neg_int(const char *param, int len) -{ - if (len == 0) { - len = strlen(param); - } - int result = 0; - for (int i = 0; i < len; i++) { - if (!isdigit((uint8_t)param[i])) { - return -1; - } - result = result * 10 + param[i] - '0'; - } - return result; -} - -static char cmd_buf[256]; -static int cmd_len = 0; - -static void process_cmd() -{ - char *argv[MAX_PARAMETERS]; - int argc; - - char *cmd = strtok(cmd_buf, " \n"); - - if (strlen(cmd) == 0) { - return; - } - - argc = 0; - while ((argc < MAX_PARAMETERS) && - (argv[argc] = strtok(NULL, " ,\n")) != NULL) { - argc++; - } - - int match = cli_match_prefix(commands, num_commands, cmd); - if (match == -2) { - printf("Ambiguous command.\n"); - return; - } else if (match == -1) { - printf("Unknown command.\n"); - handle_help(0, NULL); - return; - } - - handlers[match](argc, argv); -} - -void cli_run() -{ - int c = getchar_timeout_us(0); - if (c == EOF) { - return; - } - - if (c == '\b' || c == 127) { // both backspace and delete - if (cmd_len > 0) { - cmd_len--; - printf("\b \b"); - } - return; - } - - if ((c != '\n') && (c != '\r')) { - - if (cmd_len < sizeof(cmd_buf) - 2) { - cmd_buf[cmd_len] = c; - printf("%c", c); - cmd_len++; - } - return; - } - - cmd_buf[cmd_len] = '\0'; - cmd_len = 0; - - printf("\n"); - - process_cmd(); - - printf(cli_prompt); -} - -void cli_init(const char *prompt, const char *logo) -{ - if (prompt) { - cli_prompt = prompt; - } - if (logo) { - cli_logo = logo; - } - - cli_register("?", handle_help, "Display this help message."); - cli_register("fps", handle_fps, "Display FPS."); - cli_register("update", handle_update, "Update firmware."); -} +#include +#include +#include +#include +#include + +#include "pico/stdio.h" +#include "pico/stdlib.h" +#include "pico/bootrom.h" +#include "cli.h" +#include "save.h" + +#define MAX_COMMANDS 32 +#define MAX_PARAMETERS 6 +#define MAX_PARAMETER_LENGTH 20 + +const char *cli_prompt = "cli>"; +const char *cli_logo = "CLI"; + +static const char *commands[MAX_COMMANDS]; +static const char *helps[MAX_COMMANDS]; +static cmd_handler_t handlers[MAX_COMMANDS]; +static int max_cmd_len = 0; + +static int num_commands = 0; + +void cli_register(const char *cmd, cmd_handler_t handler, const char *help) +{ + if (num_commands < MAX_COMMANDS) { + commands[num_commands] = cmd; + handlers[num_commands] = handler; + helps[num_commands] = help; + num_commands++; + if (strlen(cmd) > max_cmd_len) { + max_cmd_len = strlen(cmd); + } + } +} + +// return -1 if not matched, return -2 if ambiguous +int cli_match_prefix(const char *str[], int num, const char *prefix) +{ + int match = -1; + bool found = false; + + for (int i = 0; (i < num) && str[i]; i++) { + if (strncasecmp(str[i], prefix, strlen(prefix)) == 0) { + if (found) { + return -2; + } + found = true; + match = i; + } + } + + return match; +} + +static void handle_help(int argc, char *argv[]) +{ + printf("%s", cli_logo); + printf("\tSN: %016llx\n\n", board_id_64()); + printf("Available commands:\n"); + for (int i = 0; i < num_commands; i++) { + printf("%*s: %s\n", max_cmd_len + 2, commands[i], helps[i]); + } +} + +static int fps[2]; +void cli_fps_count(int core) +{ + static uint32_t last[2] = {0}; + static int counter[2] = {0}; + + counter[core]++; + + uint32_t now = time_us_32(); + if (now - last[core] < 1000000) { + return; + } + last[core] = now; + fps[core] = counter[core]; + counter[core] = 0; +} + +static void handle_fps(int argc, char *argv[]) +{ + printf("FPS: core 0: %d, core 1: %d\n", fps[0], fps[1]); +} + +static void handle_update(int argc, char *argv[]) +{ + printf("Boot into update mode.\n"); + fflush(stdout); + sleep_ms(100); + reset_usb_boot(0, 2); +} + +int cli_extract_non_neg_int(const char *param, int len) +{ + if (len == 0) { + len = strlen(param); + } + int result = 0; + for (int i = 0; i < len; i++) { + if (!isdigit((uint8_t)param[i])) { + return -1; + } + result = result * 10 + param[i] - '0'; + } + return result; +} + +static char cmd_buf[256]; +static int cmd_len = 0; + +static void process_cmd() +{ + char *argv[MAX_PARAMETERS]; + int argc; + + char *cmd = strtok(cmd_buf, " \n"); + + if (strlen(cmd) == 0) { + return; + } + + argc = 0; + while ((argc < MAX_PARAMETERS) && + (argv[argc] = strtok(NULL, " ,\n")) != NULL) { + argc++; + } + + int match = cli_match_prefix(commands, num_commands, cmd); + if (match == -2) { + printf("Ambiguous command.\n"); + return; + } else if (match == -1) { + printf("Unknown command.\n"); + handle_help(0, NULL); + return; + } + + handlers[match](argc, argv); +} + +void cli_run() +{ + int c = getchar_timeout_us(0); + if (c == EOF) { + return; + } + if (c == 0) { + return; + } + + if (c == '\b' || c == 127) { // both backspace and delete + if (cmd_len > 0) { + cmd_len--; + printf("\b \b"); + } + return; + } + + if ((c != '\n') && (c != '\r')) { + + if (cmd_len < sizeof(cmd_buf) - 2) { + cmd_buf[cmd_len] = c; + printf("%c", c); + cmd_len++; + } + return; + } + + cmd_buf[cmd_len] = '\0'; + cmd_len = 0; + + printf("\n"); + + process_cmd(); + + printf(cli_prompt); +} + +void cli_init(const char *prompt, const char *logo) +{ + if (prompt) { + cli_prompt = prompt; + } + if (logo) { + cli_logo = logo; + } + + cli_register("?", handle_help, "Display this help message."); + cli_register("fps", handle_fps, "Display FPS."); + cli_register("update", handle_update, "Update firmware."); +}