qemu-options: Factor out get_opt_name_value() helper

The next commits will put it to use.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200415074927.19897-3-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2020-04-15 09:49:20 +02:00
parent 32c2dcf5e8
commit 6129803b55

View File

@ -805,61 +805,71 @@ void qemu_opts_print(QemuOpts *opts, const char *separator)
} }
} }
static void opts_do_parse(QemuOpts *opts, const char *params, static const char *get_opt_name_value(const char *params,
const char *firstname, bool prepend, const char *firstname,
bool *invalidp, Error **errp) char **name, char **value)
{ {
char *option = NULL;
char *value = NULL;
const char *p, *pe, *pc; const char *p, *pe, *pc;
Error *local_err = NULL;
for (p = params; *p != '\0'; p++) { pe = strchr(params, '=');
pe = strchr(p, '='); pc = strchr(params, ',');
pc = strchr(p, ',');
if (!pe || (pc && pc < pe)) { if (!pe || (pc && pc < pe)) {
/* found "foo,more" */ /* found "foo,more" */
if (p == params && firstname) { if (firstname) {
/* implicitly named first option */ /* implicitly named first option */
option = g_strdup(firstname); *name = g_strdup(firstname);
p = get_opt_value(p, &value); p = get_opt_value(params, value);
} else { } else {
/* option without value, probably a flag */ /* option without value, must be a flag */
p = get_opt_name(p, &option, ','); p = get_opt_name(params, name, ',');
if (strncmp(option, "no", 2) == 0) { if (strncmp(*name, "no", 2) == 0) {
memmove(option, option+2, strlen(option+2)+1); memmove(*name, *name + 2, strlen(*name + 2) + 1);
value = g_strdup("off"); *value = g_strdup("off");
} else { } else {
value = g_strdup("on"); *value = g_strdup("on");
} }
} }
} else { } else {
/* found "foo=bar,more" */ /* found "foo=bar,more" */
p = get_opt_name(p, &option, '='); p = get_opt_name(params, name, '=');
assert(*p == '='); assert(*p == '=');
p++; p++;
p = get_opt_value(p, &value); p = get_opt_value(p, value);
}
if (strcmp(option, "id") != 0) {
/* store and parse */
opt_set(opts, option, value, prepend, invalidp, &local_err);
value = NULL;
if (local_err) {
error_propagate(errp, local_err);
goto cleanup;
}
}
if (*p != ',') {
break;
}
g_free(option);
g_free(value);
option = value = NULL;
} }
cleanup: assert(!*p || *p == ',');
if (*p == ',') {
p++;
}
return p;
}
static void opts_do_parse(QemuOpts *opts, const char *params,
const char *firstname, bool prepend,
bool *invalidp, Error **errp)
{
Error *local_err = NULL;
char *option, *value;
const char *p;
for (p = params; *p;) {
p = get_opt_name_value(p, firstname, &option, &value);
firstname = NULL;
if (!strcmp(option, "id")) {
g_free(option); g_free(option);
g_free(value); g_free(value);
continue;
}
opt_set(opts, option, value, prepend, invalidp, &local_err);
g_free(option);
if (local_err) {
error_propagate(errp, local_err);
return;
}
}
} }
/** /**