Paolo Bonzini <pbonz...@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 <pbonz...@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 <arm...@redhat.com>