Statistics
| Branch: | Revision:

root / qemu-option.c @ 076d2471

History | View | Annotate | Download (20.6 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-option.h"
31

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

    
47
    q = buf;
48
    while (*p != '\0' && *p != delim) {
49
        if (q && (q - buf) < buf_size - 1)
50
            *q++ = *p;
51
        p++;
52
    }
53
    if (q)
54
        *q = '\0';
55

    
56
    return p;
57
}
58

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

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

    
85
    return p;
86
}
87

    
88
int get_next_param_value(char *buf, int buf_size,
89
                         const char *tag, const char **pstr)
90
{
91
    const char *p;
92
    char option[128];
93

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

    
116
int get_param_value(char *buf, int buf_size,
117
                    const char *tag, const char *str)
118
{
119
    return get_next_param_value(buf, buf_size, tag, &str);
120
}
121

    
122
int check_params(char *buf, int buf_size,
123
                 const char * const *params, const char *str)
124
{
125
    const char *p;
126
    int i;
127

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

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

    
165
    return NULL;
166
}
167

    
168
static int parse_option_bool(const char *name, const char *value, int *ret)
169
{
170
    if (value != NULL) {
171
        if (!strcmp(value, "on")) {
172
            *ret = 1;
173
        } else if (!strcmp(value, "off")) {
174
            *ret = 0;
175
        } else {
176
            fprintf(stderr, "Option '%s': Use 'on' or 'off'\n", name);
177
            return -1;
178
        }
179
    } else {
180
        *ret = 1;
181
    }
182
    return 0;
183
}
184

    
185
static int parse_option_number(const char *name, const char *value, uint64_t *ret)
186
{
187
    char *postfix;
188
    uint64_t number;
189

    
190
    if (value != NULL) {
191
        number = strtoull(value, &postfix, 0);
192
        if (*postfix != '\0') {
193
            fprintf(stderr, "Option '%s' needs a number as parameter\n", name);
194
            return -1;
195
        }
196
        *ret = number;
197
    } else {
198
        fprintf(stderr, "Option '%s' needs a parameter\n", name);
199
        return -1;
200
    }
201
    return 0;
202
}
203

    
204
static int parse_option_size(const char *name, const char *value, uint64_t *ret)
205
{
206
    char *postfix;
207
    double sizef;
208

    
209
    if (value != NULL) {
210
        sizef = strtod(value, &postfix);
211
        switch (*postfix) {
212
        case 'T':
213
            sizef *= 1024;
214
        case 'G':
215
            sizef *= 1024;
216
        case 'M':
217
            sizef *= 1024;
218
        case 'K':
219
        case 'k':
220
            sizef *= 1024;
221
        case 'b':
222
        case '\0':
223
            *ret = (uint64_t) sizef;
224
            break;
225
        default:
226
            fprintf(stderr, "Option '%s' needs size as parameter\n", name);
227
            fprintf(stderr, "You may use k, M, G or T suffixes for "
228
                    "kilobytes, megabytes, gigabytes and terabytes.\n");
229
            return -1;
230
        }
231
    } else {
232
        fprintf(stderr, "Option '%s' needs a parameter\n", name);
233
        return -1;
234
    }
235
    return 0;
236
}
237

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

    
260
    // Find a matching parameter
261
    list = get_option_parameter(list, name);
262
    if (list == NULL) {
263
        fprintf(stderr, "Unknown option '%s'\n", name);
264
        return -1;
265
    }
266

    
267
    // Process parameter
268
    switch (list->type) {
269
    case OPT_FLAG:
270
        if (parse_option_bool(name, value, &flag) == -1)
271
            return -1;
272
        list->value.n = flag;
273
        break;
274

    
275
    case OPT_STRING:
276
        if (value != NULL) {
277
            list->value.s = qemu_strdup(value);
278
        } else {
279
            fprintf(stderr, "Option '%s' needs a parameter\n", name);
280
            return -1;
281
        }
282
        break;
283

    
284
    case OPT_SIZE:
285
        if (parse_option_size(name, value, &list->value.n) == -1)
286
            return -1;
287
        break;
288

    
289
    default:
290
        fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
291
        return -1;
292
    }
293

    
294
    return 0;
295
}
296

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

    
313
    // Process parameter
