Right now, help options are parsed normally and then checked specially in opt_validate---but only if coming from qemu_opts_parse or qemu_opts_parse_noisily, not if coming from qemu_opt_set.
Instead, move the check from opt_validate to the common workhorses of qemu_opts_parse and qemu_opts_parse_noisily, opts_do_parse and get_opt_name_value. This will come in handy in a subsequent 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". Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- util/qemu-option.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/util/qemu-option.c b/util/qemu-option.c index b9f93a7f8b..5824b7afe2 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -520,17 +520,13 @@ 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; desc = find_desc_by_name(opt->opts->list->desc, opt->name); if (!desc && !opts_accepts_any(opt->opts)) { error_setg(errp, QERR_INVALID_PARAMETER, opt->name); - if (help_wanted && is_help_option(opt->name)) { - *help_wanted = true; - } return false; } @@ -547,7 +543,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; } @@ -783,14 +779,17 @@ 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, *pe, *pc; - - pe = strchr(params, '='); - pc = strchr(params, ','); + const char *p; + size_t len; - if (!pe || (pc && pc < pe)) { + len = strcspn(params, "=,"); + if (params[len] != '=') { + if (help_wanted && starts_with_help_option(params) == len) { + *help_wanted = true; + } /* found "foo,more" */ if (firstname) { /* implicitly named first option */ @@ -830,7 +829,10 @@ 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) { + return false; + } firstname = NULL; if (!strcmp(option, "id")) { @@ -841,7 +843,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; } @@ -856,7 +858,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; @@ -872,11 +874,10 @@ bool has_help_option(const char *params) { const char *p; char *name, *value; - bool ret; + bool ret = false; 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) { -- 2.26.2