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