]> git.proxmox.com Git - qemu.git/blob - qemu-option.c
move parser functions from vl.c to qemu-option.c
[qemu.git] / qemu-option.c
1 /*
2 * Commandline option parsing functions
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "qemu-common.h"
30 #include "qemu-option.h"
31
32 /*
33 * Extracts the name of an option from the parameter string (p points at the
34 * first byte of the option name)
35 *
36 * The option name is delimited by delim (usually , or =) or the string end
37 * and is copied into buf. If the option name is longer than buf_size, it is
38 * truncated. buf is always zero terminated.
39 *
40 * The return value is the position of the delimiter/zero byte after the option
41 * name in p.
42 */
43 const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
44 {
45 char *q;
46
47 q = buf;
48 while (*p != '\0' && *p != delim) {
49 if (q && (q - buf) < buf_size - 1)
50 *q++ = *p;
51 p++;
52 }
53 if (q)
54 *q = '\0';
55
56 return p;
57 }
58
59 /*
60 * Extracts the value of an option from the parameter string p (p points at the
61 * first byte of the option value)
62 *
63 * This function is comparable to get_opt_name with the difference that the
64 * delimiter is fixed to be comma which starts a new option. To specify an
65 * option value that contains commas, double each comma.
66 */
67 const char *get_opt_value(char *buf, int buf_size, const char *p)
68 {
69 char *q;
70
71 q = buf;
72 while (*p != '\0') {
73 if (*p == ',') {
74 if (*(p + 1) != ',')
75 break;
76 p++;
77 }
78 if (q && (q - buf) < buf_size - 1)
79 *q++ = *p;
80 p++;
81 }
82 if (q)
83 *q = '\0';
84
85 return p;
86 }
87
88 int get_next_param_value(char *buf, int buf_size,
89 const char *tag, const char **pstr)
90 {
91 const char *p;
92 char option[128];
93
94 p = *pstr;
95 for(;;) {
96 p = get_opt_name(option, sizeof(option), p, '=');
97 if (*p != '=')
98 break;
99 p++;
100 if (!strcmp(tag, option)) {
101 *pstr = get_opt_value(buf, buf_size, p);
102 if (**pstr == ',') {
103 (*pstr)++;
104 }
105 return strlen(buf);
106 } else {
107 p = get_opt_value(NULL, 0, p);
108 }
109 if (*p != ',')
110 break;
111 p++;
112 }
113 return 0;
114 }
115
116 int get_param_value(char *buf, int buf_size,
117 const char *tag, const char *str)
118 {
119 return get_next_param_value(buf, buf_size, tag, &str);
120 }
121
122 int check_params(char *buf, int buf_size,
123 const char * const *params, const char *str)
124 {
125 const char *p;
126 int i;
127
128 p = str;
129 while (*p != '\0') {
130 p = get_opt_name(buf, buf_size, p, '=');
131 if (*p != '=') {
132 return -1;
133 }
134 p++;
135 for (i = 0; params[i] != NULL; i++) {
136 if (!strcmp(params[i], buf)) {
137 break;
138 }
139 }
140 if (params[i] == NULL) {
141 return -1;
142 }
143 p = get_opt_value(NULL, 0, p);
144 if (*p != ',') {
145 break;
146 }
147 p++;
148 }
149 return 0;
150 }
151
152 /*
153 * Searches an option list for an option with the given name
154 */
155 QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
156 const char *name)
157 {
158 while (list && list->name) {
159 if (!strcmp(list->name, name)) {
160 return list;
161 }
162 list++;
163 }
164
165 return NULL;
166 }
167
168 /*
169 * Sets the value of a parameter in a given option list. The parsing of the
170 * value depends on the type of option:
171 *
172 * OPT_FLAG (uses value.n):
173 * If no value is given, the flag is set to 1.
174 * Otherwise the value must be "on" (set to 1) or "off" (set to 0)
175 *
176 * OPT_STRING (uses value.s):
177 * value is strdup()ed and assigned as option value
178 *
179 * OPT_SIZE (uses value.n):
180 * The value is converted to an integer. Suffixes for kilobytes etc. are
181 * allowed (powers of 1024).
182 *
183 * Returns 0 on succes, -1 in error cases
184 */
185 int set_option_parameter(QEMUOptionParameter *list, const char *name,
186 const char *value)
187 {
188 // Find a matching parameter
189 list = get_option_parameter(list, name);
190 if (list == NULL) {
191 fprintf(stderr, "Unknown option '%s'\n", name);
192 return -1;
193 }
194
195 // Process parameter
196 switch (list->type) {
197 case OPT_FLAG:
198 if (value != NULL) {
199 if (!strcmp(value, "on")) {
200 list->value.n = 1;
201 } else if (!strcmp(value, "off")) {
202 list->value.n = 0;
203 } else {
204 fprintf(stderr, "Option '%s': Use 'on' or 'off'\n", name);
205 return -1;
206 }
207 } else {
208 list->value.n = 1;
209 }
210 break;
211
212 case OPT_STRING:
213 if (value != NULL) {
214 list->value.s = strdup(value);
215 } else {
216 fprintf(stderr, "Option '%s' needs a parameter\n", name);
217 return -1;
218 }
219 break;
220
221 case OPT_SIZE:
222 if (value != NULL) {
223 double sizef = strtod(value, (char**) &value);
224
225 switch (*value) {
226 case 'T':
227 sizef *= 1024;
228 case 'G':
229 sizef *= 1024;
230 case 'M':
231 sizef *= 1024;
232 case 'K':
233 case 'k':
234 sizef *= 1024;
235 case 'b':
236 case '\0':
237 list->value.n = (uint64_t) sizef;
238 break;
239 default:
240 fprintf(stderr, "Option '%s' needs size as parameter\n", name);
241 fprintf(stderr, "You may use k, M, G or T suffixes for "
242 "kilobytes, megabytes, gigabytes and terabytes.\n");
243 return -1;
244 }
245 } else {
246 fprintf(stderr, "Option '%s' needs a parameter\n", name);
247 return -1;
248 }
249 break;
250 default:
251 fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
252 return -1;
253 }
254
255 return 0;
256 }
257
258 /*
259 * Sets the given parameter to an integer instead of a string.
260 * This function cannot be used to set string options.
261 *
262 * Returns 0 on success, -1 in error cases
263 */
264 int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
265 uint64_t value)
266 {
267 // Find a matching parameter
268 list = get_option_parameter(list, name);
269 if (list == NULL) {
270 fprintf(stderr, "Unknown option '%s'\n", name);
271 return -1;
272 }
273
274 // Process parameter
275 switch (list->type) {
276 case OPT_FLAG:
277 case OPT_NUMBER:
278 case OPT_SIZE:
279 list->value.n = value;
280 break;
281
282 default:
283 return -1;
284 }
285
286 return 0;
287 }
288
289 /*
290 * Frees a option list. If it contains strings, the strings are freed as well.
291 */
292 void free_option_parameters(QEMUOptionParameter *list)
293 {
294 QEMUOptionParameter *cur = list;
295
296 while (cur && cur->name) {
297 if (cur->type == OPT_STRING) {
298 free(cur->value.s);
299 }
300 cur++;
301 }
302
303 free(list);
304 }
305
306 /*
307 * Parses a parameter string (param) into an option list (dest).
308 *
309 * list is the templace is. If dest is NULL, a new copy of list is created for
310 * it. If list is NULL, this function fails.
311 *
312 * A parameter string consists of one or more parameters, separated by commas.
313 * Each parameter consists of its name and possibly of a value. In the latter
314 * case, the value is delimited by an = character. To specify a value which
315 * contains commas, double each comma so it won't be recognized as the end of
316 * the parameter.
317 *
318 * For more details of the parsing see above.
319 *
320 * Returns a pointer to the first element of dest (or the newly allocated copy)
321 * or NULL in error cases
322 */
323 QEMUOptionParameter *parse_option_parameters(const char *param,
324 QEMUOptionParameter *list, QEMUOptionParameter *dest)
325 {
326 QEMUOptionParameter *cur;
327 QEMUOptionParameter *allocated = NULL;
328 char name[256];
329 char value[256];
330 char *param_delim, *value_delim;
331 char next_delim;
332 size_t num_options;
333
334 if (list == NULL) {
335 return NULL;
336 }
337
338 if (dest == NULL) {
339 // Count valid options
340 num_options = 0;
341 cur = list;
342 while (cur->name) {
343 num_options++;
344 cur++;
345 }
346
347 // Create a copy of the option list to fill in values
348 dest = qemu_mallocz((num_options + 1) * sizeof(QEMUOptionParameter));
349 allocated = dest;
350 memcpy(dest, list, (num_options + 1) * sizeof(QEMUOptionParameter));
351 }
352
353 while (*param) {
354
355 // Find parameter name and value in the string
356 param_delim = strchr(param, ',');
357 value_delim = strchr(param, '=');
358
359 if (value_delim && (value_delim < param_delim || !param_delim)) {
360 next_delim = '=';
361 } else {
362 next_delim = ',';
363 value_delim = NULL;
364 }
365
366 param = get_opt_name(name, sizeof(name), param, next_delim);
367 if (value_delim) {
368 param = get_opt_value(value, sizeof(value), param + 1);
369 }
370 if (*param != '\0') {
371 param++;
372 }
373
374 // Set the parameter
375 if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
376 goto fail;
377 }
378 }
379
380 return dest;
381
382 fail:
383 // Only free the list if it was newly allocated
384 free_option_parameters(allocated);
385 return NULL;
386 }
387
388 /*
389 * Prints all options of a list that have a value to stdout
390 */
391 void print_option_parameters(QEMUOptionParameter *list)
392 {
393 while (list && list->name) {
394 switch (list->type) {
395 case OPT_STRING:
396 if (list->value.s != NULL) {
397 printf("%s='%s' ", list->name, list->value.s);
398 }
399 break;
400 case OPT_FLAG:
401 printf("%s=%s ", list->name, list->value.n ? "on" : "off");
402 break;
403 case OPT_SIZE:
404 case OPT_NUMBER:
405 printf("%s=%" PRId64 " ", list->name, list->value.n);
406 break;
407 default:
408 printf("%s=(unkown type) ", list->name);
409 break;
410 }
411 list++;
412 }
413 }
414
415 /*
416 * Prints an overview of all available options
417 */
418 void print_option_help(QEMUOptionParameter *list)
419 {
420 printf("Supported options:\n");
421 while (list && list->name) {
422 printf("%-16s %s\n", list->name,
423 list->help ? list->help : "No description available");
424 list++;
425 }
426 }