[U-Boot] [PATCH v4 8/9] Add cmd_process() to process commands in one place

Simon Glass sjg at chromium.org
Sat Jan 14 07:45:56 CET 2012


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 at chromium.org>
---
Changes in v4:
- Add a 'repeatable' parameter to cmd_process()
- Rationalise return codes to 0, 1 and usage
- Make cmd_process() return only success (0) or failure (1)

 common/command.c  |   43 +++++++++++++++++++++++++++++++++++++++++--
 common/hush.c     |   52 ++++++++++++----------------------------------------
 common/main.c     |   37 +------------------------------------
 include/command.h |   29 ++++++++++++++++++++++++++++-
 4 files changed, 82 insertions(+), 79 deletions(-)

diff --git a/common/command.c b/common/command.c
index d402e0f..aa0fb0a 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[],
+			       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 123dfa2..7e2a5e3 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,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 4316610..20f2e99 100644
--- a/include/command.h
+++ b/include/command.h
@@ -152,7 +152,34 @@ 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 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__ */
 
 #endif	/* __COMMAND_H */
-- 
1.7.7.3



More information about the U-Boot mailing list