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