Statistics
| Branch: | Revision:

root / qemu-option.c @ 8be7e7e4

History | View | Annotate | Download (26.8 kB)

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 "error.h"
34
#include "qerror.h"
35

    
36
/*
37
 * Extracts the name of an option from the parameter string (p points at the
38
 * first byte of the option name)
39
 *
40
 * The option name is delimited by delim (usually , or =) or the string end
41
 * and is copied into buf. If the option name is longer than buf_size, it is
42
 * truncated. buf is always zero terminated.
43
 *
44
 * The return value is the position of the delimiter/zero byte after the option
45
 * name in p.
46
 */
47
const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
48
{
49
    char *q;
50

    
51
    q = buf;
52
    while (*p != '\0' && *p != delim) {
53
        if (q && (q - buf) < buf_size - 1)
54
            *q++ = *p;
55
        p++;
56
    }
57
    if (q)
58
        *q = '\0';
59

    
60
    return p;
61
}
62

    
63
/*
64
 * Extracts the value of an option from the parameter string p (p points at the
65
 * first byte of the option value)
66
 *
67
 * This function is comparable to get_opt_name with the difference that the
68
 * delimiter is fixed to be comma which starts a new option. To specify an
69
 * option value that contains commas, double each comma.
70
 */
71
const char *get_opt_value(char *buf, int buf_size, const char *p)
72
{
73
    char *q;
74

    
75
    q = buf;
76
    while (*p != '\0') {
77
        if (*p == ',') {
78
            if (*(p + 1) != ',')
79
                break;
80
            p++;
81
        }
82
        if (q && (q - buf) < buf_size - 1)
83
            *q++ = *p;
84
        p++;
85
    }
86
    if (q)
87
        *q = '\0';
88

    
89
    return p;
90
}
91

    
92
int get_next_param_value(char *buf, int buf_size,
93
                         const char *tag, const char **pstr)
94
{
95
    const char *p;
96
    char option[128];
97

    
98
    p = *pstr;
99
    for(;;) {
100
        p = get_opt_name(option, sizeof(option), p, '=');
101
        if (*p != '=')
102
            break;
103
        p++;
104
        if (!strcmp(tag, option)) {
105
            *pstr = get_opt_value(buf, buf_size, p);
106
            if (**pstr == ',') {
107
                (*pstr)++;
108
            }
109
            return strlen(buf);
110
        } else {
111
            p = get_opt_value(NULL, 0, p);
112
        }
113
        if (*p != ',')
114
            break;
115
        p++;
116
    }
117
    return 0;
118
}
119

    
120
int get_param_value(char *buf, int buf_size,
121
                    const char *tag, const char *str)
122
{
123
    return get_next_param_value(buf, buf_size, tag, &str);
124
}
125

    
126
int check_params(char *buf, int buf_size,
127
                 const char * const *params, const char *str)
128
{
129
    const char *p;
130
    int i;
131

    
132
    p = str;
133
    while (*p != '\0') {
134
        p = get_opt_name(buf, buf_size, p, '=');
135
        if (*p != '=') {
136
            return -1;
137
        }
138
        p++;
139
        for (i = 0; params[i] != NULL; i++) {
140
            if (!strcmp(params[i], buf)) {
141
                break;
142
            }
143
        }
144
        if (params[i] == NULL) {
145
            return -1;
146
        }
147
        p = get_opt_value(NULL, 0, p);
148
        if (*p != ',') {
149
            break;
150
        }
151
        p++;
152
    }
153
    return 0;
154
}
155

    
156
/*
157
 * Searches an option list for an option with the given name
158
 */
159
QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
160
    const char *name)