314
    switch (list->type) {
315
    case OPT_FLAG:
316
    case OPT_NUMBER:
317
    case OPT_SIZE:
318
        list->value.n = value;
319
        break;
320

    
321
    default:
322
        return -1;
323
    }
324

    
325
    return 0;
326
}
327

    
328
/*
329
 * Frees a option list. If it contains strings, the strings are freed as well.
330
 */
331
void free_option_parameters(QEMUOptionParameter *list)
332
{
333
    QEMUOptionParameter *cur = list;
334

    
335
    while (cur && cur->name) {
336
        if (cur->type == OPT_STRING) {
337
            qemu_free(cur->value.s);
338
        }
339
        cur++;
340
    }
341

    
342
    qemu_free(list);
343
}
344

    
345
/*
346
 * Parses a parameter string (param) into an option list (dest).
347
 *
348
 * list is the templace is. If dest is NULL, a new copy of list is created for
349
 * it. If list is NULL, this function fails.
350
 *
351
 * A parameter string consists of one or more parameters, separated by commas.
352
 * Each parameter consists of its name and possibly of a value. In the latter
353
 * case, the value is delimited by an = character. To specify a value which
354
 * contains commas, double each comma so it won't be recognized as the end of
355
 * the parameter.
356
 *
357
 * For more details of the parsing see above.
358
 *
359
 * Returns a pointer to the first element of dest (or the newly allocated copy)
360
 * or NULL in error cases
361
 */
362
QEMUOptionParameter *parse_option_parameters(const char *param,
363
    QEMUOptionParameter *list, QEMUOptionParameter *dest)
364
{
365
    QEMUOptionParameter *cur;
366
    QEMUOptionParameter *allocated = NULL;
367
    char name[256];
368
    char value[256];
369
    char *param_delim, *value_delim;
370
    char next_delim;
371
    size_t num_options;
372

    
373
    if (list == NULL) {
374
        return NULL;
375
    }
376

    
377
    if (dest == NULL) {
378
        // Count valid options
379
        num_options = 0;
380
        cur = list;
381
        while (cur->name) {
382
            num_options++;
383
            cur++;
384
        }
385

    
386
        // Create a copy of the option list to fill in values
387
        dest = qemu_mallocz((num_options + 1) * sizeof(QEMUOptionParameter));
388
        allocated = dest;
389
        memcpy(dest, list, (num_options + 1) * sizeof(QEMUOptionParameter));
390
    }
391

    
392
    while (*param) {
393

    
394
        // Find parameter name and value in the string
395
        param_delim = strchr(param, ',');
396
        value_delim = strchr(param, '=');
397

    
398
        if (value_delim && (value_delim < param_delim || !param_delim)) {
399
            next_delim = '=';
400
        } else {
401
            next_delim = ',';
402
            value_delim = NULL;
403
        }
404

    
405
        param = get_opt_name(name, sizeof(name), param, next_delim);
406
        if (value_delim) {
407
            param = get_opt_value(value, sizeof(value), param + 1);
408
        }
409
        if (*param != '\0') {
410
            param++;
411
        }
412

    
413
        // Set the parameter
414
        if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
415
            goto fail;
416
        }
417
    }
418

    
419
    return dest;
420

    
421
fail:
422
    // Only free the list if it was newly allocated
423
    free_option_parameters(allocated);
424
    return NULL;
425
}
426

    
427
/*
428
 * Prints all options of a list that have a value to stdout
429
 */
