[PATCH v2 15/25] virCommandToStringFull: Improve linebreaking behaviour

Peter Krempa pkrempa at redhat.com
Fri Apr 9 12:50:17 UTC 2021


Put multiple values for an option if followed by another option as used
in certain iptables arguments.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/util/vircommand.c        | 29 +++++++++++++++++++++++------
 tests/commanddata/test26.log |  2 +-
 tests/commandtest.c          |  5 ++++-
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index 0eda42418f..bece296b1e 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -2076,9 +2076,9 @@ virCommandToStringFull(virCommandPtr cmd,
 {
     size_t i;
     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
-    bool prevopt = false;
     const char *command = cmd->args[0];
     g_autofree char *basename = NULL;
+    bool had_option = false;

     /* Cannot assume virCommandRun will be called; so report the error
      * now.  If virCommandRun is called, it will report the same error. */
@@ -2111,16 +2111,33 @@ virCommandToStringFull(virCommandPtr cmd,
     virBufferEscapeShell(&buf, command);
     for (i = 1; i < cmd->nargs; i++) {
         virBufferAddChar(&buf, ' ');
+
         if (linebreaks) {
-            /* Line break if this is a --arg or if
-             * the previous arg was a positional option
+            /* we don't want a linebreak only if
+             * - the previous argument is an option (starts with '-')
+             * - there was already an option and another option follows
              */
-            if (cmd->args[i][0] == '-' ||
-                !prevopt)
+            bool linebreak = true;
+
+            if (cmd->args[i][0] != '-') {
+                if (had_option) {
+                    size_t j;
+                    /* we know that arg[i - 1] is valid and arg[i] is not an option */
+                    for (j = i - 1; j < cmd->nargs; j++) {
+                        if (cmd->args[j][0] == '-') {
+                            linebreak = false;
+                            break;
+                        }
+                    }
+                }
+            } else {
+                had_option = true;
+            }
+
+            if (linebreak)
                 virBufferAddLit(&buf, "\\\n");
         }
         virBufferEscapeShell(&buf, cmd->args[i]);
-        prevopt = (cmd->args[i][0] == '-');
     }

     return virBufferContentAndReset(&buf);
diff --git a/tests/commanddata/test26.log b/tests/commanddata/test26.log
index db0d424875..72dd1af5a8 100644
--- a/tests/commanddata/test26.log
+++ b/tests/commanddata/test26.log
@@ -1 +1 @@
-A=B C=D  E true --foo bar --oooh -f --wizz eek eek -w -z -l --mmm flash bang wallop
+A=B C=D  E true --foo bar --oooh -f --wizz eek eek --m-m-m-multiarg arg arg2 -w -z -l --mmm flash bang wallop
diff --git a/tests/commandtest.c b/tests/commandtest.c
index aaf391935c..81e9914860 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -997,6 +997,7 @@ static int test26(const void *unused G_GNUC_UNUSED)
         "--oooh \\\n"
         "-f \\\n"
         "--wizz 'eek eek' \\\n"
+        "--m-m-m-multiarg arg arg2 \\\n"
         "-w \\\n"
         "-z \\\n"
         "-l \\\n"
@@ -1009,7 +1010,9 @@ static int test26(const void *unused G_GNUC_UNUSED)
     virCommandAddEnvPair(cmd, "A", "B");
     virCommandAddEnvPair(cmd, "C", "D  E");
     virCommandAddArgList(cmd, "--foo", "bar", "--oooh", "-f",
-                         "--wizz", "eek eek", "-w", "-z", "-l",
+                         "--wizz", "eek eek",
+                         "--m-m-m-multiarg", "arg", "arg2",
+                         "-w", "-z", "-l",
                          "--mmm", "flash", "bang", "wallop",
                          NULL);

-- 
2.30.2




More information about the libvir-list mailing list