161
{
162
    while (list && list->name) {
163
        if (!strcmp(list->name, name)) {
164
            return list;
165
        }
166
        list++;
167
    }
168

    
169
    return NULL;
170
}
171

    
172
static int parse_option_bool(const char *name, const char *value, bool *ret)
173
{
174
    if (value != NULL) {
175
        if (!strcmp(value, "on")) {
176
            *ret = 1;
177
        } else if (!strcmp(value, "off")) {
178
            *ret = 0;
179
        } else {
180
            qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'");
181
            return -1;
182
        }
183
    } else {
184
        *ret = 1;
185
    }
186
    return 0;
187
}
188

    
189
static int parse_option_number(const char *name, const char *value, uint64_t *ret)
190
{
191
    char *postfix;
192
    uint64_t number;
193

    
194
    if (value != NULL) {
195
        number = strtoull(value, &postfix, 0);
196
        if (*postfix != '\0') {
197
            qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number");
198
            return -1;
199
        }
200
        *ret = number;
201
    } else {
202
        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a number");
203
        return -1;
204
    }
205
    return 0;
206
}
207

    
208
static int parse_option_size(const char *name, const char *value, uint64_t *ret)
209
{
210
    char *postfix;
211
    double sizef;
212

    
213
    if (value != NULL) {
214
        sizef = strtod(value, &postfix);
215
        switch (*postfix) {
216
        case 'T':
217
            sizef *= 1024;
218
            /* fall through */
219
        case 'G':
220
            sizef *= 1024;
221
            /* fall through */
222
        case 'M':
223
            sizef *= 1024;
224
            /* fall through */
225
        case 'K':
226
        case 'k':
227
            sizef *= 1024;
228
            /* fall through */
229
        case 'b':
230
        case '\0':
231
            *ret = (uint64_t) sizef;
232
            break;
233
        default:
234
            qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size");
235
            error_printf_unless_qmp("You may use k, M, G or T suffixes for "
236
                    "kilobytes, megabytes, gigabytes and terabytes.\n");
237
            return -1;
238
        }
239
    } else {
240
        qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a size");
241
        return -1;
242
    }
243
    return 0;
244
}
245

    
246
/*
247
 * Sets the value of a parameter in a given option list. The parsing of the
248
 * value depends on the type of option:
249
 *
250
 * OPT_FLAG (uses value.n):
251
 *      If no value is given, the flag is set to 1.
252
 *      Otherwise the value must be "on" (set to 1) or "off" (set to 0)
253
 *
254
 * OPT_STRING (uses value.s):
255
 *      value is strdup()ed and assigned as option value
256
 *
257
 * OPT_SIZE (uses value.n):
258
 *      The value is converted to an integer. Suffixes for kilobytes etc. are
259
 *      allowed (powers of 1024).
260
 *
261
 * Returns 0 on succes, -1 in error cases
262
 */
263
int set_option_parameter(QEMUOptionParameter *list, const char *name,
264
    const char *value)
265
{
266
    bool flag;
267

    
268
    // Find a matching parameter
269
    list = get_option_parameter(list, name);
270
    if (list == NULL) {
271
        fprintf(stderr, "Unknown option '%s'\n", name);
272
        return -1;
273
    }
274

    
275
    // Process parameter
276
    switch (list->type) {
277
    case OPT_FLAG:
278
        if (parse_option_bool(name, value, &flag) == -1)
279
            return -1;
280
        list->value.n = flag;
281
        break;
282

    
283
    case OPT_STRING:
284
        if (value != NULL) {
285
            list->value.s = g_strdup(value);
286
        } else {
287
            fprintf(stderr, "Option '%s' needs a parameter\n", name);
288
            return -1;
289
        }
290
        break;
291

    
292
    case OPT_SIZE:
293
        if (parse_option_size(name, value, &list->value.n) == -1)
294
            return -1;
295
        break;
296

    
297
    default:
298
        fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
299
        return -1;
300
    }
301

    
302
    return 0;
303
}
304

    
305
/*
306
 * Sets the given parameter to an integer instead of a string.
307
 * This function cannot be used to set string options.
308
 *
309
 * Returns 0 on success, -1 in error cases
310
 */
311
int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
312
    uint64_t value)
313
{
314
    // Find a matching parameter
315
    list = get_option_parameter(list, name);
316
    if (list == NULL) {
317
        fprintf(stderr, "Unknown option '%s'\n", name);
318
        return -1;
319
    }
320

    
321
    // Process parameter
322
    switch (list->type) {
323
    case OPT_FLAG:
324
    case OPT_NUMBER:
325
    case OPT_SIZE:
326
        list->value.n = value;
327
        break;
328

    
329
    default:
330
        return -1;
331
    }
332

    
333
    return 0;
334
}
335

    
336
/*
337
 * Frees a option list. If it contains strings, the strings are freed as well.
338
 */
