
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 U-Boot will print a usage message for the command.
ARM code size increases about 32 bytes with this clean-up.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/command.c | 43 ++++++++++++++++++++++++++++++++++++++- common/hush.c | 56 +++++++++++++++------------------------------------- common/main.c | 39 +++--------------------------------- include/command.h | 21 ++++++++++++++++++- 4 files changed, 81 insertions(+), 78 deletions(-)
diff --git a/common/command.c b/common/command.c index d402e0f..990e901 100644 --- a/common/command.c +++ b/common/command.c @@ -497,9 +497,9 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size) * @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 - * @return 0 if command succeeded, else non-zero + * @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[]) +{ + enum command_ret_t rc = CMD_RET_ERROR; + 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]); + + /* found - check max args */ + else 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"); + else { + flag |= CMD_FLAG_BOOTD; + rc = CMD_RET_OK; + } + } +#endif + else + rc = CMD_RET_OK; + + /* If OK so far, then do the command */ + if (!rc) + rc = cmd_call(cmdtp, flag, argc, argv); + + if (rc == CMD_RET_USAGE) + cmd_usage(cmdtp); + else if (rc == CMD_RET_OK && !cmdtp->repeatable) + return CMD_RET_NO_REPEAT; + return rc; +} diff --git a/common/hush.c b/common/hush.c index 3aa9d50..f8df3fc 100644 --- a/common/hush.c +++ b/common/hush.c @@ -1538,8 +1538,8 @@ 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; + enum command_ret_t rc; # if __GNUC__ /* Avoid longjmp clobbering */ (void) &i; @@ -1652,47 +1652,23 @@ 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 */ + rc = cmd_process(flag, child->argc, child->argv); + if (rc == CMD_RET_NO_REPEAT) { + flag_repeat = 0; + rc = CMD_RET_OK; + } +#endif } +#ifndef __U_BOOT__
for (i = 0; i < pi->num_progs; i++) { child = & (pi->progs[i]); diff --git a/common/main.c b/common/main.c index f34ba71..6f247ce 100644 --- a/common/main.c +++ b/common/main.c @@ -1245,7 +1245,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 */ @@ -1323,41 +1322,11 @@ 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; - } + rc = cmd_process(flag, argc, argv); + if (rc == CMD_RET_NO_REPEAT) { + repeatable = 0; + rc = CMD_RET_OK; } -#endif - - /* OK - call function to do the command */ - if (cmd_call(cmdtp, flag, argc, argv) != 0) - rc = -1; - - repeatable &= cmdtp->repeatable;
/* Did the user stop this? */ if (had_ctrlc ()) diff --git a/include/command.h b/include/command.h index 4316610..b1a701c 100644 --- a/include/command.h +++ b/include/command.h @@ -152,7 +152,26 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size); #endif
#ifndef __ASSEMBLY__ -int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +/* Error codes that cmd_process() can return */ +enum command_ret_t { + CMD_RET_OK, /* SUccess, and can repeat command */ + CMD_RET_ERROR = -1, /* An error occurred and was reported */ + CMD_RET_USAGE = -2, /* Please report 'usage' error */ + CMD_RET_RECURSE = -3, /* Recursion error detected */ + CMD_RET_UNKNOWN = -4, /* Unknown command */ + CMD_RET_NO_REPEAT = -5, /* Success, but cannot repeat command */ +}; + +/** + * 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 + * @return value of command_rc_t depending on result + */ +enum command_ret_t cmd_process(int flag, int argc, char * const argv[]); #endif /* __ASSEMBLY__ */
#endif /* __COMMAND_H */