Add cmd_process() to process commands in one place
authorSimon Glass <sjg@chromium.org>
Tue, 14 Feb 2012 19:59:25 +0000 (19:59 +0000)
committerWolfgang Denk <wd@denx.de>
Tue, 6 Mar 2012 20:09:41 +0000 (21:09 +0100)
We currently have the same code in hush.c and main.c. This brings the
code into one place.

As an added feature, if the command function returns CMD_RET_USAGE then
cmd_process() will print a usage message for the command before
returning the standard failure code of 1.

ARM code size increases about 32 bytes with this clean-up.

Signed-off-by: Simon Glass <sjg@chromium.org>
common/command.c
common/hush.c
common/main.c
include/command.h

index fe290759cd06d871bd6779585e4c4d2c7ecadd45..aa0fb0a3d36b06830afdcbcb4c3a37bd5c158088 100644 (file)
@@ -499,7 +499,7 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size)
  * @param argv         Arguments
  * @return 0 if command succeeded, else non-zero (CMD_RET_...)
  */
-int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        int result;
 
@@ -508,3 +508,42 @@ int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                debug("Command failed, result=%d", result);
        return result;
 }
+
+enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
+                              int *repeatable)
+{
+       enum command_ret_t rc = CMD_RET_SUCCESS;
+       cmd_tbl_t *cmdtp;
+
+       /* Look up command in command table */
+       cmdtp = find_cmd(argv[0]);
+       if (cmdtp == NULL) {
+               printf("Unknown command '%s' - try 'help'\n", argv[0]);
+               return 1;
+       }
+
+       /* found - check max args */
+       if (argc > cmdtp->maxargs)
+               rc = CMD_RET_USAGE;
+
+#if defined(CONFIG_CMD_BOOTD)
+       /* avoid "bootd" recursion */
+       else if (cmdtp->cmd == do_bootd) {
+               if (flag & CMD_FLAG_BOOTD) {
+                       puts("'bootd' recursion detected\n");
+                       rc = CMD_RET_FAILURE;
+               } else {
+                       flag |= CMD_FLAG_BOOTD;
+               }
+       }
+#endif
+
+       /* If OK so far, then do the command */
+       if (!rc) {
+               rc = cmd_call(cmdtp, flag, argc, argv);
+               *repeatable &= cmdtp->repeatable;
+       }
+       if (rc == CMD_RET_USAGE)
+               rc = cmd_usage(cmdtp);
+       return rc;
+}
index 3aa9d501138328ace687fb849d911c4b5e221d85..672ab9e157ed780382b1b39e262172bfbe9c70c2 100644 (file)
@@ -1538,7 +1538,6 @@ static int run_pipe_real(struct pipe *pi)
        int nextin;
        int flag = do_repeat ? CMD_FLAG_REPEAT : 0;
        struct child_prog *child;
-       cmd_tbl_t *cmdtp;
        char *p;
 # if __GNUC__
        /* Avoid longjmp clobbering */
@@ -1652,47 +1651,20 @@ static int run_pipe_real(struct pipe *pi)
                        return rcode;
                }
 #else
-                       /* check ";", because ,example , argv consist from
-                        * "help;flinfo" must not execute
-                        */
-                       if (strchr(child->argv[i], ';')) {
-                               printf ("Unknown command '%s' - try 'help' or use 'run' command\n",
-                                       child->argv[i]);
-                               return -1;
-                       }
-                       /* Look up command in command table */
-
-
-                       if ((cmdtp = find_cmd(child->argv[i])) == NULL) {
-                               printf ("Unknown command '%s' - try 'help'\n", child->argv[i]);
-                               return -1;      /* give up after bad command */
-                       } else {
-                               int rcode;
-#if defined(CONFIG_CMD_BOOTD)
-                               /* avoid "bootd" recursion */
-                               if (cmdtp->cmd == do_bootd) {
-                                       if (flag & CMD_FLAG_BOOTD) {
-                                               printf ("'bootd' recursion detected\n");
-                                               return -1;
-                                       }
-                               else
-                                       flag |= CMD_FLAG_BOOTD;
-                               }
-#endif
-                               /* found - check max args */
-                               if ((child->argc - i) > cmdtp->maxargs)
-                                       return cmd_usage(cmdtp);
-#endif
-                               /* OK - call function to do the command */
-                               rcode = cmd_call(cmdtp, flag,  child->argc,
-                                                child->argv);
-                               if (!cmdtp->repeatable)
-                                       flag_repeat = 0;
-                               return rcode;
-                       }
+               /* check ";", because ,example , argv consist from
+                * "help;flinfo" must not execute
+                */
+               if (strchr(child->argv[i], ';')) {
+                       printf("Unknown command '%s' - try 'help' or use "
+                                       "'run' command\n", child->argv[i]);
+                       return -1;
                }
