Statistics
| Branch: | Revision:

root / util / qemu-option.c @ f4ff3b7b

History | View | Annotate | Download (29.5 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
    list->assigned = true;
279

    
280
    return 0;
281
}
282

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

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

    
307
    default:
308
        return -1;
309
    }
310

    
311
    list->assigned = true;
312

    
313
    return 0;
314
}
315

    
316
/*
317
 * Frees a option list. If it contains strings, the strings are freed as well.
318
 */
319
void free_option_parameters(QEMUOptionParameter *list)
320
{
321
    QEMUOptionParameter *cur = list;
322

    
323
    while (cur && cur->name) {
324
        if (cur->type == OPT_STRING) {
325
            g_free(cur->value.s);
326
        }
327
        cur++;
328
    }
329

    
330
    g_free(list);
331
}
332

    
333
/*
334
 * Count valid options in list
335
 */
336
static size_t count_option_parameters(QEMUOptionParameter *list)
337
{
338
    size_t num_options = 0;
339

    
340
    while (list && list->name) {
341
        num_options++;
342
        list++;
343
    }
344

    
345
    return num_options;
346
}
347

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

    
360
    num_options = count_option_parameters(dest);
361
    num_dest_options = num_options;
362

    
363
    num_options += count_option_parameters(list);
364

    
365
    dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
366
    dest[num_dest_options].name = NULL;
367

    
368
    while (list && list->name) {
369
        if (get_option_parameter(dest, list->name) == NULL) {
370
            dest[num_dest_options++] = *list;
371
            dest[num_dest_options].name = NULL;
372
        }
373
        list++;
374
    }
375

    
376
    return dest;
377
}
378

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

    
406
    if (list == NULL) {
407
        return NULL;
408
    }
409

    
410
    if (dest == NULL) {
411
        dest = allocated = append_option_parameters(NULL, list);
412
    }
413

    
414
    for (i = 0; dest[i].name; i++) {
415
        dest[i].assigned = false;
416
    }
417

    
418
    while (*param) {
419

    
420
        // Find parameter name and value in the string
421
        param_delim = strchr(param, ',');
422
        value_delim = strchr(param, '=');
423

    
424
        if (value_delim && (value_delim < param_delim || !param_delim)) {
425
            next_delim = '=';
426
        } else {
427
            next_delim = ',';
428
            value_delim = NULL;
429
        }
430

    
431
        param = get_opt_name(name, sizeof(name), param, next_delim);
432
        if (value_delim) {
433
            param = get_opt_value(value, sizeof(value), param + 1);
434
        }
435
        if (*param != '\0') {
436
            param++;
437
        }
438

    
439
        // Set the parameter
440
        if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
441
            goto fail;
442
        }
443
    }
444

    
445
    return dest;
446

    
447
fail:
448
    // Only free the list if it was newly allocated
449
    free_option_parameters(allocated);
450
    return NULL;
451
}
452

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

    
480
/*
481
 * Prints an overview of all available options
482
 */
483
void print_option_help(QEMUOptionParameter *list)
484
{
485
    printf("Supported options:\n");
486
    while (list && list->name) {
487
        printf("%-16s %s\n", list->name,
488
            list->help ? list->help : "No description available");
489
        list++;
490
    }
491
}
492

    
493
/* ------------------------------------------------------------------ */
494

    
495
static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
496
{
497
    QemuOpt *opt;
498

    
499
    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
500
        if (strcmp(opt->name, name) != 0)
501
            continue;
502
        return opt;
503
    }
504
    return NULL;
505
}
506

    
507
const char *qemu_opt_get(QemuOpts *opts, const char *name)
508
{
509
    QemuOpt *opt = qemu_opt_find(opts, name);
510
    return opt ? opt->str : NULL;
511
}
512

    
513
bool qemu_opt_has_help_opt(QemuOpts *opts)
514
{
515
    QemuOpt *opt;
516

    
517
    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
518
        if (is_help_option(opt->name)) {
519
            return true;
520
        }
521
    }
522
    return false;
523
}
524

    
525
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
526
{
527
    QemuOpt *opt = qemu_opt_find(opts, name);
528

    
529
    if (opt == NULL)
530
        return defval;
531
    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
532
    return opt->value.boolean;
533
}
534

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

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

    
545
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t 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_SIZE);
552
    return opt->value.uint;
553
}
554

    
555
static void qemu_opt_parse(QemuOpt *opt, Error **errp)
556
{
557
    if (opt->desc == NULL)
558
        return;
559

    
560
    switch (opt->desc->type) {
561
    case QEMU_OPT_STRING:
562
        /* nothing */
563
        return;
564
    case QEMU_OPT_BOOL:
565
        parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
566
        break;
567
    case QEMU_OPT_NUMBER:
568
        parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
569
        break;
570
    case QEMU_OPT_SIZE:
571
        parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
572
        break;
573
    default:
574
        abort();
575
    }
576
}
577

    
578
static void qemu_opt_del(QemuOpt *opt)
579
{
580
    QTAILQ_REMOVE(&opt->opts->head, opt, next);
581
    g_free((/* !const */ char*)opt->name);
582
    g_free((/* !const */ char*)opt->str);
583
    g_free(opt);
584
}
585

    
586
static bool opts_accepts_any(const QemuOpts *opts)
587
{
588
    return opts->list->desc[0].name == NULL;
589
}
590

    
591
static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
592
                                            const char *name)
593
{
594
    int i;
595

    
596
    for (i = 0; desc[i].name != NULL; i++) {
597
        if (strcmp(desc[i].name, name) == 0) {
598
            return &desc[i];
599
        }
600
    }
601

    
602
    return NULL;
603
}
604

    
605
int qemu_opt_unset(QemuOpts *opts, const char *name)
606
{
607
    QemuOpt *opt = qemu_opt_find(opts, name);
608

    
609
    assert(opts_accepts_any(opts));
610

    
611
    if (opt == NULL) {
612
        return -1;
613
    } else {
614
        qemu_opt_del(opt);
615
        return 0;
616
    }
617
}
618

    
619
static void opt_set(QemuOpts *opts, const char *name, const char *value,
620
                    bool prepend, Error **errp)
621
{
622
    QemuOpt *opt;
623
    const QemuOptDesc *desc;
624
    Error *local_err = NULL;
625

    
626
    desc = find_desc_by_name(opts->list->desc, name);
627
    if (!desc && !opts_accepts_any(opts)) {
628
        error_set(errp, QERR_INVALID_PARAMETER, name);
629
        return;
630
    }
631

    
632
    opt = g_malloc0(sizeof(*opt));
633
    opt->name = g_strdup(name);
634
    opt->opts = opts;
635
    if (prepend) {
636
        QTAILQ_INSERT_HEAD(&opts->head, opt, next);
637
    } else {
638
        QTAILQ_INSERT_TAIL(&opts->head, opt, next);
639
    }
640
    opt->desc = desc;
641
    opt->str = g_strdup(value);
642
    qemu_opt_parse(opt, &local_err);
643
    if (error_is_set(&local_err)) {
644
        error_propagate(errp, local_err);
645
        qemu_opt_del(opt);
646
    }
647
}
648

    
649
int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
650
{
651
    Error *local_err = NULL;
652

    
653
    opt_set(opts, name, value, false, &local_err);
654
    if (error_is_set(&local_err)) {
655
        qerror_report_err(local_err);
656
        error_free(local_err);
657
        return -1;
658
    }
659

    
660
    return 0;
661
}
662

    
663
void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
664
                      Error **errp)
665
{
666
    opt_set(opts, name, value, false, errp);
667
}
668

    
669
int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
670
{
671
    QemuOpt *opt;
672
    const QemuOptDesc *desc = opts->list->desc;
673

    
674
    opt = g_malloc0(sizeof(*opt));
675
    opt->desc = find_desc_by_name(desc, name);
676
    if (!opt->desc && !opts_accepts_any(opts)) {
677
        qerror_report(QERR_INVALID_PARAMETER, name);
678
        g_free(opt);
679
        return -1;
680
    }
681

    
682
    opt->name = g_strdup(name);
683
    opt->opts = opts;
684
    opt->value.boolean = !!val;
685
    opt->str = g_strdup(val ? "on" : "off");
686
    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
687

    
688
    return 0;
689
}
690

    
691
int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
692
{
693
    QemuOpt *opt;
694
    const QemuOptDesc *desc = opts->list->desc;
695

    
696
    opt = g_malloc0(sizeof(*opt));
697
    opt->desc = find_desc_by_name(desc, name);
698
    if (!opt->desc && !opts_accepts_any(opts)) {
699
        qerror_report(QERR_INVALID_PARAMETER, name);
700
        g_free(opt);
701
        return -1;
702
    }
703

    
704
    opt->name = g_strdup(name);
705
    opt->opts = opts;
706
    opt->value.uint = val;
707
    opt->str = g_strdup_printf("%" PRId64, val);
708
    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
709

    
710
    return 0;
711
}
712

    
713
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
714
                     int abort_on_failure)
715
{
716
    QemuOpt *opt;
717
    int rc = 0;
718

    
719
    QTAILQ_FOREACH(opt, &opts->head, next) {
720
        rc = func(opt->name, opt->str, opaque);
721
        if (abort_on_failure  &&  rc != 0)
722
            break;
723
    }
724
    return rc;
725
}
726

    
727
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
728
{
729
    QemuOpts *opts;
730

    
731
    QTAILQ_FOREACH(opts, &list->head, next) {
732
        if (!opts->id && !id) {
733
            return opts;
734
        }
735
        if (opts->id && id && !strcmp(opts->id, id)) {
736
            return opts;
737
        }
738
    }
739
    return NULL;
740
}
741

    
742
static int id_wellformed(const char *id)
743
{
744
    int i;
745

    
746
    if (!qemu_isalpha(id[0])) {
747
        return 0;
748
    }
749
    for (i = 1; id[i]; i++) {
750
        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
751
            return 0;
752
        }
753
    }
754
    return 1;
755
}
756

    
757
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
758
                           int fail_if_exists, Error **errp)
759
{
760
    QemuOpts *opts = NULL;
761

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

    
794
QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
795
{
796
    QemuOpts *opts;
797
    Error *errp = NULL;
798
    opts = qemu_opts_create(list, NULL, 0, &errp);
799
    assert_no_error(errp);
800
    return opts;
801
}
802

    
803
void qemu_opts_reset(QemuOptsList *list)
804
{
805
    QemuOpts *opts, *next_opts;
806

    
807
    QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
808
        qemu_opts_del(opts);
809
    }
810
}
811

    
812
void qemu_opts_loc_restore(QemuOpts *opts)
813
{
814
    loc_restore(&opts->loc);
815
}
816

    
817
int qemu_opts_set(QemuOptsList *list, const char *id,
818
                  const char *name, const char *value)
819
{
820
    QemuOpts *opts;
821
    Error *local_err = NULL;
822

    
823
    opts = qemu_opts_create(list, id, 1, &local_err);
824
    if (error_is_set(&local_err)) {
825
        qerror_report_err(local_err);
826
        error_free(local_err);
827
        return -1;
828
    }
829
    return qemu_opt_set(opts, name, value);
830
}
831

    
832
const char *qemu_opts_id(QemuOpts *opts)
833
{
834
    return opts->id;
835
}
836

    
837
void qemu_opts_del(QemuOpts *opts)
838
{
839
    QemuOpt *opt;
840

    
841
    for (;;) {
842
        opt = QTAILQ_FIRST(&opts->head);
843
        if (opt == NULL)
844
            break;
845
        qemu_opt_del(opt);
846
    }
847
    QTAILQ_REMOVE(&opts->list->head, opts, next);
848
    g_free(opts->id);
849
    g_free(opts);
850
}
851

    
852
int qemu_opts_print(QemuOpts *opts, void *dummy)
853
{
854
    QemuOpt *opt;
855

    
856
    fprintf(stderr, "%s: %s:", opts->list->name,
857
            opts->id ? opts->id : "<noid>");
858
    QTAILQ_FOREACH(opt, &opts->head, next) {
859
        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
860
    }
861
    fprintf(stderr, "\n");
862
    return 0;
863
}
864

    
865
static int opts_do_parse(QemuOpts *opts, const char *params,
866
                         const char *firstname, bool prepend)
867
{
868
    char option[128], value[1024];
869
    const char *p,*pe,*pc;
870
    Error *local_err = NULL;
871

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

    
916
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
917
{
918
    return opts_do_parse(opts, params, firstname, false);
919
}
920

    
921
static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
922
                            int permit_abbrev, bool defaults)
923
{
924
    const char *firstname;
925
    char value[1024], *id = NULL;
926
    const char *p;
927
    QemuOpts *opts;
928
    Error *local_err = NULL;
929

    
930
    assert(!permit_abbrev || list->implied_opt_name);
931
    firstname = permit_abbrev ? list->implied_opt_name : NULL;
932

    
933
    if (strncmp(params, "id=", 3) == 0) {
934
        get_opt_value(value, sizeof(value), params+3);
935
        id = value;
936
    } else if ((p = strstr(params, ",id=")) != NULL) {
937
        get_opt_value(value, sizeof(value), p+4);
938
        id = value;
939
    }
940

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

    
958
    if (opts_do_parse(opts, params, firstname, defaults) != 0) {
959
        qemu_opts_del(opts);
960
        return NULL;
961
    }
962

    
963
    return opts;
964
}
965

    
966
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
967
                          int permit_abbrev)
968
{
969
    return opts_parse(list, params, permit_abbrev, false);
970
}
971

    
972
void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
973
                            int permit_abbrev)
974
{
975
    QemuOpts *opts;
976

    
977
    opts = opts_parse(list, params, permit_abbrev, true);
978
    assert(opts);
979
}
980

    
981
typedef struct OptsFromQDictState {
982
    QemuOpts *opts;
983
    Error **errp;
984
} OptsFromQDictState;
985

    
986
static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
987
{
988
    OptsFromQDictState *state = opaque;
989
    char buf[32];
990
    const char *value;
991
    int n;
992

    
993
    if (!strcmp(key, "id") || error_is_set(state->errp)) {
994
        return;
995
    }
996

    
997
    switch (qobject_type(obj)) {
998
    case QTYPE_QSTRING:
999
        value = qstring_get_str(qobject_to_qstring(obj));
1000
        break;
1001
    case QTYPE_QINT:
1002
        n = snprintf(buf, sizeof(buf), "%" PRId64,
1003
                     qint_get_int(qobject_to_qint(obj)));
1004
        assert(n < sizeof(buf));
1005
        value = buf;
1006
        break;
1007
    case QTYPE_QFLOAT:
1008
        n = snprintf(buf, sizeof(buf), "%.17g",
1009
                     qfloat_get_double(qobject_to_qfloat(obj)));
1010
        assert(n < sizeof(buf));
1011
        value = buf;
1012
        break;
1013
    case QTYPE_QBOOL:
1014
        pstrcpy(buf, sizeof(buf),
1015
                qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
1016
        value = buf;
1017
        break;
1018
    default:
1019
        return;
1020
    }
1021

    
1022
    qemu_opt_set_err(state->opts, key, value, state->errp);
1023
}
1024

    
1025
/*
1026
 * Create QemuOpts from a QDict.
1027
 * Use value of key "id" as ID if it exists and is a QString.
1028
 * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
1029
 * other types are silently ignored.
1030
 */
1031
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
1032
                               Error **errp)
