qapi, qemu-options: make all parsing visitors parse boolean options the same

OptsVisitor, StringInputVisitor and the keyval visitor have
three different ideas of how a human could write the value of
a boolean option.  Pay homage to the backwards-compatibility
gods and make the new common helper accept all four sets (on/off,
true/false, y/n and yes/no), but remove case-insensitivity.

Since OptsVisitor is supposed to match qemu-options, adjust
it as well.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20201103161339.447118-1-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2020-11-03 11:13:39 -05:00
parent e27bd49876
commit 372bcb2585
6 changed files with 30 additions and 52 deletions

View File

@ -19,6 +19,8 @@ typedef struct QEnumLookup {
const char *qapi_enum_lookup(const QEnumLookup *lookup, int val); const char *qapi_enum_lookup(const QEnumLookup *lookup, int val);
int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
int def, Error **errp); int def, Error **errp);
bool qapi_bool_parse(const char *name, const char *value, bool *obj,
Error **errp);
int parse_qapi_name(const char *name, bool complete); int parse_qapi_name(const char *name, bool complete);

View File

@ -368,7 +368,6 @@ opts_type_str(Visitor *v, const char *name, char **obj, Error **errp)
} }
/* mimics qemu-option.c::parse_option_bool() */
static bool static bool
opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
{ {
@ -379,19 +378,8 @@ opts_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
if (!opt) { if (!opt) {
return false; return false;
} }
if (opt->str) { if (opt->str) {
if (strcmp(opt->str, "on") == 0 || if (!qapi_bool_parse(opt->name, opt->str, obj, errp)) {
strcmp(opt->str, "yes") == 0 ||
strcmp(opt->str, "y") == 0) {
*obj = true;
} else if (strcmp(opt->str, "off") == 0 ||
strcmp(opt->str, "no") == 0 ||
strcmp(opt->str, "n") == 0) {
*obj = false;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"on|yes|y|off|no|n");
return false; return false;
} }
} else { } else {

View File

@ -13,6 +13,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/ctype.h" #include "qemu/ctype.h"
#include "qapi/qmp/qerror.h"
const char *qapi_enum_lookup(const QEnumLookup *lookup, int val) const char *qapi_enum_lookup(const QEnumLookup *lookup, int val)
{ {
@ -40,6 +41,28 @@ int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
return def; return def;
} }
bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **errp)
{
if (g_str_equal(value, "on") ||
g_str_equal(value, "yes") ||
g_str_equal(value, "true") ||
g_str_equal(value, "y")) {
*obj = true;
return true;
}
if (g_str_equal(value, "off") ||
g_str_equal(value, "no") ||
g_str_equal(value, "false") ||
g_str_equal(value, "n")) {
*obj = false;
return true;
}
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
"'on' or 'off'");
return false;
}
/* /*
* Parse a valid QAPI name from @str. * Parse a valid QAPI name from @str.
* A valid name consists of letters, digits, hyphen and underscore. * A valid name consists of letters, digits, hyphen and underscore.

View File

@ -512,11 +512,7 @@ static bool qobject_input_type_bool_keyval(Visitor *v, const char *name,
return false; return false;
} }
if (!strcmp(str, "on")) { if (!qapi_bool_parse(name, str, obj, NULL)) {
*obj = true;
} else if (!strcmp(str, "off")) {
*obj = false;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
full_name(qiv, name), "'on' or 'off'"); full_name(qiv, name), "'on' or 'off'");
return false; return false;

View File

@ -332,22 +332,7 @@ static bool parse_type_bool(Visitor *v, const char *name, bool *obj,
StringInputVisitor *siv = to_siv(v); StringInputVisitor *siv = to_siv(v);
assert(siv->lm == LM_NONE); assert(siv->lm == LM_NONE);
if (!strcasecmp(siv->string, "on") || return qapi_bool_parse(name ? name : "null", siv->string, obj, errp);
!strcasecmp(siv->string, "yes") ||
!strcasecmp(siv->string, "true")) {
*obj = true;
return true;
}
if (!strcasecmp(siv->string, "off") ||
!strcasecmp(siv->string, "no") ||
!strcasecmp(siv->string, "false")) {
*obj = false;
return true;
}
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"boolean");
return false;
} }
static bool parse_type_str(Visitor *v, const char *name, char **obj, static bool parse_type_str(Visitor *v, const char *name, char **obj,

View File

@ -96,21 +96,6 @@ const char *get_opt_value(const char *p, char **value)
return offset; return offset;
} }
static bool parse_option_bool(const char *name, const char *value, bool *ret,
Error **errp)
{
if (!strcmp(value, "on")) {
*ret = 1;
} else if (!strcmp(value, "off")) {
*ret = 0;
} else {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name, "'on' or 'off'");
return false;
}
return true;
}
static bool parse_option_number(const char *name, const char *value, static bool parse_option_number(const char *name, const char *value,
uint64_t *ret, Error **errp) uint64_t *ret, Error **errp)
{ {
@ -363,7 +348,7 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, const char *name,
if (opt == NULL) { if (opt == NULL) {
def_val = find_default_by_name(opts, name); def_val = find_default_by_name(opts, name);
if (def_val) { if (def_val) {
parse_option_bool(name, def_val, &ret, &error_abort); qapi_bool_parse(name, def_val, &ret, &error_abort);
} }
return ret; return ret;
} }
@ -471,8 +456,7 @@ static bool qemu_opt_parse(QemuOpt *opt, Error **errp)
/* nothing */ /* nothing */
return true; return true;
case QEMU_OPT_BOOL: case QEMU_OPT_BOOL:
return parse_option_bool(opt->name, opt->str, &opt->value.boolean, return qapi_bool_parse(opt->name, opt->str, &opt->value.boolean, errp);
errp);
case QEMU_OPT_NUMBER: case QEMU_OPT_NUMBER:
return parse_option_number(opt->name, opt->str, &opt->value.uint, return parse_option_number(opt->name, opt->str, &opt->value.uint,
errp); errp);