339
void free_option_parameters(QEMUOptionParameter *list)
340
{
341
    QEMUOptionParameter *cur = list;
342

    
343
    while (cur && cur->name) {
344
        if (cur->type == OPT_STRING) {
345
            g_free(cur->value.s);
346
        }
347
        cur++;
348
    }
349

    
350
    g_free(list);
351
}
352

    
353
/*
354
 * Count valid options in list
355
 */
356
static size_t count_option_parameters(QEMUOptionParameter *list)
357
{
358
    size_t num_options = 0;
359

    
360
    while (list && list->name) {
361
        num_options++;
362
        list++;
363
    }
364

    
365
    return num_options;
366
}
367

    
368
/*
369
 * Append an option list (list) to an option list (dest).
370
 *
371
 * If dest is NULL, a new copy of list is created.
372
 *
373
 * Returns a pointer to the first element of dest (or the newly allocated copy)
374
 */
375
QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
376
    QEMUOptionParameter *list)
377
{
378
    size_t num_options, num_dest_options;
379

    
380
    num_options = count_option_parameters(dest);
381
    num_dest_options = num_options;
382

    
383
    num_options += count_option_parameters(list);
384

    
385
    dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
386
    dest[num_dest_options].name = NULL;
387

    
388
    while (list && list->name) {
389
        if (get_option_parameter(dest, list->name) == NULL) {
390
            dest[num_dest_options++] = *list;
391
            dest[num_dest_options].name = NULL;
392
        }
393
        list++;
394
    }
395

    
396
    return dest;
397
}
398

    
399
/*
400
 * Parses a parameter string (param) into an option list (dest).
401
 *
402
 * list is the template option list. If dest is NULL, a new copy of list is
403
 * created. If list is NULL, this function fails.
404
 *
405
 * A parameter string consists of one or more parameters, separated by commas.
406
 * Each parameter consists of its name and possibly of a value. In the latter
407
 * case, the value is delimited by an = character. To specify a value which
408
 * contains commas, double each comma so it won't be recognized as the end of
409
 * the parameter.
410
 *
411
 * For more details of the parsing see above.
412
 *
413
 * Returns a pointer to the first element of dest (or the newly allocated copy)
414
 * or NULL in error cases
415
 */
416
QEMUOptionParameter *parse_option_parameters(const char *param,
417
    QEMUOptionParameter *list, QEMUOptionParameter *dest)
418
{
419
    QEMUOptionParameter *allocated = NULL;
420
    char name[256];
421
    char value[256];
422
    char *param_delim, *value_delim;
423
    char next_delim;
424

    
425
    if (list == NULL) {
426
        return NULL;
427
    }
428

    
429
    if (dest == NULL) {
430
        dest = allocated = append_option_parameters(NULL, list);
431
    }
432

    
433
    while (*param) {
434

    
435
        // Find parameter name and value in the string
436
        param_delim = strchr(param, ',');
437
        value_delim = strchr(param, '=');
438

    
439
        if (value_delim && (value_delim < param_delim || !param_delim)) {
440
            next_delim = '=';
441
        } else {
442
            next_delim = ',';
443
            value_delim = NULL;
444
        }
445

    
446
        param = get_opt_name(name, sizeof(name), param, next_delim);
447
        if (value_delim) {
448
            param = get_opt_value(value, sizeof(value), param + 1);
449
        }
450
        if (*param != '\0') {
451
            param++;
452
        }
453

    
454
        // Set the parameter
455
        if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
456
            goto fail;
457
        }
458
    }
459

    
460
    return dest;
461

    
462
fail:
463
    // Only free the list if it was newly allocated
464
    free_option_parameters(allocated);
465
    return NULL;
466
}
467

    
468
/*
469
 * Prints all options of a list that have a value to stdout
470
 */
471
void print_option_parameters(QEMUOptionParameter *list)
472
{
473
    while (list && list->name) {
474
        switch (list->type) {
475
            case OPT_STRING:
476
                 if (list->value.s != NULL) {
477
                     printf("%s='%s' ", list->name, list->value.s);
478
                 }
479
                break;
480
            case OPT_FLAG:
481
                printf("%s=%s ", list->name, list->value.n ? "on" : "off");
482
                break;
483
            case OPT_SIZE:
484
            case OPT_NUMBER:
485
                printf("%s=%" PRId64 " ", list->name, list->value.n);
486
                break;
487
            default:
488
                printf("%s=(unknown type) ", list->name);
489
                break;
490
        }
491
        list++;
492
    }
493
}
494

    
495
/*
496
 * Prints an overview of all available options
497
 */
