Statistics
| Branch: | Revision:

root / util / qemu-option.c @ cb77d192

History | View | Annotate | Download (29.3 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-report.h"
31
#include "qapi/qmp/types.h"
32
#include "qapi/error.h"
33
#include "qapi/qmp/qerror.h"
34
#include "qemu/option_int.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
/*
127
 * Searches an option list for an option with the given name
128
 */
129
QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
130
    const char *name)
131
{
132
    while (list && list->name) {
133
        if (!strcmp(list->name, name)) {
134
            return list;
135
        }
136
        list++;
137
    }
138

    
139
    return NULL;
140
}
141

    
142
static void parse_option_bool(const char *name, const char *value, bool *ret,
143
                              Error **errp)
144
{
145
    if (value != NULL) {
146
        if (!strcmp(value, "on")) {
147
            *ret = 1;
148
        } else if (!strcmp(value, "off")) {
149
            *ret = 0;
150
        } else {
151
            error_set(errp,QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'");
152
        }
153
    } else {
154
        *ret = 1;
155
    }
156
}
157

    
158
static void parse_option_number(const char *name, const char *value,
159
                                uint64_t *ret, Error **errp)
160
{
161
    char *postfix;
162
    uint64_t number;
163

    
164
    if (value != NULL) {
165
        number = strtoull(value, &postfix, 0);
166
        if (*postfix != '\0') {
167
            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
168
            return;
169
        }
170
        *ret = number;
171
    } else {
172
        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
173
    }
174
}
175

    
176
void parse_option_size(const char *name, const char *value,
177
                       uint64_t *ret, Error **errp)
178
{
179
    char *postfix;
180
    double sizef;
181

    
182
    if (value != NULL) {
183
        sizef = strtod(value, &postfix);
184
        switch (*postfix) {
185
        case 'T':
186
            sizef *= 1024;
187
            /* fall through */
188
        case 'G':
189
            sizef *= 1024;
190
            /* fall through */
191
        case 'M':
192
            sizef *= 1024;
193
            /* fall through */
194
        case 'K':
195
        case 'k':
196
            sizef *= 1024;
197
            /* fall through */
198
        case 'b':
199
        case '\0':
200
            *ret = (uint64_t) sizef;
201
            break;
202
        default:
203
            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
204
#if 0 /* conversion from qerror_report() to error_set() broke this: */
205
            error_printf_unless_qmp("You may use k, M, G or T suffixes for "
206
                    "kilobytes, megabytes, gigabytes and terabytes.\n");
207
#endif
208
            return;
209
        }
210
    } else {
211
        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
212
    }
213
}
214

    
215
/*
216
 * Sets the value of a parameter in a given option list. The parsing of the
217
 * value depends on the type of option:
218
 *
219
 * OPT_FLAG (uses value.n):
220
 *      If no value is given, the flag is set to 1.
221
 *      Otherwise the value must be "on" (set to 1) or "off" (set to 0)
222
 *
223
 * OPT_STRING (uses value.s):
224
 *      value is strdup()ed and assigned as option value
225
 *
226
 * OPT_SIZE (uses value.n):
227
 *      The value is converted to an integer. Suffixes for kilobytes etc. are
228
 *      allowed (powers of 1024).
229
 *
230
 * Returns 0 on succes, -1 in error cases
231
 */
232
int set_option_parameter(QEMUOptionParameter *list, const char *name,
233
    const char *value)
234
{
235
    bool flag;
236
    Error *local_err = NULL;
237

    
238
    // Find a matching parameter
239
    list = get_option_parameter(list, name);
240
    if (list == NULL) {
241
        fprintf(stderr, "Unknown option '%s'\n", name);
242
        return -1;
243
    }
244

    
245
    // Process parameter
246
    switch (list->type) {
247
    case OPT_FLAG:
248
        parse_option_bool(name, value, &flag, &local_err);
249
        if (!error_is_set(&local_err)) {
250
            list->value.n = flag;
251
        }
252
        break;
253

    
254
    case OPT_STRING:
255
        if (value != NULL) {
256
            list->value.s = g_strdup(value);
257
        } else {
258
            fprintf(stderr, "Option '%s' needs a parameter\n", name);
259
            return -1;
260
        }
261
        break;
262

    
263
    case OPT_SIZE:
264
        parse_option_size(name, value, &list->value.n, &local_err);
265
        break;
266

    
267
    default:
268
        fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
269
        return -1;
270
    }
271

    
272
    if (error_is_set(&local_err)) {
273
        qerror_report_err(local_err);
274
        error_free(local_err);
275
        return -1;
276
    }
277

    
278
    return 0;
279
}
280

    
281
/*
282
 * Sets the given parameter to an integer instead of a string.
283
 * This function cannot be used to set string options.
284
 *
285
 * Returns 0 on success, -1 in error cases
286
 */
287
int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
288
    uint64_t value)
