[coreboot] New patch to review for filo: cc5a039 Add function to convert grub arguments to unix style argc/argv

Patrick Georgi (patrick@georgi-clan.de) gerrit at coreboot.org
Thu Nov 8 14:47:36 CET 2012


Patrick Georgi (patrick at georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1808

-gerrit

commit cc5a0399df03cda36385a2c7dd206b1f7f70d671
Author: Patrick Georgi <patrick.georgi at secunet.com>
Date:   Tue Mar 13 10:24:32 2012 +0100

    Add function to convert grub arguments to unix style argc/argv
    
    This provides a function to_argc_argv() to split a single string
    into argc/argv for easier consumption by getopt(). It honors double
    quotes, but doesn't handle \" (ie. escaped quotes) - they are
    treated like separate tokens.
    
    Change-Id: I28f408de8727c6bd2d098db24f05b04acc91eaea
    Signed-off-by: Patrick Georgi <patrick.georgi at secunet.com>
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 include/grub/shared.h |  1 +
 main/grub/builtins.c  | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/include/grub/shared.h b/include/grub/shared.h
index 9e74d7c..b293f3f 100644
--- a/include/grub/shared.h
+++ b/include/grub/shared.h
@@ -302,6 +302,7 @@ void print_a_completion (char *filename);
 int print_completions (int is_filename, int is_completion);
 
 int check_password(char *entered, char* expected, password_t type);
+int to_argc_argv(char *args, char ***argvp);
 
 /* FILO specific stuff */
 void copy_path_to_filo_bootline(char *arg, char *path, int use_rootdev, int append);
diff --git a/main/grub/builtins.c b/main/grub/builtins.c
index 3451071..e40663b 100644
--- a/main/grub/builtins.c
+++ b/main/grub/builtins.c
@@ -112,6 +112,58 @@ int check_password(char *entered, char *expected, password_t type)
 	}
 }
 
+/* TODO: handle \" */
+int to_argc_argv(char *args, char ***argvp)
+{
+	/* allocate enough space to point to all arguments:
+	 * args only contains the arguments (no command name), so
+	 * - add 1 for argv[0] (= NULL)
+	 * - add strlen(args)/2 + 1 (handles worst case scenario: "a b")
+	 * - add 1 for argv[argc] (= NULL)
+	 */
+	char **argv = malloc(sizeof(char*)*(strlen(args)/2+3));
+	int argc = 0;
+	argv[argc++] = NULL;
+	while (*args) {
+		int skipbytes = 0;
+		int quoted = 0;
+
+		/* register token */
+		argv[argc++] = args;
+
+		/* skip over token */
+		while (*args) {
+			if (!quoted && isblank(*args)) {
+				break;
+			}
+			/* if quote, skip current byte */
+			if (*args == '"') {
+				quoted = !quoted;
+				skipbytes++;
+			} else {
+				/* otherwise, proceed */
+				args++;
+			}
+			/* make up for skipped quotes */
+			*args = args[skipbytes];
+		}
+
+		/* terminate token, but don't skip over trailing NUL */
+		if (*args != '\0') {
+			*args++ = '\0';
+			args += skipbytes;
+		}
+
+		/* skip any whitespace before next token */
+		while ((*args != '\0') && (isblank(*args))) {
+			args++;
+		}
+	}
+	argv[argc] = NULL;
+	*argvp = argv;
+	return argc;
+}
+
 /* boot */
 static int boot_func(char *arg, int flags)
 {




More information about the coreboot mailing list