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

Simon Glass sjg at chromium.org
Mon Jan 23 07:48:53 CET 2012


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

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

Changes in v3:
- Only output usage on stderr if we get an error
- Tidy code style around getopt()

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

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 9f93f83..4b54fa6 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,43 @@ u64 os_get_nsec(void)
 	return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
 #endif
 }
+
+static const char options[] = "c:h";
+
+static const 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(err < 0 ? stderr : stdout, "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, options, 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 a3c1e84..f7e8c31 100644
--- a/include/os.h
+++ b/include/os.h
@@ -104,3 +104,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.7.3



More information about the U-Boot mailing list