289
{
290
    // Find a matching parameter
291
    list = get_option_parameter(list, name);
292
    if (list == NULL) {
293
        fprintf(stderr, "Unknown option '%s'\n", name);
294
        return -1;
295
    }
296

    
297
    // Process parameter
298
    switch (list->type) {
299
    case OPT_FLAG:
300
    case OPT_NUMBER:
301
    case OPT_SIZE:
302
        list->value.n = value;
303
        break;
304

    
305
    default:
306
        return -1;
307
    }
308

    
309
    return 0;
310
}
311

    
312
/*
313
 * Frees a option list. If it contains strings, the strings are freed as well.
314
 */
315
void free_option_parameters(QEMUOptionParameter *list)
316
{
317
    QEMUOptionParameter *cur = list;
318

    
319
    while (cur && cur->name) {
320
        if (cur->type == OPT_STRING) {
321
            g_free(cur->value.s);
322
        }
323
        cur++;
324
    }
325

    
326
    g_free(list);
327
}
328

    
329
/*
330
 * Count valid options in list
331
 */
332
static size_t count_option_parameters(QEMUOptionParameter *list)
333
{
334
    size_t num_options = 0;
335

    
336
    while (list && list->name) {
337
        num_options++;
338
        list++;
339
    }
340

    
341
    return num_options;
342
}
343

    
344
/*
345
 * Append an option list (list) to an option list (dest).
346
 *
347
 * If dest is NULL, a new copy of list is created.
348
 *
349
 * Returns a pointer to the first element of dest (or the newly allocated copy)
350
 */
351
QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
352
    QEMUOptionParameter *list)
353
{
354
    size_t num_options, num_dest_options;
355

    
356
    num_options = count_option_parameters(dest);
357
    num_dest_options = num_options;
358

    
359
    num_options += count_option_parameters(list);
360

    
361
    dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
362
    dest[num_dest_options].name = NULL;
363

    
364
    while (list && list->name) {
365
        if (get_option_parameter(dest, list->name) == NULL) {
366
            dest[num_dest_options++] = *list;
367
            dest[num_dest_options].name = NULL;
368
        }
369
        list++;
370
    }
371

    
372
    return dest;
373
}
374

    
375
/*
376
 * Parses a parameter string (param) into an option list (dest).
377
 *
378
 * list is the template option list. If dest is NULL, a new copy of list is
379
 * created. If list is NULL, this function fails.
380
 *
381
 * A parameter string consists of one or more parameters, separated by commas.
382
 * Each parameter consists of its name and possibly of a value. In the latter
383
 * case, the value is delimited by an = character. To specify a value which
384
 * contains commas, double each comma so it won't be recognized as the end of
385
 * the parameter.
386
 *
387
 * For more details of the parsing see above.
388
 *
389
 * Returns a pointer to the first element of dest (or the newly allocated copy)
390
 * or NULL in error cases
391
 */
392
QEMUOptionParameter *parse_option_parameters(const char *param,
393
    QEMUOptionParameter *list, QEMUOptionParameter *dest)
394
{
395
    QEMUOptionParameter *allocated = NULL;
396
    char name[256];
397
    char value[256];
398
    char *param_delim, *value_delim;
399
    char next_delim;
400

    
401
    if (list == NULL) {
402
        return NULL;
403
    }
404

    
405
    if (dest == NULL) {
406
        dest = allocated = append_option_parameters(NULL, list);
407
    }
408

    
409
    while (*param) {
410

    
411
        // Find parameter name and value in the string
412
        param_delim = strchr(param, ',');
413
        value_delim = strchr(param, '=');
414

    
415
        if (value_delim && (value_delim < param_delim || !param_delim)) {
416
            next_delim = '=';
417
        } else {
418
            next_delim = ',';
419
            value_delim = NULL;
420
        }
421

    
422
        param = get_opt_name(name, sizeof(name), param, next_delim);
423
        if (value_delim) {
424
            param = get_opt_value(value, sizeof(value), param + 1);
425
        }
426
        if (*param != '\0') {
427
            param++;
428
        }
429

    
430
        // Set the parameter
431
        if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
432
            goto fail;
433
        }
434
    }
