1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved 4 * Copyright 2009 Intel Corporation; author: H. Peter Anvin 5 * 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software and associated documentation 8 * files (the "Software"), to deal in the Software without 9 * restriction, including without limitation the rights to use, 10 * copy, modify, merge, publish, distribute, sublicense, and/or 11 * sell copies of the Software, and to permit persons to whom 12 * the Software is furnished to do so, subject to the following 13 * conditions: 14 * 15 * The above copyright notice and this permission notice shall 16 * be included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * ----------------------------------------------------------------------- */ 28 29 /* 30 * argv.c 31 * 32 * Parse a single C string into argc and argv (argc is return value.) 33 * memptr points to available memory. 34 */ 35 36 #include <inttypes.h> 37 #include <stddef.h> 38 #include <stdio.h> 39 #include <syslinux/align.h> 40 #include <com32.h> 41 42 extern char _end[]; /* Symbol created by linker */ 43 void *__mem_end = &_end; /* Global variable for use by malloc() */ 44 45 int __parse_argv(char ***argv, const char *str) 46 { 47 char dummy_argv0[] = ""; 48 char *mem = __mem_end; 49 const char *p = str; 50 char *q = mem; 51 char *r; 52 char **arg; 53 int wasspace = 1; 54 int argc = 1; 55 56 /* First copy the string, turning whitespace runs into nulls */ 57 for (p = str;; p++) { 58 if (*p <= ' ') { 59 if (!wasspace) { 60 wasspace = 1; 61 *q++ = '\0'; 62 } 63 } else { 64 if (wasspace) { 65 argc++; 66 wasspace = 0; 67 } 68 *q++ = *p; 69 } 70 71 /* This test is AFTER we have processed the null byte; 72 we treat it as a whitespace character so it terminates 73 the last argument */ 74 if (!*p) 75 break; 76 } 77 78 /* Now create argv */ 79 arg = (char **)ALIGN_UP_FOR(q, char *); 80 *argv = arg; 81 *arg++ = __com32.cs_name ? (char *)__com32.cs_name : dummy_argv0; /* argv[0] */ 82 83 q--; /* Point q to final null */ 84 if (mem < q) 85 *arg++ = mem; /* argv[1] */ 86 87 for (r = mem; r < q; r++) { 88 if (*r == '\0') { 89 *arg++ = r + 1; 90 } 91 } 92 93 *arg++ = NULL; /* Null pointer at the end */ 94 __mem_end = arg; /* End of memory we used */ 95 96 return argc; 97 } 98