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