435

    
436
    return dest;
437

    
438
fail:
439
    // Only free the list if it was newly allocated
440
    free_option_parameters(allocated);
441
    return NULL;
442
}
443

    
444
/*
445
 * Prints all options of a list that have a value to stdout
446
 */
447
void print_option_parameters(QEMUOptionParameter *list)
448
{
449
    while (list && list->name) {
450
        switch (list->type) {
451
            case OPT_STRING:
452
                 if (list->value.s != NULL) {
453
                     printf("%s='%s' ", list->name, list->value.s);
454
                 }
455
                break;
456
            case OPT_FLAG:
457
                printf("%s=%s ", list->name, list->value.n ? "on" : "off");
458
                break;
459
            case OPT_SIZE:
460
            case OPT_NUMBER:
461
                printf("%s=%" PRId64 " ", list->name, list->value.n);
462
                break;
463
            default:
464
                printf("%s=(unknown type) ", list->name);
465
                break;
466
        }
467
        list++;
468
    }
469
}
470

    
471
/*
472
 * Prints an overview of all available options
473
 */
474
void print_option_help(QEMUOptionParameter *list)
475
{
476
    printf("Supported options:\n");
477
    while (list && list->name) {
478
        printf("%-16s %s\n", list->name,
479
            list->help ? list->help : "No description available");
480
        list++;
481
    }
482
}
483

    
484
/* ------------------------------------------------------------------ */
485

    
486
static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
487
{
488
    QemuOpt *opt;
489

    
490
    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
491
        if (strcmp(opt->name, name) != 0)
492
            continue;
493
        return opt;
494
    }
495
    return NULL;
496
}
497

    
498
const char *qemu_opt_get(QemuOpts *opts, const char *name)
499
{
500
    QemuOpt *opt = qemu_opt_find(opts, name);
501
    return opt ? opt->str : NULL;
502
}
503

    
504
bool qemu_opt_has_help_opt(QemuOpts *opts)
505
{
506
    QemuOpt *opt;
507

    
508
    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
509
        if (is_help_option(opt->name)) {
510
            return true;
511
        }
512
    }
513
    return false;
514
}
515

    
516
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
517
{
518
    QemuOpt *opt = qemu_opt_find(opts, name);
519

    
520
    if (opt == NULL)
521
        return defval;
522
    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
523
    return opt->value.boolean;
524
}
525

    
526
uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
527
{
528
    QemuOpt *opt = qemu_opt_find(opts, name);
529

    
530
    if (opt == NULL)
531
        return defval;
532
    assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
533
    return opt->value.uint;
534
}
535

    
536
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
537
{
538
    QemuOpt *opt = qemu_opt_find(opts, name);
539

    
540
    if (opt == NULL)
541
        return defval;
542
    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
543
    return opt->value.uint;
544
}
545

    
546
static void qemu_opt_parse(QemuOpt *opt, Error **errp)
547
{
548
    if (opt->desc == NULL)
549
        return;
550

    
551
    switch (opt->desc->type) {
552
    case QEMU_OPT_STRING:
553
        /* nothing */
554
        return;
555
    case QEMU_OPT_BOOL:
556
        parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
557
        break;
558
    case QEMU_OPT_NUMBER:
559
        parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
560
        break;
561
    case QEMU_OPT_SIZE:
562
        parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
563
        break;
564
    default:
565
        abort();
566
    }
567
}
568

    
569
static void qemu_opt_del(QemuOpt *opt)
570
{
571
    QTAILQ_REMOVE(&opt->opts->head, opt, next);
572
    g_free((/* !const */ char*)opt->name);
573
    g_free((/* !const */ char*)opt->str);
574
    g_free(opt);
575
}
576

    
577
static bool opts_accepts_any(const QemuOpts *opts)
578
{
579
    return opts->list->desc[0].name == NULL;
580
}
581

    
582
static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
583
                                            const char *name)
