qemu-option: Replace opt_set() by cleaner opt_validate()

opt_set() frees its argument @value on failure.  Slightly unclean;
functions ideally do nothing on failure.

To tidy this up, move opt_create() from opt_set() into its callers,
along with the cleanup.  Rename opt_set() to opt_validate(), noting
its similarity to qemu_opts_validate().  Drop redundant parameter
@opts; use opt->opts instead.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-13-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2020-07-07 18:05:40 +02:00
parent 81a8a0726a
commit 64af7a8bad

View File

@ -516,36 +516,39 @@ static QemuOpt *opt_create(QemuOpts *opts, const char *name, char *value,
return opt; return opt;
} }
static void opt_set(QemuOpts *opts, const char *name, char *value, static bool opt_validate(QemuOpt *opt, bool *help_wanted,
bool prepend, bool *help_wanted, Error **errp) Error **errp)
{ {
QemuOpt *opt;
const QemuOptDesc *desc; const QemuOptDesc *desc;
Error *local_err = NULL; Error *local_err = NULL;
desc = find_desc_by_name(opts->list->desc, name); desc = find_desc_by_name(opt->opts->list->desc, opt->name);
if (!desc && !opts_accepts_any(opts)) { if (!desc && !opts_accepts_any(opt->opts)) {
g_free(value); error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
error_setg(errp, QERR_INVALID_PARAMETER, name); if (help_wanted && is_help_option(opt->name)) {
if (help_wanted && is_help_option(name)) {
*help_wanted = true; *help_wanted = true;
} }
return; return false;
} }
opt = opt_create(opts, name, value, prepend);
opt->desc = desc; opt->desc = desc;
qemu_opt_parse(opt, &local_err); qemu_opt_parse(opt, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
qemu_opt_del(opt); return false;
} }
return true;
} }
void qemu_opt_set(QemuOpts *opts, const char *name, const char *value, void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
Error **errp) Error **errp)
{ {
opt_set(opts, name, g_strdup(value), false, NULL, errp); QemuOpt *opt = opt_create(opts, name, g_strdup(value), false);
if (!opt_validate(opt, NULL, errp)) {
qemu_opt_del(opt);
}
} }
void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val, void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
@ -817,9 +820,9 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
const char *firstname, bool prepend, const char *firstname, bool prepend,
bool *help_wanted, Error **errp) bool *help_wanted, Error **errp)
{ {
Error *local_err = NULL;
char *option, *value; char *option, *value;
const char *p; const char *p;
QemuOpt *opt;
for (p = params; *p;) { for (p = params; *p;) {
p = get_opt_name_value(p, firstname, &option, &value); p = get_opt_name_value(p, firstname, &option, &value);
@ -831,10 +834,10 @@ static void opts_do_parse(QemuOpts *opts, const char *params,
continue; continue;
} }
opt_set(opts, option, value, prepend, help_wanted, &local_err); opt = opt_create(opts, option, value, prepend);
g_free(option); g_free(option);
if (local_err) { if (!opt_validate(opt, help_wanted, errp)) {
error_propagate(errp, local_err); qemu_opt_del(opt);
return; return;
} }
} }