]> git.saurik.com Git - apple/xnu.git/blob - pexpert/gen/bootargs.c
55817534946c1380c3c8903769329717ae808e2b
[apple/xnu.git] / pexpert / gen / bootargs.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 #include <pexpert/pexpert.h>
23
24 extern boolean_t isargsep( char c);
25 extern int argstrcpy(char *from, char *to);
26 extern int getval(char *s, int *val);
27
28 #define NUM 0
29 #define STR 1
30
31 boolean_t
32 PE_parse_boot_arg(
33 const char *arg_string,
34 void *arg_ptr)
35 {
36 return PE_parse_boot_argn(arg_string, arg_ptr, -1);
37 }
38
39 boolean_t
40 PE_parse_boot_argn(
41 const char *arg_string,
42 void *arg_ptr,
43 int max_len)
44 {
45 char *args;
46 char *cp, c;
47 int i;
48 int val;
49 boolean_t arg_boolean;
50 boolean_t arg_found;
51
52 args = PE_boot_args();
53 if (*args == '\0') return FALSE;
54
55 arg_found = FALSE;
56
57 while(isargsep(*args)) args++;
58
59 while (*args)
60 {
61 if (*args == '-')
62 arg_boolean = TRUE;
63 else
64 arg_boolean = FALSE;
65
66 cp = args;
67 while (!isargsep (*cp) && *cp != '=')
68 cp++;
69 if (*cp != '=' && !arg_boolean)
70 goto gotit;
71
72 c = *cp;
73
74 i = cp-args;
75 if (strncmp(args, arg_string, i) ||
76 (i!=strlen(arg_string)))
77 goto gotit;
78 if (arg_boolean) {
79 *(unsigned int *)arg_ptr = TRUE;
80 arg_found = TRUE;
81 break;
82 } else {
83 while (isargsep (*cp))
84 cp++;
85 if (*cp == '=' && c != '=') {
86 args = cp+1;
87 goto gotit;
88 }
89 if ('_' == *arg_string) /* Force a string copy if the argument name begins with an underscore */
90 {
91 int hacklen = 16 > max_len ? 16 : max_len;
92 argstrcpy2 (++cp, (char *)arg_ptr, hacklen); /* Hack - terminate after 16 characters */
93 arg_found = TRUE;
94 break;
95 }
96 switch (getval(cp, &val))
97 {
98 case NUM:
99 *(unsigned int *)arg_ptr = val;
100 arg_found = TRUE;
101 break;
102 case STR:
103 if(max_len > 0) //max_len of 0 performs no copy at all
104 argstrcpy2(++cp, (char *)arg_ptr, max_len);
105 else if(max_len == -1)
106 argstrcpy(++cp, (char *)arg_ptr);
107 arg_found = TRUE;
108 break;
109 }
110 goto gotit;
111 }
112 gotit:
113 /* Skip over current arg */
114 while(!isargsep(*args)) args++;
115
116 /* Skip leading white space (catch end of args) */
117 while(*args && isargsep(*args)) args++;
118 }
119
120 return(arg_found);
121 }
122
123 boolean_t isargsep(
124 char c)
125 {
126 if (c == ' ' || c == '\0' || c == '\t')
127 return(TRUE);
128 else
129 return(FALSE);
130 }
131
132 int
133 argstrcpy(
134 char *from,
135 char *to)
136 {
137 int i = 0;
138
139 while (!isargsep(*from)) {
140 i++;
141 *to++ = *from++;
142 }
143 *to = 0;
144 return(i);
145 }
146
147 int
148 argstrcpy2(
149 char *from,
150 char *to,
151 unsigned maxlen)
152 {
153 int i = 0;
154
155 while (!isargsep(*from) && i < maxlen) {
156 i++;
157 *to++ = *from++;
158 }
159 *to = 0;
160 return(i);
161 }
162
163 int
164 getval(
165 char *s,
166 int *val)
167 {
168 unsigned int radix, intval;
169 char c;
170 int sign = 1;
171
172 if (*s == '=') {
173 s++;
174 if (*s == '-')
175 sign = -1, s++;
176 intval = *s++-'0';
177 radix = 10;
178 if (intval == 0) {
179 switch(*s) {
180
181 case 'x':
182 radix = 16;
183 s++;
184 break;
185
186 case 'b':
187 radix = 2;
188 s++;
189 break;
190
191 case '0': case '1': case '2': case '3':
192 case '4': case '5': case '6': case '7':
193 intval = *s-'0';
194 s++;
195 radix = 8;
196 break;
197
198 default:
199 if (!isargsep(*s))
200 return (STR);
201 }
202 } else if (intval >= radix) {
203 return (STR);
204 }
205 for(;;) {
206 c = *s++;
207 if (isargsep(c))
208 break;
209 if ((radix <= 10) &&
210 ((c >= '0') && (c <= ('9' - (10 - radix))))) {
211 c -= '0';
212 } else if ((radix == 16) &&
213 ((c >= '0') && (c <= '9'))) {
214 c -= '0';
215 } else if ((radix == 16) &&
216 ((c >= 'a') && (c <= 'f'))) {
217 c -= 'a' - 10;
218 } else if ((radix == 16) &&
219 ((c >= 'A') && (c <= 'F'))) {
220 c -= 'A' - 10;
221 } else if (c == 'k' || c == 'K') {
222 sign *= 1024;
223 break;
224 } else if (c == 'm' || c == 'M') {
225 sign *= 1024 * 1024;
226 break;
227 } else if (c == 'g' || c == 'G') {
228 sign *= 1024 * 1024 * 1024;
229 break;
230 } else {
231 return (STR);
232 }
233 if (c >= radix)
234 return (STR);
235 intval *= radix;
236 intval += c;
237 }
238 if (!isargsep(c) && !isargsep(*s))
239 return STR;
240 *val = intval * sign;
241 return (NUM);
242 }
243 *val = 1;
244 return (NUM);
245 }