This patch adds option to specify that a json qemu command argument is
optional without the need to use if's or ternary operators to pass the
list. Additionally all the modifier characters are documented to avoid
user confusion.
---
 src/qemu/qemu_monitor_json.c | 122 +++++++++++++++++++++++++++++--------------
 1 file changed, 84 insertions(+), 38 deletions(-)

diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index f8ab975..04249c5 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -451,7 +451,28 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char 
*cmdname, ...)
             goto error;
         }

-        /* Keys look like   s:name  the first letter is a type code */
+        /* Keys look like   s:name  the first letter is a type code:
+         * Explanation of type codes:
+         * s: string value, must be non-null
+         * S: string value, signed, omitted if null
+         *
+         * i: signed integer value
+         * z: signed integer value, omitted if zero
+         *
+         * I: signed long integer value
+         * Z: integer value, signed, omitted if zero
+         *
+         * u: unsigned integer value
+         * p: unsigned integer value, omitted if zero
+         *
+         * U: unsigned long integer value (see below for quirks)
+         * P: unsigned long integer value, omitted if zero,
+         *
+         * d: double precision floating point number
+         * b: boolean value
+         * n: json null value
+         * a: json array
+         */
         type = key[0];
         key += 2;

@@ -461,9 +482,13 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char 
*cmdname, ...)

         /* This doesn't support maps, but no command uses those.  */
         switch (type) {
+        case 'S':
         case 's': {
             char *val = va_arg(args, char *);
             if (!val) {
+                if (type == 'S')
+                    continue;
+
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("argument key '%s' must not have null value"),
                                key);
@@ -471,18 +496,38 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char 
*cmdname, ...)
             }
             ret = virJSONValueObjectAppendString(jargs, key, val);
         }   break;
+
+        case 'z':
         case 'i': {
             int val = va_arg(args, int);
+
+            if (!val && type == 'z')
+                continue;
+
             ret = virJSONValueObjectAppendNumberInt(jargs, key, val);
         }   break;
+
+        case 'p':
         case 'u': {
             unsigned int val = va_arg(args, unsigned int);
+
+            if (!val && type == 'p')
+                continue;
+
             ret = virJSONValueObjectAppendNumberUint(jargs, key, val);
         }   break;
+
+        case 'Z':
         case 'I': {
             long long val = va_arg(args, long long);
+
+            if (!val && type == 'Z')
+                continue;
+
             ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
         }   break;
+
+        case 'P':
         case 'U': {
             /* qemu silently truncates numbers larger than LLONG_MAX,
              * so passing the full range of unsigned 64 bit integers
@@ -490,23 +535,32 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char 
*cmdname, ...)
              * instead.
              */
             long long val = va_arg(args, long long);
+
+            if (!val && type == 'P')
+                continue;
+
             ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
         }   break;
+
         case 'd': {
             double val = va_arg(args, double);
             ret = virJSONValueObjectAppendNumberDouble(jargs, key, val);
         }   break;
+
         case 'b': {
             int val = va_arg(args, int);
             ret = virJSONValueObjectAppendBoolean(jargs, key, val);
         }   break;
+
         case 'n': {
             ret = virJSONValueObjectAppendNull(jargs, key);
         }   break;
+
         case 'a': {
             virJSONValuePtr val = va_arg(args, virJSONValuePtr);
             ret = virJSONValueObjectAppend(jargs, key, val);
         }   break;
