xref: /openbmc/qemu/util/qemu-option.c (revision 14a650ec)
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 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     list->assigned = true;
279 
280     return 0;
281 }
282 
283 /*
284  * Sets the given parameter to an integer instead of a string.
285  * This function cannot be used to set string options.
286  *
287  * Returns 0 on success, -1 in error cases
288  */
289 int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
290     uint64_t value)
291 {
292     // Find a matching parameter
293     list = get_option_parameter(list, name);
294     if (list == NULL) {
295         fprintf(stderr, "Unknown option '%s'\n", name);
296         return -1;
297     }
298 
299     // Process parameter
300     switch (list->type) {
301     case OPT_FLAG:
302     case OPT_NUMBER:
303     case OPT_SIZE:
304         list->value.n = value;
305         break;
306 
307     default:
308         return -1;
309     }
310 
311     list->assigned = true;
312 
313     return 0;
314 }
315 
316 /*
317  * Frees a option list. If it contains strings, the strings are freed as well.
318  */
319 void free_option_parameters(QEMUOptionParameter *list)
320 {
321     QEMUOptionParameter *cur = list;
322 
323     while (cur && cur->name) {
324         if (cur->type == OPT_STRING) {
325             g_free(cur->value.s);
326         }
327         cur++;
328     }
329 
330     g_free(list);
331 }
332 
333 /*
334  * Count valid options in list
335  */
336 static size_t count_option_parameters(QEMUOptionParameter *list)
337 {
338     size_t num_options = 0;
339 
340     while (list && list->name) {
341         num_options++;
342         list++;
343     }
344 
345     return num_options;
346 }
347 
348 /*
349  * Append an option list (list) to an option list (dest).
350  *
351  * If dest is NULL, a new copy of list is created.
352  *
353  * Returns a pointer to the first element of dest (or the newly allocated copy)
354  */
355 QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
356     QEMUOptionParameter *list)
357 {
358     size_t num_options, num_dest_options;
359 
360     num_options = count_option_parameters(dest);
361     num_dest_options = num_options;
362 
363     num_options += count_option_parameters(list);
364 
365     dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
366     dest[num_dest_options].name = NULL;
367 
368     while (list && list->name) {
369         if (get_option_parameter(dest, list->name) == NULL) {
370             dest[num_dest_options++] = *list;
371             dest[num_dest_options].name = NULL;
372         }
373         list++;
374     }
375 
376     return dest;
377 }
378 
379 /*
380  * Parses a parameter string (param) into an option list (dest).
381  *
382  * list is the template option list. If dest is NULL, a new copy of list is
383  * created. If list is NULL, this function fails.
384  *
385  * A parameter string consists of one or more parameters, separated by commas.
386  * Each parameter consists of its name and possibly of a value. In the latter
387  * case, the value is delimited by an = character. To specify a value which
388  * contains commas, double each comma so it won't be recognized as the end of
389  * the parameter.
390  *
391  * For more details of the parsing see above.
392  *
393  * Returns a pointer to the first element of dest (or the newly allocated copy)
394  * or NULL in error cases
395  */
396 QEMUOptionParameter *parse_option_parameters(const char *param,
397     QEMUOptionParameter *list, QEMUOptionParameter *dest)
398 {
399     QEMUOptionParameter *allocated = NULL;
400     char name[256];
401     char value[256];
402     char *param_delim, *value_delim;
403     char next_delim;
404     int i;
405 
406     if (list == NULL) {
407         return NULL;
408     }
409 
410     if (dest == NULL) {
411         dest = allocated = append_option_parameters(NULL, list);
412     }
413 
414     for (i = 0; dest[i].name; i++) {
415         dest[i].assigned = false;
416     }
417 
418     while (*param) {
419 
420         // Find parameter name and value in the string
421         param_delim = strchr(param, ',');
422         value_delim = strchr(param, '=');
423 
424         if (value_delim && (value_delim < param_delim || !param_delim)) {
425             next_delim = '=';
426         } else {
427             next_delim = ',';
428             value_delim = NULL;
429         }
430 
431         param = get_opt_name(name, sizeof(name), param, next_delim);
432         if (value_delim) {
433             param = get_opt_value(value, sizeof(value), param + 1);
434         }
435         if (*param != '\0') {
436             param++;
437         }
438 
439         // Set the parameter
440         if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
441             goto fail;
442         }
443     }
444 
445     return dest;
446 
447 fail:
448     // Only free the list if it was newly allocated
449     free_option_parameters(allocated);
450     return NULL;
451 }
452 
453 /*
454  * Prints all options of a list that have a value to stdout
455  */
456 void print_option_parameters(QEMUOptionParameter *list)
457 {
458     while (list && list->name) {
459         switch (list->type) {
460             case OPT_STRING:
461                  if (list->value.s != NULL) {
462                      printf("%s='%s' ", list->name, list->value.s);
463                  }
464                 break;
465             case OPT_FLAG:
466                 printf("%s=%s ", list->name, list->value.n ? "on" : "off");
467                 break;
468             case OPT_SIZE:
469             case OPT_NUMBER:
470                 printf("%s=%" PRId64 " ", list->name, list->value.n);
471                 break;
472             default:
473                 printf("%s=(unknown type) ", list->name);
474                 break;
475         }
476         list++;
477     }
478 }
479 
480 /*
481  * Prints an overview of all available options
482  */
483 void print_option_help(QEMUOptionParameter *list)
484 {
485     printf("Supported options:\n");
486     while (list && list->name) {
487         printf("%-16s %s\n", list->name,
488             list->help ? list->help : "No description available");
489         list++;
490     }
491 }
492 
493 /* ------------------------------------------------------------------ */
494 
495 static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
496 {
497     QemuOpt *opt;
498 
499     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
500         if (strcmp(opt->name, name) != 0)
501             continue;
502         return opt;
503     }
504     return NULL;
505 }
506 
507 const char *qemu_opt_get(QemuOpts *opts, const char *name)
508 {
509     QemuOpt *opt = qemu_opt_find(opts, name);
510     return opt ? opt->str : NULL;
511 }
512 
513 bool qemu_opt_has_help_opt(QemuOpts *opts)
514 {
515     QemuOpt *opt;
516 
517     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
518         if (is_help_option(opt->name)) {
519             return true;
520         }
521     }
522     return false;
523 }
524 
525 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
526 {
527     QemuOpt *opt = qemu_opt_find(opts, name);
528 
529     if (opt == NULL)
530         return defval;
531     assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
532     return opt->value.boolean;
533 }
534 
535 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
536 {
537     QemuOpt *opt = qemu_opt_find(opts, name);
538 
539     if (opt == NULL)
540         return defval;
541     assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
542     return opt->value.uint;
543 }
544 
545 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
546 {
547     QemuOpt *opt = qemu_opt_find(opts, name);
548 
549     if (opt == NULL)
550         return defval;
551     assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
552     return opt->value.uint;
553 }
554 
555 static void qemu_opt_parse(QemuOpt *opt, Error **errp)
556 {
557     if (opt->desc == NULL)
558         return;
559 
560     switch (opt->desc->type) {
561     case QEMU_OPT_STRING:
562         /* nothing */
563         return;
564     case QEMU_OPT_BOOL:
565         parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
566         break;
567     case QEMU_OPT_NUMBER:
568         parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
569         break;
570     case QEMU_OPT_SIZE:
571         parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
572         break;
573     default:
574         abort();
575     }
576 }
577 
578 static void qemu_opt_del(QemuOpt *opt)
579 {
580     QTAILQ_REMOVE(&opt->opts->head, opt, next);
581     g_free((/* !const */ char*)opt->name);
582     g_free((/* !const */ char*)opt->str);
583     g_free(opt);
584 }
585 
586 static bool opts_accepts_any(const QemuOpts *opts)
587 {
588     return opts->list->desc[0].name == NULL;
589 }
590 
591 static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
592                                             const char *name)
593 {
594     int i;
595 
596     for (i = 0; desc[i].name != NULL; i++) {
597         if (strcmp(desc[i].name, name) == 0) {
598             return &desc[i];
599         }
600     }
601 
602     return NULL;
603 }
604 
605 int qemu_opt_unset(QemuOpts *opts, const char *name)
606 {
607     QemuOpt *opt = qemu_opt_find(opts, name);
608 
609     assert(opts_accepts_any(opts));
610 
611     if (opt == NULL) {
612         return -1;
613     } else {
614         qemu_opt_del(opt);
615         return 0;
616     }
617 }
618 
619 static void opt_set(QemuOpts *opts, const char *name, const char *value,
620                     bool prepend, Error **errp)
621 {
622     QemuOpt *opt;
623     const QemuOptDesc *desc;
624     Error *local_err = NULL;
625 
626     desc = find_desc_by_name(opts->list->desc, name);
627     if (!desc && !opts_accepts_any(opts)) {
628         error_set(errp, QERR_INVALID_PARAMETER, name);
629         return;
630     }
631 
632     opt = g_malloc0(sizeof(*opt));
633     opt->name = g_strdup(name);
634     opt->opts = opts;
635     if (prepend) {
636         QTAILQ_INSERT_HEAD(&opts->head, opt, next);
637     } else {
638         QTAILQ_INSERT_TAIL(&opts->head, opt, next);
639     }
640     opt->desc = desc;
641     opt->str = g_strdup(value);
642     qemu_opt_parse(opt, &local_err);
643     if (error_is_set(&local_err)) {
644         error_propagate(errp, local_err);
645         qemu_opt_del(opt);
646     }
647 }
648 
649 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
650 {
651     Error *local_err = NULL;
652 
653     opt_set(opts, name, value, false, &local_err);
654     if (error_is_set(&local_err)) {
655         qerror_report_err(local_err);
656         error_free(local_err);
657         return -1;
658     }
659 
660     return 0;
661 }
662 
663 void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
664                       Error **errp)
665 {
666     opt_set(opts, name, value, false, errp);
667 }
668 
669 int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
670 {
671     QemuOpt *opt;
672     const QemuOptDesc *desc = opts->list->desc;
673 
674     opt = g_malloc0(sizeof(*opt));
675     opt->desc = find_desc_by_name(desc, name);
676     if (!opt->desc && !opts_accepts_any(opts)) {
677         qerror_report(QERR_INVALID_PARAMETER, name);
678         g_free(opt);
679         return -1;
680     }
681 
682     opt->name = g_strdup(name);
683     opt->opts = opts;
684     opt->value.boolean = !!val;
685     opt->str = g_strdup(val ? "on" : "off");
686     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
687 
688     return 0;
689 }
690 
691 int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
692 {
693     QemuOpt *opt;
694     const QemuOptDesc *desc = opts->list->desc;
695 
696     opt = g_malloc0(sizeof(*opt));
697     opt->desc = find_desc_by_name(desc, name);
698     if (!opt->desc && !opts_accepts_any(opts)) {
699         qerror_report(QERR_INVALID_PARAMETER, name);
700         g_free(opt);
701         return -1;
702     }
703 
704     opt->name = g_strdup(name);
705     opt->opts = opts;
706     opt->value.uint = val;
707     opt->str = g_strdup_printf("%" PRId64, val);
708     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
709 
710     return 0;
711 }
712 
713 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
714                      int abort_on_failure)
715 {
716     QemuOpt *opt;
717     int rc = 0;
718 
719     QTAILQ_FOREACH(opt, &opts->head, next) {
720         rc = func(opt->name, opt->str, opaque);
721         if (abort_on_failure  &&  rc != 0)
722             break;
723     }
724     return rc;
725 }
726 
727 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
728 {
729     QemuOpts *opts;
730 
731     QTAILQ_FOREACH(opts, &list->head, next) {
732         if (!opts->id && !id) {
733             return opts;
734         }
735         if (opts->id && id && !strcmp(opts->id, id)) {
736             return opts;
737         }
738     }
739     return NULL;
740 }
741 
742 static int id_wellformed(const char *id)
743 {
744     int i;
745 
746     if (!qemu_isalpha(id[0])) {
747         return 0;
748     }
749     for (i = 1; id[i]; i++) {
750         if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
751             return 0;
752         }
753     }
754     return 1;
755 }
756 
757 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
758                            int fail_if_exists, Error **errp)
759 {
760     QemuOpts *opts = NULL;
761 
762     if (id) {
763         if (!id_wellformed(id)) {
764             error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
765 #if 0 /* conversion from qerror_report() to error_set() broke this: */
766             error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
767 #endif
768             return NULL;
769         }
770         opts = qemu_opts_find(list, id);
771         if (opts != NULL) {
772             if (fail_if_exists && !list->merge_lists) {
773                 error_set(errp, QERR_DUPLICATE_ID, id, list->name);
774                 return NULL;
775             } else {
776                 return opts;
777             }
778         }
779     } else if (list->merge_lists) {
780         opts = qemu_opts_find(list, NULL);
781         if (opts) {
782             return opts;
783         }
784     }
785     opts = g_malloc0(sizeof(*opts));
786     opts->id = g_strdup(id);
787     opts->list = list;
788     loc_save(&opts->loc);
789     QTAILQ_INIT(&opts->head);
790     QTAILQ_INSERT_TAIL(&list->head, opts, next);
791     return opts;
792 }
793 
794 QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
795 {
796     QemuOpts *opts;
797     Error *errp = NULL;
798     opts = qemu_opts_create(list, NULL, 0, &errp);
799     assert_no_error(errp);
800     return opts;
801 }
802 
803 void qemu_opts_reset(QemuOptsList *list)
804 {
805     QemuOpts *opts, *next_opts;
806 
807     QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
808         qemu_opts_del(opts);
809     }
810 }
811 
812 void qemu_opts_loc_restore(QemuOpts *opts)
813 {
814     loc_restore(&opts->loc);
815 }
816 
817 int qemu_opts_set(QemuOptsList *list, const char *id,
818                   const char *name, const char *value)
819 {
820     QemuOpts *opts;
821     Error *local_err = NULL;
822 
823     opts = qemu_opts_create(list, id, 1, &local_err);
824     if (error_is_set(&local_err)) {
825         qerror_report_err(local_err);
826         error_free(local_err);
827         return -1;
828     }
829     return qemu_opt_set(opts, name, value);
830 }
831 
832 const char *qemu_opts_id(QemuOpts *opts)
833 {
834     return opts->id;
835 }
836 
837 /* The id string will be g_free()d by qemu_opts_del */
838 void qemu_opts_set_id(QemuOpts *opts, char *id)
839 {
840     opts->id = id;
841 }
842 
843 void qemu_opts_del(QemuOpts *opts)
844 {
845     QemuOpt *opt;
846 
847     for (;;) {
848         opt = QTAILQ_FIRST(&opts->head);
849         if (opt == NULL)
850             break;
851         qemu_opt_del(opt);
852     }
853     QTAILQ_REMOVE(&opts->list->head, opts, next);
854     g_free(opts->id);
855     g_free(opts);
856 }
857 
858 int qemu_opts_print(QemuOpts *opts, void *dummy)
859 {
860     QemuOpt *opt;
861 
862     fprintf(stderr, "%s: %s:", opts->list->name,
863             opts->id ? opts->id : "<noid>");
864     QTAILQ_FOREACH(opt, &opts->head, next) {
865         fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
866     }
867     fprintf(stderr, "\n");
868     return 0;
869 }
870 
871 static int opts_do_parse(QemuOpts *opts, const char *params,
872                          const char *firstname, bool prepend)
873 {
874     char option[128], value[1024];
875     const char *p,*pe,*pc;
876     Error *local_err = NULL;
877 
878     for (p = params; *p != '\0'; p++) {
879         pe = strchr(p, '=');
880         pc = strchr(p, ',');
881         if (!pe || (pc && pc < pe)) {
882             /* found "foo,more" */
883             if (p == params && firstname) {
884                 /* implicitly named first option */
885                 pstrcpy(option, sizeof(option), firstname);
886                 p = get_opt_value(value, sizeof(value), p);
887             } else {
888                 /* option without value, probably a flag */
889                 p = get_opt_name(option, sizeof(option), p, ',');
890                 if (strncmp(option, "no", 2) == 0) {
891                     memmove(option, option+2, strlen(option+2)+1);
892                     pstrcpy(value, sizeof(value), "off");
893                 } else {
894                     pstrcpy(value, sizeof(value), "on");
895                 }
896             }
897         } else {
898             /* found "foo=bar,more" */
899             p = get_opt_name(option, sizeof(option), p, '=');
900             if (*p != '=') {
901                 break;
902             }
903             p++;
904             p = get_opt_value(value, sizeof(value), p);
905         }
906         if (strcmp(option, "id") != 0) {
907             /* store and parse */
908             opt_set(opts, option, value, prepend, &local_err);
909             if (error_is_set(&local_err)) {
910                 qerror_report_err(local_err);
911                 error_free(local_err);
912                 return -1;
913             }
914         }
915         if (*p != ',') {
916             break;
917         }
918     }
919     return 0;
920 }
921 
922 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
923 {
924     return opts_do_parse(opts, params, firstname, false);
925 }
926 
927 static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
928                             int permit_abbrev, bool defaults)
929 {
930     const char *firstname;
931     char value[1024], *id = NULL;
932     const char *p;
933     QemuOpts *opts;
934     Error *local_err = NULL;
935 
936     assert(!permit_abbrev || list->implied_opt_name);
937     firstname = permit_abbrev ? list->implied_opt_name : NULL;
938 
939     if (strncmp(params, "id=", 3) == 0) {
940         get_opt_value(value, sizeof(value), params+3);
941         id = value;
942     } else if ((p = strstr(params, ",id=")) != NULL) {
943         get_opt_value(value, sizeof(value), p+4);
944         id = value;
945     }
946 
947     /*
948      * This code doesn't work for defaults && !list->merge_lists: when
949      * params has no id=, and list has an element with !opts->id, it
950      * appends a new element instead of returning the existing opts.
951      * However, we got no use for this case.  Guard against possible
952      * (if unlikely) future misuse:
953      */
954     assert(!defaults || list->merge_lists);
955     opts = qemu_opts_create(list, id, !defaults, &local_err);
956     if (opts == NULL) {
957         if (error_is_set(&local_err)) {
958             qerror_report_err(local_err);
959             error_free(local_err);
960         }
961         return NULL;
962     }
963 
964     if (opts_do_parse(opts, params, firstname, defaults) != 0) {
965         qemu_opts_del(opts);
966         return NULL;
967     }
968 
969     return opts;
970 }
971 
972 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
973                           int permit_abbrev)
974 {
975     return opts_parse(list, params, permit_abbrev, false);
976 }
977 
978 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
979                             int permit_abbrev)
980 {
981     QemuOpts *opts;
982 
983     opts = opts_parse(list, params, permit_abbrev, true);
984     assert(opts);
985 }
986 
987 typedef struct OptsFromQDictState {
988     QemuOpts *opts;
989     Error **errp;
990 } OptsFromQDictState;
991 
992 static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
993 {
994     OptsFromQDictState *state = opaque;
995     char buf[32];
996     const char *value;
997     int n;
998 
999     if (!strcmp(key, "id") || error_is_set(state->errp)) {
1000         return;
1001     }
1002 
1003     switch (qobject_type(obj)) {
1004     case QTYPE_QSTRING:
1005         value = qstring_get_str(qobject_to_qstring(obj));
1006         break;
1007     case QTYPE_QINT:
1008         n = snprintf(buf, sizeof(buf), "%" PRId64,
1009                      qint_get_int(qobject_to_qint(obj)));
1010         assert(n < sizeof(buf));
1011         value = buf;
1012         break;
1013     case QTYPE_QFLOAT:
1014         n = snprintf(buf, sizeof(buf), "%.17g",
1015                      qfloat_get_double(qobject_to_qfloat(obj)));
1016         assert(n < sizeof(buf));
1017         value = buf;
1018         break;
1019     case QTYPE_QBOOL:
1020         pstrcpy(buf, sizeof(buf),
1021                 qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
1022         value = buf;
1023         break;
1024     default:
1025         return;
1026     }
1027 
1028     qemu_opt_set_err(state->opts, key, value, state->errp);
1029 }
1030 
1031 /*
1032  * Create QemuOpts from a QDict.
1033  * Use value of key "id" as ID if it exists and is a QString.
1034  * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
1035  * other types are silently ignored.
1036  */
1037 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
1038                                Error **errp)
1039 {
1040     OptsFromQDictState state;
1041     Error *local_err = NULL;
1042     QemuOpts *opts;
1043 
1044     opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
1045                             &local_err);
1046     if (error_is_set(&local_err)) {
1047         error_propagate(errp, local_err);
1048         return NULL;
1049     }
1050 
1051     assert(opts != NULL);
1052 
1053     state.errp = &local_err;
1054     state.opts = opts;
1055     qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
1056     if (error_is_set(&local_err)) {
1057         error_propagate(errp, local_err);
1058         qemu_opts_del(opts);
1059         return NULL;
1060     }
1061 
1062     return opts;
1063 }
1064 
1065 /*
1066  * Adds all QDict entries to the QemuOpts that can be added and removes them
1067  * from the QDict. When this function returns, the QDict contains only those
1068  * entries that couldn't be added to the QemuOpts.
1069  */
1070 void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
1071 {
1072     const QDictEntry *entry, *next;
1073 
1074     entry = qdict_first(qdict);
1075 
1076     while (entry != NULL) {
1077         Error *local_err = NULL;
1078         OptsFromQDictState state = {
1079             .errp = &local_err,
1080             .opts = opts,
1081         };
1082 
1083         next = qdict_next(qdict, entry);
1084 
1085         if (find_desc_by_name(opts->list->desc, entry->key)) {
1086             qemu_opts_from_qdict_1(entry->key, entry->value, &state);
1087             if (error_is_set(&local_err)) {
1088                 error_propagate(errp, local_err);
1089                 return;
1090             } else {
1091                 qdict_del(qdict, entry->key);
1092             }
1093         }
1094 
1095         entry = next;
1096     }
1097 }
1098 
1099 /*
1100  * Convert from QemuOpts to QDict.
1101  * The QDict values are of type QString.
1102  * TODO We'll want to use types appropriate for opt->desc->type, but
1103  * this is enough for now.
1104  */
1105 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1106 {
1107     QemuOpt *opt;
1108     QObject *val;
1109 
1110     if (!qdict) {
1111         qdict = qdict_new();
1112     }
1113     if (opts->id) {
1114         qdict_put(qdict, "id", qstring_from_str(opts->id));
1115     }
1116     QTAILQ_FOREACH(opt, &opts->head, next) {
1117         val = QOBJECT(qstring_from_str(opt->str));
1118         qdict_put_obj(qdict, opt->name, val);
1119     }
1120     return qdict;
1121 }
1122 
1123 /* Validate parsed opts against descriptions where no
1124  * descriptions were provided in the QemuOptsList.
1125  */
1126 void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
1127 {
1128     QemuOpt *opt;
1129     Error *local_err = NULL;
1130 
1131     assert(opts_accepts_any(opts));
1132 
1133     QTAILQ_FOREACH(opt, &opts->head, next) {
1134         opt->desc = find_desc_by_name(desc, opt->name);
1135         if (!opt->desc) {
1136             error_set(errp, QERR_INVALID_PARAMETER, opt->name);
1137             return;
1138         }
1139 
1140         qemu_opt_parse(opt, &local_err);
1141         if (error_is_set(&local_err)) {
1142             error_propagate(errp, local_err);
1143             return;
1144         }
1145     }
1146 }
1147 
1148 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
1149                       int abort_on_failure)
1150 {
1151     Location loc;
1152     QemuOpts *opts;
1153     int rc = 0;
1154 
1155     loc_push_none(&loc);
1156     QTAILQ_FOREACH(opts, &list->head, next) {
1157         loc_restore(&opts->loc);
1158         rc |= func(opts, opaque);
1159         if (abort_on_failure  &&  rc != 0)
1160             break;
1161     }
1162     loc_pop(&loc);
1163     return rc;
1164 }
1165