};
struct QemuOpts {
- const char *id;
+ char *id;
QemuOptsList *list;
- QTAILQ_HEAD(, QemuOpt) head;
+ QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
QTAILQ_ENTRY(QemuOpts) next;
};
{
QemuOpt *opt;
- QTAILQ_FOREACH(opt, &opts->head, next) {
+ QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
if (strcmp(opt->name, name) != 0)
continue;
return opt;
int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
{
QemuOpt *opt;
+ QemuOptDesc *desc = opts->list->desc;
+ int i;
- opt = qemu_opt_find(opts, name);
- if (!opt) {
- QemuOptDesc *desc = opts->list->desc;
- int i;
-
- for (i = 0; desc[i].name != NULL; i++) {
- if (strcmp(desc[i].name, name) == 0) {
- break;
- }
- }
- if (desc[i].name == NULL) {
- if (i == 0) {
- /* empty list -> allow any */;
- } else {
- fprintf(stderr, "option \"%s\" is not valid for %s\n",
- name, opts->list->name);
- return -1;
- }
+ for (i = 0; desc[i].name != NULL; i++) {
+ if (strcmp(desc[i].name, name) == 0) {
+ break;
}
- opt = qemu_mallocz(sizeof(*opt));
- opt->name = qemu_strdup(name);
- opt->opts = opts;
- QTAILQ_INSERT_TAIL(&opts->head, opt, next);
- if (desc[i].name != NULL) {
- opt->desc = desc+i;
+ }
+ if (desc[i].name == NULL) {
+ if (i == 0) {
+ /* empty list -> allow any */;
+ } else {
+ fprintf(stderr, "option \"%s\" is not valid for %s\n",
+ name, opts->list->name);
+ return -1;
}
}
- qemu_free((/* !const */ char*)opt->str);
- opt->str = NULL;
+
+ opt = qemu_mallocz(sizeof(*opt));
+ opt->name = qemu_strdup(name);
+ opt->opts = opts;
+ QTAILQ_INSERT_TAIL(&opts->head, opt, next);
+ if (desc[i].name != NULL) {
+ opt->desc = desc+i;
+ }
if (value) {
opt->str = qemu_strdup(value);
}
opts = qemu_opts_create(list, id, 1);
if (opts == NULL) {
- fprintf(stderr, "id \"%s\" not found for \"%s\"\n",
- id, list->name);
return -1;
}
return qemu_opt_set(opts, name, value);
qemu_opt_del(opt);
}
QTAILQ_REMOVE(&opts->list->head, opts, next);
+ qemu_free(opts->id);
qemu_free(opts);
}
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
{
- char option[128], value[128];
+ char option[128], value[1024];
const char *p,*pe,*pc;
- p = params;
- for(;;) {
+ for (p = params; *p != '\0'; p++) {
pe = strchr(p, '=');
pc = strchr(p, ',');
if (!pe || (pc && pc < pe)) {
if (*p != ',') {
break;
}
- p++;
}
return 0;
}
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
{
- char value[128], *id = NULL;
+ char value[1024], *id = NULL;
const char *p;
QemuOpts *opts;
return opts;
}
+/* Validate parsed opts against descriptions where no
+ * descriptions were provided in the QemuOptsList.
+ */
+int qemu_opts_validate(QemuOpts *opts, QemuOptDesc *desc)
+{
+ QemuOpt *opt;
+
+ assert(opts->list->desc[0].name == NULL);
+
+ QTAILQ_FOREACH(opt, &opts->head, next) {
+ int i;
+
+ for (i = 0; desc[i].name != NULL; i++) {
+ if (strcmp(desc[i].name, opt->name) == 0) {
+ break;
+ }
+ }
+ if (desc[i].name == NULL) {
+ fprintf(stderr, "option \"%s\" is not valid for %s\n",
+ opt->name, opts->list->name);
+ return -1;
+ }
+
+ opt->desc = &desc[i];
+
+ if (qemu_opt_parse(opt) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
int abort_on_failure)
{