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