xref: /openbmc/qemu/util/qemu-option.c (revision 56983463)
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 && !id) {
710             return opts;
711         }
712         if (opts->id && id && !strcmp(opts->id, id)) {
713             return opts;
714         }
715     }
716     return NULL;
717 }
718 
719 static int id_wellformed(const char *id)
720 {
721     int i;
722 
723     if (!qemu_isalpha(id[0])) {
724         return 0;
725     }
726     for (i = 1; id[i]; i++) {
727         if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
728             return 0;
729         }
730     }
731     return 1;
732 }
733 
734 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
735                            int fail_if_exists, Error **errp)
736 {
737     QemuOpts *opts = NULL;
738 
739     if (id) {
740         if (!id_wellformed(id)) {
741             error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
742 #if 0 /* conversion from qerror_report() to error_set() broke this: */
743             error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
744 #endif
745             return NULL;
746         }
747         opts = qemu_opts_find(list, id);
748         if (opts != NULL) {
749             if (fail_if_exists && !list->merge_lists) {
750                 error_set(errp, QERR_DUPLICATE_ID, id, list->name);
751                 return NULL;
752             } else {
753                 return opts;
754             }
755         }
756     } else if (list->merge_lists) {
757         opts = qemu_opts_find(list, NULL);
758         if (opts) {
759             return opts;
760         }
761     }
762     opts = g_malloc0(sizeof(*opts));
763     opts->id = g_strdup(id);
764     opts->list = list;
765     loc_save(&opts->loc);
766     QTAILQ_INIT(&opts->head);
767     QTAILQ_INSERT_TAIL(&list->head, opts, next);
768     return opts;
769 }
770 
771 QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
772 {
773     QemuOpts *opts;
774     Error *errp = NULL;
775     opts = qemu_opts_create(list, NULL, 0, &errp);
776     assert_no_error(errp);
777     return opts;
778 }
779 
780 void qemu_opts_reset(QemuOptsList *list)
781 {
782     QemuOpts *opts, *next_opts;
783 
784     QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
785         qemu_opts_del(opts);
786     }
787 }
788 
789 void qemu_opts_loc_restore(QemuOpts *opts)
790 {
791     loc_restore(&opts->loc);
792 }
793 
794 int qemu_opts_set(QemuOptsList *list, const char *id,
795                   const char *name, const char *value)
796 {
797     QemuOpts *opts;
798     Error *local_err = NULL;
799 
800     opts = qemu_opts_create(list, id, 1, &local_err);
801     if (error_is_set(&local_err)) {
802         qerror_report_err(local_err);
803         error_free(local_err);
804         return -1;
805     }
806     return qemu_opt_set(opts, name, value);
807 }
808 
809 const char *qemu_opts_id(QemuOpts *opts)
810 {
811     return opts->id;
812 }
813 
814 void qemu_opts_del(QemuOpts *opts)
815 {
816     QemuOpt *opt;
817 
818     for (;;) {
819         opt = QTAILQ_FIRST(&opts->head);
820         if (opt == NULL)
821             break;
822         qemu_opt_del(opt);
823     }
824     QTAILQ_REMOVE(&opts->list->head, opts, next);
825     g_free(opts->id);
826     g_free(opts);
827 }
828 
829 int qemu_opts_print(QemuOpts *opts, void *dummy)
830 {
831     QemuOpt *opt;
832 
833     fprintf(stderr, "%s: %s:", opts->list->name,
834             opts->id ? opts->id : "<noid>");
835     QTAILQ_FOREACH(opt, &opts->head, next) {
836         fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
837     }
838     fprintf(stderr, "\n");
839     return 0;
840 }
841 
842 static int opts_do_parse(QemuOpts *opts, const char *params,
843                          const char *firstname, bool prepend)
844 {
845     char option[128], value[1024];
846     const char *p,*pe,*pc;
847     Error *local_err = NULL;
848 
849     for (p = params; *p != '\0'; p++) {
850         pe = strchr(p, '=');
851         pc = strchr(p, ',');
852         if (!pe || (pc && pc < pe)) {
853             /* found "foo,more" */
854             if (p == params && firstname) {
855                 /* implicitly named first option */
856                 pstrcpy(option, sizeof(option), firstname);
857                 p = get_opt_value(value, sizeof(value), p);
858             } else {
859                 /* option without value, probably a flag */
860                 p = get_opt_name(option, sizeof(option), p, ',');
861                 if (strncmp(option, "no", 2) == 0) {
862                     memmove(option, option+2, strlen(option+2)+1);
863                     pstrcpy(value, sizeof(value), "off");
864                 } else {
865                     pstrcpy(value, sizeof(value), "on");
866                 }
867             }
868         } else {
869             /* found "foo=bar,more" */
870             p = get_opt_name(option, sizeof(option), p, '=');
871             if (*p != '=') {
872                 break;
873             }
874             p++;
875             p = get_opt_value(value, sizeof(value), p);
876         }
877         if (strcmp(option, "id") != 0) {
878             /* store and parse */
879             opt_set(opts, option, value, prepend, &local_err);
880             if (error_is_set(&local_err)) {
881                 qerror_report_err(local_err);
882                 error_free(local_err);
883                 return -1;
884             }
885         }
886         if (*p != ',') {
887             break;
888         }
889     }
890     return 0;
891 }
892 
893 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
894 {
895     return opts_do_parse(opts, params, firstname, false);
896 }
897 
898 static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
899                             int permit_abbrev, bool defaults)
900 {
901     const char *firstname;
902     char value[1024], *id = NULL;
903     const char *p;
904     QemuOpts *opts;
905     Error *local_err = NULL;
906 
907     assert(!permit_abbrev || list->implied_opt_name);
908     firstname = permit_abbrev ? list->implied_opt_name : NULL;
909 
910     if (strncmp(params, "id=", 3) == 0) {
911         get_opt_value(value, sizeof(value), params+3);
912         id = value;
913     } else if ((p = strstr(params, ",id=")) != NULL) {
914         get_opt_value(value, sizeof(value), p+4);
915         id = value;
916     }
917     opts = qemu_opts_create(list, id, !defaults, &local_err);
918     if (opts == NULL) {
919         if (error_is_set(&local_err)) {
920             qerror_report_err(local_err);
921             error_free(local_err);
922         }
923         return NULL;
924     }
925 
926     if (opts_do_parse(opts, params, firstname, defaults) != 0) {
927         qemu_opts_del(opts);
928         return NULL;
929     }
930 
931     return opts;
932 }
933 
934 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
935                           int permit_abbrev)
936 {
937     return opts_parse(list, params, permit_abbrev, false);
938 }
939 
940 void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
941                             int permit_abbrev)
942 {
943     QemuOpts *opts;
944 
945     opts = opts_parse(list, params, permit_abbrev, true);
946     assert(opts);
947 }
948 
949 typedef struct OptsFromQDictState {
950     QemuOpts *opts;
951     Error **errp;
952 } OptsFromQDictState;
953 
954 static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
955 {
956     OptsFromQDictState *state = opaque;
957     char buf[32];
958     const char *value;
959     int n;
960 
961     if (!strcmp(key, "id") || error_is_set(state->errp)) {
962         return;
963     }
964 
965     switch (qobject_type(obj)) {
966     case QTYPE_QSTRING:
967         value = qstring_get_str(qobject_to_qstring(obj));
968         break;
969     case QTYPE_QINT:
970         n = snprintf(buf, sizeof(buf), "%" PRId64,
971                      qint_get_int(qobject_to_qint(obj)));
972         assert(n < sizeof(buf));
973         value = buf;
974         break;
975     case QTYPE_QFLOAT:
976         n = snprintf(buf, sizeof(buf), "%.17g",
977                      qfloat_get_double(qobject_to_qfloat(obj)));
978         assert(n < sizeof(buf));
979         value = buf;
980         break;
981     case QTYPE_QBOOL:
982         pstrcpy(buf, sizeof(buf),
983                 qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
984         value = buf;
985         break;
986     default:
987         return;
988     }
989 
990     qemu_opt_set_err(state->opts, key, value, state->errp);
991 }
992 
993 /*
994  * Create QemuOpts from a QDict.
995  * Use value of key "id" as ID if it exists and is a QString.
996  * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
997  * other types are silently ignored.
998  */
999 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
1000                                Error **errp)
1001 {
1002     OptsFromQDictState state;
1003     Error *local_err = NULL;
1004     QemuOpts *opts;
1005 
1006     opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
1007                             &local_err);
1008     if (error_is_set(&local_err)) {
1009         error_propagate(errp, local_err);
1010         return NULL;
1011     }
1012 
1013     assert(opts != NULL);
1014 
1015     state.errp = &local_err;
1016     state.opts = opts;
1017     qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
1018     if (error_is_set(&local_err)) {
1019         error_propagate(errp, local_err);
1020         qemu_opts_del(opts);
1021         return NULL;
1022     }
1023 
1024     return opts;
1025 }
1026 
1027 /*
1028  * Adds all QDict entries to the QemuOpts that can be added and removes them
1029  * from the QDict. When this function returns, the QDict contains only those
1030  * entries that couldn't be added to the QemuOpts.
1031  */
1032 void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
1033 {
1034     const QDictEntry *entry, *next;
1035 
1036     entry = qdict_first(qdict);
1037 
1038     while (entry != NULL) {
1039         Error *local_err = NULL;
1040         OptsFromQDictState state = {
1041             .errp = &local_err,
1042             .opts = opts,
1043         };
1044 
1045         next = qdict_next(qdict, entry);
1046 
1047         if (find_desc_by_name(opts->list->desc, entry->key)) {
1048             qemu_opts_from_qdict_1(entry->key, entry->value, &state);
1049             if (error_is_set(&local_err)) {
1050                 error_propagate(errp, local_err);
1051                 return;
1052             } else {
1053                 qdict_del(qdict, entry->key);
1054             }
1055         }
1056 
1057         entry = next;
1058     }
1059 }
1060 
1061 /*
1062  * Convert from QemuOpts to QDict.
1063  * The QDict values are of type QString.
1064  * TODO We'll want to use types appropriate for opt->desc->type, but
1065  * this is enough for now.
1066  */
1067 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1068 {
1069     QemuOpt *opt;
1070     QObject *val;
1071 
1072     if (!qdict) {
1073         qdict = qdict_new();
1074     }
1075     if (opts->id) {
1076         qdict_put(qdict, "id", qstring_from_str(opts->id));
1077     }
1078     QTAILQ_FOREACH(opt, &opts->head, next) {
1079         val = QOBJECT(qstring_from_str(opt->str));
1080         qdict_put_obj(qdict, opt->name, val);
1081     }
1082     return qdict;
1083 }
1084 
1085 /* Validate parsed opts against descriptions where no
1086  * descriptions were provided in the QemuOptsList.
1087  */
1088 void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
1089 {
1090     QemuOpt *opt;
1091     Error *local_err = NULL;
1092 
1093     assert(opts_accepts_any(opts));
1094 
1095     QTAILQ_FOREACH(opt, &opts->head, next) {
1096         opt->desc = find_desc_by_name(desc, opt->name);
1097         if (!opt->desc) {
1098             error_set(errp, QERR_INVALID_PARAMETER, opt->name);
1099             return;
1100         }
1101 
1102         qemu_opt_parse(opt, &local_err);
1103         if (error_is_set(&local_err)) {
1104             error_propagate(errp, local_err);
1105             return;
1106         }
1107     }
1108 }
1109 
1110 int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
1111                       int abort_on_failure)
1112 {
1113     Location loc;
1114     QemuOpts *opts;
1115     int rc = 0;
1116 
1117     loc_push_none(&loc);
1118     QTAILQ_FOREACH(opts, &list->head, next) {
1119         loc_restore(&opts->loc);
1120         rc |= func(opts, opaque);
1121         if (abort_on_failure  &&  rc != 0)
1122             break;
1123     }
1124     loc_pop(&loc);
1125     return rc;
1126 }
1127