diff --git a/common/command.c b/common/command.c index fe29075..aa0fb0a 100644 --- a/common/command.c +++ b/common/command.c @@ -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; +} diff --git a/common/hush.c b/common/hush.c index 3aa9d50..672ab9e 100644 --- a/common/hush.c +++ b/common/hush.c @@ -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]); diff --git a/common/main.c b/common/main.c index 6a3eac2..4adc17a 100644 --- a/common/main.c +++ b/common/main.c @@ -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 ()) diff --git a/include/command.h b/include/command.h index 6dc694f..6e1bdc2 100644 --- a/include/command.h +++ b/include/command.h @@ -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__ */