498
void print_option_help(QEMUOptionParameter *list)
499
{
500
    printf("Supported options:\n");
501
    while (list && list->name) {
502
        printf("%-16s %s\n", list->name,
503
            list->help ? list->help : "No description available");
504
        list++;
505
    }
506
}
507

    
508
/* ------------------------------------------------------------------ */
509

    
510
struct QemuOpt {
511
    const char   *name;
512
    const char   *str;
513

    
514
    const QemuOptDesc *desc;
515
    union {
516
        bool boolean;
517
        uint64_t uint;
518
    } value;
519

    
520
    QemuOpts     *opts;
521
    QTAILQ_ENTRY(QemuOpt) next;
522
};
523

    
524
struct QemuOpts {
525
    char *id;
526
    QemuOptsList *list;
527
    Location loc;
528
    QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
529
    QTAILQ_ENTRY(QemuOpts) next;
530
};
531

    
532
static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
533
{
534
    QemuOpt *opt;
535

    
536
    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
537
        if (strcmp(opt->name, name) != 0)
538
            continue;
539
        return opt;
540
    }
541
    return NULL;
542
}
543

    
544
const char *qemu_opt_get(QemuOpts *opts, const char *name)
545
{
546
    QemuOpt *opt = qemu_opt_find(opts, name);
547
    return opt ? opt->str : NULL;
548
}
549

    
550
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
551
{
552
    QemuOpt *opt = qemu_opt_find(opts, name);
553

    
554
    if (opt == NULL)
555
        return defval;
556
    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
557
    return opt->value.boolean;
558
}
559

    
560
uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
561
{
562
    QemuOpt *opt = qemu_opt_find(opts, name);
563

    
564
    if (opt == NULL)
565
        return defval;
566
    assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
567
    return opt->value.uint;
568
}
569

    
570
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
571
{
572
    QemuOpt *opt = qemu_opt_find(opts, name);
573

    
574
    if (opt == NULL)
575
        return defval;
576
    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
577
    return opt->value.uint;
578
}
579

    
580
static int qemu_opt_parse(QemuOpt *opt)
581
{
582
    if (opt->desc == NULL)
583
        return 0;
584
    switch (opt->desc->type) {
585
    case QEMU_OPT_STRING:
586
        /* nothing */
587
        return 0;
588
    case QEMU_OPT_BOOL:
589
        return parse_option_bool(opt->name, opt->str, &opt->value.boolean);
590
    case QEMU_OPT_NUMBER:
591
        return parse_option_number(opt->name, opt->str, &opt->value.uint);
592
    case QEMU_OPT_SIZE:
593
        return parse_option_size(opt->name, opt->str, &opt->value.uint);
594
    default:
595
        abort();
596
    }
597
}
598

    
599
static void qemu_opt_del(QemuOpt *opt)
600
{
601
    QTAILQ_REMOVE(&opt->opts->head, opt, next);
602
    g_free((/* !const */ char*)opt->name);
603
    g_free((/* !const */ char*)opt->str);
604
    g_free(opt);
605
}
606

    
607
static int opt_set(QemuOpts *opts, const char *name, const char *value,
608
                   bool prepend)