430
void print_option_parameters(QEMUOptionParameter *list)
431
{
432
    while (list && list->name) {
433
        switch (list->type) {
434
            case OPT_STRING:
435
                 if (list->value.s != NULL) {
436
                     printf("%s='%s' ", list->name, list->value.s);
437
                 }
438
                break;
439
            case OPT_FLAG:
440
                printf("%s=%s ", list->name, list->value.n ? "on" : "off");
441
                break;
442
            case OPT_SIZE:
443
            case OPT_NUMBER:
444
                printf("%s=%" PRId64 " ", list->name, list->value.n);
445
                break;
446
            default:
447
                printf("%s=(unkown type) ", list->name);
448
                break;
449
        }
450
        list++;
451
    }
452
}
453

    
454
/*
455
 * Prints an overview of all available options
456
 */
457
void print_option_help(QEMUOptionParameter *list)
458
{
459
    printf("Supported options:\n");
460
    while (list && list->name) {
461
        printf("%-16s %s\n", list->name,
462
            list->help ? list->help : "No description available");
463
        list++;
464
    }
465
}
466

    
467
/* ------------------------------------------------------------------ */
468

    
469
struct QemuOpt {
470
    const char   *name;
471
    const char   *str;
472

    
473
    QemuOptDesc  *desc;
474
    union {
475
        int      boolean;
476
        uint64_t uint;
477
    } value;
478

    
479
    QemuOpts     *opts;
480
    QTAILQ_ENTRY(QemuOpt) next;
481
};
482

    
483
struct QemuOpts {
484
    char *id;
485
    QemuOptsList *list;
486
    QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
487
    QTAILQ_ENTRY(QemuOpts) next;
488
};
489

    
490
static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
491
{
492
    QemuOpt *opt;
493

    
494
    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
495
        if (strcmp(opt->name, name) != 0)
496
            continue;
497
        return opt;
498
    }
499
    return NULL;
500
}
501

    
502
const char *qemu_opt_get(QemuOpts *opts, const char *name)
503
{
504
    QemuOpt *opt = qemu_opt_find(opts, name);
505
    return opt ? opt->str : NULL;
506
}
507

    
508
int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval)
509
{
510
    QemuOpt *opt = qemu_opt_find(opts, name);
511

    
512
    if (opt == NULL)
513
        return defval;
514
    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
515
    return opt->value.boolean;
516
}
517

    
518
uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
519
{
520
    QemuOpt *opt = qemu_opt_find(opts, name);
521

    
522
    if (opt == NULL)
523
        return defval;
524
    assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
525
    return opt->value.uint;
526
}
527

    
528
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
529
{
530
    QemuOpt *opt = qemu_opt_find(opts, name);
531

    
532
    if (opt == NULL)
533
        return defval;
534
    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
535
    return opt->value.uint;
536
}
537

    
538
static int qemu_opt_parse(QemuOpt *opt)
539
{
540
    if (opt->desc == NULL)
541
        return 0;
542
    switch (opt->desc->type) {
543
    case QEMU_OPT_STRING:
544
        /* nothing */
545
        return 0;
546
    case QEMU_OPT_BOOL:
547
        return parse_option_bool(opt->name, opt->str, &opt->value.boolean);
548
    case QEMU_OPT_NUMBER:
549
        return parse_option_number(opt->name, opt->str, &opt->value.uint);
550
    case QEMU_OPT_SIZE:
551
        return parse_option_size(opt->name, opt->str, &opt->value.uint);
552
    default:
553
        abort();
554
    }
555
}
556

    
557
static void qemu_opt_del(QemuOpt *opt)
558
{
559
    QTAILQ_REMOVE(&opt->opts->head, opt, next);
560
    qemu_free((/* !const */ char*)opt->name);
561
    qemu_free((/* !const */ char*)opt->str);
562
    qemu_free(opt);
563
}
564

    
565
int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
566
{
567
    QemuOpt *opt;
568
    QemuOptDesc *desc = opts->list->desc;
569
    int i;
570

    
571
    for (i = 0; desc[i].name != NULL; i++) {
572
        if (strcmp(desc[i].name, name) == 0) {
573
            break;
574
        }
575
    }
576
    if (desc[i].name == NULL) {
577
        if (i == 0) {
578
            /* empty list -> allow any */;
579
        } else {
580
            fprintf(stderr, "option \"%s\" is not valid for %s\n",
581
                    name, opts->list->name);
582
            return -1;
583
        }
584
    }
585

    
586
    opt = qemu_mallocz(sizeof(*opt));
587
    opt->name = qemu_strdup(name);
588
    opt->opts = opts;
589
    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
590
    if (desc[i].name != NULL) {
591
        opt->desc = desc+i;
592
    }
593
    if (value) {
594
        opt->str = qemu_strdup(value);
595
    }
596
    if (qemu_opt_parse(opt) < 0) {
597
        fprintf(stderr, "Failed to parse \"%s\" for \"%s.%s\"\n", opt->str,
598
                opts->list->name, opt->name);
599
        qemu_opt_del(opt);
600
        return -1;
601
    }
602
    return 0;
603
}
604

    
605
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
606
                     int abort_on_failure)
