From: Markus Armbruster <armbru@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: kwolf@redhat.com, imammedo@redhat.com, qemu-devel@nongnu.org
Subject: Re: [PATCH 02/25] qemu-option: move help handling to get_opt_name_value
Date: Tue, 19 Jan 2021 16:10:12 +0100 [thread overview]
Message-ID: <87y2gpvu7f.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <20210118163113.780171-3-pbonzini@redhat.com> (Paolo Bonzini's message of "Mon, 18 Jan 2021 11:30:50 -0500")
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>
next prev parent reply other threads:[~2021-01-19 15:12 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-18 16:30 [PATCH 00/25] qemu-option, keyval, vl: switch -object/-M/-accel to keyval parsing Paolo Bonzini
2021-01-18 16:30 ` [PATCH 01/25] qemu-option: clean up id vs. list->merge_lists Paolo Bonzini
2021-01-19 12:33 ` Kevin Wolf
2021-01-19 13:58 ` Markus Armbruster
2021-01-19 14:20 ` Paolo Bonzini
2021-01-20 8:03 ` Markus Armbruster
2021-01-20 12:37 ` Paolo Bonzini
2021-01-20 12:50 ` Markus Armbruster
2021-01-18 16:30 ` [PATCH 02/25] qemu-option: move help handling to get_opt_name_value Paolo Bonzini
2021-01-19 15:10 ` Markus Armbruster [this message]
2021-01-18 16:30 ` [PATCH 03/25] qemu-option: warn for short-form boolean options Paolo Bonzini
2021-01-19 15:56 ` Markus Armbruster
2021-01-19 17:04 ` Paolo Bonzini
2021-01-20 8:42 ` Markus Armbruster
2021-01-20 12:40 ` Paolo Bonzini
2021-01-20 12:59 ` Markus Armbruster
2021-01-20 14:05 ` Paolo Bonzini
2021-01-18 16:30 ` [PATCH 04/25] keyval: accept escaped commas in implied option Paolo Bonzini
2021-01-21 12:58 ` Markus Armbruster
2021-01-22 8:39 ` Markus Armbruster
2021-01-18 16:30 ` [PATCH 05/25] keyval: simplify keyval_parse_one Paolo Bonzini
2021-01-22 13:48 ` Markus Armbruster
2021-01-22 15:00 ` Paolo Bonzini
2021-01-22 15:44 ` Markus Armbruster
2021-01-18 16:30 ` [PATCH 06/25] tests: convert check-qom-proplist to keyval Paolo Bonzini
2021-01-22 14:14 ` Markus Armbruster
2021-01-22 14:38 ` Paolo Bonzini
2021-01-22 14:48 ` Paolo Bonzini
2021-01-18 16:30 ` [PATCH 07/25] keyval: introduce keyval_parse_into Paolo Bonzini
2021-01-22 14:22 ` Markus Armbruster
2021-01-22 14:30 ` Paolo Bonzini
2021-01-18 16:30 ` [PATCH 08/25] hmp: replace "O" parser with keyval Paolo Bonzini
2021-01-25 9:00 ` Markus Armbruster
2021-02-26 11:25 ` Paolo Bonzini
2021-03-01 10:14 ` Markus Armbruster
2021-03-01 10:23 ` Paolo Bonzini
2021-03-01 13:35 ` Markus Armbruster
2021-03-01 10:43 ` Markus Armbruster
2021-03-01 11:54 ` Paolo Bonzini
2021-01-18 16:30 ` [PATCH 09/25] qom: use qemu_printf to print help for user-creatable objects Paolo Bonzini
2021-01-25 12:47 ` Markus Armbruster
2021-01-18 16:30 ` [PATCH 10/25] hmp: special case help options for object_add Paolo Bonzini
2021-01-25 12:48 ` Markus Armbruster
2021-01-25 12:49 ` Paolo Bonzini
2021-01-25 14:02 ` Markus Armbruster
2021-01-18 16:30 ` [PATCH 11/25] remove -writeconfig Paolo Bonzini
2021-01-25 12:53 ` Markus Armbruster
2021-01-25 14:01 ` Paolo Bonzini
2021-01-25 14:12 ` Daniel P. Berrangé
2021-01-18 16:31 ` [PATCH 12/25] qemu-config: add error propagation to qemu_config_parse Paolo Bonzini
2021-01-25 13:54 ` Markus Armbruster
2021-01-18 16:31 ` [PATCH 13/25] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict Paolo Bonzini
2021-01-18 16:31 ` [PATCH 14/25] qemu-config: parse configuration files to a QDict Paolo Bonzini
2021-01-18 16:31 ` [PATCH 15/25] vl: plumb keyval-based options into -set and -readconfig Paolo Bonzini
2021-01-25 11:48 ` Markus Armbruster
2021-01-25 13:59 ` Paolo Bonzini
2021-01-18 16:31 ` [PATCH 16/25] qom: do not modify QDict argument in user_creatable_add_dict Paolo Bonzini
2021-01-18 16:31 ` [PATCH 17/25] qemu-io: use keyval for -object parsing Paolo Bonzini
2021-01-18 16:31 ` [PATCH 18/25] qemu-nbd: " Paolo Bonzini
2021-01-18 16:31 ` [PATCH 19/25] qemu-img: " Paolo Bonzini
2021-01-18 16:31 ` [PATCH 20/25] qemu: " Paolo Bonzini
2021-01-18 16:31 ` [PATCH 21/25] storage-daemon: do not register the "object" group with QemuOpts Paolo Bonzini
2021-01-18 16:31 ` [PATCH 22/25] qom: export more functions for use with non-UserCreatable objects Paolo Bonzini
2021-01-18 16:31 ` [PATCH 23/25] vl: switch -M parsing to keyval Paolo Bonzini
2021-01-18 16:31 ` [PATCH 24/25] qemu-option: remove now-dead code Paolo Bonzini
2021-01-18 16:31 ` [PATCH 25/25] vl: switch -accel parsing to keyval Paolo Bonzini
2021-01-18 17:18 ` [PATCH 00/25] qemu-option, keyval, vl: switch -object/-M/-accel to keyval parsing no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y2gpvu7f.fsf@dusky.pond.sub.org \
--to=armbru@redhat.com \
--cc=imammedo@redhat.com \
--cc=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.