move parser functions from vl.c to qemu-option.c
[qemu] / 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 }