584
{
585
    int i;
586

    
587
    for (i = 0; desc[i].name != NULL; i++) {
588
        if (strcmp(desc[i].name, name) == 0) {
589
            return &desc[i];
590
        }
591
    }
592

    
593
    return NULL;
594
}
595

    
596
int qemu_opt_unset(QemuOpts *opts, const char *name)
597
{
598
    QemuOpt *opt = qemu_opt_find(opts, name);
599

    
600
    assert(opts_accepts_any(opts));
601

    
602
    if (opt == NULL) {
603
        return -1;
604
    } else {
605
        qemu_opt_del(opt);
606
        return 0;
607
    }
608
}
609

    
610
static void opt_set(QemuOpts *opts, const char *name, const char *value,
611
                    bool prepend, Error **errp)
612
{
613
    QemuOpt *opt;
614
    const QemuOptDesc *desc;
615
    Error *local_err = NULL;
616

    
617
    desc = find_desc_by_name(opts->list->desc, name);
618
    if (!desc && !opts_accepts_any(opts)) {
619
        error_set(errp, QERR_INVALID_PARAMETER, name);
620
        return;
621
    }
622

    
623
    opt = g_malloc0(sizeof(*opt));
624
    opt->name = g_strdup(name);
625
    opt->opts = opts;
626
    if (prepend) {
627
        QTAILQ_INSERT_HEAD(&opts->head, opt, next);
628
    } else {
629
        QTAILQ_INSERT_TAIL(&opts->head, opt, next);
630
    }
631
    opt->desc = desc;
632
    opt->str = g_strdup(value);
633
    qemu_opt_parse(opt, &local_err);
634
    if (error_is_set(&local_err)) {
635
        error_propagate(errp, local_err);
636
        qemu_opt_del(opt);
637
    }
638
}
639

    
640
int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
641
{
642
    Error *local_err = NULL;
643

    
644
    opt_set(opts, name, value, false, &local_err);
645
    if (error_is_set(&local_err)) {
646
        qerror_report_err(local_err);
647
        error_free(local_err);
648
        return -1;
649
    }
650

    
651
    return 0;
652
}
653

    
654
void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
655
                      Error **errp)
656
{
657
    opt_set(opts, name, value, false, errp);
658
}
659

    
660
int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
661
{
662
    QemuOpt *opt;
663
    const QemuOptDesc *desc = opts->list->desc;
664

    
665
    opt = g_malloc0(sizeof(*opt));
666
    opt->desc = find_desc_by_name(desc, name);
667
    if (!opt->desc && !opts_accepts_any(opts)) {
668
        qerror_report(QERR_INVALID_PARAMETER, name);
669
        g_free(opt);
670
        return -1;
671
    }
672

    
673
    opt->name = g_strdup(name);
674
    opt->opts = opts;
675
    opt->value.boolean = !!val;
676
    opt->str = g_strdup(val ? "on" : "off");
677
    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
678

    
679
    return 0;
680
}
681

    
682
int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
683
{
684
    QemuOpt *opt;
685
    const QemuOptDesc *desc = opts->list->desc;
686

    
687
    opt = g_malloc0(sizeof(*opt));
688
    opt->desc = find_desc_by_name(desc, name);
689
    if (!opt->desc && !opts_accepts_any(opts)) {
690
        qerror_report(QERR_INVALID_PARAMETER, name);
691
        g_free(opt);
692
        return -1;
693
    }
694

    
695
    opt->name = g_strdup(name);
696
    opt->opts = opts;
697
    opt->value.uint = val;
698
    opt->str = g_strdup_printf("%" PRId64, val);
699
    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
700

    
701
    return 0;
702
}
703

    
704
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
705
                     int abort_on_failure)
706
{
707
    QemuOpt *opt;
708
    int rc = 0;
709

    
710
    QTAILQ_FOREACH(opt, &opts->head, next) {
711
        rc = func(opt->name, opt->str, opaque);
712
        if (abort_on_failure  &&  rc != 0)
713
            break;
714
    }
715
    return rc;
716
}
717

    
718
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
719
{
720
    QemuOpts *opts;
721

    
722
    QTAILQ_FOREACH(opts, &list->head, next) {
723
        if (!opts->id && !id) {
724
            return opts;
725
        }
726
        if (opts->id && id && !strcmp(opts->id, id)) {
727
            return opts;
728
        }
729
    }
730
    return NULL;
731
}
732

    
733
static int id_wellformed(const char *id)
734
{
735
    int i;
736

    
737
    if (!qemu_isalpha(id[0])) {
738
        return 0;
739
    }
740
    for (i = 1; id[i]; i++) {
741
        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
742
            return 0;
743
        }
744
    }
