xref: /openbmc/qemu/util/qemu-option.c (revision 2c9b15ca)
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-report.h"
31 #include "qapi/qmp/types.h"
32 #include "qapi/error.h"
33 #include "qapi/qmp/qerror.h"
34 #include "qemu/option_int.h"
35 
36 /*
37  * Extracts the name of an option from the parameter string (p points at the
38  * first byte of the option name)
39  *
40  * The option name is delimited by delim (usually , or =) or the string end
41  * and is copied into buf. If the option name is longer than buf_size, it is
42  * truncated. buf is always zero terminated.
43  *
44  * The return value is the position of the delimiter/zero byte after the option
45  * name in p.
46  */
47 const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
48 {
49     char *q;
50 
51     q = buf;
52     while (*p != '\0' && *p != delim) {
53         if (q && (q - buf) < buf_size - 1)
54             *q++ = *p;
55         p++;
56     }
57     if (q)
58         *q = '\0';
59 
60     return p;
61 }
62 
63 /*
64  * Extracts the value of an option from the parameter string p (p points at the
65  * first byte of the option value)
66  *
67  * This function is comparable to get_opt_name with the difference that the
68  * delimiter is fixed to be comma which starts a new option. To specify an
69  * option value that contains commas, double each comma.
70  */
71 const char *get_opt_value(char *buf, int buf_size, const char *p)
72 {
73     char *q;
74 
75     q = buf;
76     while (*p != '\0') {
77         if (*p == ',') {
78             if (*(p + 1) != ',')
79                 break;
80             p++;
81         }
82         if (q && (q - buf) < buf_size - 1)
83             *q++ = *p;
84         p++;
85     }
86     if (q)
87         *q = '\0';
88 
89     return p;
90 }
91 
92 int get_next_param_value(char *buf, int buf_size,
93                          const char *tag, const char **pstr)
94 {
95     const char *p;
96     char option[128];
97 
98     p = *pstr;
99     for(;;) {
100         p = get_opt_name(option, sizeof(option), p, '=');
101         if (*p != '=')
102             break;
103         p++;
104         if (!strcmp(tag, option)) {
105             *pstr = get_opt_value(buf, buf_size, p);
106             if (**pstr == ',') {
107                 (*pstr)++;
108             }
109             return strlen(buf);
110         } else {
111             p = get_opt_value(NULL, 0, p);
112         }
113         if (*p != ',')
114             break;
115         p++;
116     }
117     return 0;
118 }
119 
120 int get_param_value(char *buf, int buf_size,
121                     const char *tag, const char *str)
122 {
123     return get_next_param_value(buf, buf_size, tag, &str);
124 }
125 
126 /*
127  * Searches an option list for an option with the given name
128  */
129 QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
130     const char *name)
131 {
132     while (list && list->name) {
133         if (!strcmp(list->name, name)) {
134             return list;
135         }
136         list++;
137     }
138 
139     return NULL;
140 }
141 
142 static void parse_option_bool(const char *name, const char *value, bool *ret,
143                               Error **errp)
144 {
145     if (value != NULL) {
146         if (!strcmp(value, "on")) {
147             *ret = 1;
148         } else if (!strcmp(value, "off")) {
149             *ret = 0;
150         } else {
151             error_set(errp,QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'");
152         }
153     } else {
154         *ret = 1;
155     }
156 }
157 
158 static void parse_option_number(const char *name, const char *value,
159                                 uint64_t *ret, Error **errp)
160 {
161     char *postfix;
162     uint64_t number;
163 
164     if (value != NULL) {
165         number = strtoull(value, &postfix, 0);
166         if (*postfix != '\0') {
167             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
168             return;
169         }
170         *ret = number;
171     } else {
172         error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
173     }
174 }
175 
176 static void parse_option_size(const char *name, const char *value,
177                               uint64_t *ret, Error **errp)
178 {
179     char *postfix;
180     double sizef;
181 
182     if (value != NULL) {
183         sizef = strtod(value, &postfix);
184         switch (*postfix) {
185         case 'T':
186             sizef *= 1024;
187             /* fall through */
188         case 'G':
189             sizef *= 1024;
190             /* fall through */
191         case 'M':
192             sizef *= 1024;
193             /* fall through */
194         case 'K':
195         case 'k':
196             sizef *= 1024;
197             /* fall through */
198         case 'b':
199         case '\0':
200             *ret = (uint64_t) sizef;
201             break;
202         default:
203             error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
204 #if 0 /* conversion from qerror_report() to error_set() broke this: */
205             error_printf_unless_qmp("You may use k, M, G or T suffixes for "
206                     "kilobytes, megabytes, gigabytes and terabytes.\n");
207 #endif
208             return;
209         }
210     } else {
211         error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
212     }
213 }
214 
215 /*
216  * Sets the value of a parameter in a given option list. The parsing of the
217  * value depends on the type of option:
218  *
219  * OPT_FLAG (uses value.n):
220  *      If no value is given, the flag is set to 1.
221  *      Otherwise the value must be "on" (set to 1) or "off" (set to 0)
222  *
223  * OPT_STRING (uses value.s):
224  *      value is strdup()ed and assigned as option value
225  *
226  * OPT_SIZE (uses value.n):
227  *      The value is converted to an integer. Suffixes for kilobytes etc. are
228  *      allowed (powers of 1024).
229  *
230  * Returns 0 on succes, -1 in error cases
231  */
232 int set_option_parameter(QEMUOptionParameter *list, const char *name,
233     const char *value)
234 {
235     bool flag;
236     Error *local_err = NULL;
237 
238     // Find a matching parameter
239     list = get_option_parameter(list, name);
240     if (list == NULL) {
241         fprintf(stderr, "Unknown option '%s'\n", name);
242         return -1;
243     }
244 
245     // Process parameter
246     switch (list->type) {
247     case OPT_FLAG:
248         parse_option_bool(name, value, &flag, &local_err);
249         if (!error_is_set(&local_err)) {
250             list->value.n = flag;
251         }
252         break;
253 
254     case OPT_STRING:
255         if (value != NULL) {
256             list->value.s = g_strdup(value);
257         } else {
258             fprintf(stderr, "Option '%s' needs a parameter\n", name);
259             return -1;
260         }
261         break;
262 
263     case OPT_SIZE:
264         parse_option_size(name, value, &list->value.n, &local_err);
265         break;
266 
267     default:
268         fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
269         return -1;
270     }
271 
272     if (error_is_set(&local_err)) {
273         qerror_report_err(local_err);
274         error_free(local_err);
275         return -1;
276     }
277 
278     return 0;
279 }
280 
281 /*
282  * Sets the given parameter to an integer instead of a string.
283  * This function cannot be used to set string options.
284  *
285  * Returns 0 on success, -1 in error cases
286  */
287 int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
288     uint64_t value)
289 {
290     // Find a matching parameter
291     list = get_option_parameter(list, name);
292     if (list == NULL) {
293         fprintf(stderr, "Unknown option '%s'\n", name);
294         return -1;
295     }
296 
297     // Process parameter
298     switch (list->type) {
299     case OPT_FLAG:
300     case OPT_NUMBER:
301     case OPT_SIZE:
302         list->value.n = value;
303         break;
304 
305     default:
306         return -1;
307     }
308 
309     return 0;
310 }
311 
312 /*
313  * Frees a option list. If it contains strings, the strings are freed as well.
314  */
315 void free_option_parameters(QEMUOptionParameter *list)
316 {
317     QEMUOptionParameter *cur = list;
318 
319     while (cur && cur->name) {
320         if (cur->type == OPT_STRING) {
321             g_free(cur->value.s);
322         }
323         cur++;
324     }
325 
326     g_free(list);
327 }
328 
329 /*
330  * Count valid options in list
331  */
332 static size_t count_option_parameters(QEMUOptionParameter *list)
333 {
334     size_t num_options = 0;
335 
336     while (list && list->name) {
337         num_options++;
338         list++;
339     }
340 
341     return num_options;
342 }
343 
344 /*
345  * Append an option list (list) to an option list (dest).
346  *
347  * If dest is NULL, a new copy of list is created.
348  *
349  * Returns a pointer to the first element of dest (or the newly allocated copy)
350  */
351 QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
352     QEMUOptionParameter *list)
353 {
354     size_t num_options, num_dest_options;
355 
356     num_options = count_option_parameters(dest);
357     num_dest_options = num_options;
358 
359     num_options += count_option_parameters(list);
360 
361     dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
362     dest[num_dest_options].name = NULL;
363 
364     while (list && list->name) {
365         if (get_option_parameter(dest, list->name) == NULL) {
366             dest[num_dest_options++] = *list;
367             dest[num_dest_options].name = NULL;
368         }
369         list++;
370     }
371 
372     return dest;
373 }
374 
375 /*
376  * Parses a parameter string (param) into an option list (dest).
377  *
378  * list is the template option list. If dest is NULL, a new copy of list is
379  * created. If list is NULL, this function fails.
380  *
381  * A parameter string consists of one or more parameters, separated by commas.
382  * Each parameter consists of its name and possibly of a value. In the latter
383  * case, the value is delimited by an = character. To specify a value which
384  * contains commas, double each comma so it won't be recognized as the end of
385  * the parameter.
386  *
387  * For more details of the parsing see above.
388  *
389  * Returns a pointer to the first element of dest (or the newly allocated copy)
390  * or NULL in error cases
391  */
392 QEMUOptionParameter *parse_option_parameters(const char *param,
393     QEMUOptionParameter *list, QEMUOptionParameter *dest)
394 {
395     QEMUOptionParameter *allocated = NULL;
396     char name[256];
397     char value[256];
398     char *param_delim, *value_delim;
399     char next_delim;
400 
401     if (list == NULL) {
402         return NULL;
403     }
404 
405     if (dest == NULL) {
406         dest = allocated = append_option_parameters(NULL, list);
407     }
408 
409     while (*param) {
410 
411         // Find parameter name and value in the string
412         param_delim = strchr(param, ',');
413         value_delim = strchr(param, '=');
414 
415         if (value_delim && (value_delim < param_delim || !param_delim)) {
416             next_delim = '=';
417         } else {
418             next_delim = ',';
419             value_delim = NULL;
420         }
421 
422         param = get_opt_name(name, sizeof(name), param, next_delim);
423         if (value_delim) {
424             param = get_opt_value(value, sizeof(value), param + 1);
425         }
426         if (*param != '\0') {
427             param++;
428         }
429 
430         // Set the parameter
431         if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
432             goto fail;
433         }
434     }
435 
436     return dest;
437 
438 fail:
439     // Only free the list if it was newly allocated
440     free_option_parameters(allocated);
441     return NULL;
442 }
443 
444 /*
445  * Prints all options of a list that have a value to stdout
446  */
447 void print_option_parameters(QEMUOptionParameter *list)
448 {
449     while (list && list->name) {
450         switch (list->type) {
451             case OPT_STRING:
452                  if (list->value.s != NULL) {
453                      printf("%s='%s' ", list->name, list->value.s);
454                  }
455                 break;
456             case OPT_FLAG:
457                 printf("%s=%s ", list->name, list->value.n ? "on" : "off");
458                 break;
459             case OPT_SIZE:
460             case OPT_NUMBER:
461                 printf("%s=%" PRId64 " ", list->name, list->value.n);
462                 break;
463             default:
464                 printf("%s=(unknown type) ", list->name);
465                 break;
466         }
467         list++;
468     }
469 }
470 
471 /*
472  * Prints an overview of all available options
473  */
474 void print_option_help(QEMUOptionParameter *list)
475 {
476     printf("Supported options:\n");
477     while (list && list->name) {
478         printf("%-16s %s\n", list->name,
479             list->help ? list->help : "No description available");
480         list++;
481     }
482 }
483 
484 /* ------------------------------------------------------------------ */
485 
486 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
487 {
488     QemuOpt *opt;
489 
490     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
491         if (strcmp(opt->name, name) != 0)
492             continue;
493         return opt;
494     }
495     return NULL;
496 }
497 
498 const char *qemu_opt_get(QemuOpts *opts, const char *name)
499 {
500     QemuOpt *opt = qemu_opt_find(opts, name);
501     return opt ? opt->str : NULL;
502 }
503 
504 bool qemu_opt_has_help_opt(QemuOpts *opts)
505 {
506     QemuOpt *opt;
507 
508     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
509         if (is_help_option(opt->name)) {
510             return true;
511         }
512     }
513     return false;
514 }
515 
516 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
517 {
518     QemuOpt *opt = qemu_opt_find(opts, name);
519 
520     if (opt == NULL)
521         return defval;
522     assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
523     return opt->value.boolean;
524 }
525 
526 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
527 {
528     QemuOpt *opt = qemu_opt_find(opts, name);
529 
530     if (opt == NULL)
531         return defval;
532     assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
533     return opt->value.uint;
534 }
535 
536 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
537 {
538     QemuOpt *opt = qemu_opt_find(opts, name);
539 
540     if (opt == NULL)
541         return defval;
542     assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
543     return opt->value.uint;
544 }
545 
546 static void qemu_opt_parse(QemuOpt *opt, Error **errp)
547 {
548     if (opt->desc == NULL)
549         return;
550 
551     switch (opt->desc->type) {
552     case QEMU_OPT_STRING:
553         /* nothing */
554         return;
555     case QEMU_OPT_BOOL:
556         parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
557         break;
558     case QEMU_OPT_NUMBER:
559         parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
560         break;
561     case QEMU_OPT_SIZE:
562         parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
563         break;
564     default:
565         abort();
566     }
567 }
568 
569 static void qemu_opt_del(QemuOpt *opt)
570 {
571     QTAILQ_REMOVE(&opt->opts->head, opt, next);
572     g_free((/* !const */ char*)opt->name);
573     g_free((/* !const */ char*)opt->str);
574     g_free(opt);
575 }
576 
577 static bool opts_accepts_any(const QemuOpts *opts)
578 {
579     return opts->list->desc[0].name == NULL;
580 }
581 
582 static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
583                                             const char *name)
584 {
585     int i;
586 
587     for (i = 0; desc[i].name != NULL; i++) {
588         if (strcmp(desc[i].name, name) == 0) {
589             return &desc[i];
590         }
591     }
592 
593     return NULL;
594 }
595 
596 static void opt_set(QemuOpts *opts, const char *name, const char *value,
597                     bool prepend, Error **errp)
598 {
599     QemuOpt *opt;
600     const QemuOptDesc *desc;
601     Error *local_err = NULL;
602 
603     desc = find_desc_by_name(opts->list->desc, name);
604     if (!desc && !opts_accepts_any(opts)) {
605         error_set(errp, QERR_INVALID_PARAMETER, name);
606         return;
607     }
608 
609     opt = g_malloc0(sizeof(*opt));
610     opt->name = g_strdup(name);
611     opt->opts = opts;
612     if (prepend) {
613         QTAILQ_INSERT_HEAD(&opts->head, opt, next);
614     } else {
615         QTAILQ_INSERT_TAIL(&opts->head, opt, next);
616     }
617     opt->desc = desc;
618     opt->str = g_strdup(value);
619     qemu_opt_parse(opt, &local_err);
620     if (error_is_set(&local_err)) {
621         error_propagate(errp, local_err);
622         qemu_opt_del(opt);
623     }
624 }
625 
626 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
627 {
628     Error *local_err = NULL;
629 
630     opt_set(opts, name, value, false, &local_err);
631     if (error_is_set(&local_err)) {
632         qerror_report_err(local_err);
633         error_free(local_err);
634         return -1;
635     }
636 
637     return 0;
638 }
639 
640 void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
641                       Error **errp)
642 {
643     opt_set(opts, name, value, false, errp);
644 }
645 
646 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
647 {
648     QemuOpt *opt;
649     const QemuOptDesc *desc = opts->list->desc;
650 
651     opt = g_malloc0(sizeof(*opt));
652     opt->desc = find_desc_by_name(desc, name);
653     if (!opt->desc && !opts_accepts_any(opts)) {
654         qerror_report(QERR_INVALID_PARAMETER, name);
655         g_free(opt);
656         return -1;
657     }
658 
659     opt->name = g_strdup(name);
660     opt->opts = opts;
661     opt->value.boolean = !!val;
662     opt->str = g_strdup(val ? "on" : "off");
663     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
664 
665     return 0;
666 }
667 
668 int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
669 {
670     QemuOpt *opt;
671     const QemuOptDesc *desc = opts->list->desc;
672 
673     opt = g_malloc0(sizeof(*opt));
674     opt->desc = find_desc_by_name(desc, name);
675     if (!opt->desc && !opts_accepts_any(opts)) {
676         qerror_report(QERR_INVALID_PARAMETER, name);
677         g_free(opt);
678         return -1;
679     }
680 
681     opt->name = g_strdup(name);
682     opt->opts = opts;
683     opt->value.uint = val;
684     opt->str = g_strdup_printf("%" PRId64, val);
685     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
686 
687     return 0;
688 }
689 
690 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
691                      int abort_on_failure)
692 {
693     QemuOpt *opt;
694     int rc = 0;
695 
696     QTAILQ_FOREACH(opt, &opts->head, next) {
697         rc = func(opt->name, opt->str, opaque);
698         if (abort_on_failure  &&  rc != 0)
699             break;
700     }
701     return rc;
702 }
703 
704 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
705 {
706     QemuOpts *opts;
707 
708     QTAILQ_FOREACH(opts, &list->head, next) {
709         if (!opts->id) {
710             if (!id) {
711                 return opts;
712             }
713             continue;
714         }
715         if (strcmp(opts->id, id) != 0) {
716             continue;
717         }
718         return opts;
719     }
720     return NULL;
721 }
722 
723 static int id_wellformed(const char *id)
724 {
725     int i;
726 
727     if (!qemu_isalpha(id[0])) {
728         return 0;
729     }
730     for (i = 1; id[i]; i++) {
731         if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
732             return 0;
733         }
734     }
735     return 1;
736 }
737 
738 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
739                            int fail_if_exists, Error **errp)
740 {
741     QemuOpts *opts = NULL;
742 
743     if (id) {
744         if (!id_wellformed(id)) {
745             error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
746 #if 0 /* conversion from qerror_report() to error_set() broke this: */
747             error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
748 #endif
749             return NULL;
750         }
751         opts = qemu_opts_find(list, id);
752         if (opts != NULL) {
753             if (fail_if_exists && !list->merge_lists) {
754                 error_set(errp, QERR_DUPLICATE_ID, id, list->name);
755                 return NULL;
756             } else {
757                 return opts;
758             }
759         }
760     } else if (list->merge_lists) {
761         opts = qemu_opts_find(list, NULL);
762         if (opts) {
763             return opts;
764         }
765     }
766     opts = g_malloc0(sizeof(*opts));
767     opts->id = g_strdup(id);
768     opts->list = list;
769     loc_save(&opts->loc);
770     QTAILQ_INIT(&opts->head);
771     QTAILQ_INSERT_TAIL(&list->head, opts, next);
772     return opts;
773 }
774 
775 QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
776 {
777     QemuOpts *opts;
778     Error *errp = NULL;
779     opts = qemu_opts_create(list, NULL, 0, &errp);
780     assert_no_error(errp);
781     return opts;
782 }
783 
784 void qemu_opts_reset(QemuOptsList *list)
785 {
786     QemuOpts *opts, *next_opts;
787 
788     QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
789         qemu_opts_del(opts);
790     }
791 }
792 
793 void qemu_opts_loc_restore(QemuOpts *opts)
794 {
795     loc_restore(&opts->loc);
796 }
797 
798 int qemu_opts_set(QemuOptsList *list, const char *id,
799                   const char *name, const char *value)
800 {
801     QemuOpts *opts;
802     Error *local_err = NULL;
803 
804     opts = qemu_opts_create(list, id, 1, &local_err);
805     if (error_is_set(&local_err)) {
806         qerror_report_err(local_err);
807         error_free(local_err);
808         return -1;
809     }
810     return qemu_opt_set(opts, name, value);
811 }
812 
813 const char *qemu_opts_id(QemuOpts *opts)
814 {
815     return opts->id;
816 }
817 
818 void qemu_opts_del(QemuOpts *opts)
819 {
820     QemuOpt *opt;
821 
822     for (;;) {
823         opt = QTAILQ_FIRST(&opts->head);
824         if (opt == NULL)
825             break;
826         qemu_opt_del(opt);
827     }
828     QTAILQ_REMOVE(&opts->list->head, opts, next);
829     g_free(opts->id);
830     g_free(opts);
831 }
832 
833 int qemu_opts_print(QemuOpts *opts, void *dummy)
834 {
835     QemuOpt *opt;
836 
837     fprintf(stderr, "%s: %s:", opts->list->name,
838             opts->id ? opts->id : "<noid>");
839     QTAILQ_FOREACH(opt, &opts->head, next) {
840         fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
841     }
842     fprintf(stderr, "\n");
843     return 0;
844 }
845 
846 static int opts_do_parse(QemuOpts *opts, const char *params,
847                          const char *firstname, bool prepend)
848 {
849     char option[128], value[1024];
850     const char *p,*pe,*pc;
851     Error *local_err = NULL;
852 
853     for (p = params; *p != '\0'; p++) {
854         pe = strchr(p, '=');
855         pc = strchr(p, ',');
856         if (!pe || (pc && pc < pe)) {
857             /* found "foo,more" */
858             if (p == params && firstname) {
859                 /* implicitly named first option */
860                 pstrcpy(option, sizeof(option), firstname);
861                 p = get_opt_value(value, sizeof(value), p);
862             } else {
863                 /* option without value, probably a flag */
864                 p = get_opt_name(option, sizeof(option), p, ',');
865                 if (strncmp(option, "no", 2) == 0) {
866                     memmove(option, option+2, strlen(option+2)+1);
867                     pstrcpy(value, sizeof(value), "off");
868                 } else {
869                     pstrcpy(value, sizeof(value), "on");
870                 }
871             }
872         } else {
873             /* found "foo=bar,more" */
874             p = get_opt_name(option, sizeof(option), p, '=');
875             if (*p != '=') {
876                 break;
877             }
878             p++;
879             p = get_opt_value(value, sizeof(value), p);
880         }
881         if (strcmp(option, "id") != 0) {
882             /* store and parse */
883             opt_set(opts, option, value, prepend, &local_err);
884             if (error_is_set(&local_err)) {
885                 qerror_report_err(local_err);
886                 error_free(local_err);
887                 return -1;
888             }
889         }
890         if (*p != ',') {
891             break;
892         }
893     }
894     return 0;
895 }
896 
897 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
898 {
899     return opts_do_parse(opts, params, firstname, false);
900 }
901 
902 static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
903                             int permit_abbrev, bool defaults)
904 {
905     const char *firstname;
906     char value[1024], *id = NULL;
907     const char *p;
908     QemuOpts *opts;
909     Error *local_err = NULL;
910 
911     assert(!permit_abbrev || list->implied_opt_name);
912     firstname = permit_abbrev ? list->implied_opt_name : NULL;
913 
914     if (strncmp(params, "id=", 3) == 0) {
915         get_opt_value(value, sizeof(value), params+3);
916         id = value;
917     } else if ((p = strstr(params, ",id=")) != NULL) {
918         get_opt_value(value, sizeof(value), p+4);
919         id = value;
920     }
921     if (defaults) {
922         if (!id && !QTAILQ_EMPTY(&list->head)) {
923             opts = qemu_opts_find(list, NULL);
924         } else {
925             opts = qemu_opts_create(list, id, 0, &local_err);
926         }
927     } else {
928         opts = qemu_opts_create(list, id, 1, &local_err);
929     }
930     if (opts == NULL) {
931         if (error_is_set(&local_err)) {
932             qerror_report_err(local_err);
933             error_free(local_err);
934         }
935         return NULL;
936     }
937 
938     if (opts_do_parse(opts, params, firstname, defaults) != 0) {
939         qemu_opts_del(opts);
940         return NULL;
941     }
942 
943     return opts;
944 }
945 
946 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
947                           int permit_abbrev)
948 {
949     return opts_parse(list, params, permit_abbrev, false);
950 }
951 
952 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
953                             int permit_abbrev)
954 {
955     QemuOpts *opts;
956 
957     opts = opts_parse(list, params, permit_abbrev, true);
958     assert(opts);
959 }
960 
961 typedef struct OptsFromQDictState {
962     QemuOpts *opts;
963     Error **errp;
964 } OptsFromQDictState;
965 
966 static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
967 {
968     OptsFromQDictState *state = opaque;
969     char buf[32];
970     const char *value;
971     int n;
972 
973     if (!strcmp(key, "id") || error_is_set(state->errp)) {
974         return;
975     }
976 
977     switch (qobject_type(obj)) {
978     case QTYPE_QSTRING:
979         value = qstring_get_str(qobject_to_qstring(obj));
980         break;
981     case QTYPE_QINT:
982         n = snprintf(buf, sizeof(buf), "%" PRId64,
983                      qint_get_int(qobject_to_qint(obj)));
984         assert(n < sizeof(buf));
985         value = buf;
986         break;
987     case QTYPE_QFLOAT:
988         n = snprintf(buf, sizeof(buf), "%.17g",
989                      qfloat_get_double(qobject_to_qfloat(obj)));
990         assert(n < sizeof(buf));
991         value = buf;
992         break;
993     case QTYPE_QBOOL:
994         pstrcpy(buf, sizeof(buf),
995                 qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
996         value = buf;
997         break;
998     default:
999         return;
1000     }
1001 
1002     qemu_opt_set_err(state->opts, key, value, state->errp);
1003 }
1004 
1005 /*
1006  * Create QemuOpts from a QDict.
1007  * Use value of key "id" as ID if it exists and is a QString.
1008  * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
1009  * other types are silently ignored.
1010  */
1011 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
1012                                Error **errp)
1013 {
1014     OptsFromQDictState state;
1015     Error *local_err = NULL;
1016     QemuOpts *opts;
1017 
1018     opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
1019                             &local_err);
1020     if (error_is_set(&local_err)) {
1021         error_propagate(errp, local_err);
1022         return NULL;
1023     }
1024 
1025     assert(opts != NULL);
1026 
1027     state.errp = &local_err;
1028     state.opts = opts;
1029     qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
1030     if (error_is_set(&local_err)) {
1031         error_propagate(errp, local_err);
1032         qemu_opts_del(opts);
1033         return NULL;
1034     }
1035 
1036     return opts;
1037 }
1038 
1039 /*
1040  * Adds all QDict entries to the QemuOpts that can be added and removes them
1041  * from the QDict. When this function returns, the QDict contains only those
1042  * entries that couldn't be added to the QemuOpts.
1043  */
1044 void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
1045 {
1046     const QDictEntry *entry, *next;
1047 
1048     entry = qdict_first(qdict);
1049 
1050     while (entry != NULL) {
1051         Error *local_err = NULL;
1052         OptsFromQDictState state = {
1053             .errp = &local_err,
1054             .opts = opts,
1055         };
1056 
1057         next = qdict_next(qdict, entry);
1058 
1059         if (find_desc_by_name(opts->list->desc, entry->key)) {
1060             qemu_opts_from_qdict_1(entry->key, entry->value, &state);
1061             if (error_is_set(&local_err)) {
1062                 error_propagate(errp, local_err);
1063                 return;
1064             } else {
1065                 qdict_del(qdict, entry->key);
1066             }
1067         }
1068 
1069         entry = next;
1070     }
1071 }
1072 
1073 /*
1074  * Convert from QemuOpts to QDict.
1075  * The QDict values are of type QString.
1076  * TODO We'll want to use types appropriate for opt->desc->type, but
1077  * this is enough for now.
1078  */
1079 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1080 {
1081     QemuOpt *opt;
1082     QObject *val;
1083 
1084     if (!qdict) {
1085         qdict = qdict_new();
1086     }
1087     if (opts->id) {
1088         qdict_put(qdict, "id", qstring_from_str(opts->id));
1089     }
1090     QTAILQ_FOREACH(opt, &opts->head, next) {
1091         val = QOBJECT(qstring_from_str(opt->str));
1092         qdict_put_obj(qdict, opt->name, val);
1093     }
1094     return qdict;
1095 }
1096 
1097 /* Validate parsed opts against descriptions where no
1098  * descriptions were provided in the QemuOptsList.
1099  */
1100 void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
1101 {
1102     QemuOpt *opt;
1103     Error *local_err = NULL;
1104 
1105     assert(opts_accepts_any(opts));
1106 
1107     QTAILQ_FOREACH(opt, &opts->head, next) {
1108         opt->desc = find_desc_by_name(desc, opt->name);
1109         if (!opt->desc) {
1110             error_set(errp, QERR_INVALID_PARAMETER, opt->name);
1111             return;
1112         }
1113 
1114         qemu_opt_parse(opt, &local_err);
1115         if (error_is_set(&local_err)) {
1116             error_propagate(errp, local_err);
1117             return;
1118         }
1119     }
1120 }
1121 
1122 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
1123                       int abort_on_failure)
1124 {
1125     Location loc;
1126     QemuOpts *opts;
1127     int rc = 0;
1128 
1129     loc_push_none(&loc);
1130     QTAILQ_FOREACH(opts, &list->head, next) {
1131         loc_restore(&opts->loc);
1132         rc |= func(opts, opaque);
1133         if (abort_on_failure  &&  rc != 0)
1134             break;
1135     }
1136     loc_pop(&loc);
1137     return rc;
1138 }
1139