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