745
    return 1;
746
}
747

    
748
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
749
                           int fail_if_exists, Error **errp)
750
{
751
    QemuOpts *opts = NULL;
752

    
753
    if (id) {
754
        if (!id_wellformed(id)) {
755
            error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
756
#if 0 /* conversion from qerror_report() to error_set() broke this: */
757
            error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
758
#endif
759
            return NULL;
760
        }
761
        opts = qemu_opts_find(list, id);
762
        if (opts != NULL) {
763
            if (fail_if_exists && !list->merge_lists) {
764
                error_set(errp, QERR_DUPLICATE_ID, id, list->name);
765
                return NULL;
766
            } else {
767
                return opts;
768
            }
769
        }
770
    } else if (list->merge_lists) {
771
        opts = qemu_opts_find(list, NULL);
772
        if (opts) {
773
            return opts;
774
        }
775
    }
776
    opts = g_malloc0(sizeof(*opts));
777
    opts->id = g_strdup(id);
778
    opts->list = list;
779
    loc_save(&opts->loc);
780
    QTAILQ_INIT(&opts->head);
781
    QTAILQ_INSERT_TAIL(&list->head, opts, next);
782
    return opts;
783
}
784

    
785
QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
786
{
787
    QemuOpts *opts;
788
    Error *errp = NULL;
789
    opts = qemu_opts_create(list, NULL, 0, &errp);
790
    assert_no_error(errp);
791
    return opts;
792
}
793

    
794
void qemu_opts_reset(QemuOptsList *list)
795
{
796
    QemuOpts *opts, *next_opts;
797

    
798
    QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
799
        qemu_opts_del(opts);
800
    }
801
}
802

    
803
void qemu_opts_loc_restore(QemuOpts *opts)
804
{
805
    loc_restore(&opts->loc);
806
}
807

    
808
int qemu_opts_set(QemuOptsList *list, const char *id,
809
                  const char *name, const char *value)
810
{
811
    QemuOpts *opts;
812
    Error *local_err = NULL;
813

    
814
    opts = qemu_opts_create(list, id, 1, &local_err);
815
    if (error_is_set(&local_err)) {
816
        qerror_report_err(local_err);
817
        error_free(local_err);
818
        return -1;
819
    }
820
    return qemu_opt_set(opts, name, value);
821
}
822

    
823
const char *qemu_opts_id(QemuOpts *opts)
824
{
825
    return opts->id;
826
}
827

    
828
void qemu_opts_del(QemuOpts *opts)
829
{
830
    QemuOpt *opt;
831

    
832
    for (;;) {
833
        opt = QTAILQ_FIRST(&opts->head);
834
        if (opt == NULL)
835
            break;
836
        qemu_opt_del(opt);
837
    }
838
    QTAILQ_REMOVE(&opts->list->head, opts, next);
839
    g_free(opts->id);
840
    g_free(opts);
841
}
842

    
843
int qemu_opts_print(QemuOpts *opts, void *dummy)
844
{
845
    QemuOpt *opt;
846

    
847
    fprintf(stderr, "%s: %s:", opts->list->name,
848
            opts->id ? opts->id : "<noid>");
849
    QTAILQ_FOREACH(opt, &opts->head, next) {
850
        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
851
    }
852
    fprintf(stderr, "\n");
853
    return 0;
854
}
855

    
856
static int opts_do_parse(QemuOpts *opts, const char *params,
857
                         const char *firstname, bool prepend)
