[U-Boot] [PATCH v2 8/8] sandbox: Add basic command line parsing

Simon Glass sjg at chromium.org
Wed Jan 11 01:45:52 CET 2012


This adds simple command-line parssing to sandbox. The idea is that it
sets up the state with options provided, and this state can then be
queried as needed later.

For now we just allow it to run a command.

Passing a command to U-Boot on stdin is not as convenient IMO.

The parsing code is in os.c since it gives us easy access to getopt and
friends. We could create a separate parse.c file if this grows.

Signed-off-by: Simon Glass <sjg at chromium.org>
---
Changes in v2:
- Clean up, added a few fdt and config patches
- Rebase on master

 arch/sandbox/cpu/os.c                         |   41 +++++++++++++++++++++++++
 arch/sandbox/cpu/start.c                      |   23 +++++++++++++-
 arch/sandbox/include/asm/arch-sandbox/state.h |    1 +
 include/os.h                                  |   20 ++++++++++++
 4 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 9f93f83..1b50442 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -21,6 +21,8 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <getopt.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <termios.h>
 #include <time.h>
@@ -30,6 +32,7 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <linux/types.h>
+#include <asm/arch/state.h>
 
 #include <os.h>
 
@@ -122,3 +125,41 @@ u64 os_get_nsec(void)
 	return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
 #endif
 }
+
+static struct option long_options[] = {
+	{"command", required_argument, NULL, 'c'},
+	{"help", no_argument, NULL, 'h'},
+	{NULL, 0, NULL, 0}
+};
+
+void os_usage(int err)
+{
+	if (err < 0)
+		fprintf(stderr, "Try `--help' for more information.\n");
+	fprintf(stderr, "u-boot, "
+		"a command line test interface to U-Boot\n\n"
+		"usage:\tu-boot [-ch]\n"
+		"Options:\n"
+		"\t-h\tDisplay help\n"
+		"\t-c <command>\tExecute U-Boot command\n");
+	exit(1);
+}
+
+int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
+{
+	int c;
+
+	while ((c = getopt_long(argc, argv, "c:h",
+		long_options, NULL)) != EOF) {
+		switch (c) {
+		case 'c':
+			state->cmd = optarg;
+			break;
+		case 'h':
+			return 1;
+		default: /* '?' */
+			return -1;
+		}
+	}
+	return 0;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index d7402be..fa7a907 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -26,8 +26,26 @@
 
 void start_main_loop(void)
 {
-	for (;;)
-		main_loop();
+	struct sandbox_state *state = state_get_current();
+
+	if (state->err)
+		os_usage(state->err);	/* does not return */
+
+	/* Execute command if required */
+	if (state->cmd) {
+		/* TODO: redo this when cmd tidy-up series lands */
+#ifdef CONFIG_SYS_HUSH_PARSER
+		run_command(state->cmd, 0);
+#else
+		parse_string_outer(state->cmd, FLAG_PARSE_SEMICOLON |
+				    FLAG_EXIT_FROM_LOOP);
+#endif
+	} else {
+		for (;;)
+			main_loop();
+	}
+	printf("U-Boot exited with state %d\n", state->exit_type);
+	os_exit(state->exit_type);
 }
 
 int main(int argc, char *argv[])
@@ -39,6 +57,7 @@ int main(int argc, char *argv[])
 	if (!err) {
 		state = state_get_current();
 		assert(state);
+		state->err = os_parse_args(state, argc, argv);
 	}
 
 	/*
diff --git a/arch/sandbox/include/asm/arch-sandbox/state.h b/arch/sandbox/include/asm/arch-sandbox/state.h
index 3023368..1e035fa 100644
--- a/arch/sandbox/include/asm/arch-sandbox/state.h
+++ b/arch/sandbox/include/asm/arch-sandbox/state.h
@@ -30,6 +30,7 @@ enum exit_type_id {
 struct sandbox_state {
 	const char *cmd;		/* Command to execute */
 	enum exit_type_id exit_type;	/* How we exited U-Boot */
+	int err;			/* Error to report from parsing */
 };
 
 /**
diff --git a/include/os.h b/include/os.h
index 66e60f8..2b66813 100644
--- a/include/os.h
+++ b/include/os.h
@@ -106,3 +106,23 @@ void os_usleep(unsigned long usec);
  * \return A monotonic increasing time scaled in nano seconds
  */
 u64 os_get_nsec(void);
+
+/**
+ * Parse arguments and update sandbox state.
+ *
+ * @param state		Sandbox state to update
+ * @param argc		Argument count
+ * @param argv		Argument vector
+ * @return 0 if ok, and program should continue;
+ *	1 if ok, but program should stop;
+ *	-1 on error: program should terminate.
+ */
+int os_parse_args(struct sandbox_state *state, int argc, char *argv[]);
+
+/**
+ * Display a usage message on stderr and exit
+ *
+ * @param err		Error code (-ve means the user entered an invalid
+ *			option)
+ */
+void os_usage(int err);
-- 
1.7.3.1



More information about the U-Boot mailing list