mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-02 22:41:07 +00:00
qemu-option: move help handling to get_opt_name_value
Right now, help options are parsed normally and then checked specially in opt_validate, but only if coming from qemu_opts_parse_noisily. has_help_option does the check on its own. opt_validate() has two callers: qemu_opt_set(), which passes null and is therefore unaffected, and opts_do_parse(), which is affected. opts_do_parse() is called by qemu_opts_do_parse(), which passes null and is therefore unaffected, and opts_parse(). opts_parse() is called by qemu_opts_parse() and qemu_opts_set_defaults(), which pass null and are therefore unaffected, and qemu_opts_parse_noisily(). Move the check from opt_validate to the parsing workhorse of QemuOpts, get_opt_name_value. This will come in handy in the next patch, which will raise a warning for "-object memory-backend-ram,share" ("flag" option with no =on/=off part) but not for "-object memory-backend-ram,help". As a result: - opts_parse and opts_do_parse do not return an error anymore when help is requested; qemu_opts_parse_noisily does not have to work around that anymore. - various crazy ways to request help are not recognized anymore: - "help=..." - "nohelp" (sugar for "help=off") - "?=..." - "no?" (sugar for "?=off") - "help" would be recognized as help request even if there is a (foolishly named) parameter "help". No such parameters exist, though. Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
63758d1073
commit
afd736252f
1 changed files with 23 additions and 15 deletions
|
@ -496,8 +496,7 @@ static QemuOpt *opt_create(QemuOpts *opts, const char *name, char *value,
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool opt_validate(QemuOpt *opt, bool *help_wanted,
|
static bool opt_validate(QemuOpt *opt, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
const QemuOptDesc *desc;
|
const QemuOptDesc *desc;
|
||||||
const QemuOptsList *list = opt->opts->list;
|
const QemuOptsList *list = opt->opts->list;
|
||||||
|
@ -505,9 +504,6 @@ static bool opt_validate(QemuOpt *opt, bool *help_wanted,
|
||||||
desc = find_desc_by_name(list->desc, opt->name);
|
desc = find_desc_by_name(list->desc, opt->name);
|
||||||
if (!desc && !opts_accepts_any(list)) {
|
if (!desc && !opts_accepts_any(list)) {
|
||||||
error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
|
error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
|
||||||
if (help_wanted && is_help_option(opt->name)) {
|
|
||||||
*help_wanted = true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,7 +520,7 @@ bool qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
|
||||||
{
|
{
|
||||||
QemuOpt *opt = opt_create(opts, name, g_strdup(value), false);
|
QemuOpt *opt = opt_create(opts, name, g_strdup(value), false);
|
||||||
|
|
||||||
if (!opt_validate(opt, NULL, errp)) {
|
if (!opt_validate(opt, errp)) {
|
||||||
qemu_opt_del(opt);
|
qemu_opt_del(opt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -760,10 +756,12 @@ void qemu_opts_print(QemuOpts *opts, const char *separator)
|
||||||
|
|
||||||
static const char *get_opt_name_value(const char *params,
|
static const char *get_opt_name_value(const char *params,
|
||||||
const char *firstname,
|
const char *firstname,
|
||||||
|
bool *help_wanted,
|
||||||
char **name, char **value)
|
char **name, char **value)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
bool is_help = false;
|
||||||
|
|
||||||
len = strcspn(params, "=,");
|
len = strcspn(params, "=,");
|
||||||
if (params[len] != '=') {
|
if (params[len] != '=') {
|
||||||
|
@ -780,6 +778,7 @@ static const char *get_opt_name_value(const char *params,
|
||||||
*value = g_strdup("off");
|
*value = g_strdup("off");
|
||||||
} else {
|
} else {
|
||||||
*value = g_strdup("on");
|
*value = g_strdup("on");
|
||||||
|
is_help = is_help_option(*name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -791,6 +790,9 @@ static const char *get_opt_name_value(const char *params,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!*p || *p == ',');
|
assert(!*p || *p == ',');
|
||||||
|
if (help_wanted && is_help) {
|
||||||
|
*help_wanted = true;
|
||||||
|
}
|
||||||
if (*p == ',') {
|
if (*p == ',') {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
@ -806,7 +808,12 @@ static bool opts_do_parse(QemuOpts *opts, const char *params,
|
||||||
QemuOpt *opt;
|
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, help_wanted, &option, &value);
|
||||||
|
if (help_wanted && *help_wanted) {
|
||||||
|
g_free(option);
|
||||||
|
g_free(value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
firstname = NULL;
|
firstname = NULL;
|
||||||
|
|
||||||
if (!strcmp(option, "id")) {
|
if (!strcmp(option, "id")) {
|
||||||
|
@ -817,7 +824,7 @@ static bool opts_do_parse(QemuOpts *opts, const char *params,
|
||||||
|
|
||||||
opt = opt_create(opts, option, value, prepend);
|
opt = opt_create(opts, option, value, prepend);
|
||||||
g_free(option);
|
g_free(option);
|
||||||
if (!opt_validate(opt, help_wanted, errp)) {
|
if (!opt_validate(opt, errp)) {
|
||||||
qemu_opt_del(opt);
|
qemu_opt_del(opt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +839,7 @@ static char *opts_parse_id(const char *params)
|
||||||
char *name, *value;
|
char *name, *value;
|
||||||
|
|
||||||
for (p = params; *p;) {
|
for (p = params; *p;) {
|
||||||
p = get_opt_name_value(p, NULL, &name, &value);
|
p = get_opt_name_value(p, NULL, NULL, &name, &value);
|
||||||
if (!strcmp(name, "id")) {
|
if (!strcmp(name, "id")) {
|
||||||
g_free(name);
|
g_free(name);
|
||||||
return value;
|
return value;
|
||||||
|
@ -848,11 +855,10 @@ bool has_help_option(const char *params)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
char *name, *value;
|
char *name, *value;
|
||||||
bool ret;
|
bool ret = false;
|
||||||
|
|
||||||
for (p = params; *p;) {
|
for (p = params; *p;) {
|
||||||
p = get_opt_name_value(p, NULL, &name, &value);
|
p = get_opt_name_value(p, NULL, &ret, &name, &value);
|
||||||
ret = is_help_option(name);
|
|
||||||
g_free(name);
|
g_free(name);
|
||||||
g_free(value);
|
g_free(value);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -937,11 +943,13 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
bool help_wanted = false;
|
bool help_wanted = false;
|
||||||
|
|
||||||
opts = opts_parse(list, params, permit_abbrev, false, &help_wanted, &err);
|
opts = opts_parse(list, params, permit_abbrev, false,
|
||||||
if (err) {
|
opts_accepts_any(list) ? NULL : &help_wanted,
|
||||||
|
&err);
|
||||||
|
if (!opts) {
|
||||||
|
assert(!!err + !!help_wanted == 1);
|
||||||
if (help_wanted) {
|
if (help_wanted) {
|
||||||
qemu_opts_print_help(list, true);
|
qemu_opts_print_help(list, true);
|
||||||
error_free(err);
|
|
||||||
} else {
|
} else {
|
||||||
error_report_err(err);
|
error_report_err(err);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue