X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/9d6c43faec80158445b1131640356cc0c90b45e3..4077419cee470571ea8f7f202b141faf385b6e5a:/avr/command.c diff --git a/avr/command.c b/avr/command.c index aa784cb..085dfdc 100644 --- a/avr/command.c +++ b/avr/command.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2014, 2016 Leo C. + * (C) Copyright 2014, 2016, 2018 Leo C. * * (C) Copyright 2000-2009 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. @@ -13,8 +13,6 @@ #include "command.h" #include "common.h" -#include -#include #include #include @@ -24,6 +22,11 @@ #include "env.h" #include "debug.h" +#define DEBUG_CMD 1 /* set to 1 to debug */ + +#define debug_cmd(fmt, args...) \ + debug_cond(DEBUG_CMD, fmt, ##args) + jmp_buf cmd_jbuf; @@ -66,7 +69,17 @@ int cmd_tbl_item_count(cmd_tbl_t *p) int count = 0; while (p->name != NULL) { - p++; count++; + if (p->subcmd) { + cmd_tbl_t *sub = p->subcmd; + while (sub->name != NULL) { + if (sub->flags & CTBL_SUBCMDAUTO) + count++; + sub++; + } + } + if ((p->flags & CTBL_SUBCMDAUTO) == 0) + count++; + p++; } return count; } @@ -85,49 +98,46 @@ cmd_tbl_t *get_cmd_tbl_base(cmd_tbl_t *cmdtp) /* * find command table entry for a command */ + cmd_tbl_t *find_cmd (const char *cmd, cmd_tbl_t *table) { - cmd_tbl_t *cmdtp; - cmd_tbl_t *cmdtp_temp = table; /*Init value */ - int table_len = cmd_tbl_item_count(table); - size_t len; - uint_fast8_t n_found = 0; - - char *optenv = getenv_str(PSTR("cmd")); - bool opt_debug = optenv && strstr_P(optenv, PSTR("debug")) != NULL; - if (!cmd) return NULL; - len = strlen(cmd); + char *optenv = getenv_str(PSTR("cmd")); + uint8_t opt_debug = optenv && strstr_P(optenv, PSTR("debug")) != NULL; - for (cmdtp = table; - cmdtp != table + table_len; - cmdtp++) { - if (strncmp_P(cmd, cmdtp->name, len) == 0 && - (opt_debug || cmdtp->name[0] != '!')) { + cmd_tbl_t *cmdtp_ret = NULL; + uint_fast8_t n_found = 0; + uint_fast8_t len = strlen(cmd); + + for (cmd_tbl_t *cmdtp = table; cmdtp->name != NULL; cmdtp++) { + if (cmdtp->subcmd) { + for (cmd_tbl_t *sub = cmdtp->subcmd; sub->name != NULL; sub++) { + if (sub->flags & CTBL_SUBCMDAUTO && + strncmp_P(cmd, sub->name, len) == 0 && + (opt_debug || !(sub->flags & CTBL_DBG))) { + if (len == strlen_P(sub->name)) + return sub; /* full match */ + cmdtp_ret = sub; /* abbreviated command ? */ + ++n_found; + } + } + } + if ((cmdtp->flags & CTBL_SUBCMDAUTO) == 0 && + strncmp_P(cmd, cmdtp->name, len) == 0 && + (opt_debug || !(cmdtp->flags & CTBL_DBG))) { if (len == strlen_P(cmdtp->name)) - return cmdtp; /* full match */ - - cmdtp_temp = cmdtp; /* abbreviated command ? */ - n_found++; + return cmdtp; /* full match */ + cmdtp_ret = cmdtp; /* abbreviated command ? */ + ++n_found; } } - if (n_found == 1) /* exactly one match */ - return cmdtp_temp; - - return NULL; /* not found or ambiguous command */ -} -cmd_tbl_t *find_cmd_sub(const char *cmd, cmd_tbl_t *table) -{ - cmd_tbl_t *entry = NULL; - - for (cmd_tbl_t *tp = get_cmd_tbl_base(table); tp->name && entry == NULL; tp++) - if (tp->subcmd && tp->flags & CTBL_SUBCMDAUTO) - entry = find_cmd(cmd, tp->subcmd); + if (n_found == 1) + return cmdtp_ret; /* exactly one match */ - return entry; + return NULL; /* not found or ambiguous command */ } /* @@ -135,10 +145,8 @@ cmd_tbl_t *find_cmd_sub(const char *cmd, cmd_tbl_t *table) * for long help messages */ -command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[]) +command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag UNUSED, int argc, char * const argv[]) { - (void) flag; - cmd_tbl_t *tbl_start = get_cmd_tbl_base(cmdtp); char *optenv = getenv_str(PSTR("cmd")); @@ -146,39 +154,57 @@ command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * cons if (argc == 1) { /*show list of commands */ int cmd_items = cmd_tbl_item_count(tbl_start); - cmd_tbl_t *cmd_array[cmd_items]; - cmd_tbl_t *tp = tbl_start; - uint_fast8_t max_len = 0; + cmd_tbl_t **cmd_list = (cmd_tbl_t **) malloc(cmd_items * sizeof(cmd_tbl_t *)); + uint_fast8_t maxlen_cmd = 0; - /* Make array of commands from .uboot_cmd section */ - for (int i = 0; i < cmd_items; i++) { - cmd_array[i] = tp++; - uint_fast8_t l = strlen_P(cmd_array[i]->name); - if (l > max_len) - max_len = l; + /* Make array of commands */ + cmd_tbl_t *tp = tbl_start; + int i = 0; + while (tp->name != NULL) { + if (tp->subcmd) { + cmd_tbl_t *sub = tp->subcmd; + while (sub->name != NULL) { + if (sub->flags & CTBL_SUBCMDAUTO) { + uint_fast8_t len = strlen_P(sub->name); + if (len > maxlen_cmd) + maxlen_cmd = len; + cmd_list[i++] = sub; + } + sub++; + } + } + if ((tp->flags & CTBL_SUBCMDAUTO) == 0) { + uint_fast8_t len = strlen_P(tp->name); + if (len > maxlen_cmd) + maxlen_cmd = len; + cmd_list[i++] = tp; + } + tp++; } - /* Sort command list */ - qsort(cmd_array, cmd_items, sizeof (cmd_tbl_t *), cmpstring_PP); + qsort(cmd_list, cmd_items, sizeof (cmd_tbl_t *), cmpstring_PP); /* print short help (usage) */ for (int i = 0; i < cmd_items; i++) { - if (opt_debug || cmd_array[i]->name[0] != '!') { - const FLASH char *usage = cmd_array[i]->usage; + if (opt_debug || !(cmd_list[i]->flags & CTBL_DBG)) { + const FLASH char *usage = cmd_list[i]->usage; /* allow user abort */ - if (ctrlc ()) + if (ctrlc ()) { + free(cmd_list); return CMD_RET_FAILURE; + } if (usage == NULL) continue; #if defined(GCC_BUG_61443) || 1 - print_usage_line(cmd_array[i]->name, max_len, usage); + print_usage_line(cmd_list[i]->name, maxlen_cmd, usage); #else printf_P(PSTR("%-" stringify(8) /*FIXME*/ "S - %S\n"), - cmd_array[i]->name, usage); + cmd_list[i]->name, usage); #endif } } + free(cmd_list); return CMD_RET_SUCCESS; } @@ -186,8 +212,7 @@ command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * cons * command help (long version) */ for (uint8_t i = 1; i < argc; ++i) { - if ((cmdtp = find_cmd(argv[i], tbl_start)) != NULL && - (opt_debug || cmdtp->name[0] != '!')) { + if ((cmdtp = find_cmd(argv[i], tbl_start)) != NULL) { cmd_usage(cmdtp); } else { printf_P(PSTR("Unknown command '%s' - try 'help'" @@ -201,7 +226,7 @@ command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * cons } -command_ret_t cmd_usage(const FLASH cmd_tbl_t *cmdtp) +command_ret_t cmd_usage(cmd_tbl_t *cmdtp) { // printf("%s - %s\n\n", cmdtp->name, cmdtp->usage); print_usage_line(cmdtp->name, 0, cmdtp->usage); @@ -535,9 +560,6 @@ command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], --argc; ++argv; } - } else { - /* Search subcommands */ - cmdtp = find_cmd_sub(argv[0], cmd_tbl); } if (cmdtp == NULL) { @@ -567,7 +589,7 @@ command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], /* If OK so far, then do the command */ if (!rc) { rc = cmd_call(cmdtp, flag, argc, argv); - *repeatable &= (cmdtp->flags & CTBL_REPEAT) != 0; + *repeatable &= (cmdtp->flags & CTBL_RPT) != 0; } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp);