[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 02/25] qemu-option: move help handling to get_opt_name_value
From: |
Markus Armbruster |
Subject: |
Re: [PATCH 02/25] qemu-option: move help handling to get_opt_name_value |
Date: |
Tue, 19 Jan 2021 16:10:12 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) |
Paolo Bonzini <pbonzini@redhat.com> writes:
> 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")
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> util/qemu-option.c | 38 +++++++++++++++++++++++---------------
> 1 file changed, 23 insertions(+), 15 deletions(-)
>
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index 91f4120ce1..5f27d4369d 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -496,8 +496,7 @@ static QemuOpt *opt_create(QemuOpts *opts, const char
> *name, char *value,
> return opt;
> }
>
> -static bool opt_validate(QemuOpt *opt, bool *help_wanted,
> - Error **errp)
> +static bool opt_validate(QemuOpt *opt, Error **errp)
> {
> const QemuOptDesc *desc;
> 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);
> if (!desc && !opts_accepts_any(list)) {
> error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
> - if (help_wanted && is_help_option(opt->name)) {
> - *help_wanted = true;
> - }
> 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);
>
> - if (!opt_validate(opt, NULL, errp)) {
> + if (!opt_validate(opt, errp)) {
> qemu_opt_del(opt);
> 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,
> const char *firstname,
> + bool *help_wanted,
> char **name, char **value)
> {
> const char *p;
> size_t len;
> + bool is_help = false;
>
> len = strcspn(params, "=,");
> if (params[len] != '=') {
> @@ -780,6 +778,7 @@ static const char *get_opt_name_value(const char *params,
> *value = g_strdup("off");
> } else {
> *value = g_strdup("on");
> + is_help = is_help_option(*name);
> }
> }
> } else {
> @@ -791,6 +790,9 @@ static const char *get_opt_name_value(const char *params,
> }
>
> assert(!*p || *p == ',');
> + if (help_wanted && is_help) {
> + *help_wanted = true;
Note [1] for later: we only ever set *help_wanted to true.
> + }
> if (*p == ',') {
> p++;
> }
> @@ -806,7 +808,12 @@ static bool opts_do_parse(QemuOpts *opts, const char
> *params,
> QemuOpt *opt;
>
> 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;
>
> 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);
> g_free(option);
> - if (!opt_validate(opt, help_wanted, errp)) {
> + if (!opt_validate(opt, errp)) {
> qemu_opt_del(opt);
> return false;
> }
> @@ -832,7 +839,7 @@ static char *opts_parse_id(const char *params)
> char *name, *value;
>
> 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")) {
> g_free(name);
> return value;
> @@ -848,11 +855,10 @@ bool has_help_option(const char *params)
> {
> const char *p;
> char *name, *value;
> - bool ret;
> + bool ret = false;
This initializer is required due to [1].
>
> for (p = params; *p;) {
> - p = get_opt_name_value(p, NULL, &name, &value);
> - ret = is_help_option(name);
> + p = get_opt_name_value(p, NULL, &ret, &name, &value);
> g_free(name);
> g_free(value);
> if (ret) {
Works, but I'd prefer get_opt_name_value() to always set *help_wanted
when help_wanted isn't null. Up to you.
> @@ -937,11 +943,13 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list,
> const char *params,
> QemuOpts *opts;
> bool help_wanted = false;
>
> - opts = opts_parse(list, params, permit_abbrev, false, &help_wanted,
> &err);
> - if (err) {
> + opts = opts_parse(list, params, permit_abbrev, false,
> + opts_accepts_any(list) ? NULL : &help_wanted,
> + &err);
> + if (!opts) {
> + assert(!!err + !!help_wanted == 1);
Either err or help_wanted. This is logical inequality. I'd write it as
assert(!err != !help_wanted);
or maybe as
assert(!err ^ !help_wanted);
But your artistic license applies.
> if (help_wanted) {
> qemu_opts_print_help(list, true);
> - error_free(err);
> } else {
> error_report_err(err);
> }
Before the patch, we recognize help requests only if they aren't
captured by a (foolishly named) parameter name.
Afterwards, we recognize only sane help requests regardless of
parameters. In other words:
- various crazy ways to request help are not recognized anymore:
- "help=..."
- "nohelp" (sugar for "help=off")
- "?=..."
- "no?" (sugar for "?=off")
- "help" is recognized as help request even if there is a (foolishly
named) parameter "help". No such parameters exist.
Let's add the last item to the commit message, too.
Preferably with the commit message amended:
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[PATCH 02/25] qemu-option: move help handling to get_opt_name_value, Paolo Bonzini, 2021/01/18
- Re: [PATCH 02/25] qemu-option: move help handling to get_opt_name_value,
Markus Armbruster <=
[PATCH 04/25] keyval: accept escaped commas in implied option, Paolo Bonzini, 2021/01/18
[PATCH 05/25] keyval: simplify keyval_parse_one, Paolo Bonzini, 2021/01/18
[PATCH 03/25] qemu-option: warn for short-form boolean options, Paolo Bonzini, 2021/01/18