]> Git Repo - qemu.git/blob - qemu-option.c
Revert "qdev: Use QError for 'device not found' error"
[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 <[email protected]>
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-error.h"
31 #include "qemu-option.h"
32
33 /*
34  * Extracts the name of an option from the parameter string (p points at the
35  * first byte of the option name)
36  *
37  * The option name is delimited by delim (usually , or =) or the string end
38  * and is copied into buf. If the option name is longer than buf_size, it is
39  * truncated. buf is always zero terminated.
40  *
41  * The return value is the position of the delimiter/zero byte after the option
42  * name in p.
43  */
44 const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
45 {
46     char *q;
47
48     q = buf;
49     while (*p != '\0' && *p != delim) {
50         if (q && (q - buf) < buf_size - 1)
51             *q++ = *p;
52         p++;
53     }
54     if (q)
55         *q = '\0';
56
57     return p;
58 }
59
60 /*
61  * Extracts the value of an option from the parameter string p (p points at the
62  * first byte of the option value)
63  *
64  * This function is comparable to get_opt_name with the difference that the
65  * delimiter is fixed to be comma which starts a new option. To specify an
66  * option value that contains commas, double each comma.
67  */
68 const char *get_opt_value(char *buf, int buf_size, const char *p)
69 {
70     char *q;
71
72     q = buf;
73     while (*p != '\0') {
74         if (*p == ',') {
75             if (*(p + 1) != ',')
76                 break;
77             p++;
78         }
79         if (q && (q - buf) < buf_size - 1)
80             *q++ = *p;
81         p++;
82     }
83     if (q)
84         *q = '\0';
85
86     return p;
87 }
88
89 int get_next_param_value(char *buf, int buf_size,
90                          const char *tag, const char **pstr)
91 {
92     const char *p;
93     char option[128];
94
95     p = *pstr;
96     for(;;) {
97         p = get_opt_name(option, sizeof(option), p, '=');
98         if (*p != '=')
99             break;
100         p++;
101         if (!strcmp(tag, option)) {
102             *pstr = get_opt_value(buf, buf_size, p);
103             if (**pstr == ',') {
104                 (*pstr)++;
105             }
106             return strlen(buf);
107         } else {
108             p = get_opt_value(NULL, 0, p);
109         }
110         if (*p != ',')
111             break;
112         p++;
113     }
114     return 0;
115 }
116
117 int get_param_value(char *buf, int buf_size,
118                     const char *tag, const char *str)
119 {
120     return get_next_param_value(buf, buf_size, tag, &str);
121 }
122
123 int check_params(char *buf, int buf_size,
124                  const char * const *params, const char *str)
125 {
126     const char *p;
127     int i;
128
129     p = str;
130     while (*p != '\0') {
131         p = get_opt_name(buf, buf_size, p, '=');
132         if (*p != '=') {
133             return -1;
134         }
135         p++;
136         for (i = 0; params[i] != NULL; i++) {
137             if (!strcmp(params[i], buf)) {
138                 break;
139             }
140         }
141         if (params[i] == NULL) {
142             return -1;
143         }
144         p = get_opt_value(NULL, 0, p);
145         if (*p != ',') {
146             break;
147         }
148         p++;
149     }
150     return 0;
151 }
152
153 /*
154  * Searches an option list for an option with the given name
155  */
156 QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
157     const char *name)
158 {
159     while (list && list->name) {
160         if (!strcmp(list->name, name)) {
161             return list;
162         }
163         list++;
164     }
165
166     return NULL;
167 }
168
169 static int parse_option_bool(const char *name, const char *value, int *ret)
170 {
171     if (value != NULL) {
172         if (!strcmp(value, "on")) {
173             *ret = 1;
174         } else if (!strcmp(value, "off")) {
175             *ret = 0;
176         } else {
177             fprintf(stderr, "Option '%s': Use 'on' or 'off'\n", name);
178             return -1;
179         }
180     } else {
181         *ret = 1;
182     }
183     return 0;
184 }
185
186 static int parse_option_number(const char *name, const char *value, uint64_t *ret)
187 {
188     char *postfix;
189     uint64_t number;
190
191     if (value != NULL) {
192         number = strtoull(value, &postfix, 0);
193         if (*postfix != '\0') {
194             fprintf(stderr, "Option '%s' needs a number as parameter\n", name);
195             return -1;
196         }
197         *ret = number;
198     } else {
199         fprintf(stderr, "Option '%s' needs a parameter\n", name);
200         return -1;
201     }
202     return 0;
203 }
204
205 static int parse_option_size(const char *name, const char *value, uint64_t *ret)
206 {
207     char *postfix;
208     double sizef;
209
210     if (value != NULL) {
211         sizef = strtod(value, &postfix);
212         switch (*postfix) {
213         case 'T':
214             sizef *= 1024;
215         case 'G':
216             sizef *= 1024;
217         case 'M':
218             sizef *= 1024;
219         case 'K':
220         case 'k':
221             sizef *= 1024;
222         case 'b':
223         case '\0':
224             *ret = (uint64_t) sizef;
225             break;
226         default:
227             fprintf(stderr, "Option '%s' needs size as parameter\n", name);
228             fprintf(stderr, "You may use k, M, G or T suffixes for "
229                     "kilobytes, megabytes, gigabytes and terabytes.\n");
230             return -1;
231         }
232     } else {
233         fprintf(stderr, "Option '%s' needs a parameter\n", name);
234         return -1;
235     }
236     return 0;
237 }
238
239 /*
240  * Sets the value of a parameter in a given option list. The parsing of the
241  * value depends on the type of option:
242  *
243  * OPT_FLAG (uses value.n):
244  *      If no value is given, the flag is set to 1.
245  *      Otherwise the value must be "on" (set to 1) or "off" (set to 0)
246  *
247  * OPT_STRING (uses value.s):
248  *      value is strdup()ed and assigned as option value
249  *
250  * OPT_SIZE (uses value.n):
251  *      The value is converted to an integer. Suffixes for kilobytes etc. are
252  *      allowed (powers of 1024).
253  *
254  * Returns 0 on succes, -1 in error cases
255  */
256 int set_option_parameter(QEMUOptionParameter *list, const char *name,
257     const char *value)
258 {
259     int flag;
260
261     // Find a matching parameter
262     list = get_option_parameter(list, name);
263     if (list == NULL) {
264         fprintf(stderr, "Unknown option '%s'\n", name);
265         return -1;
266     }
267
268     // Process parameter
269     switch (list->type) {
270     case OPT_FLAG:
271         if (parse_option_bool(name, value, &flag) == -1)
272             return -1;
273         list->value.n = flag;
274         break;
275
276     case OPT_STRING:
277         if (value != NULL) {
278             list->value.s = qemu_strdup(value);
279         } else {
280             fprintf(stderr, "Option '%s' needs a parameter\n", name);
281             return -1;
282         }
283         break;
284
285     case OPT_SIZE:
286         if (parse_option_size(name, value, &list->value.n) == -1)
287             return -1;
288         break;
289
290     default:
291         fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
292         return -1;
293     }
294
295     return 0;
296 }
297
298 /*
299  * Sets the given parameter to an integer instead of a string.
300  * This function cannot be used to set string options.
301  *
302  * Returns 0 on success, -1 in error cases
303  */
304 int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
305     uint64_t value)
306 {
307     // Find a matching parameter
308     list = get_option_parameter(list, name);
309     if (list == NULL) {
310         fprintf(stderr, "Unknown option '%s'\n", name);
311         return -1;
312     }
313
314     // Process parameter
315     switch (list->type) {
316     case OPT_FLAG:
317     case OPT_NUMBER:
318     case OPT_SIZE:
319         list->value.n = value;
320         break;
321
322     default:
323         return -1;
324     }
325
326     return 0;
327 }
328
329 /*
330  * Frees a option list. If it contains strings, the strings are freed as well.
331  */
332 void free_option_parameters(QEMUOptionParameter *list)
333 {
334     QEMUOptionParameter *cur = list;
335
336     while (cur && cur->name) {
337         if (cur->type == OPT_STRING) {
338             qemu_free(cur->value.s);
339         }
340         cur++;
341     }
342
343     qemu_free(list);
344 }
345
346 /*
347  * Parses a parameter string (param) into an option list (dest).
348  *
349  * list is the templace is. If dest is NULL, a new copy of list is created for
350  * it. If list is NULL, this function fails.
351  *
352  * A parameter string consists of one or more parameters, separated by commas.
353  * Each parameter consists of its name and possibly of a value. In the latter
354  * case, the value is delimited by an = character. To specify a value which
355  * contains commas, double each comma so it won't be recognized as the end of
356  * the parameter.
357  *
358  * For more details of the parsing see above.
359  *
360  * Returns a pointer to the first element of dest (or the newly allocated copy)
361  * or NULL in error cases
362  */
363 QEMUOptionParameter *parse_option_parameters(const char *param,
364     QEMUOptionParameter *list, QEMUOptionParameter *dest)
365 {
366     QEMUOptionParameter *cur;
367     QEMUOptionParameter *allocated = NULL;
368     char name[256];
369     char value[256];
370     char *param_delim, *value_delim;
371     char next_delim;
372     size_t num_options;
373
374     if (list == NULL) {
375         return NULL;
376     }
377
378     if (dest == NULL) {
379         // Count valid options
380         num_options = 0;
381         cur = list;
382         while (cur->name) {
383             num_options++;
384             cur++;
385         }
386
387         // Create a copy of the option list to fill in values
388         dest = qemu_mallocz((num_options + 1) * sizeof(QEMUOptionParameter));
389         allocated = dest;
390         memcpy(dest, list, (num_options + 1) * sizeof(QEMUOptionParameter));
391     }
392
393     while (*param) {
394
395         // Find parameter name and value in the string
396         param_delim = strchr(param, ',');
397         value_delim = strchr(param, '=');
398
399         if (value_delim && (value_delim < param_delim || !param_delim)) {
400             next_delim = '=';
401         } else {
402             next_delim = ',';
403             value_delim = NULL;
404         }
405
406         param = get_opt_name(name, sizeof(name), param, next_delim);
407         if (value_delim) {
408             param = get_opt_value(value, sizeof(value), param + 1);
409         }
410         if (*param != '\0') {
411             param++;
412         }
413
414         // Set the parameter
415         if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
416             goto fail;
417         }
418     }
419
420     return dest;
421
422 fail:
423     // Only free the list if it was newly allocated
424     free_option_parameters(allocated);
425     return NULL;
426 }
427
428 /*
429  * Prints all options of a list that have a value to stdout
430  */
431 void print_option_parameters(QEMUOptionParameter *list)
432 {
433     while (list && list->name) {
434         switch (list->type) {
435             case OPT_STRING:
436                  if (list->value.s != NULL) {
437                      printf("%s='%s' ", list->name, list->value.s);
438                  }
439                 break;
440             case OPT_FLAG:
441                 printf("%s=%s ", list->name, list->value.n ? "on" : "off");
442                 break;
443             case OPT_SIZE:
444             case OPT_NUMBER:
445                 printf("%s=%" PRId64 " ", list->name, list->value.n);
446                 break;
447             default:
448                 printf("%s=(unkown type) ", list->name);
449                 break;
450         }
451         list++;
452     }
453 }
454
455 /*
456  * Prints an overview of all available options
457  */
458 void print_option_help(QEMUOptionParameter *list)
459 {
460     printf("Supported options:\n");
461     while (list && list->name) {
462         printf("%-16s %s\n", list->name,
463             list->help ? list->help : "No description available");
464         list++;
465     }
466 }
467
468 /* ------------------------------------------------------------------ */
469
470 struct QemuOpt {
471     const char   *name;
472     const char   *str;
473
474     const QemuOptDesc *desc;
475     union {
476         int      boolean;
477         uint64_t uint;
478     } value;
479
480     QemuOpts     *opts;
481     QTAILQ_ENTRY(QemuOpt) next;
482 };
483
484 struct QemuOpts {
485     char *id;
486     QemuOptsList *list;
487     Location loc;
488     QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
489     QTAILQ_ENTRY(QemuOpts) next;
490 };
491
492 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
493 {
494     QemuOpt *opt;
495
496     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
497         if (strcmp(opt->name, name) != 0)
498             continue;
499         return opt;
500     }
501     return NULL;
502 }
503
504 const char *qemu_opt_get(QemuOpts *opts, const char *name)
505 {
506     QemuOpt *opt = qemu_opt_find(opts, name);
507     return opt ? opt->str : NULL;
508 }
509
510 int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval)
511 {
512     QemuOpt *opt = qemu_opt_find(opts, name);
513
514     if (opt == NULL)
515         return defval;
516     assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
517     return opt->value.boolean;
518 }
519
520 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
521 {
522     QemuOpt *opt = qemu_opt_find(opts, name);
523
524     if (opt == NULL)
525         return defval;
526     assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
527     return opt->value.uint;
528 }
529
530 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
531 {
532     QemuOpt *opt = qemu_opt_find(opts, name);
533
534     if (opt == NULL)
535         return defval;
536     assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
537     return opt->value.uint;
538 }
539
540 static int qemu_opt_parse(QemuOpt *opt)
541 {
542     if (opt->desc == NULL)
543         return 0;
544     switch (opt->desc->type) {
545     case QEMU_OPT_STRING:
546         /* nothing */
547         return 0;
548     case QEMU_OPT_BOOL:
549         return parse_option_bool(opt->name, opt->str, &opt->value.boolean);
550     case QEMU_OPT_NUMBER:
551         return parse_option_number(opt->name, opt->str, &opt->value.uint);
552     case QEMU_OPT_SIZE:
553         return parse_option_size(opt->name, opt->str, &opt->value.uint);
554     default:
555         abort();
556     }
557 }
558
559 static void qemu_opt_del(QemuOpt *opt)
560 {
561     QTAILQ_REMOVE(&opt->opts->head, opt, next);
562     qemu_free((/* !const */ char*)opt->name);
563     qemu_free((/* !const */ char*)opt->str);
564     qemu_free(opt);
565 }
566
567 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
568 {
569     QemuOpt *opt;
570     const QemuOptDesc *desc = opts->list->desc;
571     int i;
572
573     for (i = 0; desc[i].name != NULL; i++) {
574         if (strcmp(desc[i].name, name) == 0) {
575             break;
576         }
577     }
578     if (desc[i].name == NULL) {
579         if (i == 0) {
580             /* empty list -> allow any */;
581         } else {
582             fprintf(stderr, "option \"%s\" is not valid for %s\n",
583                     name, opts->list->name);
584             return -1;
585         }
586     }
587
588     opt = qemu_mallocz(sizeof(*opt));
589     opt->name = qemu_strdup(name);
590     opt->opts = opts;
591     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
592     if (desc[i].name != NULL) {
593         opt->desc = desc+i;
594     }
595     if (value) {
596         opt->str = qemu_strdup(value);
597     }
598     if (qemu_opt_parse(opt) < 0) {
599         fprintf(stderr, "Failed to parse \"%s\" for \"%s.%s\"\n", opt->str,
600                 opts->list->name, opt->name);
601         qemu_opt_del(opt);
602         return -1;
603     }
604     return 0;
605 }
606
607 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
608                      int abort_on_failure)
609 {
610     QemuOpt *opt;
611     int rc = 0;
612
613     QTAILQ_FOREACH(opt, &opts->head, next) {
614         rc = func(opt->name, opt->str, opaque);
615         if (abort_on_failure  &&  rc != 0)
616             break;
617     }
618     return rc;
619 }
620
621 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
622 {
623     QemuOpts *opts;
624
625     QTAILQ_FOREACH(opts, &list->head, next) {
626         if (!opts->id) {
627             continue;
628         }
629         if (strcmp(opts->id, id) != 0) {
630             continue;
631         }
632         return opts;
633     }
634     return NULL;
635 }
636
637 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists)
638 {
639     QemuOpts *opts = NULL;
640
641     if (id) {
642         opts = qemu_opts_find(list, id);
643         if (opts != NULL) {
644             if (fail_if_exists) {
645                 fprintf(stderr, "tried to create id \"%s\" twice for \"%s\"\n",
646                         id, list->name);
647                 return NULL;
648             } else {
649                 return opts;
650             }
651         }
652     }
653     opts = qemu_mallocz(sizeof(*opts));
654     if (id) {
655         opts->id = qemu_strdup(id);
656     }
657     opts->list = list;
658     loc_save(&opts->loc);
659     QTAILQ_INIT(&opts->head);
660     QTAILQ_INSERT_TAIL(&list->head, opts, next);
661     return opts;
662 }
663
664 int qemu_opts_set(QemuOptsList *list, const char *id,
665                   const char *name, const char *value)
666 {
667     QemuOpts *opts;
668
669     opts = qemu_opts_create(list, id, 1);
670     if (opts == NULL) {
671         return -1;
672     }
673     return qemu_opt_set(opts, name, value);
674 }
675
676 const char *qemu_opts_id(QemuOpts *opts)
677 {
678     return opts->id;
679 }
680
681 void qemu_opts_del(QemuOpts *opts)
682 {
683     QemuOpt *opt;
684
685     for (;;) {
686         opt = QTAILQ_FIRST(&opts->head);
687         if (opt == NULL)
688             break;
689         qemu_opt_del(opt);
690     }
691     QTAILQ_REMOVE(&opts->list->head, opts, next);
692     qemu_free(opts->id);
693     qemu_free(opts);
694 }
695
696 int qemu_opts_print(QemuOpts *opts, void *dummy)
697 {
698     QemuOpt *opt;
699
700     fprintf(stderr, "%s: %s:", opts->list->name,
701             opts->id ? opts->id : "<noid>");
702     QTAILQ_FOREACH(opt, &opts->head, next) {
703         fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
704     }
705     fprintf(stderr, "\n");
706     return 0;
707 }
708
709 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
710 {
711     char option[128], value[1024];
712     const char *p,*pe,*pc;
713
714     for (p = params; *p != '\0'; p++) {
715         pe = strchr(p, '=');
716         pc = strchr(p, ',');
717         if (!pe || (pc && pc < pe)) {
718             /* found "foo,more" */
719             if (p == params && firstname) {
720                 /* implicitly named first option */
721                 pstrcpy(option, sizeof(option), firstname);
722                 p = get_opt_value(value, sizeof(value), p);
723             } else {
724                 /* option without value, probably a flag */
725                 p = get_opt_name(option, sizeof(option), p, ',');
726                 if (strncmp(option, "no", 2) == 0) {
727                     memmove(option, option+2, strlen(option+2)+1);
728                     pstrcpy(value, sizeof(value), "off");
729                 } else {
730                     pstrcpy(value, sizeof(value), "on");
731                 }
732             }
733         } else {
734             /* found "foo=bar,more" */
735             p = get_opt_name(option, sizeof(option), p, '=');
736             if (*p != '=') {
737                 break;
738             }
739             p++;
740             p = get_opt_value(value, sizeof(value), p);
741         }
742         if (strcmp(option, "id") != 0) {
743             /* store and parse */
744             if (qemu_opt_set(opts, option, value) == -1) {
745                 return -1;
746             }
747         }
748         if (*p != ',') {
749             break;
750         }
751     }
752     return 0;
753 }
754
755 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
756 {
757     char value[1024], *id = NULL;
758     const char *p;
759     QemuOpts *opts;
760
761     if (strncmp(params, "id=", 3) == 0) {
762         get_opt_value(value, sizeof(value), params+3);
763         id = qemu_strdup(value);
764     } else if ((p = strstr(params, ",id=")) != NULL) {
765         get_opt_value(value, sizeof(value), p+4);
766         id = qemu_strdup(value);
767     }
768     opts = qemu_opts_create(list, id, 1);
769     if (opts == NULL)
770         return NULL;
771
772     if (qemu_opts_do_parse(opts, params, firstname) != 0) {
773         qemu_opts_del(opts);
774         return NULL;
775     }
776
777     return opts;
778 }
779
780 /* Validate parsed opts against descriptions where no
781  * descriptions were provided in the QemuOptsList.
782  */
783 int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
784 {
785     QemuOpt *opt;
786
787     assert(opts->list->desc[0].name == NULL);
788
789     QTAILQ_FOREACH(opt, &opts->head, next) {
790         int i;
791
792         for (i = 0; desc[i].name != NULL; i++) {
793             if (strcmp(desc[i].name, opt->name) == 0) {
794                 break;
795             }
796         }
797         if (desc[i].name == NULL) {
798             fprintf(stderr, "option \"%s\" is not valid for %s\n",
799                     opt->name, opts->list->name);
800             return -1;
801         }
802
803         opt->desc = &desc[i];
804
805         if (qemu_opt_parse(opt) < 0) {
806             return -1;
807         }
808     }
809
810     return 0;
811 }
812
813 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
814                       int abort_on_failure)
815 {
816     Location loc;
817     QemuOpts *opts;
818     int rc = 0;
819
820     loc_push_none(&loc);
821     QTAILQ_FOREACH(opts, &list->head, next) {
822         loc_restore(&opts->loc);
823         rc |= func(opts, opaque);
824         if (abort_on_failure  &&  rc != 0)
825             break;
826     }
827     loc_pop(&loc);
828     return rc;
829 }
This page took 0.067908 seconds and 4 git commands to generate.