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

Simon Glass sjg at chromium.org
Thu Feb 16 00:51:18 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()

Changes in v4:
- Store command-line arguments in the state structure

 arch/sandbox/cpu/os.c                         |   45 +++++++++++++++++++++++++
 arch/sandbox/cpu/start.c                      |   23 +++++++++++-
 arch/sandbox/include/asm/arch-sandbox/state.h |    3 ++
 include/os.h                                  |   22 ++++++++++++
 4 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 9f93f83..b37d13f 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,45 @@ 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;
+
+	state->argc = argc;
+	state->argv = argv;
+	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 ba000cd..783ea6e 100644
--- a/arch/sandbox/include/asm/arch-sandbox/state.h
+++ b/arch/sandbox/include/asm/arch-sandbox/state.h
@@ -33,6 +33,9 @@ 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 */
+	int argc;			/* Program arguments */
+	char **argv;
 };
 
 /**
diff --git a/include/os.h b/include/os.h
index 136b6c4..df07d19 100644
--- a/include/os.h
+++ b/include/os.h
@@ -24,6 +24,8 @@
  * MA 02111-1307 USA
  */
 
+struct sandbox_state;
+
 /**
  * Access to the OS read() system call
  *
@@ -102,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