1
0
mirror of https://github.com/whowechina/chu_pico.git synced 2024-11-11 22:47:09 +01:00

cli allows abbreviation when no ambiguity

This commit is contained in:
whowechina 2023-09-23 11:40:30 +08:00
parent fb51404caf
commit 3f985d706e
2 changed files with 86 additions and 63 deletions

Binary file not shown.

View File

@ -15,7 +15,6 @@
#define SENSE_LIMIT_MIN -7 #define SENSE_LIMIT_MIN -7
#define MAX_COMMANDS 20 #define MAX_COMMANDS 20
#define MAX_COMMAND_LENGTH 20
#define MAX_PARAMETERS 5 #define MAX_PARAMETERS 5
#define MAX_PARAMETER_LENGTH 20 #define MAX_PARAMETER_LENGTH 20
@ -23,32 +22,47 @@ const char *chu_prompt = "chu_pico>";
typedef void (*cmd_handler_t)(int argc, char *argv[]); typedef void (*cmd_handler_t)(int argc, char *argv[]);
typedef struct { static const char *commands[MAX_COMMANDS];
char name[MAX_COMMAND_LENGTH]; static cmd_handler_t handlers[MAX_COMMANDS];
cmd_handler_t handler; static int num_commands = 0;
} command_t;
command_t commands[MAX_COMMANDS]; static void register_command(const char *cmd, cmd_handler_t handler)
int num_commands = 0;
static void register_command(char *name, cmd_handler_t handler)
{ {
if (num_commands < MAX_COMMANDS) { if (num_commands < MAX_COMMANDS) {
strcpy(commands[num_commands].name, name); commands[num_commands] = cmd;
commands[num_commands].handler = handler; handlers[num_commands] = handler;
num_commands++; num_commands++;
} }
} }
// return -1 if not matched, return -2 if ambiguous
static int 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 (strncmp(str[i], prefix, strlen(prefix)) == 0) {
if (found) {
return -2;
}
found = true;
match = i;
}
}
return match;
}
static void handle_help(int argc, char *argv[]) static void handle_help(int argc, char *argv[])
{ {
printf("Available commands:\n"); printf("Available commands:\n");
for (int i = 0; i < num_commands; i++) { for (int i = 0; i < num_commands; i++) {
printf("%s\n", commands[i].name); printf("%s\n", commands[i]);
} }
} }
static void list_colors() static void disp_colors()
{ {
printf("[Colors]\n"); printf("[Colors]\n");
printf(" Key upper: %06x, lower: %06x, both: %06x, off: %06x\n", printf(" Key upper: %06x, lower: %06x, both: %06x, off: %06x\n",
@ -57,7 +71,7 @@ static void list_colors()
printf(" Gap: %06x\n", chu_cfg->colors.gap); printf(" Gap: %06x\n", chu_cfg->colors.gap);
} }
static void list_style() static void disp_style()
{ {
printf("[Style]\n"); printf("[Style]\n");
printf(" Key: %d, Gap: %d, ToF: %d, Level: %d\n", printf(" Key: %d, Gap: %d, ToF: %d, Level: %d\n",
@ -65,31 +79,31 @@ static void list_style()
chu_cfg->style.tof, chu_cfg->style.level); chu_cfg->style.tof, chu_cfg->style.level);
} }
static void list_tof() static void disp_tof()
{ {
printf("[ToF]\n"); printf("[ToF]\n");
printf(" Offset: %d, Pitch: %d\n", chu_cfg->tof.offset, chu_cfg->tof.pitch); printf(" Offset: %d, Pitch: %d\n", chu_cfg->tof.offset, chu_cfg->tof.pitch);
} }
static void list_sense() static void disp_sense()
{ {
printf("[Sense]\n"); printf("[Sense]\n");
printf(" Global: %d, debounce (touch, release): %d, %d\n", chu_cfg->sense.global, printf(" Global: %+d, debounce (touch, release): %d, %d\n", chu_cfg->sense.global,
chu_cfg->sense.debounce_touch, chu_cfg->sense.debounce_release); chu_cfg->sense.debounce_touch, chu_cfg->sense.debounce_release);
printf(" | 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16|\n"); printf(" | 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16|\n");
printf(" -------------------------------------------------\n"); printf(" ---------------------------------------------------\n");
printf(" A |"); printf(" A |");
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
printf("%2d|", chu_cfg->sense.keys[i * 2]); printf("%+2d|", chu_cfg->sense.keys[i * 2]);
} }
printf("\n B |"); printf("\n B |");
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
printf("%2d|", chu_cfg->sense.keys[i * 2 + 1]); printf("%+2d|", chu_cfg->sense.keys[i * 2 + 1]);
} }
printf("\n"); printf("\n");
} }
static void list_hid() static void disp_hid()
{ {
printf("[HID]\n"); printf("[HID]\n");
printf(" Joy: %s, NKRO: %s.\n", printf(" Joy: %s, NKRO: %s.\n",
@ -97,35 +111,43 @@ static void list_hid()
chu_cfg->hid.nkro ? "on" : "off" ); chu_cfg->hid.nkro ? "on" : "off" );
} }
void handle_list(int argc, char *argv[]) void handle_display(int argc, char *argv[])
{ {
const char *usage = "Usage: list [colors|style|tof|sense|hid]\n"; const char *usage = "Usage: display [colors|style|tof|sense|hid]\n";
if (argc > 1) { if (argc > 1) {
printf(usage); printf(usage);
return; return;
} }
if (argc == 0) { if (argc == 0) {
list_colors(); disp_colors();
list_style(); disp_style();
list_tof(); disp_tof();
list_sense(); disp_sense();
list_hid(); disp_hid();
return; return;
} }
if (strcmp(argv[0], "colors") == 0) { const char *choices[] = {"colors", "style", "tof", "sense", "hid"};
list_colors(); switch (match_prefix(choices, 5, argv[0])) {
} else if (strcmp(argv[0], "style") == 0) { case 0:
list_style(); disp_colors();
} else if (strcmp(argv[0], "tof") == 0) { break;
list_tof(); case 1:
} else if (strcmp(argv[0], "sense") == 0) { disp_style();
list_sense(); break;
} else if (strcmp(argv[0], "hid") == 0) { case 2:
list_hid(); disp_tof();
} else { break;
printf(usage); case 3:
disp_sense();
break;
case 4:
disp_hid();
break;
default:
printf(usage);
break;
} }
} }
@ -153,26 +175,23 @@ static void handle_fps(int argc, char *argv[])
static void handle_hid(int argc, char *argv[]) static void handle_hid(int argc, char *argv[])
{ {
const char *usage = "Usage: hid <joy|nkro>\n"; const char *usage = "Usage: hid <joy|nkro|both>\n";
if (argc != 1) { if (argc != 1) {
printf(usage); printf(usage);
return; return;
} }
if (strcmp(argv[0], "joy") == 0) { const char *choices[] = {"joy", "nkro", "both"};
chu_cfg->hid.joy = 1; int match = match_prefix(choices, 3, argv[0]);
chu_cfg->hid.nkro = 0; if (match < 0) {
} else if (strcmp(argv[0], "nkro") == 0) {
chu_cfg->hid.joy = 0;
chu_cfg->hid.nkro = 1;
} else if (strcmp(argv[0], "both") == 0) {
chu_cfg->hid.joy = 1;
chu_cfg->hid.nkro = 1;
} else {
printf(usage); printf(usage);
return; return;
} }
chu_cfg->hid.joy = ((match == 0) || (match == 2)) ? 1 : 0;
chu_cfg->hid.nkro = ((match == 1) || (match == 2)) ? 1 : 0;
config_changed(); config_changed();
disp_hid();
} }
static int extract_non_neg_int(const char *param, int len) static int extract_non_neg_int(const char *param, int len)
@ -218,7 +237,7 @@ static void handle_tof(int argc, char *argv[])
chu_cfg->tof.pitch = pitch; chu_cfg->tof.pitch = pitch;
config_changed(); config_changed();
list_tof(); disp_tof();
} }
static uint8_t *extract_key(const char *param) static uint8_t *extract_key(const char *param)
@ -282,7 +301,7 @@ static void handle_sense(int argc, char *argv[])
slider_update_config(); slider_update_config();
config_changed(); config_changed();
list_sense(); disp_sense();
} }
static void handle_debounce(int argc, char *argv[]) static void handle_debounce(int argc, char *argv[])
@ -314,7 +333,7 @@ static void handle_debounce(int argc, char *argv[])
slider_update_config(); slider_update_config();
config_changed(); config_changed();
list_sense(); disp_sense();
} }
static void handle_save() static void handle_save()
@ -331,7 +350,7 @@ static void handle_factory_reset()
void cmd_init() void cmd_init()
{ {
register_command("?", handle_help); register_command("?", handle_help);
register_command("list", handle_list); register_command("display", handle_display);
register_command("fps", handle_fps); register_command("fps", handle_fps);
register_command("hid", handle_hid); register_command("hid", handle_hid);
register_command("tof", handle_tof); register_command("tof", handle_tof);
@ -346,24 +365,28 @@ static int cmd_len = 0;
static void process_cmd() static void process_cmd()
{ {
char *command;
char *argv[MAX_PARAMETERS]; char *argv[MAX_PARAMETERS];
int argc; int argc;
command = strtok(cmd_buf, " \n"); char *cmd = strtok(cmd_buf, " \n");
argc = 0; argc = 0;
while ((argc < MAX_PARAMETERS) && while ((argc < MAX_PARAMETERS) &&
(argv[argc] = strtok(NULL, " \n")) != NULL) { (argv[argc] = strtok(NULL, " \n")) != NULL) {
argc++; argc++;
} }
for (int i = 0; i < num_commands; i++) { int match = match_prefix(commands, num_commands, cmd);
if (strcmp(commands[i].name, command) == 0) { if (match == -2) {
commands[i].handler(argc, argv); printf("Ambiguous command.\n");
printf("\n"); return;
break;
}
} }
if (match == -1) {
printf("Unknown command.\n");
handle_help(0, NULL);
return;
}
handlers[match](argc, argv);
} }
void cmd_run() void cmd_run()