From b1e8b606813b1097cdb3a0d9e9f04c629d7bcf29 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 09:41:48 +0200
Subject: [PATCH 01/18] virQEMUBuildCommandLineJSON: Allow skipping certain
 keys

Allow reusing this for formatting of netdev_add arguments into -netdev.
We need to be able to skip the 'type' property as it's used without the
prefix by our generator.

Add infrastructure which allows skipping property with a specific name.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 src/util/virqemu.c          | 30 +++++++++++++++++++++---------
 src/util/virqemu.h          | 10 +++++++---
 tests/qemucommandutiltest.c |  2 +-
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 78a9e0480b..0e6fa412bc 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -36,6 +36,7 @@ VIR_LOG_INIT("util.qemu");
 struct virQEMUCommandLineJSONIteratorData {
     const char *prefix;
     virBufferPtr buf;
+    const char *skipKey;
     virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc;
 };
 
@@ -44,6 +45,7 @@ static int
 virQEMUBuildCommandLineJSONRecurse(const char *key,
                                    virJSONValuePtr value,
                                    virBufferPtr buf,
+                                   const char *skipKey,
                                    virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
                                    bool nested);
 
@@ -52,7 +54,8 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
 int
 virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
                                        virJSONValuePtr array,
-                                       virBufferPtr buf)
+                                       virBufferPtr buf,
+                                       const char *skipKey G_GNUC_UNUSED)
 {
     ssize_t pos = -1;
     ssize_t end;
@@ -80,7 +83,8 @@ virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
 int
 virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
                                          virJSONValuePtr array,
-                                         virBufferPtr buf)
+                                         virBufferPtr buf,
+                                         const char *skipKey)
 {
     virJSONValuePtr member;
     size_t i;
@@ -91,7 +95,7 @@ virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
 
         prefix = g_strdup_printf("%s.%zu", key, i);
 
-        if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf,
+        if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, skipKey,
                                                virQEMUBuildCommandLineJSONArrayNumbered,
                                                true) < 0)
             return 0;
@@ -109,15 +113,20 @@ virQEMUBuildCommandLineJSONIterate(const char *key,
 {
     struct virQEMUCommandLineJSONIteratorData *data = opaque;
 
+    if (STREQ_NULLABLE(key, data->skipKey))
+        return 0;
+
     if (data->prefix) {
         g_autofree char *tmpkey = NULL;
 
         tmpkey = g_strdup_printf("%s.%s", data->prefix, key);
 
         return virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf,
+                                                  data->skipKey,
                                                   data->arrayFunc, false);
     } else {
         return virQEMUBuildCommandLineJSONRecurse(key, value, data->buf,
+                                                  data->skipKey,
                                                   data->arrayFunc, false);
     }
 }
@@ -127,10 +136,11 @@ static int
 virQEMUBuildCommandLineJSONRecurse(const char *key,
                                    virJSONValuePtr value,
                                    virBufferPtr buf,
+                                   const char *skipKey,
                                    virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
                                    bool nested)
 {
-    struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc };
+    struct virQEMUCommandLineJSONIteratorData data = { key, buf, skipKey, arrayFunc };
     virJSONType type = virJSONValueGetType(value);
     virJSONValuePtr elem;
     bool tmp;
@@ -170,14 +180,14 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
             return -1;
         }
 
-        if (!arrayFunc || arrayFunc(key, value, buf) < 0) {
+        if (!arrayFunc || arrayFunc(key, value, buf, skipKey) < 0) {
             /* fallback, treat the array as a non-bitmap, adding the key
              * for each member */
             for (i = 0; i < virJSONValueArraySize(value); i++) {
                 elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
 
                 /* recurse to avoid duplicating code */
-                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf,
+                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, skipKey,
                                                        arrayFunc, true) < 0)
                     return -1;
             }
@@ -205,6 +215,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
  * virQEMUBuildCommandLineJSON:
  * @value: json object containing the value
  * @buf: otuput buffer
+ * @skipKey: name of key that will be handled separately by caller
  * @arrayFunc: array formatter function to allow for different syntax
  *
  * Formats JSON value object into command line parameters suitable for use with
@@ -215,9 +226,10 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
 int
 virQEMUBuildCommandLineJSON(virJSONValuePtr value,
                             virBufferPtr buf,
+                            const char *skipKey,
                             virQEMUBuildCommandLineJSONArrayFormatFunc array)
 {
-    if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, array, false) < 0)
+    if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, skipKey, array, false) < 0)
         return -1;
 
     virBufferTrim(buf, ",");
@@ -243,7 +255,7 @@ virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
 
     if (props) {
         virBufferAddLit(buf, ",");
-        if (virQEMUBuildCommandLineJSON(props, buf,
+        if (virQEMUBuildCommandLineJSON(props, buf, NULL,
                                 virQEMUBuildCommandLineJSONArrayBitmap) < 0)
             return -1;
     }
@@ -270,7 +282,7 @@ virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef)
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *ret = NULL;
 
-    if (virQEMUBuildCommandLineJSON(srcdef, &buf,
+    if (virQEMUBuildCommandLineJSON(srcdef, &buf, NULL,
                                     virQEMUBuildCommandLineJSONArrayNumbered) < 0)
         goto cleanup;
 
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 227325e80e..9d3db7c2a2 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -29,16 +29,20 @@
 
 typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
                                                           virJSONValuePtr array,
-                                                          virBufferPtr buf);
+                                                          virBufferPtr buf,
+                                                          const char *skipKey);
 int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
                                            virJSONValuePtr array,
-                                           virBufferPtr buf);
+                                           virBufferPtr buf,
+                                           const char *skipKey);
 int virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
                                              virJSONValuePtr array,
-                                             virBufferPtr buf);
+                                             virBufferPtr buf,
+                                             const char *skipKey);
 
 int virQEMUBuildCommandLineJSON(virJSONValuePtr value,
                                 virBufferPtr buf,
+                                const char *skipKey,
                                 virQEMUBuildCommandLineJSONArrayFormatFunc array);
 
 int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
index c5b3e7b735..923776e642 100644
--- a/tests/qemucommandutiltest.c
+++ b/tests/qemucommandutiltest.c
@@ -47,7 +47,7 @@ testQemuCommandBuildFromJSON(const void *opaque)
         return -1;
     }
 
-    if (virQEMUBuildCommandLineJSON(val, &buf, data->arrayfunc) < 0) {
+    if (virQEMUBuildCommandLineJSON(val, &buf, NULL, data->arrayfunc) < 0) {
         fprintf(stderr,
                 "\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
                 data->props);
-- 
2.23.0.windows.1