858
{
859
    char option[128], value[1024];
860
    const char *p,*pe,*pc;
861
    Error *local_err = NULL;
862

    
863
    for (p = params; *p != '\0'; p++) {
864
        pe = strchr(p, '=');
865
        pc = strchr(p, ',');
866
        if (!pe || (pc && pc < pe)) {
867
            /* found "foo,more" */
868
            if (p == params && firstname) {
869
                /* implicitly named first option */
870
                pstrcpy(option, sizeof(option), firstname);
871
                p = get_opt_value(value, sizeof(value), p);
872
            } else {
873
                /* option without value, probably a flag */
874
                p = get_opt_name(option, sizeof(option), p, ',');
875
                if (strncmp(option, "no", 2) == 0) {
876
                    memmove(option, option+2, strlen(option+2)+1);
877
                    pstrcpy(value, sizeof(value), "off");
878
                } else {
879
                    pstrcpy(value, sizeof(value), "on");
880
                }
881
            }
882
        } else {
883
            /* found "foo=bar,more" */
884
            p = get_opt_name(option, sizeof(option), p, '=');
885
            if (*p != '=') {
886
                break;
887
            }
888
            p++;
889
            p = get_opt_value(value, sizeof(value), p);
890
        }
891
        if (strcmp(option, "id") != 0) {
892
            /* store and parse */
893
            opt_set(opts, option, value, prepend, &local_err);
894
            if (error_is_set(&local_err)) {
895
                qerror_report_err(local_err);
896
                error_free(local_err);
897
                return -1;
898
            }
899
        }
900
        if (*p != ',') {
901
            break;
902
        }
903
    }
904
    return 0;
905
}
906

    
907
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
908
{
909
    return opts_do_parse(opts, params, firstname, false);
910
}
911

    
912
static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
913
                            int permit_abbrev, bool defaults)
914
{
915
    const char *firstname;
916
    char value[1024], *id = NULL;
917
    const char *p;
918
    QemuOpts *opts;
919
    Error *local_err = NULL;
920

    
921
    assert(!permit_abbrev || list->implied_opt_name);
922
    firstname = permit_abbrev ? list->implied_opt_name : NULL;
923

    
924
    if (strncmp(params, "id=", 3) == 0) {
925
        get_opt_value(value, sizeof(value), params+3);
926
        id = value;
927
    } else if ((p = strstr(params, ",id=")) != NULL) {
928
        get_opt_value(value, sizeof(value), p+4);
929
        id = value;
930
    }
931

    
932
    /*
933
     * This code doesn't work for defaults && !list->merge_lists: when
934
     * params has no id=, and list has an element with !opts->id, it
935
     * appends a new element instead of returning the existing opts.
936
     * However, we got no use for this case.  Guard against possible
937
     * (if unlikely) future misuse:
938
     */
939
    assert(!defaults || list->merge_lists);
940
    opts = qemu_opts_create(list, id, !defaults, &local_err);
941
    if (opts == NULL) {
942
        if (error_is_set(&local_err)) {
943
            qerror_report_err(local_err);
944
            error_free(local_err);
945
        }
946
        return NULL;
947
    }
948

    
949
    if (opts_do_parse(opts, params, firstname, defaults) != 0) {
950
        qemu_opts_del(opts);
951
        return NULL;
952
    }
953

    
954
    return opts;
955
}
956

    
957
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
958
                          int permit_abbrev)
959
{
960
    return opts_parse(list, params, permit_abbrev, false);
961
}
962

    
963
void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
964
                            int permit_abbrev)
965
{
966
    QemuOpts *opts;
967

    
968
    opts = opts_parse(list, params, permit_abbrev, true);
969
    assert(opts);
970
}
971

    
972
typedef struct OptsFromQDictState {
973
    QemuOpts *opts;
974
    Error **errp;
975
} OptsFromQDictState;
976

    
977
static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
978
{
979
    OptsFromQDictState *state = opaque;
980
    char buf[32];
981
    const char *value;
982
    int n;
983

    
984
    if (!strcmp(key, "id") || error_is_set(state->errp)) {
985
        return;
986
    }
987

    
988
    switch (qobject_type(obj)) {
989
    case QTYPE_QSTRING:
990
        value = qstring_get_str(qobject_to_qstring(obj));
991
        break;
992
    case QTYPE_QINT:
993
        n = snprintf(buf, sizeof(buf), "%" PRId64,
994
                     qint_get_int(qobject_to_qint(obj)));
995
        assert(n < sizeof(buf));
996
        value = buf;
997
        break;
998
    case QTYPE_QFLOAT:
999
        n = snprintf(buf, sizeof(buf), "%.17g",
1000
                     qfloat_get_double(qobject_to_qfloat(obj)));
1001
        assert(n < sizeof(buf));
1002
        value = buf;
1003
        break;
1004
    case QTYPE_QBOOL:
1005
        pstrcpy(buf, sizeof(buf),
1006
                qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
1007
        value = buf;
1008
        break;
1009
    default:
1010
        return;
1011
    }
1012

    
1013
    qemu_opt_set_err(state->opts, key, value, state->errp);
1014
}
1015

    
1016
/*
1017
 * Create QemuOpts from a QDict.
1018
 * Use value of key "id" as ID if it exists and is a QString.
1019
 * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
1020
 * other types are silently ignored.
1021
 */
1022
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
1023
                               Error **errp)