609
{
610
    QemuOpt *opt;
611
    const QemuOptDesc *desc = opts->list->desc;
612
    int i;
613

    
614
    for (i = 0; desc[i].name != NULL; i++) {
615
        if (strcmp(desc[i].name, name) == 0) {
616
            break;
617
        }
618
    }
619
    if (desc[i].name == NULL) {
620
        if (i == 0) {
621
            /* empty list -> allow any */;
622
        } else {
623
            qerror_report(QERR_INVALID_PARAMETER, name);
624
            return -1;
625
        }
626
    }
627

    
628
    opt = g_malloc0(sizeof(*opt));
629
    opt->name = g_strdup(name);
630
    opt->opts = opts;
631
    if (prepend) {
632
        QTAILQ_INSERT_HEAD(&opts->head, opt, next);
633
    } else {
634
        QTAILQ_INSERT_TAIL(&opts->head, opt, next);
635
    }
636
    if (desc[i].name != NULL) {
637
        opt->desc = desc+i;
638
    }
639
    if (value) {
640
        opt->str = g_strdup(value);
641
    }
642
    if (qemu_opt_parse(opt) < 0) {
643
        qemu_opt_del(opt);
644
        return -1;
645
    }
646
    return 0;
647
}
648

    
649
int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
650
{
651
    return opt_set(opts, name, value, false);
652
}
653

    
654
int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
655
{
656
    QemuOpt *opt;
657
    const QemuOptDesc *desc = opts->list->desc;
658
    int i;
659

    
660
    for (i = 0; desc[i].name != NULL; i++) {
661
        if (strcmp(desc[i].name, name) == 0) {
662
            break;
663
        }
664
    }
665
    if (desc[i].name == NULL) {
666
        if (i == 0) {
667
            /* empty list -> allow any */;
668
        } else {
669
            qerror_report(QERR_INVALID_PARAMETER, name);
670
            return -1;
671
        }
672
    }
673

    
674
    opt = g_malloc0(sizeof(*opt));
675
    opt->name = g_strdup(name);
676
    opt->opts = opts;
677
    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
678
    if (desc[i].name != NULL) {
679
        opt->desc = desc+i;
680
    }
681
    opt->value.boolean = !!val;
682
    return 0;
683
}
684

    
685
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
686
                     int abort_on_failure)
687
{
688
    QemuOpt *opt;
689
    int rc = 0;
690

    
691
    QTAILQ_FOREACH(opt, &opts->head, next) {
692
        rc = func(opt->name, opt->str, opaque);
693
        if (abort_on_failure  &&  rc != 0)
694
            break;
695
    }
696
    return rc;
697
}
698

    
699
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
700
{
701
    QemuOpts *opts;
702

    
703
    QTAILQ_FOREACH(opts, &list->head, next) {
704
        if (!opts->id) {
705
            if (!id) {
706
                return opts;
707
            }
708
            continue;
709
        }
710
        if (strcmp(opts->id, id) != 0) {
711
            continue;
712
        }
713
        return opts;
714
    }
715
    return NULL;
716
}
717

    
718
static int id_wellformed(const char *id)
719
{
720
    int i;
721

    
722
    if (!qemu_isalpha(id[0])) {
723
        return 0;
724
    }
725
    for (i = 1; id[i]; i++) {
726
        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
727
            return 0;
728
        }
729
    }
730
    return 1;
731
}
732

    
733
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
734
                           int fail_if_exists, Error **errp)
735
{
736
    QemuOpts *opts = NULL;
737

    
738
    if (id) {
739
        if (!id_wellformed(id)) {
740
            error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
741
            error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
742
            return NULL;
743
        }
744
        opts = qemu_opts_find(list, id);
745
        if (opts != NULL) {
746
            if (fail_if_exists && !list->merge_lists) {
747
                error_set(errp, QERR_DUPLICATE_ID, id, list->name);
748
                return NULL;
749
            } else {
750
                return opts;
751
            }
752
        }
753
    } else if (list->merge_lists) {
754
        opts = qemu_opts_find(list, NULL);
755
        if (opts) {
756
            return opts;
757
        }
758
    }
759
    opts = g_malloc0(sizeof(*opts));
760
    if (id) {
761
        opts->id = g_strdup(id);
762
    }
763
    opts->list = list;
764
    loc_save(&opts->loc);
765
    QTAILQ_INIT(&opts->head);
766
    QTAILQ_INSERT_TAIL(&list->head, opts, next);
767
    return opts;
768
}
769

    
770
void qemu_opts_reset(QemuOptsList *list)
771
{
772
    QemuOpts *opts, *next_opts;
773

    
774
    QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
775
        qemu_opts_del(opts);
776
    }
777
}
778

    
779
void qemu_opts_loc_restore(QemuOpts *opts)
780
{
781
    loc_restore(&opts->loc);
782
}
783

    
784
int qemu_opts_set(QemuOptsList *list, const char *id,
785
                  const char *name, const char *value)
