diff mbox series

[for-5.2,2/4] qemu-option: move help handling to get_opt_name_value

Message ID 20201103151452.416784-3-pbonzini@redhat.com (mailing list archive)
State New, archived
Headers show
Series deprecate short-form boolean options | expand

Commit Message

Paolo Bonzini Nov. 3, 2020, 3:14 p.m. UTC
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 <pbonzini@redhat.com>
---
 util/qemu-option.c | 35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)

Comments

Markus Armbruster Nov. 4, 2020, 12:21 p.m. UTC | #1
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 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 <pbonzini@redhat.com>

I'm afraid this fails my smoke test:

    $ o=`sed -n '/HAS_ARG,/s/DEF("\([^"]*\)".*/\1/p' qemu-options.hx`
    $ for i in $o; do echo "= $i"; upstream-qemu -$i help -version; done 2>&1 | egrep -v 'QEMU emulator|Copyright'

Many output differences.  False positives due to help printing lists in
random order.  Arbitrarily picked true positive:

    $ upstream-qemu -msg help
    msg options:
      guest-name=<bool (on/off)> - Prepends guest name for error messages but only if -name guest is set otherwise option is ignored

      timestamp=<bool (on/off)>
    $ echo $?
    1

regresses to silent failure.
Paolo Bonzini Nov. 4, 2020, 12:49 p.m. UTC | #2
On 04/11/20 13:21, Markus Armbruster wrote:
> 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 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 <pbonzini@redhat.com>
> 
> I'm afraid this fails my smoke test:
> 
>      $ o=`sed -n '/HAS_ARG,/s/DEF("\([^"]*\)".*/\1/p' qemu-options.hx`
>      $ for i in $o; do echo "= $i"; upstream-qemu -$i help -version; done 2>&1 | egrep -v 'QEMU emulator|Copyright'
> 
> Many output differences.  False positives due to help printing lists in
> random order.  Arbitrarily picked true positive:
> 
>      $ upstream-qemu -msg help
>      msg options:
>        guest-name=<bool (on/off)> - Prepends guest name for error messages but only if -name guest is set otherwise option is ignored
> 
>        timestamp=<bool (on/off)>
>      $ echo $?
>      1
> 
> regresses to silent failure.

Hmm, indeed. :/  Fortunately the fix is simple:

diff --git a/util/qemu-option.c b/util/qemu-option.c
index fcd1119a5d..5a3c287611 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -947,10 +947,10 @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList 
*list, const char *params,
      bool help_wanted = false;

      opts = opts_parse(list, params, permit_abbrev, false, 
&help_wanted, &err);
-    if (err) {
+    if (!opts) {
+        assert(!!err + !!help_wanted == 1);
          if (help_wanted) {
              qemu_opts_print_help(list, true);
-            error_free(err);
          } else {
              error_report_err(err);
          }


I've queued 1 and 3 since they were reviewed already and are fixes for 
tests.  I'll run these two through the whole CI and repost.

Paolo
diff mbox series

Patch

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) {