Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Dec 2002 15:32:49 -0800 (PST)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 22082 for review
Message-ID:  <200212082332.gB8NWnxH002504@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=22082

Change 22082 by marcel@marcel_nfs on 2002/12/08 15:32:34

	Finish the option string parsing. First we normalize the
	option string to be in Unicode-16 This is a poor man's
	algorithm that merely casts. If the string was already in
	Unicode, we make a copy so that we can be sure we can modify
	it.
	Secondly, we count the number of words in the string. This
	does not deal with quoting or other shell-like features.
	If such is needed, it can be added.
	Lastly, we construct the argv vector. For now we hardcode
	argv[0] to point to L"loader.efi", but it would be really
	nice if we could construct a real pathname. That would
	allow if to determine from which file system we were loaded.
	Again, this functionality can be added seperately.

Affected files ...

.. //depot/projects/ia64/sys/boot/efi/libefi/libefi.c#3 edit

Differences ...

==== //depot/projects/ia64/sys/boot/efi/libefi/libefi.c#3 (text+ko) ====

@@ -31,6 +31,7 @@
 
 #include <efi.h>
 #include <efilib.h>
+#include <stand.h>
 
 EFI_HANDLE		IH;
 EFI_SYSTEM_TABLE	*ST;
@@ -40,6 +41,24 @@
 static EFI_PHYSICAL_ADDRESS heap;
 static UINTN heapsize;
 
+static CHAR16 *
+arg_skipsep(CHAR16 *argp)
+{
+
+	while (*argp == ' ' || *argp == '\t')
+		argp++;
+	return (argp);
+}
+
+static CHAR16 *
+arg_skipword(CHAR16 *argp)
+{
+
+	while (*argp && *argp != ' ' && *argp != '\t')
+		argp++;
+	return (argp);
+}
+
 void *
 efi_get_table(EFI_GUID *tbl)
 {
@@ -65,8 +84,10 @@
 efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
 {
 	static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL;
-	EFI_LOADED_IMAGE *image;
+	EFI_LOADED_IMAGE *img;
+	CHAR16 *argp, *args, **argv;
 	EFI_STATUS status;
+	int argc;
 
 	IH = image_handle;
 	ST = system_table;
@@ -83,10 +104,67 @@
 
 	/* Use exit() from here on... */
 
-	status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&image);
+	status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img);
 	if (status != EFI_SUCCESS)
 		exit(status);
 
-	status = main(image->LoadOptionsSize, image->LoadOptions);
+	/*
+	 * Pre-process the (optional) load options. If the option string
+	 * is given as an ASCII string, we use a poor man's ASCII to
+	 * Unicode-16 translation. The size of the option string as given
+	 * to us includes the terminating null character. We assume the
+	 * string is an ASCII string if strlen() plus the terminating
+	 * '\0' is less than LoadOptionsSize. Even if all Unicode-16
+	 * characters have the upper 8 bits non-zero, the terminating
+	 * null character will cause a one-off.
+	 * If the string is already in Unicode-16, we make a copy so that
+	 * we know we can always modify the string.
+	 */
+	if (img->LoadOptionsSize) {
+		if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) {
+			args = malloc(img->LoadOptionsSize << 1);
+			for (argc = 0; argc < img->LoadOptionsSize; argc++)
+				args[argc] = ((char*)img->LoadOptions)[argc];
+		} else {
+			args = malloc(img->LoadOptionsSize);
+			memcpy(args, img->LoadOptions, img->LoadOptionsSize);
+		}
+	} else
+		args = NULL;
+
+	/*
+	 * Use a quick and dirty algorithm to build the argv vector. We
+	 * first count the number of words. Then, after allocating the
+	 * vector, we split the string up. We don't deal with quotes or
+	 * other more advanced shell features.
+	 */
+	/* Part 1: count words. */
+	argc = 1;	/* The EFI program name. */
+	argp = args;
+	while (argp != NULL && *argp != 0) {
+		argp = arg_skipsep(argp);
+		if (*argp == 0)
+			break;
+		argc++;
+		argp = arg_skipword(argp);
+	}
+	/* Part 2: build vector. */
+	argv = malloc((argc + 1) * sizeof(CHAR16*));
+	argv[0] = L"loader.efi";		/* XXX kludge. */
+	argc = 1;
+	argp = args;
+	while (argp != NULL && *argp != 0) {
+		argp = arg_skipsep(argp);
+		if (*argp == 0)
+			break;
+		argv[argc++] = argp;
+		argp = arg_skipword(argp);
+		/* Terminate the words. */
+		if (*argp != 0)
+			*argp++ = 0;
+	}
+	argv[argc] = NULL;
+
+	status = main(argc, argv);
 	exit(status);
 }

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212082332.gB8NWnxH002504>