786
{
787
    QemuOpts *opts;
788
    Error *local_err = NULL;
789

    
790
    opts = qemu_opts_create(list, id, 1, &local_err);
791
    if (error_is_set(&local_err)) {
792
        qerror_report_err(local_err);
793
        error_free(local_err);
794
        return -1;
795
    }
796
    return qemu_opt_set(opts, name, value);
797
}
798

    
799
const char *qemu_opts_id(QemuOpts *opts)
800
{
801
    return opts->id;
802
}
803

    
804
void qemu_opts_del(QemuOpts *opts)
805
{
806
    QemuOpt *opt;
807

    
808
    for (;;) {
809
        opt = QTAILQ_FIRST(&opts->head);
810
        if (opt == NULL)
811
            break;
812
        qemu_opt_del(opt);
813
    }
814
    QTAILQ_REMOVE(&opts->list->head, opts, next);
815
    g_free(opts->id);
816
    g_free(opts);
817
}
818

    
819
int qemu_opts_print(QemuOpts *opts, void *dummy)
820
{
821
    QemuOpt *opt;
822

    
823
    fprintf(stderr, "%s: %s:", opts->list->name,
824
            opts->id ? opts->id : "<noid>");
825
    QTAILQ_FOREACH(opt, &opts->head, next) {
826
        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
827
    }
828
    fprintf(stderr, "\n");
829
    return 0;
830
}
831

    
832
static int opts_do_parse(QemuOpts *opts, const char *params,
833
                         const char *firstname, bool prepend)
834
{
835
    char option[128], value[1024];
836
    const char *p,*pe,*pc;
837

    
838
    for (p = params; *p != '\0'; p++) {
839
        pe = strchr(p, '=');
840
        pc = strchr(p, ',');
841
        if (!pe || (pc && pc < pe)) {
842
            /* found "foo,more" */
843
            if (p == params && firstname) {
844
                /* implicitly named first option */
845
                pstrcpy(option, sizeof(option), firstname);
846
                p = get_opt_value(value, sizeof(value), p);
847
            } else {
848
                /* option without value, probably a flag */
849
                p = get_opt_name(option, sizeof(option), p, ',');
850
                if (strncmp(option, "no", 2) == 0) {
851
                    memmove(option, option+2, strlen(option+2)+1);
852
                    pstrcpy(value, sizeof(value), "off");
853
                } else {
854
                    pstrcpy(value, sizeof(value), "on");
855
                }
856
            }
857
        } else {
858
            /* found "foo=bar,more" */
859
            p = get_opt_name(option, sizeof(option), p, '=');
860
            if (*p != '=') {
861
                break;
862
            }
863
            p++;
864
            p = get_opt_value(value, sizeof(value), p);
865
        }
866
        if (strcmp(option, "id") != 0) {
867
            /* store and parse */
868
            if (opt_set(opts, option, value, prepend) == -1) {
869
                return -1;
870
            }
871
        }
872
        if (*p != ',') {
873
            break;
874
        }
875
    }
876
    return 0;
877
}
878

    
879
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
880
{
881
    return opts_do_parse(opts, params, firstname, false);
882
}
883

    
884
static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
885
                            int permit_abbrev, bool defaults)
886
{
887
    const char *firstname;
888
    char value[1024], *id = NULL;
889
    const char *p;
890
    QemuOpts *opts;
891
    Error *local_err = NULL;
892

    
893
    assert(!permit_abbrev || list->implied_opt_name);
894
    firstname = permit_abbrev ? list->implied_opt_name : NULL;
895

    
896
    if (strncmp(params, "id=", 3) == 0) {
897
        get_opt_value(value, sizeof(value), params+3);
898
        id = value;
899
    } else if ((p = strstr(params, ",id=")) != NULL) {
900
        get_opt_value(value, sizeof(value), p+4);
901
        id = value;
902
    }
903
    if (defaults) {
904
        if (!id && !QTAILQ_EMPTY(&list->head)) {
905
            opts = qemu_opts_find(list, NULL);
906
        } else {
907
            opts = qemu_opts_create(list, id, 0, &local_err);
908
        }
909
    } else {
910
        opts = qemu_opts_create(list, id, 1, &local_err);
911
    }
912
    if (opts == NULL) {
913
        if (error_is_set(&local_err)) {
914
            qerror_report_err(local_err);
915
            error_free(local_err);
916
        }
917
        return NULL;
918
    }
919

    
920
    if (opts_do_parse(opts, params, firstname, defaults) != 0) {
921
        qemu_opts_del(opts);
922
        return NULL;
923
    }
924

    
925
    return opts;
926
}
927

    
928
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
929
                          int permit_abbrev)
930
{
931
    return opts_parse(list, params, permit_abbrev, false);
932
}
933

    
934
void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
935
                            int permit_abbrev)
