qemu/qemu-option.c
<<
>>
Prefs
   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 <stdio.h>
  27#include <string.h>
  28
  29#include "qemu-common.h"
  30#include "qemu-error.h"
  31#include "qemu-objects.h"
  32#include "qemu-option.h"
  33#include "qerror.h"
  34
  35/*
  36 * Extracts the name of an option from the parameter string (p points at the
  37 * first byte of the option name)
  38 *
  39 * The option name is delimited by delim (usually , or =) or the string end
  40 * and is copied into buf. If the option name is longer than buf_size, it is
  41 * truncated. buf is always zero terminated.
  42 *
  43 * The return value is the position of the delimiter/zero byte after the option
  44 * name in p.
  45 */
  46const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
  47{
  48    char *q;
  49
  50    q = buf;
  51    while (*p != '\0' && *p != delim) {
  52        if (q && (q - buf) < buf_size - 1)
  53            *q++ = *p;
  54        p++;
  55    }
  56    if (q)
  57        *q = '\0';
  58
  59    return p;
  60}
  61
  62/*
  63 * Extracts the value of an option from the parameter string p (p points at the
  64 * first byte of the option value)
  65 *
  66 * This function is comparable to get_opt_name with the difference that the
  67 * delimiter is fixed to be comma which starts a new option. To specify an
  68 * option value that contains commas, double each comma.
  69 */
  70const char *get_opt_value(char *buf, int buf_size, const char *p)
  71{
  72    char *q;
  73
  74    q = buf;
  75    while (*p != '\0') {
  76        if (*p == ',') {
  77            if (*(p + 1) != ',')
  78                break;
  79            p++;
  80        }
  81        if (q && (q - buf) < buf_size - 1)
  82            *q++ = *p;
  83        p++;
  84    }
  85    if (q)
  86        *q = '\0';
  87
  88    return p;
  89}
  90
  91int get_next_param_value(char *buf, int buf_size,
  92                         const char *tag, const char **pstr)
  93{
  94    const char *p;
  95    char option[128];
  96
  97    p = *pstr;
  98    for(;;) {
  99        p = get_opt_name(option, sizeof(option), p, '=');
 100        if (*p != '=')
 101            break;
 102        p++;
 103        if (!strcmp(tag, option)) {
 104            *pstr = get_opt_value(buf, buf_size, p);
 105            if (**pstr == ',') {
 106                (*pstr)++;
 107            }
 108            return strlen(buf);
 109        } else {
 110            p = get_opt_value(NULL, 0, p);
 111        }
 112        if (*p != ',')
 113            break;
 114        p++;
 115    }
 116    return 0;
 117}
 118
 119int get_param_value(char *buf, int buf_size,
 120                    const char *tag, const char *str)
 121{
 122    return get_next_param_value(buf, buf_size, tag, &str);
 123}
 124
 125int check_params(char *buf, int buf_size,
 126                 const char * const *params, const char *str)
 127{
 128    const char *p;
 129    int i;
 130
 131    p = str;
 132    while (*p != '\0') {
 133        p = get_opt_name(buf, buf_size, p, '=');
 134        if (*p != '=') {
 135            return -1;
 136        }
 137        p++;
 138        for (i = 0; params[i] != NULL; i++) {
 139            if (!strcmp(params[i], buf)) {
 140                break;
 141            }
 142        }
 143        if (params[i] == NULL) {
 144            return -1;
 145        }
 146        p = get_opt_value(NULL, 0, p);
 147        if (*p != ',') {
 148            break;
 149        }
 150        p++;
 151    }
 152    return 0;
 153}
 154
 155/*
 156 * Searches an option list for an option with the given name
 157 */
 158QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
 159    const char *name)
 160{
 161    while (list && list->name) {
 162        if (!strcmp(list->name, name)) {
 163            return list;
 164        }
 165        list++;
 166    }
 167
 168    return NULL;
 169}
 170
 171static int parse_option_bool(const char *name, const char *value, int *ret)
 172{
 173    if (value != NULL) {
 174        if (!strcmp(value, "on")) {
 175            *ret = 1;
 176        } else if (!strcmp(value, "off")) {
 177            *ret = 0;
 178        } else {
 179            qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'");
 180            return -1;
 181        }
 182    } else {
 183        *ret = 1;
 184    }
 185    return 0;
 186}
 187
 188static int parse_option_number(const char *name, const char *value, uint64_t *ret)
 189{
 190    char *postfix;
 191    uint64_t number;
 192
 193    if (value != NULL) {
 194        number = strtoull(value, &postfix, 0);
 195        if (*postfix != '\0') {
 196            qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number");
 197            return -1;
 198        }
 199        *ret = number;
 200    } else {
 201        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number");
 202        return -1;
 203    }
 204    return 0;
 205}
 206
 207static int parse_option_size(const char *name, const char *value, uint64_t *ret)
 208{
 209    char *postfix;
 210    double sizef;
 211
 212    if (value != NULL) {
 213        sizef = strtod(value, &postfix);
 214        switch (*postfix) {
 215        case 'T':
 216            sizef *= 1024;
 217        case 'G':
 218            sizef *= 1024;
 219        case 'M':
 220            sizef *= 1024;
 221        case 'K':
 222        case 'k':
 223            sizef *= 1024;
 224        case 'b':
 225        case '\0':
 226            *ret = (uint64_t) sizef;
 227            break;
 228        default:
 229            qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size");
 230            error_printf_unless_qmp("You may use k, M, G or T suffixes for "
 231                    "kilobytes, megabytes, gigabytes and terabytes.\n");
 232            return -1;
 233        }
 234    } else {
 235        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size");
 236        return -1;
 237    }
 238    return 0;
 239}
 240
 241/*
 242 * Sets the value of a parameter in a given option list. The parsing of the
 243 * value depends on the type of option:
 244 *
 245 * OPT_FLAG (uses value.n):
 246 *      If no value is given, the flag is set to 1.
 247 *      Otherwise the value must be "on" (set to 1) or "off" (set to 0)
 248 *
 249 * OPT_STRING (uses value.s):
 250 *      value is strdup()ed and assigned as option value
 251 *
 252 * OPT_SIZE (uses value.n):
 253 *      The value is converted to an integer. Suffixes for kilobytes etc. are
 254 *      allowed (powers of 1024).
 255 *
 256 * Returns 0 on succes, -1 in error cases
 257 */
 258int set_option_parameter(QEMUOptionParameter *list, const char *name,
 259    const char *value)
 260{
 261    int flag;
 262
 263    // Find a matching parameter
 264    list = get_option_parameter(list, name);
 265    if (list == NULL) {
 266        fprintf(stderr, "Unknown option '%s'\n", name);
 267        return -1;
 268    }
 269
 270    // Process parameter
 271    switch (list->type) {
 272    case OPT_FLAG:
 273        if (parse_option_bool(name, value, &flag) == -1)
 274            return -1;
 275        list->value.n = flag;
 276        break;
 277
 278    case OPT_STRING:
 279        if (value != NULL) {
 280            list->value.s = qemu_strdup(value);
 281        } else {
 282            fprintf(stderr, "Option '%s' needs a parameter\n", name);
 283            return -1;
 284        }
 285        break;
 286
 287    case OPT_SIZE:
 288        if (parse_option_size(name, value, &list->value.n) == -1)
 289            return -1;
 290        break;
 291
 292    default:
 293        fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
 294        return -1;
 295    }
 296
 297    return 0;
 298}
 299
 300/*
 301 * Sets the given parameter to an integer instead of a string.
 302 * This function cannot be used to set string options.
 303 *
 304 * Returns 0 on success, -1 in error cases
 305 */
 306int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
 307    uint64_t value)
 308{
 309    // Find a matching parameter
 310    list = get_option_parameter(list, name);
 311    if (list == NULL) {
 312        fprintf(stderr, "Unknown option '%s'\n", name);
 313        return -1;
 314    }
 315
 316    // Process parameter
 317    switch (list->type) {
 318    case OPT_FLAG:
 319    case OPT_NUMBER:
 320    case OPT_SIZE:
 321        list->value.n = value;
 322        break;
 323
 324    default:
 325        return -1;
 326    }
 327
 328    return 0;
 329}
 330
 331/*
 332 * Frees a option list. If it contains strings, the strings are freed as well.
 333 */
 334void free_option_parameters(QEMUOptionParameter *list)
 335{
 336    QEMUOptionParameter *cur = list;
 337
 338    while (cur && cur->name) {
 339        if (cur->type == OPT_STRING) {
 340            qemu_free(cur->value.s);
 341        }
 342        cur++;
 343    }
 344
 345    qemu_free(list);
 346}
 347
 348/*
 349 * Count valid options in list
 350 */
 351static size_t count_option_parameters(QEMUOptionParameter *list)
 352{
 353    size_t num_options = 0;
 354
 355    while (list && list->name) {
 356        num_options++;
 357        list++;
 358    }
 359
 360    return num_options;
 361}
 362
 363/*
 364 * Append an option list (list) to an option list (dest).
 365 *
 366 * If dest is NULL, a new copy of list is created.
 367 *
 368 * Returns a pointer to the first element of dest (or the newly allocated copy)
 369 */
 370QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
 371    QEMUOptionParameter *list)
 372{
 373    size_t num_options, num_dest_options;
 374
 375    num_options = count_option_parameters(dest);
 376    num_dest_options = num_options;
 377
 378    num_options += count_option_parameters(list);
 379
 380    dest = qemu_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
 381    dest[num_dest_options].name = NULL;
 382
 383    while (list && list->name) {
 384        if (get_option_parameter(dest, list->name) == NULL) {
 385            dest[num_dest_options++] = *list;
 386            dest[num_dest_options].name = NULL;
 387        }
 388        list++;
 389    }
 390
 391    return dest;
 392}
 393
 394/*
 395 * Parses a parameter string (param) into an option list (dest).
 396 *
 397 * list is the template option list. If dest is NULL, a new copy of list is
 398 * created. If list is NULL, this function fails.
 399 *
 400 * A parameter string consists of one or more parameters, separated by commas.
 401 * Each parameter consists of its name and possibly of a value. In the latter
 402 * case, the value is delimited by an = character. To specify a value which
 403 * contains commas, double each comma so it won't be recognized as the end of
 404 * the parameter.
 405 *
 406 * For more details of the parsing see above.
 407 *
 408 * Returns a pointer to the first element of dest (or the newly allocated copy)
 409 * or NULL in error cases
 410 */
 411QEMUOptionParameter *parse_option_parameters(const char *param,
 412    QEMUOptionParameter *list, QEMUOptionParameter *dest)
 413{
 414    QEMUOptionParameter *allocated = NULL;
 415    char name[256];
 416    char value[256];
 417    char *param_delim, *value_delim;
 418    char next_delim;
 419
 420    if (list == NULL) {
 421        return NULL;
 422    }
 423
 424    if (dest == NULL) {
 425        dest = allocated = append_option_parameters(NULL, list);
 426    }
 427
 428    while (*param) {
 429
 430        // Find parameter name and value in the string
 431        param_delim = strchr(param, ',');
 432        value_delim = strchr(param, '=');
 433
 434        if (value_delim && (value_delim < param_delim || !param_delim)) {
 435            next_delim = '=';
 436        } else {
 437            next_delim = ',';
 438            value_delim = NULL;
 439        }
 440
 441        param = get_opt_name(name, sizeof(name), param, next_delim);
 442        if (value_delim) {
 443            param = get_opt_value(value, sizeof(value), param + 1);
 444        }
 445        if (*param != '\0') {
 446            param++;
 447        }
 448
 449        // Set the parameter
 450        if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
 451            goto fail;
 452        }
 453    }
 454
 455    return dest;
 456
 457fail:
 458    // Only free the list if it was newly allocated
 459    free_option_parameters(allocated);
 460    return NULL;
 461}
 462
 463/*
 464 * Prints all options of a list that have a value to stdout
 465 */
 466void print_option_parameters(QEMUOptionParameter *list)
 467{
 468    while (list && list->name) {
 469        switch (list->type) {
 470            case OPT_STRING:
 471                 if (list->value.s != NULL) {
 472                     printf("%s='%s' ", list->name, list->value.s);
 473                 }
 474                break;
 475            case OPT_FLAG:
 476                printf("%s=%s ", list->name, list->value.n ? "on" : "off");
 477                break;
 478            case OPT_SIZE:
 479            case OPT_NUMBER:
 480                printf("%s=%" PRId64 " ", list->name, list->value.n);
 481                break;
 482            default:
 483                printf("%s=(unkown type) ", list->name);
 484                break;
 485        }
 486        list++;
 487    }
 488}
 489
 490/*
 491 * Prints an overview of all available options
 492 */
 493void print_option_help(QEMUOptionParameter *list)
 494{
 495    printf("Supported options:\n");
 496    while (list && list->name) {
 497        printf("%-16s %s\n", list->name,
 498            list->help ? list->help : "No description available");
 499        list++;
 500    }
 501}
 502
 503/* ------------------------------------------------------------------ */
 504
 505struct QemuOpt {
 506    const char   *name;
 507    const char   *str;
 508
 509    const QemuOptDesc *desc;
 510    union {
 511        int      boolean;
 512        uint64_t uint;
 513    } value;
 514
 515    QemuOpts     *opts;
 516    QTAILQ_ENTRY(QemuOpt) next;
 517};
 518
 519struct QemuOpts {
 520    char *id;
 521    QemuOptsList *list;
 522    Location loc;
 523    QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
 524    QTAILQ_ENTRY(QemuOpts) next;
 525};
 526
 527static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
 528{
 529    QemuOpt *opt;
 530
 531    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
 532        if (strcmp(opt->name, name) != 0)
 533            continue;
 534        return opt;
 535    }
 536    return NULL;
 537}
 538
 539const char *qemu_opt_get(QemuOpts *opts, const char *name)
 540{
 541    QemuOpt *opt = qemu_opt_find(opts, name);
 542    return opt ? opt->str : NULL;
 543}
 544
 545int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval)
 546{
 547    QemuOpt *opt = qemu_opt_find(opts, name);
 548
 549    if (opt == NULL)
 550        return defval;
 551    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
 552    return opt->value.boolean;
 553}
 554
 555uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
 556{
 557    QemuOpt *opt = qemu_opt_find(opts, name);
 558
 559    if (opt == NULL)
 560        return defval;
 561    assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
 562    return opt->value.uint;
 563}
 564
 565uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
 566{
 567    QemuOpt *opt = qemu_opt_find(opts, name);
 568
 569    if (opt == NULL)
 570        return defval;
 571    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
 572    return opt->value.uint;
 573}
 574
 575static int qemu_opt_parse(QemuOpt *opt)
 576{
 577    if (opt->desc == NULL)
 578        return 0;
 579    switch (opt->desc->type) {
 580    case QEMU_OPT_STRING:
 581        /* nothing */
 582        return 0;
 583    case QEMU_OPT_BOOL:
 584        return parse_option_bool(opt->name, opt->str, &opt->value.boolean);
 585    case QEMU_OPT_NUMBER:
 586        return parse_option_number(opt->name, opt->str, &opt->value.uint);
 587    case QEMU_OPT_SIZE:
 588        return parse_option_size(opt->name, opt->str, &opt->value.uint);
 589    default:
 590        abort();
 591    }
 592}
 593
 594static void qemu_opt_del(QemuOpt *opt)
 595{
 596    QTAILQ_REMOVE(&opt->opts->head, opt, next);
 597    qemu_free((/* !const */ char*)opt->name);
 598    qemu_free((/* !const */ char*)opt->str);
 599    qemu_free(opt);
 600}
 601
 602int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
 603{
 604    QemuOpt *opt;
 605    const QemuOptDesc *desc = opts->list->desc;
 606    int i;
 607
 608    for (i = 0; desc[i].name != NULL; i++) {
 609        if (strcmp(desc[i].name, name) == 0) {
 610            break;
 611        }
 612    }
 613    if (desc[i].name == NULL) {
 614        if (i == 0) {
 615            /* empty list -> allow any */;
 616        } else {
 617            qerror_report(QERR_INVALID_PARAMETER, name);
 618            return -1;
 619        }
 620    }
 621
 622    opt = qemu_mallocz(sizeof(*opt));
 623    opt->name = qemu_strdup(name);
 624    opt->opts = opts;
 625    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
 626    if (desc[i].name != NULL) {
 627        opt->desc = desc+i;
 628    }
 629    if (value) {
 630        opt->str = qemu_strdup(value);
 631    }
 632    if (qemu_opt_parse(opt) < 0) {
 633        qemu_opt_del(opt);
 634        return -1;
 635    }
 636    return 0;
 637}
 638
 639int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
 640                     int abort_on_failure)
 641{
 642    QemuOpt *opt;
 643    int rc = 0;
 644
 645    QTAILQ_FOREACH(opt, &opts->head, next) {
 646        rc = func(opt->name, opt->str, opaque);
 647        if (abort_on_failure  &&  rc != 0)
 648            break;
 649    }
 650    return rc;
 651}
 652
 653QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
 654{
 655    QemuOpts *opts;
 656
 657    QTAILQ_FOREACH(opts, &list->head, next) {
 658        if (!opts->id) {
 659            continue;
 660        }
 661        if (strcmp(opts->id, id) != 0) {
 662            continue;
 663        }
 664        return opts;
 665    }
 666    return NULL;
 667}
 668
 669static int id_wellformed(const char *id)
 670{
 671    int i;
 672
 673    if (!qemu_isalpha(id[0])) {
 674        return 0;
 675    }
 676    for (i = 1; id[i]; i++) {
 677        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
 678            return 0;
 679        }
 680    }
 681    return 1;
 682}
 683
 684QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists)
 685{
 686    QemuOpts *opts = NULL;
 687
 688    if (id) {
 689        if (!id_wellformed(id)) {
 690            qerror_report(QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
 691            error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
 692            return NULL;
 693        }
 694        opts = qemu_opts_find(list, id);
 695        if (opts != NULL) {
 696            if (fail_if_exists) {
 697                qerror_report(QERR_DUPLICATE_ID, id, list->name);
 698                return NULL;
 699            } else {
 700                return opts;
 701            }
 702        }
 703    }
 704    opts = qemu_mallocz(sizeof(*opts));
 705    if (id) {
 706        opts->id = qemu_strdup(id);
 707    }
 708    opts->list = list;
 709    loc_save(&opts->loc);
 710    QTAILQ_INIT(&opts->head);
 711    QTAILQ_INSERT_TAIL(&list->head, opts, next);
 712    return opts;
 713}
 714
 715void qemu_opts_reset(QemuOptsList *list)
 716{
 717    QemuOpts *opts, *next_opts;
 718
 719    QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
 720        qemu_opts_del(opts);
 721    }
 722}
 723
 724void qemu_opts_loc_restore(QemuOpts *opts)
 725{
 726    loc_restore(&opts->loc);
 727}
 728
 729int qemu_opts_set(QemuOptsList *list, const char *id,
 730                  const char *name, const char *value)
 731{
 732    QemuOpts *opts;
 733
 734    opts = qemu_opts_create(list, id, 1);
 735    if (opts == NULL) {
 736        return -1;
 737    }
 738    return qemu_opt_set(opts, name, value);
 739}
 740
 741const char *qemu_opts_id(QemuOpts *opts)
 742{
 743    return opts->id;
 744}
 745
 746void qemu_opts_del(QemuOpts *opts)
 747{
 748    QemuOpt *opt;
 749
 750    for (;;) {
 751        opt = QTAILQ_FIRST(&opts->head);
 752        if (opt == NULL)
 753            break;
 754        qemu_opt_del(opt);
 755    }
 756    QTAILQ_REMOVE(&opts->list->head, opts, next);
 757    qemu_free(opts->id);
 758    qemu_free(opts);
 759}
 760
 761int qemu_opts_print(QemuOpts *opts, void *dummy)
 762{
 763    QemuOpt *opt;
 764
 765    fprintf(stderr, "%s: %s:", opts->list->name,
 766            opts->id ? opts->id : "<noid>");
 767    QTAILQ_FOREACH(opt, &opts->head, next) {
 768        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
 769    }
 770    fprintf(stderr, "\n");
 771    return 0;
 772}
 773
 774int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
 775{
 776    char option[128], value[1024];
 777    const char *p,*pe,*pc;
 778
 779    for (p = params; *p != '\0'; p++) {
 780        pe = strchr(p, '=');
 781        pc = strchr(p, ',');
 782        if (!pe || (pc && pc < pe)) {
 783            /* found "foo,more" */
 784            if (p == params && firstname) {
 785                /* implicitly named first option */
 786                pstrcpy(option, sizeof(option), firstname);
 787                p = get_opt_value(value, sizeof(value), p);
 788            } else {
 789                /* option without value, probably a flag */
 790                p = get_opt_name(option, sizeof(option), p, ',');
 791                if (strncmp(option, "no", 2) == 0) {
 792                    memmove(option, option+2, strlen(option+2)+1);
 793                    pstrcpy(value, sizeof(value), "off");
 794                } else {
 795                    pstrcpy(value, sizeof(value), "on");
 796                }
 797            }
 798        } else {
 799            /* found "foo=bar,more" */
 800            p = get_opt_name(option, sizeof(option), p, '=');
 801            if (*p != '=') {
 802                break;
 803            }
 804            p++;
 805            p = get_opt_value(value, sizeof(value), p);
 806        }
 807        if (strcmp(option, "id") != 0) {
 808            /* store and parse */
 809            if (qemu_opt_set(opts, option, value) == -1) {
 810                return -1;
 811            }
 812        }
 813        if (*p != ',') {
 814            break;
 815        }
 816    }
 817    return 0;
 818}
 819
 820QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
 821                          int permit_abbrev)
 822{
 823    const char *firstname;
 824    char value[1024], *id = NULL;
 825    const char *p;
 826    QemuOpts *opts;
 827
 828    assert(!permit_abbrev || list->implied_opt_name);
 829    firstname = permit_abbrev ? list->implied_opt_name : NULL;
 830
 831    if (strncmp(params, "id=", 3) == 0) {
 832        get_opt_value(value, sizeof(value), params+3);
 833        id = value;
 834    } else if ((p = strstr(params, ",id=")) != NULL) {
 835        get_opt_value(value, sizeof(value), p+4);
 836        id = value;
 837    }
 838    opts = qemu_opts_create(list, id, 1);
 839    if (opts == NULL)
 840        return NULL;
 841
 842    if (qemu_opts_do_parse(opts, params, firstname) != 0) {
 843        qemu_opts_del(opts);
 844        return NULL;
 845    }
 846
 847    return opts;
 848}
 849
 850static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
 851{
 852    char buf[32];
 853    const char *value;
 854    int n;
 855
 856    if (!strcmp(key, "id")) {
 857        return;
 858    }
 859
 860    switch (qobject_type(obj)) {
 861    case QTYPE_QSTRING:
 862        value = qstring_get_str(qobject_to_qstring(obj));
 863        break;
 864    case QTYPE_QINT:
 865        n = snprintf(buf, sizeof(buf), "%" PRId64,
 866                     qint_get_int(qobject_to_qint(obj)));
 867        assert(n < sizeof(buf));
 868        value = buf;
 869        break;
 870    case QTYPE_QFLOAT:
 871        n = snprintf(buf, sizeof(buf), "%.17g",
 872                     qfloat_get_double(qobject_to_qfloat(obj)));
 873        assert(n < sizeof(buf));
 874        value = buf;
 875        break;
 876    case QTYPE_QBOOL:
 877        pstrcpy(buf, sizeof(buf),
 878                qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
 879        value = buf;
 880        break;
 881    default:
 882        return;
 883    }
 884    qemu_opt_set(opaque, key, value);
 885}
 886
 887/*
 888 * Create QemuOpts from a QDict.
 889 * Use value of key "id" as ID if it exists and is a QString.
 890 * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
 891 * other types are silently ignored.
 892 */
 893QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict)
 894{
 895    QemuOpts *opts;
 896
 897    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1);
 898    if (opts == NULL)
 899        return NULL;
 900
 901    qdict_iter(qdict, qemu_opts_from_qdict_1, opts);
 902    return opts;
 903}
 904
 905/*
 906 * Convert from QemuOpts to QDict.
 907 * The QDict values are of type QString.
 908 * TODO We'll want to use types appropriate for opt->desc->type, but
 909 * this is enough for now.
 910 */
 911QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
 912{
 913    QemuOpt *opt;
 914    QObject *val;
 915
 916    if (!qdict) {
 917        qdict = qdict_new();
 918    }
 919    if (opts->id) {
 920        qdict_put(qdict, "id", qstring_from_str(opts->id));
 921    }
 922    QTAILQ_FOREACH(opt, &opts->head, next) {
 923        val = QOBJECT(qstring_from_str(opt->str));
 924        qdict_put_obj(qdict, opt->name, val);
 925    }
 926    return qdict;
 927}
 928
 929/* Validate parsed opts against descriptions where no
 930 * descriptions were provided in the QemuOptsList.
 931 */
 932int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
 933{
 934    QemuOpt *opt;
 935
 936    assert(opts->list->desc[0].name == NULL);
 937
 938    QTAILQ_FOREACH(opt, &opts->head, next) {
 939        int i;
 940
 941        for (i = 0; desc[i].name != NULL; i++) {
 942            if (strcmp(desc[i].name, opt->name) == 0) {
 943                break;
 944            }
 945        }
 946        if (desc[i].name == NULL) {
 947            qerror_report(QERR_INVALID_PARAMETER, opt->name);
 948            return -1;
 949        }
 950
 951        opt->desc = &desc[i];
 952
 953        if (qemu_opt_parse(opt) < 0) {
 954            return -1;
 955        }
 956    }
 957
 958    return 0;
 959}
 960
 961int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
 962                      int abort_on_failure)
 963{
 964    Location loc;
 965    QemuOpts *opts;
 966    int rc = 0;
 967
 968    loc_push_none(&loc);
 969    QTAILQ_FOREACH(opts, &list->head, next) {
 970        loc_restore(&opts->loc);
 971        rc |= func(opts, opaque);
 972        if (abort_on_failure  &&  rc != 0)
 973            break;
 974    }
 975    loc_pop(&loc);
 976    return rc;
 977}
 978