607
{
608
    QemuOpt *opt;
609
    int rc = 0;
610

    
611
    QTAILQ_FOREACH(opt, &opts->head, next) {
612
        rc = func(opt->name, opt->str, opaque);
613
        if (abort_on_failure  &&  rc != 0)
614
            break;
615
    }
616
    return rc;
617
}
618

    
619
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
620
{
621
    QemuOpts *opts;
622

    
623
    QTAILQ_FOREACH(opts, &list->head, next) {
624
        if (!opts->id) {
625
            continue;
626
        }
627
        if (strcmp(opts->id, id) != 0) {
628
            continue;
629
        }
630
        return opts;
631
    }
632
    return NULL;
633
}
634

    
635
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists)
636
{
637
    QemuOpts *opts = NULL;
638

    
639
    if (id) {
640
        opts = qemu_opts_find(list, id);
641
        if (opts != NULL) {
642
            if (fail_if_exists) {
643
                fprintf(stderr, "tried to create id \"%s\" twice for \"%s\"\n",
644
                        id, list->name);
645
                return NULL;
646
            } else {
647
                return opts;
648
            }
649
        }
650
    }
651
    opts = qemu_mallocz(sizeof(*opts));
652
    if (id) {
653
        opts->id = qemu_strdup(id);
654
    }
655
    opts->list = list;
656
    QTAILQ_INIT(&opts->head);
657
    QTAILQ_INSERT_TAIL(&list->head, opts, next);
658
    return opts;
659
}
660

    
661
int qemu_opts_set(QemuOptsList *list, const char *id,
662
                  const char *name, const char *value)
