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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list