1033
{
1034
    OptsFromQDictState state;
1035
    Error *local_err = NULL;
1036
    QemuOpts *opts;
1037

    
1038
    opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
1039
                            &local_err);
1040
    if (error_is_set(&local_err)) {
1041
        error_propagate(errp, local_err);
1042
        return NULL;
1043
    }
1044

    
1045
    assert(opts != NULL);
1046

    
1047
    state.errp = &local_err;
1048
    state.opts = opts;
1049
    qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
1050
    if (error_is_set(&local_err)) {
1051
        error_propagate(errp, local_err);
1052
        qemu_opts_del(opts);
1053
        return NULL;
1054
    }
1055

    
1056
    return opts;
1057
}
1058

    
1059
/*
1060
 * Adds all QDict entries to the QemuOpts that can be added and removes them
1061
 * from the QDict. When this function returns, the QDict contains only those
1062
 * entries that couldn't be added to the QemuOpts.
1063
 */
1064
void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
1065
{
1066
    const QDictEntry *entry, *next;
1067

    
1068
    entry = qdict_first(qdict);
1069

    
1070
    while (entry != NULL) {
1071
        Error *local_err = NULL;
1072
        OptsFromQDictState state = {
1073
            .errp = &local_err,
1074
            .opts = opts,
1075
        };
1076

    
1077
        next = qdict_next(qdict, entry);
1078

    
1079
        if (find_desc_by_name(opts->list->desc, entry->key)) {
1080
            qemu_opts_from_qdict_1(entry->key, entry->value, &state);
1081
            if (error_is_set(&local_err)) {
1082
                error_propagate(errp, local_err);
1083
                return;
1084
            } else {
1085
                qdict_del(qdict, entry->key);
1086
            }
1087
        }
1088

    
1089
        entry = next;
1090
    }
1091
}
1092

    
1093
/*
1094
 * Convert from QemuOpts to QDict.
1095
 * The QDict values are of type QString.
1096
 * TODO We'll want to use types appropriate for opt->desc->type, but
1097
 * this is enough for now.
1098
 */
1099
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
1100
{
1101
    QemuOpt *opt;
1102
    QObject *val;
1103

    
1104
    if (!qdict) {
1105
        qdict = qdict_new();
1106
    }
1107
    if (opts->id) {
1108
        qdict_put(qdict, "id", qstring_from_str(opts->id));
1109
    }
1110
    QTAILQ_FOREACH(opt, &opts->head, next) {
1111
        val = QOBJECT(qstring_from_str(opt->str));
1112
        qdict_put_obj(qdict, opt->name, val);
1113
    }
1114
    return qdict;
1115
}
1116

    
1117
/* Validate parsed opts against descriptions where no
1118
 * descriptions were provided in the QemuOptsList.
1119
 */
1120
void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
1121
{
1122
    QemuOpt *opt;
1123
    Error *local_err = NULL;
1124

    
1125
    assert(opts_accepts_any(opts));
1126

    
1127
    QTAILQ_FOREACH(opt, &opts->head, next) {
1128
        opt->desc = find_desc_by_name(desc, opt->name);
1129
        if (!opt->desc) {
1130
            error_set(errp, QERR_INVALID_PARAMETER, opt->name);
1131
            return;
1132
        }
1133

    
1134
        qemu_opt_parse(opt, &local_err);
1135
        if (error_is_set(&local_err)) {
1136
            error_propagate(errp, local_err);
1137
            return;
1138
        }
1139
    }
1140
}
1141

    
1142
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
1143
                      int abort_on_failure)
1144
{
1145
    Location loc;
1146
    QemuOpts *opts;
1147
    int rc = 0;
1148

    
1149
    loc_push_none(&loc);
1150
    QTAILQ_FOREACH(opts, &list->head, next) {
1151
        loc_restore(&opts->loc);
1152
        rc |= func(opts, opaque);
1153
        if (abort_on_failure  &&  rc != 0)
1154
            break;
1155
    }
1156
    loc_pop(&loc);
1157
    return rc;
1158
}