663
{
664
    QemuOpts *opts;
665

    
666
    opts = qemu_opts_create(list, id, 1);
667
    if (opts == NULL) {
668
        return -1;
669
    }
670
    return qemu_opt_set(opts, name, value);
671
}
672

    
673
const char *qemu_opts_id(QemuOpts *opts)
674
{
675
    return opts->id;
676
}
677

    
678
void qemu_opts_del(QemuOpts *opts)
679
{
680
    QemuOpt *opt;
681

    
682
    for (;;) {
683
        opt = QTAILQ_FIRST(&opts->head);
684
        if (opt == NULL)
685
            break;
686
        qemu_opt_del(opt);
687
    }
688
    QTAILQ_REMOVE(&opts->list->head, opts, next);
689
    qemu_free(opts->id);
690
    qemu_free(opts);
691
}
692

    
693
int qemu_opts_print(QemuOpts *opts, void *dummy)
694
{
695
    QemuOpt *opt;
696

    
697
    fprintf(stderr, "%s: %s:", opts->list->name,
698
            opts->id ? opts->id : "<noid>");
699
    QTAILQ_FOREACH(opt, &opts->head, next) {
700
        fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
701
    }
702
    fprintf(stderr, "\n");
703
    return 0;
704
}
705

    
706
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
707
{
708
    char option[128], value[1024];
709
    const char *p,*pe,*pc;
710

    
711
    for (p = params; *p != '\0'; p++) {
712
        pe = strchr(p, '=');
713
        pc = strchr(p, ',');
714
        if (!pe || (pc && pc < pe)) {
715
            /* found "foo,more" */
716
            if (p == params && firstname) {
717
                /* implicitly named first option */
718
                pstrcpy(option, sizeof(option), firstname);
719
                p = get_opt_value(value, sizeof(value), p);
720
            } else {
721
                /* option without value, probably a flag */
722
                p = get_opt_name(option, sizeof(option), p, ',');
723
                if (strncmp(option, "no", 2) == 0) {
724
                    memmove(option, option+2, strlen(option+2)+1);
725
                    pstrcpy(value, sizeof(value), "off");
726
                } else {
727
                    pstrcpy(value, sizeof(value), "on");
728
                }
729
            }
730
        } else {
731
            /* found "foo=bar,more" */
732
            p = get_opt_name(option, sizeof(option), p, '=');
733
            if (*p != '=') {
734
                break;
735
            }
736
            p++;
737
            p = get_opt_value(value, sizeof(value), p);
738
        }
739
        if (strcmp(option, "id") != 0) {
740
            /* store and parse */
741
            if (qemu_opt_set(opts, option, value) == -1) {
742
                return -1;
743
            }
744
        }
745
        if (*p != ',') {
746
            break;
747
        }
748
    }
749
    return 0;
750
}
751

    
752
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
753
{
754
    char value[1024], *id = NULL;
755
    const char *p;
756
    QemuOpts *opts;
757

    
758
    if (strncmp(params, "id=", 3) == 0) {
759
        get_opt_value(value, sizeof(value), params+3);
760
        id = qemu_strdup(value);
761
    } else if ((p = strstr(params, ",id=")) != NULL) {
762
        get_opt_value(value, sizeof(value), p+4);
763
        id = qemu_strdup(value);
764
    }
765
    opts = qemu_opts_create(list, id, 1);
766
    if (opts == NULL)
767
        return NULL;
768

    
769
    if (qemu_opts_do_parse(opts, params, firstname) != 0) {
770
        qemu_opts_del(opts);
771
        return NULL;
772
    }
773

    
774
    return opts;
775
}
776

    
777
/* Validate parsed opts against descriptions where no
778
 * descriptions were provided in the QemuOptsList.
779
 */
780
int qemu_opts_validate(QemuOpts *opts, QemuOptDesc *desc)
781
{
782
    QemuOpt *opt;
783

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

    
786
    QTAILQ_FOREACH(opt, &opts->head, next) {
787
        int i;
788

    
789
        for (i = 0; desc[i].name != NULL; i++) {
790
            if (strcmp(desc[i].name, opt->name) == 0) {
791
                break;
792
            }
793
        }
794
        if (desc[i].name == NULL) {
795
            fprintf(stderr, "option \"%s\" is not valid for %s\n",
796
                    opt->name, opts->list->name);
797
            return -1;
798
        }
799

    
800
        opt->desc = &desc[i];
801

    
802
        if (qemu_opt_parse(opt) < 0) {
803
            return -1;
804
        }
805
    }
806

    
807
    return 0;
808
}
809

    
810
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
811
                      int abort_on_failure)
812
{
813
    QemuOpts *opts;
814
    int rc = 0;
815

    
816
    QTAILQ_FOREACH(opts, &list->head, next) {
817
        rc = func(opts, opaque);
818
        if (abort_on_failure  &&  rc != 0)
819
            break;
820
    }
821
    return rc;
822
}