1024
{
1025
    OptsFromQDictState state;
1026
    Error *local_err = NULL;
1027
    QemuOpts *opts;
1028

    
1029
    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
1030
                            &local_err);
1031
    if (error_is_set(&local_err)) {
1032
        error_propagate(errp, local_err);
1033
        return NULL;
1034
    }
1035

    
1036
    assert(opts != NULL);
1037

    
1038
    state.errp = &local_err;
1039
    state.opts = opts;
1040
    qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
1041
    if (error_is_set(&local_err)) {
1042
        error_propagate(errp, local_err);
1043
        qemu_opts_del(opts);
1044
        return NULL;
1045
    }
1046

    
1047
    return opts;
1048
}
1049

    
1050
/*
1051
 * Adds all QDict entries to the QemuOpts that can be added and removes them
1052
 * from the QDict. When this function returns, the QDict contains only those
1053
 * entries that couldn't be added to the QemuOpts.
1054
 */
1055
void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
1056
{
1057
    const QDictEntry *entry, *next;
1058

    
1059
    entry = qdict_first(qdict);
1060

    
1061
    while (entry != NULL) {
1062
        Error *local_err = NULL;
1063
        OptsFromQDictState state = {
1064
            .errp = &local_err,
1065
            .opts = opts,
1066
        };
1067

    
1068
        next = qdict_next(qdict, entry);
1069

    
1070
        if (find_desc_by_name(opts->list->desc, entry->key)) {
1071
            qemu_opts_from_qdict_1(entry->key, entry->value, &state);
1072
            if (error_is_set(&local_err)) {
1073
                error_propagate(errp, local_err);
1074
                return;
1075
            } else {
1076
                qdict_del(qdict, entry->key);
1077
            }
1078
        }
1079

    
1080
        entry = next;
1081
    }
1082
}
1083

    
1084
/*
1085
 * Convert from QemuOpts to QDict.
1086
 * The QDict values are of type QString.
1087
 * TODO We'll want to use types appropriate for opt->desc->type, but
1088
 * this is enough for now.
1089
 */
1090
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1091
{
1092
    QemuOpt *opt;
1093
    QObject *val;
1094

    
1095
    if (!qdict) {
1096
        qdict = qdict_new();
1097
    }
1098
    if (opts->id) {
1099
        qdict_put(qdict, "id", qstring_from_str(opts->id));
1100
    }
1101
    QTAILQ_FOREACH(opt, &opts->head, next) {
1102
        val = QOBJECT(qstring_from_str(opt->str));
1103
        qdict_put_obj(qdict, opt->name, val);
1104
    }
1105
    return qdict;
1106
}
1107

    
1108
/* Validate parsed opts against descriptions where no
1109
 * descriptions were provided in the QemuOptsList.
1110
 */
1111
void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
1112
{
1113
    QemuOpt *opt;
1114
    Error *local_err = NULL;
1115

    
1116
    assert(opts_accepts_any(opts));
1117

    
1118
    QTAILQ_FOREACH(opt, &opts->head, next) {
1119
        opt->desc = find_desc_by_name(desc, opt->name);
1120
        if (!opt->desc) {
1121
            error_set(errp, QERR_INVALID_PARAMETER, opt->name);
1122
            return;
1123
        }
1124

    
1125
        qemu_opt_parse(opt, &local_err);
1126
        if (error_is_set(&local_err)) {
1127
            error_propagate(errp, local_err);
1128
            return;
1129
        }
1130
    }
1131
}
1132

    
1133
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
1134
                      int abort_on_failure)
1135
{
1136
    Location loc;
1137
    QemuOpts *opts;
1138
    int rc = 0;
1139

    
1140
    loc_push_none(&loc);
1141
    QTAILQ_FOREACH(opts, &list->head, next) {
1142
        loc_restore(&opts->loc);
1143
        rc |= func(opts, opaque);
1144
        if (abort_on_failure  &&  rc != 0)
1145
            break;
1146
    }
1147
    loc_pop(&loc);
1148
    return rc;
1149
}