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>