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