+
         default:
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("unsupported data type '%c' for arg '%s'"), type, 
key - 2);
@@ -2193,19 +2247,14 @@ int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon,
 {
     int ret;
     virJSONValuePtr cmd;
-    if (format)
-        cmd = qemuMonitorJSONMakeCommand("change",
-                                         "s:device", dev_name,
-                                         "s:target", newmedia,
-                                         "s:arg", format,
-                                         NULL);
-    else
-        cmd = qemuMonitorJSONMakeCommand("change",
-                                         "s:device", dev_name,
-                                         "s:target", newmedia,
-                                         NULL);
-
     virJSONValuePtr reply = NULL;
+
+    cmd = qemuMonitorJSONMakeCommand("change",
+                                     "s:device", dev_name,
+                                     "s:target", newmedia,
+                                     "S:arg", format,
+                                     NULL);
+
     if (!cmd)
         return -1;

@@ -2771,8 +2820,7 @@ int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon,
                                                      "s:hostname", hostname,
                                                      "i:port", port,
                                                      "i:tls-port", tlsPort,
-                                                     (tlsSubject ? 
"s:cert-subject" : NULL),
-                                                     (tlsSubject ? tlsSubject 
: NULL),
+                                                     "S:cert-subject", 
tlsSubject,
                                                      NULL);
     virJSONValuePtr reply = NULL;
     if (!cmd)
@@ -2909,8 +2957,8 @@ qemuMonitorJSONAddFd(qemuMonitorPtr mon, int fdset, int 
fd, const char *name)
     int ret;
     virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("add-fd",
                                                      "i:fdset-id", fdset,
-                                                     name ? "s:opaque" : NULL,
-                                                     name, NULL);
+                                                     "S:opaque", name,
+                                                     NULL);
     virJSONValuePtr reply = NULL;
     if (!cmd)
         return -1;
@@ -3304,8 +3352,7 @@ qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, 
virJSONValuePtr actions,
                                         "s:device", device,
                                         "s:snapshot-file", file,
                                         "s:format", format,
-                                        reuse ? "s:mode" : NULL,
-                                        reuse ? "existing" : NULL,
+                                        "S:mode", reuse ? "existing" : NULL,
                                         NULL);
     if (!cmd)
         return -1;
@@ -3346,9 +3393,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                                      "s:target", file,
                                      "U:speed", speed,
                                      "s:sync", shallow ? "top" : "full",
-                                     "s:mode",
-                                     reuse ? "existing" : "absolute-paths",
-                                     format ? "s:format" : NULL, format,
+                                     "s:mode", reuse ? "existing" : 
"absolute-paths",
+                                     "S:format", format,
                                      NULL);
     if (!cmd)
         return -1;
@@ -3547,7 +3593,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,

     cmd = qemuMonitorJSONMakeCommand("send-key",
                                      "a:keys", keys,
-                                      holdtime ? "U:hold-time" : NULL, 
holdtime,
+                                      "P:hold-time", holdtime,
                                       NULL);
     if (!cmd)
         goto cleanup;
@@ -3726,31 +3772,31 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
     switch (mode) {
     case BLOCK_JOB_ABORT:
         cmd_name = modern ? "block-job-cancel" : "block_job_cancel";
-        cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device, NULL);
+        cmd = qemuMonitorJSONMakeCommand(cmd_name,
+                                         "s:device", device,
+                                         NULL);
         break;
+
     case BLOCK_JOB_INFO:
         cmd_name = "query-block-jobs";
         cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL);
         break;
+
     case BLOCK_JOB_SPEED:
         cmd_name = modern ? "block-job-set-speed" : "block_job_set_speed";
-        cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device,
-                                         modern ? "U:speed" : "U:value",
-                                         speed, NULL);
+        cmd = qemuMonitorJSONMakeCommand(cmd_name,
+                                         "s:device", device,
+                                         modern ? "U:speed" : "U:value", speed,
+                                         NULL);
         break;
+
     case BLOCK_JOB_PULL:
         cmd_name = modern ? "block-stream" : "block_stream";
-        if (speed)
-            cmd = qemuMonitorJSONMakeCommand(cmd_name,
-                                             "s:device", device,
-                                             "U:speed", speed,
-                                             base ? "s:base" : NULL, base,
-                                             NULL);
-        else
-            cmd = qemuMonitorJSONMakeCommand(cmd_name,
-                                             "s:device", device,
-                                             base ? "s:base" : NULL, base,
-                                             NULL);
+        cmd = qemuMonitorJSONMakeCommand(cmd_name,
+                                         "s:device", device,
+                                         "P:speed", speed,
+                                         "S:base", base,
+                                         NULL);
         break;
     }

-- 
1.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to