936
{
937
    QemuOpts *opts;
938

    
939
    opts = opts_parse(list, params, permit_abbrev, true);
940
    assert(opts);
941
}
942

    
943
static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
944
{
945
    char buf[32];
946
    const char *value;
947
    int n;
948

    
949
    if (!strcmp(key, "id")) {
950
        return;
951
    }
952

    
953
    switch (qobject_type(obj)) {
954
    case QTYPE_QSTRING:
955
        value = qstring_get_str(qobject_to_qstring(obj));
956
        break;
957
    case QTYPE_QINT:
958
        n = snprintf(buf, sizeof(buf), "%" PRId64,
959
                     qint_get_int(qobject_to_qint(obj)));
960
        assert(n < sizeof(buf));
961
        value = buf;
962
        break;
963
    case QTYPE_QFLOAT:
964
        n = snprintf(buf, sizeof(buf), "%.17g",
965
                     qfloat_get_double(qobject_to_qfloat(obj)));
966
        assert(n < sizeof(buf));
967
        value = buf;
968
        break;
969
    case QTYPE_QBOOL:
970
        pstrcpy(buf, sizeof(buf),
971
                qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
972
        value = buf;
973
        break;
974
    default:
975
        return;
976
    }
977
    qemu_opt_set(opaque, key, value);
978
}
979

    
980
/*
981
 * Create QemuOpts from a QDict.
982
 * Use value of key "id" as ID if it exists and is a QString.
983
 * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
984
 * other types are silently ignored.
985
 */
986
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict)
987
{
988
    QemuOpts *opts;
989
    Error *local_err = NULL;
990

    
991
    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
992
                            &local_err);
993
    if (error_is_set(&local_err)) {
994
        qerror_report_err(local_err);
995
        error_free(local_err);
996
        return NULL;
997
    }
998

    
999
    assert(opts != NULL);
1000
    qdict_iter(qdict, qemu_opts_from_qdict_1, opts);
1001
    return opts;
1002
}
1003

    
1004
/*
1005
 * Convert from QemuOpts to QDict.
1006
 * The QDict values are of type QString.
1007
 * TODO We'll want to use types appropriate for opt->desc->type, but
1008
 * this is enough for now.
1009
 */
1010
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1011
{
1012
    QemuOpt *opt;
1013
    QObject *val;
1014

    
1015
    if (!qdict) {
1016
        qdict = qdict_new();
1017
    }
1018
    if (opts->id) {
1019
        qdict_put(qdict, "id", qstring_from_str(opts->id));
1020
    }
1021
    QTAILQ_FOREACH(opt, &opts->head, next) {
1022
        val = QOBJECT(qstring_from_str(opt->str));
1023
        qdict_put_obj(qdict, opt->name, val);
1024
    }
1025
    return qdict;
1026
}
1027

    
1028
/* Validate parsed opts against descriptions where no
1029
 * descriptions were provided in the QemuOptsList.
1030
 */
1031
int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
1032
{
1033
    QemuOpt *opt;
1034

    
1035
    assert(opts->list->desc[0].name == NULL);
1036

    
1037
    QTAILQ_FOREACH(opt, &opts->head, next) {
1038
        int i;
1039

    
1040
        for (i = 0; desc[i].name != NULL; i++) {
1041
            if (strcmp(desc[i].name, opt->name) == 0) {
1042
                break;
1043
            }
1044
        }
1045
        if (desc[i].name == NULL) {
1046
            qerror_report(QERR_INVALID_PARAMETER, opt->name);
1047
            return -1;
1048
        }
1049

    
1050
        opt->desc = &desc[i];
1051

    
1052
        if (qemu_opt_parse(opt) < 0) {
1053
            return -1;
1054
        }
1055
    }
1056

    
1057
    return 0;
1058
}
1059

    
1060
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
1061
                      int abort_on_failure)
1062
{
1063
    Location loc;
1064
    QemuOpts *opts;
1065
    int rc = 0;
1066

    
1067
    loc_push_none(&loc);
1068
    QTAILQ_FOREACH(opts, &list->head, next) {
1069
        loc_restore(&opts->loc);
1070
        rc |= func(opts, opaque);
1071
        if (abort_on_failure  &&  rc != 0)
1072
            break;
1073
    }
1074
    loc_pop(&loc);
1075
    return rc;
1076
}