-#ifndef __U_BOOT__
+               /* Process the command */
+               return cmd_process(flag, child->argc, child->argv,
+                                  &flag_repeat);
+#endif
        }
+#ifndef __U_BOOT__
 
        for (i = 0; i < pi->num_progs; i++) {
                child = & (pi->progs[i]);
index 6a3eac28aa7e280fbd8b6f508e5cd938c3e15375..4adc17a9f78470efb1643dd6f43cac8e78030989 100644 (file)
@@ -1261,7 +1261,6 @@ static void process_macros (const char *input, char *output)
  */
 static int builtin_run_command(const char *cmd, int flag)
 {
-       cmd_tbl_t *cmdtp;
        char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd          */
        char *token;                    /* start of token in cmdbuf     */
        char *sep;                      /* end of token (separator) in cmdbuf */
@@ -1339,41 +1338,7 @@ static int builtin_run_command(const char *cmd, int flag)
                        continue;
                }
 
-               /* Look up command in command table */
-               if ((cmdtp = find_cmd(argv[0])) == NULL) {
-                       printf ("Unknown command '%s' - try 'help'\n", argv[0]);
-                       rc = -1;        /* give up after bad command */
-                       continue;
-               }
-
-               /* found - check max args */
-               if (argc > cmdtp->maxargs) {
-                       cmd_usage(cmdtp);
-                       rc = -1;
-                       continue;
-               }
-
-#if defined(CONFIG_CMD_BOOTD)
-               /* avoid "bootd" recursion */
-               if (cmdtp->cmd == do_bootd) {
-#ifdef DEBUG_PARSER
-                       printf ("[%s]\n", finaltoken);
-#endif
-                       if (flag & CMD_FLAG_BOOTD) {
-                               puts ("'bootd' recursion detected\n");
-                               rc = -1;
-                               continue;
-                       } else {
-                               flag |= CMD_FLAG_BOOTD;
-                       }
-               }
-#endif
-
-               /* OK - call function to do the command */
-               if (cmd_call(cmdtp, flag, argc, argv) != 0)
-                       rc = -1;
-
-               repeatable &= cmdtp->repeatable;
+               rc = cmd_process(flag, argc, argv, &repeatable);
 
                /* Did the user stop this? */
                if (had_ctrlc ())
index 6dc694f7a83d31d90346b5af875797298620cc0f..6e1bdc2ab27479dc61b2e4f1e020b524eaa40792 100644 (file)
@@ -112,7 +112,34 @@ static inline int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd)
 #endif
 extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 
-int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+/*
+ * Error codes that commands return to cmd_process(). We use the standard 0
+ * and 1 for success and failure, but add one more case - failure with a
+ * request to call cmd_usage(). But the cmd_process() function handles
+ * CMD_RET_USAGE itself and after calling cmd_usage() it will return 1.
+ * This is just a convenience for commands to avoid them having to call
+ * cmd_usage() all over the place.
+ */
+enum command_ret_t {
+       CMD_RET_SUCCESS,        /* 0 = Success */
+       CMD_RET_FAILURE,        /* 1 = Failure */
+       CMD_RET_USAGE = -1,     /* Failure, please report 'usage' error */
+};
+
+/**
+ * Process a command with arguments. We look up the command and execute it
+ * if valid. Otherwise we print a usage message.
+ *
+ * @param flag         Some flags normally 0 (see CMD_FLAG_.. above)
+ * @param argc         Number of arguments (arg 0 must be the command text)
+ * @param argv         Arguments
+ * @param repeatable   This function sets this to 0 if the command is not
+ *                     repeatable. If the command is repeatable, the value
+ *                     is left unchanged.
+ * @return 0 if the command succeeded, 1 if it failed
+ */
+int cmd_process(int flag, int argc, char * const argv[],
+                              int *repeatable);
 
 #endif /* __ASSEMBLY__ */