xref: /openbmc/qemu/util/qemu-option.c (revision 40cf6a54)
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 "qemu/osdep.h"
27 
28 #include "qapi/error.h"
29 #include "qemu-common.h"
30 #include "qemu/error-report.h"
31 #include "qapi/qmp/qbool.h"
32 #include "qapi/qmp/qdict.h"
33 #include "qapi/qmp/qnum.h"
34 #include "qapi/qmp/qstring.h"
35 #include "qapi/qmp/qerror.h"
36 #include "qemu/option_int.h"
37 #include "qemu/cutils.h"
38 #include "qemu/id.h"
39 #include "qemu/help_option.h"
40 
41 /*
42  * Extracts the name of an option from the parameter string (p points at the
43  * first byte of the option name)
44  *
45  * The option name is delimited by delim (usually , or =) or the string end
46  * and is copied into option. The caller is responsible for free'ing option
47  * when no longer required.
48  *
49  * The return value is the position of the delimiter/zero byte after the option
50  * name in p.
51  */
52 static const char *get_opt_name(const char *p, char **option, char delim)
53 {
54     char *offset = strchr(p, delim);
55 
56     if (offset) {
57         *option = g_strndup(p, offset - p);
58         return offset;
59     } else {
60         *option = g_strdup(p);
61         return p + strlen(p);
62     }
63 }
64 
65 /*
66  * Extracts the value of an option from the parameter string p (p points at the
67  * first byte of the option value)
68  *
69  * This function is comparable to get_opt_name with the difference that the
70  * delimiter is fixed to be comma which starts a new option. To specify an
71  * option value that contains commas, double each comma.
72  */
73 const char *get_opt_value(const char *p, char **value)
74 {
75     size_t capacity = 0, length;
76     const char *offset;
77 
78     *value = NULL;
79     while (1) {
80         offset = qemu_strchrnul(p, ',');
81         length = offset - p;
82         if (*offset != '\0' && *(offset + 1) == ',') {
83             length++;
84         }
85         *value = g_renew(char, *value, capacity + length + 1);
86         strncpy(*value + capacity, p, length);
87         (*value)[capacity + length] = '\0';
88         capacity += length;
89         if (*offset == '\0' ||
90             *(offset + 1) != ',') {
91             break;
92         }
93 
94         p += (offset - p) + 2;
95     }
96 
97     return offset;
98 }
99 
100 static void parse_option_bool(const char *name, const char *value, bool *ret,
101                               Error **errp)
102 {
103     if (!strcmp(value, "on")) {
104         *ret = 1;
105     } else if (!strcmp(value, "off")) {
106         *ret = 0;
107     } else {
108         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
109                    name, "'on' or 'off'");
110     }
111 }
112 
113 static void parse_option_number(const char *name, const char *value,
114                                 uint64_t *ret, Error **errp)
115 {
116     uint64_t number;
117     int err;
118 
119     err = qemu_strtou64(value, NULL, 0, &number);
120     if (err == -ERANGE) {
121         error_setg(errp, "Value '%s' is too large for parameter '%s'",
122                    value, name);
123         return;
124     }
125     if (err) {
126         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
127         return;
128     }
129     *ret = number;
130 }
131 
132 static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
133                                             const char *name)
134 {
135     int i;
136 
137     for (i = 0; desc[i].name != NULL; i++) {
138         if (strcmp(desc[i].name, name) == 0) {
139             return &desc[i];
140         }
141     }
142 
143     return NULL;
144 }
145 
146 void parse_option_size(const char *name, const char *value,
147                        uint64_t *ret, Error **errp)
148 {
149     uint64_t size;
150     int err;
151 
152     err = qemu_strtosz(value, NULL, &size);
153     if (err == -ERANGE) {
154         error_setg(errp, "Value '%s' is out of range for parameter '%s'",
155                    value, name);
156         return;
157     }
158     if (err) {
159         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
160                    "a non-negative number below 2^64");
161         error_append_hint(errp, "Optional suffix k, M, G, T, P or E means"
162                           " kilo-, mega-, giga-, tera-, peta-\n"
163                           "and exabytes, respectively.\n");
164         return;
165     }
166     *ret = size;
167 }
168 
169 bool has_help_option(const char *param)
170 {
171     const char *p = param;
172     bool result = false;
173 
174     while (*p && !result) {
175         char *value;
176 
177         p = get_opt_value(p, &value);
178         if (*p) {
179             p++;
180         }
181 
182         result = is_help_option(value);
183         g_free(value);
184     }
185 
186     return result;
187 }
188 
189 bool is_valid_option_list(const char *p)
190 {
191     char *value = NULL;
192     bool result = false;
193 
194     while (*p) {
195         p = get_opt_value(p, &value);
196         if ((*p && !*++p) ||
197             (!*value || *value == ',')) {
198             goto out;
199         }
200 
201         g_free(value);
202         value = NULL;
203     }
204 
205     result = true;
206 out:
207     g_free(value);
208     return result;
209 }
210 
211 static const char *opt_type_to_string(enum QemuOptType type)
212 {
213     switch (type) {
214     case QEMU_OPT_STRING:
215         return "str";
216     case QEMU_OPT_BOOL:
217         return "bool (on/off)";
218     case QEMU_OPT_NUMBER:
219         return "num";
220     case QEMU_OPT_SIZE:
221         return "size";
222     }
223 
224     g_assert_not_reached();
225 }
226 
227 /**
228  * Print the list of options available in the given list.  If
229  * @print_caption is true, a caption (including the list name, if it
230  * exists) is printed.  The options itself will be indented, so
231  * @print_caption should only be set to false if the caller prints its
232  * own custom caption (so that the indentation makes sense).
233  */
234 void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
235 {
236     QemuOptDesc *desc;
237     int i;
238     GPtrArray *array = g_ptr_array_new();
239 
240     assert(list);
241     desc = list->desc;
242     while (desc && desc->name) {
243         GString *str = g_string_new(NULL);
244         g_string_append_printf(str, "  %s=<%s>", desc->name,
245                                opt_type_to_string(desc->type));
246         if (desc->help) {
247             if (str->len < 24) {
248                 g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
249             }
250             g_string_append_printf(str, " - %s", desc->help);
251         }
252         g_ptr_array_add(array, g_string_free(str, false));
253         desc++;
254     }
255 
256     g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
257     if (print_caption && array->len > 0) {
258         if (list->name) {
259             printf("%s options:\n", list->name);
260         } else {
261             printf("Options:\n");
262         }
263     } else if (array->len == 0) {
264         if (list->name) {
265             printf("There are no options for %s.\n", list->name);
266         } else {
267             printf("No options available.\n");
268         }
269     }
270     for (i = 0; i < array->len; i++) {
271         printf("%s\n", (char *)array->pdata[i]);
272     }
273     g_ptr_array_set_free_func(array, g_free);
274     g_ptr_array_free(array, true);
275 
276 }
277 /* ------------------------------------------------------------------ */
278 
279 QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
280 {
281     QemuOpt *opt;
282 
283     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
284         if (strcmp(opt->name, name) != 0)
285             continue;
286         return opt;
287     }
288     return NULL;
289 }
290 
291 static void qemu_opt_del(QemuOpt *opt)
292 {
293     QTAILQ_REMOVE(&opt->opts->head, opt, next);
294     g_free(opt->name);
295     g_free(opt->str);
296     g_free(opt);
297 }
298 
299 /* qemu_opt_set allows many settings for the same option.
300  * This function deletes all settings for an option.
301  */
302 static void qemu_opt_del_all(QemuOpts *opts, const char *name)
303 {
304     QemuOpt *opt, *next_opt;
305 
306     QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next_opt) {
307         if (!strcmp(opt->name, name)) {
308             qemu_opt_del(opt);
309         }
310     }
311 }
312 
313 const char *qemu_opt_get(QemuOpts *opts, const char *name)
314 {
315     QemuOpt *opt;
316 
317     if (opts == NULL) {
318         return NULL;
319     }
320 
321     opt = qemu_opt_find(opts, name);
322     if (!opt) {
323         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
324         if (desc && desc->def_value_str) {
325             return desc->def_value_str;
326         }
327     }
328     return opt ? opt->str : NULL;
329 }
330 
331 void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *name)
332 {
333     iter->opts = opts;
334     iter->opt = QTAILQ_FIRST(&opts->head);
335     iter->name = name;
336 }
337 
338 const char *qemu_opt_iter_next(QemuOptsIter *iter)
339 {
340     QemuOpt *ret = iter->opt;
341     if (iter->name) {
342         while (ret && !g_str_equal(iter->name, ret->name)) {
343             ret = QTAILQ_NEXT(ret, next);
344         }
345     }
346     iter->opt = ret ? QTAILQ_NEXT(ret, next) : NULL;
347     return ret ? ret->str : NULL;
348 }
349 
350 /* Get a known option (or its default) and remove it from the list
351  * all in one action. Return a malloced string of the option value.
352  * Result must be freed by caller with g_free().
353  */
354 char *qemu_opt_get_del(QemuOpts *opts, const char *name)
355 {
356     QemuOpt *opt;
357     const QemuOptDesc *desc;
358     char *str = NULL;
359 
360     if (opts == NULL) {
361         return NULL;
362     }
363 
364     opt = qemu_opt_find(opts, name);
365     if (!opt) {
366         desc = find_desc_by_name(opts->list->desc, name);
367         if (desc && desc->def_value_str) {
368             str = g_strdup(desc->def_value_str);
369         }
370         return str;
371     }
372     str = opt->str;
373     opt->str = NULL;
374     qemu_opt_del_all(opts, name);
375     return str;
376 }
377 
378 bool qemu_opt_has_help_opt(QemuOpts *opts)
379 {
380     QemuOpt *opt;
381 
382     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
383         if (is_help_option(opt->name)) {
384             return true;
385         }
386     }
387     return false;
388 }
389 
390 static bool qemu_opt_get_bool_helper(QemuOpts *opts, const char *name,
391                                      bool defval, bool del)
392 {
393     QemuOpt *opt;
394     bool ret = defval;
395 
396     if (opts == NULL) {
397         return ret;
398     }
399 
400     opt = qemu_opt_find(opts, name);
401     if (opt == NULL) {
402         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
403         if (desc && desc->def_value_str) {
404             parse_option_bool(name, desc->def_value_str, &ret, &error_abort);
405         }
406         return ret;
407     }
408     assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
409     ret = opt->value.boolean;
410     if (del) {
411         qemu_opt_del_all(opts, name);
412     }
413     return ret;
414 }
415 
416 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
417 {
418     return qemu_opt_get_bool_helper(opts, name, defval, false);
419 }
420 
421 bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval)
422 {
423     return qemu_opt_get_bool_helper(opts, name, defval, true);
424 }
425 
426 static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, const char *name,
427                                            uint64_t defval, bool del)
428 {
429     QemuOpt *opt;
430     uint64_t ret = defval;
431 
432     if (opts == NULL) {
433         return ret;
434     }
435 
436     opt = qemu_opt_find(opts, name);
437     if (opt == NULL) {
438         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
439         if (desc && desc->def_value_str) {
440             parse_option_number(name, desc->def_value_str, &ret, &error_abort);
441         }
442         return ret;
443     }
444     assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
445     ret = opt->value.uint;
446     if (del) {
447         qemu_opt_del_all(opts, name);
448     }
449     return ret;
450 }
451 
452 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
453 {
454     return qemu_opt_get_number_helper(opts, name, defval, false);
455 }
456 
457 uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name,
458                                  uint64_t defval)
459 {
460     return qemu_opt_get_number_helper(opts, name, defval, true);
461 }
462 
463 static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, const char *name,
464                                          uint64_t defval, bool del)
465 {
466     QemuOpt *opt;
467     uint64_t ret = defval;
468 
469     if (opts == NULL) {
470         return ret;
471     }
472 
473     opt = qemu_opt_find(opts, name);
474     if (opt == NULL) {
475         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
476         if (desc && desc->def_value_str) {
477             parse_option_size(name, desc->def_value_str, &ret, &error_abort);
478         }
479         return ret;
480     }
481     assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
482     ret = opt->value.uint;
483     if (del) {
484         qemu_opt_del_all(opts, name);
485     }
486     return ret;
487 }
488 
489 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
490 {
491     return qemu_opt_get_size_helper(opts, name, defval, false);
492 }
493 
494 uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
495                                uint64_t defval)
496 {
497     return qemu_opt_get_size_helper(opts, name, defval, true);
498 }
499 
500 static void qemu_opt_parse(QemuOpt *opt, Error **errp)
501 {
502     if (opt->desc == NULL)
503         return;
504 
505     switch (opt->desc->type) {
506     case QEMU_OPT_STRING:
507         /* nothing */
508         return;
509     case QEMU_OPT_BOOL:
510         parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
511         break;
512     case QEMU_OPT_NUMBER:
513         parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
514         break;
515     case QEMU_OPT_SIZE:
516         parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
517         break;
518     default:
519         abort();
520     }
521 }
522 
523 static bool opts_accepts_any(const QemuOpts *opts)
524 {
525     return opts->list->desc[0].name == NULL;
526 }
527 
528 int qemu_opt_unset(QemuOpts *opts, const char *name)
529 {
530     QemuOpt *opt = qemu_opt_find(opts, name);
531 
532     assert(opts_accepts_any(opts));
533 
534     if (opt == NULL) {
535         return -1;
536     } else {
537         qemu_opt_del(opt);
538         return 0;
539     }
540 }
541 
542 static void opt_set(QemuOpts *opts, const char *name, char *value,
543                     bool prepend, bool *invalidp, Error **errp)
544 {
545     QemuOpt *opt;
546     const QemuOptDesc *desc;
547     Error *local_err = NULL;
548 
549     desc = find_desc_by_name(opts->list->desc, name);
550     if (!desc && !opts_accepts_any(opts)) {
551         g_free(value);
552         error_setg(errp, QERR_INVALID_PARAMETER, name);
553         if (invalidp) {
554             *invalidp = true;
555         }
556         return;
557     }
558 
559     opt = g_malloc0(sizeof(*opt));
560     opt->name = g_strdup(name);
561     opt->opts = opts;
562     if (prepend) {
563         QTAILQ_INSERT_HEAD(&opts->head, opt, next);
564     } else {
565         QTAILQ_INSERT_TAIL(&opts->head, opt, next);
566     }
567     opt->desc = desc;
568     opt->str = value;
569     qemu_opt_parse(opt, &local_err);
570     if (local_err) {
571         error_propagate(errp, local_err);
572         qemu_opt_del(opt);
573     }
574 }
575 
576 void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
577                   Error **errp)
578 {
579     opt_set(opts, name, g_strdup(value), false, NULL, errp);
580 }
581 
582 void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
583                        Error **errp)
584 {
585     QemuOpt *opt;
586     const QemuOptDesc *desc = opts->list->desc;
587 
588     opt = g_malloc0(sizeof(*opt));
589     opt->desc = find_desc_by_name(desc, name);
590     if (!opt->desc && !opts_accepts_any(opts)) {
591         error_setg(errp, QERR_INVALID_PARAMETER, name);
592         g_free(opt);
593         return;
594     }
595 
596     opt->name = g_strdup(name);
597     opt->opts = opts;
598     opt->value.boolean = !!val;
599     opt->str = g_strdup(val ? "on" : "off");
600     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
601 }
602 
603 void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
604                          Error **errp)
605 {
606     QemuOpt *opt;
607     const QemuOptDesc *desc = opts->list->desc;
608 
609     opt = g_malloc0(sizeof(*opt));
610     opt->desc = find_desc_by_name(desc, name);
611     if (!opt->desc && !opts_accepts_any(opts)) {
612         error_setg(errp, QERR_INVALID_PARAMETER, name);
613         g_free(opt);
614         return;
615     }
616 
617     opt->name = g_strdup(name);
618     opt->opts = opts;
619     opt->value.uint = val;
620     opt->str = g_strdup_printf("%" PRId64, val);
621     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
622 }
623 
624 /**
625  * For each member of @opts, call @func(@opaque, name, value, @errp).
626  * @func() may store an Error through @errp, but must return non-zero then.
627  * When @func() returns non-zero, break the loop and return that value.
628  * Return zero when the loop completes.
629  */
630 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
631                      Error **errp)
632 {
633     QemuOpt *opt;
634     int rc;
635 
636     QTAILQ_FOREACH(opt, &opts->head, next) {
637         rc = func(opaque, opt->name, opt->str, errp);
638         if (rc) {
639             return rc;
640         }
641         assert(!errp || !*errp);
642     }
643     return 0;
644 }
645 
646 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
647 {
648     QemuOpts *opts;
649 
650     QTAILQ_FOREACH(opts, &list->head, next) {
651         if (!opts->id && !id) {
652             return opts;
653         }
654         if (opts->id && id && !strcmp(opts->id, id)) {
655             return opts;
656         }
657     }
658     return NULL;
659 }
660 
661 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
662                            int fail_if_exists, Error **errp)
663 {
664     QemuOpts *opts = NULL;
665 
666     if (id) {
667         if (!id_wellformed(id)) {
668             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id",
669                        "an identifier");
670             error_append_hint(errp, "Identifiers consist of letters, digits, "
671                               "'-', '.', '_', starting with a letter.\n");
672             return NULL;
673         }
674         opts = qemu_opts_find(list, id);
675         if (opts != NULL) {
676             if (fail_if_exists && !list->merge_lists) {
677                 error_setg(errp, "Duplicate ID '%s' for %s", id, list->name);
678                 return NULL;
679             } else {
680                 return opts;
681             }
682         }
683     } else if (list->merge_lists) {
684         opts = qemu_opts_find(list, NULL);
685         if (opts) {
686             return opts;
687         }
688     }
689     opts = g_malloc0(sizeof(*opts));
690     opts->id = g_strdup(id);
691     opts->list = list;
692     loc_save(&opts->loc);
693     QTAILQ_INIT(&opts->head);
694     QTAILQ_INSERT_TAIL(&list->head, opts, next);
695     return opts;
696 }
697 
698 void qemu_opts_reset(QemuOptsList *list)
699 {
700     QemuOpts *opts, *next_opts;
701 
702     QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
703         qemu_opts_del(opts);
704     }
705 }
706 
707 void qemu_opts_loc_restore(QemuOpts *opts)
708 {
709     loc_restore(&opts->loc);
710 }
711 
712 void qemu_opts_set(QemuOptsList *list, const char *id,
713                    const char *name, const char *value, Error **errp)
714 {
715     QemuOpts *opts;
716     Error *local_err = NULL;
717 
718     opts = qemu_opts_create(list, id, 1, &local_err);
719     if (local_err) {
720         error_propagate(errp, local_err);
721         return;
722     }
723     qemu_opt_set(opts, name, value, errp);
724 }
725 
726 const char *qemu_opts_id(QemuOpts *opts)
727 {
728     return opts->id;
729 }
730 
731 /* The id string will be g_free()d by qemu_opts_del */
732 void qemu_opts_set_id(QemuOpts *opts, char *id)
733 {
734     opts->id = id;
735 }
736 
737 void qemu_opts_del(QemuOpts *opts)
738 {
739     QemuOpt *opt;
740 
741     if (opts == NULL) {
742         return;
743     }
744 
745     for (;;) {
746         opt = QTAILQ_FIRST(&opts->head);
747         if (opt == NULL)
748             break;
749         qemu_opt_del(opt);
750     }
751     QTAILQ_REMOVE(&opts->list->head, opts, next);
752     g_free(opts->id);
753     g_free(opts);
754 }
755 
756 /* print value, escaping any commas in value */
757 static void escaped_print(const char *value)
758 {
759     const char *ptr;
760 
761     for (ptr = value; *ptr; ++ptr) {
762         if (*ptr == ',') {
763             putchar(',');
764         }
765         putchar(*ptr);
766     }
767 }
768 
769 void qemu_opts_print(QemuOpts *opts, const char *separator)
770 {
771     QemuOpt *opt;
772     QemuOptDesc *desc = opts->list->desc;
773     const char *sep = "";
774 
775     if (opts->id) {
776         printf("id=%s", opts->id); /* passed id_wellformed -> no commas */
777         sep = separator;
778     }
779 
780     if (desc[0].name == NULL) {
781         QTAILQ_FOREACH(opt, &opts->head, next) {
782             printf("%s%s=", sep, opt->name);
783             escaped_print(opt->str);
784             sep = separator;
785         }
786         return;
787     }
788     for (; desc && desc->name; desc++) {
789         const char *value;
790         opt = qemu_opt_find(opts, desc->name);
791 
792         value = opt ? opt->str : desc->def_value_str;
793         if (!value) {
794             continue;
795         }
796         if (desc->type == QEMU_OPT_STRING) {
797             printf("%s%s=", sep, desc->name);
798             escaped_print(value);
799         } else if ((desc->type == QEMU_OPT_SIZE ||
800                     desc->type == QEMU_OPT_NUMBER) && opt) {
801             printf("%s%s=%" PRId64, sep, desc->name, opt->value.uint);
802         } else {
803             printf("%s%s=%s", sep, desc->name, value);
804         }
805         sep = separator;
806     }
807 }
808 
809 static void opts_do_parse(QemuOpts *opts, const char *params,
810                           const char *firstname, bool prepend,
811                           bool *invalidp, Error **errp)
812 {
813     char *option = NULL;
814     char *value = NULL;
815     const char *p,*pe,*pc;
816     Error *local_err = NULL;
817 
818     for (p = params; *p != '\0'; p++) {
819         pe = strchr(p, '=');
820         pc = strchr(p, ',');
821         if (!pe || (pc && pc < pe)) {
822             /* found "foo,more" */
823             if (p == params && firstname) {
824                 /* implicitly named first option */
825                 option = g_strdup(firstname);
826                 p = get_opt_value(p, &value);
827             } else {
828                 /* option without value, probably a flag */
829                 p = get_opt_name(p, &option, ',');
830                 if (strncmp(option, "no", 2) == 0) {
831                     memmove(option, option+2, strlen(option+2)+1);
832                     value = g_strdup("off");
833                 } else {
834                     value = g_strdup("on");
835                 }
836             }
837         } else {
838             /* found "foo=bar,more" */
839             p = get_opt_name(p, &option, '=');
840             assert(*p == '=');
841             p++;
842             p = get_opt_value(p, &value);
843         }
844         if (strcmp(option, "id") != 0) {
845             /* store and parse */
846             opt_set(opts, option, value, prepend, invalidp, &local_err);
847             value = NULL;
848             if (local_err) {
849                 error_propagate(errp, local_err);
850                 goto cleanup;
851             }
852         }
853         if (*p != ',') {
854             break;
855         }
856         g_free(option);
857         g_free(value);
858         option = value = NULL;
859     }
860 
861  cleanup:
862     g_free(option);
863     g_free(value);
864 }
865 
866 /**
867  * Store options parsed from @params into @opts.
868  * If @firstname is non-null, the first key=value in @params may omit
869  * key=, and is treated as if key was @firstname.
870  * On error, store an error object through @errp if non-null.
871  */
872 void qemu_opts_do_parse(QemuOpts *opts, const char *params,
873                        const char *firstname, Error **errp)
874 {
875     opts_do_parse(opts, params, firstname, false, NULL, errp);
876 }
877 
878 static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
879                             bool permit_abbrev, bool defaults,
880                             bool *invalidp, Error **errp)
881 {
882     const char *firstname;
883     char *id = NULL;
884     const char *p;
885     QemuOpts *opts;
886     Error *local_err = NULL;
887 
888     assert(!permit_abbrev || list->implied_opt_name);
889     firstname = permit_abbrev ? list->implied_opt_name : NULL;
890 
891     if (strncmp(params, "id=", 3) == 0) {
892         get_opt_value(params + 3, &id);
893     } else if ((p = strstr(params, ",id=")) != NULL) {
894         get_opt_value(p + 4, &id);
895     }
896 
897     /*
898      * This code doesn't work for defaults && !list->merge_lists: when
899      * params has no id=, and list has an element with !opts->id, it
900      * appends a new element instead of returning the existing opts.
901      * However, we got no use for this case.  Guard against possible
902      * (if unlikely) future misuse:
903      */
904     assert(!defaults || list->merge_lists);
905     opts = qemu_opts_create(list, id, !defaults, &local_err);
906     g_free(id);
907     if (opts == NULL) {
908         error_propagate(errp, local_err);
909         return NULL;
910     }
911 
912     opts_do_parse(opts, params, firstname, defaults, invalidp, &local_err);
913     if (local_err) {
914         error_propagate(errp, local_err);
915         qemu_opts_del(opts);
916         return NULL;
917     }
918 
919     return opts;
920 }
921 
922 /**
923  * Create a QemuOpts in @list and with options parsed from @params.
924  * If @permit_abbrev, the first key=value in @params may omit key=,
925  * and is treated as if key was @list->implied_opt_name.
926  * On error, store an error object through @errp if non-null.
927  * Return the new QemuOpts on success, null pointer on error.
928  */
929 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
930                           bool permit_abbrev, Error **errp)
931 {
932     return opts_parse(list, params, permit_abbrev, false, NULL, errp);
933 }
934 
935 /**
936  * Create a QemuOpts in @list and with options parsed from @params.
937  * If @permit_abbrev, the first key=value in @params may omit key=,
938  * and is treated as if key was @list->implied_opt_name.
939  * Report errors with error_report_err().  This is inappropriate in
940  * QMP context.  Do not use this function there!
941  * Return the new QemuOpts on success, null pointer on error.
942  */
943 QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
944                                   bool permit_abbrev)
945 {
946     Error *err = NULL;
947     QemuOpts *opts;
948     bool invalidp = false;
949 
950     opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
951     if (err) {
952         if (invalidp && has_help_option(params)) {
953             qemu_opts_print_help(list, true);
954             error_free(err);
955         } else {
956             error_report_err(err);
957         }
958     }
959     return opts;
960 }
961 
962 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
963                             int permit_abbrev)
964 {
965     QemuOpts *opts;
966 
967     opts = opts_parse(list, params, permit_abbrev, true, NULL, NULL);
968     assert(opts);
969 }
970 
971 typedef struct OptsFromQDictState {
972     QemuOpts *opts;
973     Error **errp;
974 } OptsFromQDictState;
975 
976 static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
977 {
978     OptsFromQDictState *state = opaque;
979     char buf[32], *tmp = NULL;
980     const char *value;
981 
982     if (!strcmp(key, "id") || *state->errp) {
983         return;
984     }
985 
986     switch (qobject_type(obj)) {
987     case QTYPE_QSTRING:
988         value = qstring_get_str(qobject_to(QString, obj));
989         break;
990     case QTYPE_QNUM:
991         tmp = qnum_to_string(qobject_to(QNum, obj));
992         value = tmp;
993         break;
994     case QTYPE_QBOOL:
995         pstrcpy(buf, sizeof(buf),
996                 qbool_get_bool(qobject_to(QBool, obj)) ? "on" : "off");
997         value = buf;
998         break;
999     default:
1000         return;
1001     }
1002 
1003     qemu_opt_set(state->opts, key, value, state->errp);
1004     g_free(tmp);
1005 }
1006 
1007 /*
1008  * Create QemuOpts from a QDict.
1009  * Use value of key "id" as ID if it exists and is a QString.  Only
1010  * QStrings, QNums and QBools are copied.  Entries with other types
1011  * are silently ignored.
1012  */
1013 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
1014                                Error **errp)
1015 {
1016     OptsFromQDictState state;
1017     Error *local_err = NULL;
1018     QemuOpts *opts;
1019 
1020     opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
1021                             &local_err);
1022     if (local_err) {
1023         error_propagate(errp, local_err);
1024         return NULL;
1025     }
1026 
1027     assert(opts != NULL);
1028 
1029     state.errp = &local_err;
1030     state.opts = opts;
1031     qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
1032     if (local_err) {
1033         error_propagate(errp, local_err);
1034         qemu_opts_del(opts);
1035         return NULL;
1036     }
1037 
1038     return opts;
1039 }
1040 
1041 /*
1042  * Adds all QDict entries to the QemuOpts that can be added and removes them
1043  * from the QDict. When this function returns, the QDict contains only those
1044  * entries that couldn't be added to the QemuOpts.
1045  */
1046 void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
1047 {
1048     const QDictEntry *entry, *next;
1049 
1050     entry = qdict_first(qdict);
1051 
1052     while (entry != NULL) {
1053         Error *local_err = NULL;
1054         OptsFromQDictState state = {
1055             .errp = &local_err,
1056             .opts = opts,
1057         };
1058 
1059         next = qdict_next(qdict, entry);
1060 
1061         if (find_desc_by_name(opts->list->desc, entry->key)) {
1062             qemu_opts_from_qdict_1(entry->key, entry->value, &state);
1063             if (local_err) {
1064                 error_propagate(errp, local_err);
1065                 return;
1066             } else {
1067                 qdict_del(qdict, entry->key);
1068             }
1069         }
1070 
1071         entry = next;
1072     }
1073 }
1074 
1075 /*
1076  * Convert from QemuOpts to QDict. The QDict values are of type QString.
1077  *
1078  * If @list is given, only add those options to the QDict that are contained in
1079  * the list. If @del is true, any options added to the QDict are removed from
1080  * the QemuOpts, otherwise they remain there.
1081  *
1082  * If two options in @opts have the same name, they are processed in order
1083  * so that the last one wins (consistent with the reverse iteration in
1084  * qemu_opt_find()), but all of them are deleted if @del is true.
1085  *
1086  * TODO We'll want to use types appropriate for opt->desc->type, but
1087  * this is enough for now.
1088  */
1089 QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict,
1090                                    QemuOptsList *list, bool del)
1091 {
1092     QemuOpt *opt, *next;
1093 
1094     if (!qdict) {
1095         qdict = qdict_new();
1096     }
1097     if (opts->id) {
1098         qdict_put_str(qdict, "id", opts->id);
1099     }
1100     QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next) {
1101         if (list) {
1102             QemuOptDesc *desc;
1103             bool found = false;
1104             for (desc = list->desc; desc->name; desc++) {
1105                 if (!strcmp(desc->name, opt->name)) {
1106                     found = true;
1107                     break;
1108                 }
1109             }
1110             if (!found) {
1111                 continue;
1112             }
1113         }
1114         qdict_put_str(qdict, opt->name, opt->str);
1115         if (del) {
1116             qemu_opt_del(opt);
1117         }
1118     }
1119     return qdict;
1120 }
1121 
1122 /* Copy all options in a QemuOpts to the given QDict. See
1123  * qemu_opts_to_qdict_filtered() for details. */
1124 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1125 {
1126     return qemu_opts_to_qdict_filtered(opts, qdict, NULL, false);
1127 }
1128 
1129 /* Validate parsed opts against descriptions where no
1130  * descriptions were provided in the QemuOptsList.
1131  */
1132 void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
1133 {
1134     QemuOpt *opt;
1135     Error *local_err = NULL;
1136 
1137     assert(opts_accepts_any(opts));
1138 
1139     QTAILQ_FOREACH(opt, &opts->head, next) {
1140         opt->desc = find_desc_by_name(desc, opt->name);
1141         if (!opt->desc) {
1142             error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
1143             return;
1144         }
1145 
1146         qemu_opt_parse(opt, &local_err);
1147         if (local_err) {
1148             error_propagate(errp, local_err);
1149             return;
1150         }
1151     }
1152 }
1153 
1154 /**
1155  * For each member of @list, call @func(@opaque, member, @errp).
1156  * Call it with the current location temporarily set to the member's.
1157  * @func() may store an Error through @errp, but must return non-zero then.
1158  * When @func() returns non-zero, break the loop and return that value.
1159  * Return zero when the loop completes.
1160  */
1161 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
1162                       void *opaque, Error **errp)
1163 {
1164     Location loc;
1165     QemuOpts *opts;
1166     int rc = 0;
1167 
1168     loc_push_none(&loc);
1169     QTAILQ_FOREACH(opts, &list->head, next) {
1170         loc_restore(&opts->loc);
1171         rc = func(opaque, opts, errp);
1172         if (rc) {
1173             break;
1174         }
1175         assert(!errp || !*errp);
1176     }
1177     loc_pop(&loc);
1178     return rc;
1179 }
1180 
1181 static size_t count_opts_list(QemuOptsList *list)
1182 {
1183     QemuOptDesc *desc = NULL;
1184     size_t num_opts = 0;
1185 
1186     if (!list) {
1187         return 0;
1188     }
1189 
1190     desc = list->desc;
1191     while (desc && desc->name) {
1192         num_opts++;
1193         desc++;
1194     }
1195 
1196     return num_opts;
1197 }
1198 
1199 void qemu_opts_free(QemuOptsList *list)
1200 {
1201     g_free(list);
1202 }
1203 
1204 /* Realloc dst option list and append options from an option list (list)
1205  * to it. dst could be NULL or a malloced list.
1206  * The lifetime of dst must be shorter than the input list because the
1207  * QemuOptDesc->name, ->help, and ->def_value_str strings are shared.
1208  */
1209 QemuOptsList *qemu_opts_append(QemuOptsList *dst,
1210                                QemuOptsList *list)
1211 {
1212     size_t num_opts, num_dst_opts;
1213     QemuOptDesc *desc;
1214     bool need_init = false;
1215     bool need_head_update;
1216 
1217     if (!list) {
1218         return dst;
1219     }
1220 
1221     /* If dst is NULL, after realloc, some area of dst should be initialized
1222      * before adding options to it.
1223      */
1224     if (!dst) {
1225         need_init = true;
1226         need_head_update = true;
1227     } else {
1228         /* Moreover, even if dst is not NULL, the realloc may move it to a
1229          * different address in which case we may get a stale tail pointer
1230          * in dst->head. */
1231         need_head_update = QTAILQ_EMPTY(&dst->head);
1232     }
1233 
1234     num_opts = count_opts_list(dst);
1235     num_dst_opts = num_opts;
1236     num_opts += count_opts_list(list);
1237     dst = g_realloc(dst, sizeof(QemuOptsList) +
1238                     (num_opts + 1) * sizeof(QemuOptDesc));
1239     if (need_init) {
1240         dst->name = NULL;
1241         dst->implied_opt_name = NULL;
1242         dst->merge_lists = false;
1243     }
1244     if (need_head_update) {
1245         QTAILQ_INIT(&dst->head);
1246     }
1247     dst->desc[num_dst_opts].name = NULL;
1248 
1249     /* append list->desc to dst->desc */
1250     if (list) {
1251         desc = list->desc;
1252         while (desc && desc->name) {
1253             if (find_desc_by_name(dst->desc, desc->name) == NULL) {
1254                 dst->desc[num_dst_opts++] = *desc;
1255                 dst->desc[num_dst_opts].name = NULL;
1256             }
1257             desc++;
1258         }
1259     }
1260 
1261     return dst;
1262 }
1263