X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/8da60ec50c642816ed55a2004e99afea1cc25147..b9aef06edc26e3d7560a7ab2d83fe033349ef874:/avr/command.c diff --git a/avr/command.c b/avr/command.c index 07fff78..aa784cb 100644 --- a/avr/command.c +++ b/avr/command.c @@ -59,6 +59,8 @@ int cmpstring_PP(const void *p1, const void *p2) (*(const FLASH cmd_tbl_t **) p2)->name); } +/****************************************************************************/ + int cmd_tbl_item_count(cmd_tbl_t *p) { int count = 0; @@ -69,17 +71,76 @@ int cmd_tbl_item_count(cmd_tbl_t *p) return count; } + +cmd_tbl_t *get_cmd_tbl_base(cmd_tbl_t *cmdtp) +{ + cmd_tbl_t *p = cmdtp; + + while (p->name != NULL) + ++p; + + return p->subcmd; +} + +/* + * 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); + + for (cmdtp = table; + cmdtp != table + table_len; + cmdtp++) { + if (strncmp_P(cmd, cmdtp->name, len) == 0 && + (opt_debug || cmdtp->name[0] != '!')) { + if (len == strlen_P(cmdtp->name)) + return cmdtp; /* full match */ + + cmdtp_temp = 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); + + return entry; +} + /* * Use puts() instead of printf() to avoid printf buffer overflow * for long help messages */ -command_ret_t _do_help(cmd_tbl_t *tbl_start, 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, int argc, char * const argv[]) { - (void) flag; + cmd_tbl_t *tbl_start = get_cmd_tbl_base(cmdtp); + char *optenv = getenv_str(PSTR("cmd")); bool opt_debug = optenv && strstr_P(optenv, PSTR("debug")) != NULL; @@ -139,44 +200,6 @@ command_ret_t _do_help(cmd_tbl_t *tbl_start, cmd_tbl_t * cmdtp, return CMD_RET_SUCCESS; } -/*************************************************************************** - * 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); - - for (cmdtp = table; - cmdtp != table + table_len; - cmdtp++) { - if (strncmp_P(cmd, cmdtp->name, len) == 0 && - (opt_debug || cmdtp->name[0] != '!')) { - if (len == strlen_P(cmdtp->name)) - return cmdtp; /* full match */ - - cmdtp_temp = cmdtp; /* abbreviated command ? */ - n_found++; - } - } - if (n_found == 1) /* exactly one match */ - return cmdtp_temp; - - return NULL; /* not found or ambiguous command */ -} - - command_ret_t cmd_usage(const FLASH cmd_tbl_t *cmdtp) { @@ -488,6 +511,8 @@ command_ret_t cmd_call(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * con return result; } +#pragma GCC diagnostic ignored "-Wclobbered" + command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], uint_fast8_t *repeatable) { @@ -496,25 +521,30 @@ command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], /* Look up command in command table */ cmdtp = find_cmd(argv[0], cmd_tbl); + if (cmdtp != NULL) { + /* Check if this command has subcommands */ + if (cmdtp->subcmd && argc > 1) { + + /* Look up subcommand in subcommand table */ + cmd_tbl_t *cmdtpsub = find_cmd(argv[1], cmdtp->subcmd); + if (cmdtpsub == NULL) { + printf_P(PSTR("Unknown '%s' subcommand '%s' - try '%s help'\n"), argv[0], argv[1], argv[0]); + return CMD_RET_FAILURE; + } + cmdtp = cmdtpsub; + --argc; + ++argv; + } + } else { + /* Search subcommands */ + cmdtp = find_cmd_sub(argv[0], cmd_tbl); + } + if (cmdtp == NULL) { printf_P(PSTR("Unknown command '%s' - try 'help'\n"), argv[0]); return CMD_RET_FAILURE; } - /* Check for subcommand */ - if (cmdtp->subcmd && argc > 1) { - - /* Look up subcommand in subcommand table */ - cmd_tbl_t *cmdtpsub = find_cmd(argv[1], cmdtp->subcmd); - if (cmdtpsub == NULL) { - printf_P(PSTR("Unknown '%s' subcommand '%s' - try '%s help'\n"), argv[0], argv[1], argv[0]); - return CMD_RET_FAILURE; - } - cmdtp = cmdtpsub; - --argc; - ++argv; - } - /* found - check max args */ if (argc > cmdtp->maxargs) rc = CMD_RET_USAGE;