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