]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/command.c
New debug command: dump heap
[z180-stamp.git] / avr / command.c
index 07fff78fbf24dce4cf1498fb5e2843561a8bee29..aa784cbca637246810ecbf9eb056830f29cc5b12 100644 (file)
@@ -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;