aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-01-01 14:33:03 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-01-01 14:33:03 +0000
commit1f7c02797fa189ce4b34382020bbce63262a5758 (patch)
tree467ab5404de2084c44df0f9d97b8524fa210c789
parent50536341b47f1e6478c42d4b4a1337b72762721b (diff)
parent4ac76ba414ecb94f086d73621775d8b38b6f0a43 (diff)
downloadqemu-1f7c02797fa189ce4b34382020bbce63262a5758.zip
qemu-1f7c02797fa189ce4b34382020bbce63262a5758.tar.gz
qemu-1f7c02797fa189ce4b34382020bbce63262a5758.tar.bz2
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2020-12-19' into staging
QAPI patches patches for 2020-12-19 # gpg: Signature made Sat 19 Dec 2020 09:40:05 GMT # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2020-12-19: (33 commits) qobject: Make QString immutable block: Use GString instead of QString to build filenames keyval: Use GString to accumulate value strings json: Use GString instead of QString to accumulate strings migration: Replace migration's JSON writer by the general one qobject: Factor JSON writer out of qobject_to_json() qobject: Factor quoted_str() out of to_json() qobject: Drop qstring_get_try_str() qobject: Drop qobject_get_try_str() Revert "qobject: let object_property_get_str() use new API" block: Avoid qobject_get_try_str() qmp: Fix tracing of non-string command IDs qobject: Move internals to qobject-internal.h hw/rdma: Replace QList by GQueue Revert "qstring: add qstring_free()" qobject: Change qobject_to_json()'s value to GString qobject: Use GString instead of QString to accumulate JSON qobject: Make qobject_to_json_pretty() take a pretty argument monitor: Use GString instead of QString for output buffer hmp: Simplify how qmp_human_monitor_command() gets output ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--block.c23
-rw-r--r--block/gluster.c4
-rw-r--r--block/qapi.c7
-rw-r--r--block/rbd.c2
-rw-r--r--chardev/char.c20
-rw-r--r--docs/devel/writing-qmp-commands.txt12
-rw-r--r--hw/core/machine-qmp-cmds.c6
-rw-r--r--hw/core/machine.c11
-rw-r--r--hw/display/virtio-gpu.c2
-rw-r--r--hw/intc/s390_flic_kvm.c2
-rw-r--r--hw/net/rocker/rocker.c8
-rw-r--r--hw/net/rocker/rocker_fp.c17
-rw-r--r--hw/net/rocker/rocker_fp.h2
-rw-r--r--hw/net/rocker/rocker_of_dpa.c20
-rw-r--r--hw/net/virtio-net.c21
-rw-r--r--hw/nvram/eeprom93xx.c2
-rw-r--r--hw/nvram/fw_cfg.c2
-rw-r--r--hw/pci/msix.c2
-rw-r--r--hw/pci/pci.c4
-rw-r--r--hw/pci/shpc.c2
-rw-r--r--hw/rdma/rdma_backend.c10
-rw-r--r--hw/rdma/rdma_backend_defs.h2
-rw-r--r--hw/rdma/rdma_utils.c29
-rw-r--r--hw/rdma/rdma_utils.h15
-rw-r--r--hw/rtc/twl92230.c2
-rw-r--r--hw/scsi/scsi-bus.c2
-rw-r--r--hw/usb/redirect.c7
-rw-r--r--hw/virtio/virtio.c4
-rw-r--r--include/migration/vmstate.h7
-rw-r--r--include/qapi/qmp/json-writer.h35
-rw-r--r--include/qapi/qmp/qbool.h2
-rw-r--r--include/qapi/qmp/qdict.h2
-rw-r--r--include/qapi/qmp/qjson.h4
-rw-r--r--include/qapi/qmp/qlist.h2
-rw-r--r--include/qapi/qmp/qnull.h2
-rw-r--r--include/qapi/qmp/qnum.h3
-rw-r--r--include/qapi/qmp/qobject.h9
-rw-r--r--include/qapi/qmp/qstring.h14
-rw-r--r--include/qemu/typedefs.h4
-rw-r--r--migration/meson.build1
-rw-r--r--migration/migration.c29
-rw-r--r--migration/postcopy-ram.c7
-rw-r--r--migration/qjson.c114
-rw-r--r--migration/qjson.h29
-rw-r--r--migration/savevm.c53
-rw-r--r--migration/vmstate-types.c38
-rw-r--r--migration/vmstate.c52
-rw-r--r--monitor/hmp-cmds.c13
-rw-r--r--monitor/misc.c31
-rw-r--r--monitor/monitor-internal.h2
-rw-r--r--monitor/monitor.c20
-rw-r--r--monitor/qmp-cmds-control.c10
-rw-r--r--monitor/qmp.c46
-rw-r--r--qapi/string-output-visitor.c2
-rw-r--r--qemu-img.c38
-rw-r--r--qga/commands-posix-ssh.c7
-rw-r--r--qga/commands-posix.c47
-rw-r--r--qga/commands-win32.c32
-rw-r--r--qga/commands.c6
-rw-r--r--qga/main.c22
-rw-r--r--qobject/json-parser.c30
-rw-r--r--qobject/json-writer.c247
-rw-r--r--qobject/meson.build5
-rw-r--r--qobject/qbool.c1
-rw-r--r--qobject/qdict.c1
-rw-r--r--qobject/qjson.c146
-rw-r--r--qobject/qlist.c1
-rw-r--r--qobject/qnull.c1
-rw-r--r--qobject/qnum.c28
-rw-r--r--qobject/qobject-internal.h39
-rw-r--r--qobject/qobject.c1
-rw-r--r--qobject/qstring.c113
-rw-r--r--qom/object.c9
-rw-r--r--qom/object_interfaces.c4
-rw-r--r--qom/qom-hmp-cmds.c7
-rw-r--r--qom/qom-qmp-cmds.c29
-rw-r--r--target/alpha/machine.c2
-rw-r--r--target/arm/helper.c6
-rw-r--r--target/arm/machine.c6
-rw-r--r--target/arm/monitor.c13
-rw-r--r--target/avr/machine.c4
-rw-r--r--target/hppa/machine.c4
-rw-r--r--target/i386/cpu.c6
-rw-r--r--target/microblaze/machine.c2
-rw-r--r--target/mips/cpu.c6
-rw-r--r--target/mips/machine.c4
-rw-r--r--target/openrisc/machine.c2
-rw-r--r--target/ppc/machine.c10
-rw-r--r--target/ppc/translate_init.c.inc12
-rw-r--r--target/s390x/cpu_models.c12
-rw-r--r--target/sparc/machine.c2
-rw-r--r--tests/check-qjson.c195
-rw-r--r--tests/check-qnum.c8
-rw-r--r--tests/check-qobject.c3
-rw-r--r--tests/check-qstring.c16
-rw-r--r--tests/qtest/libqtest.c20
-rw-r--r--tests/test-clone-visitor.c7
-rw-r--r--tests/test-qobject-output-visitor.c48
-rw-r--r--tests/test-string-output-visitor.c4
-rw-r--r--tests/test-visitor-serialization.c181
-rw-r--r--trace/qmp.c22
-rw-r--r--ui/input.c16
-rw-r--r--ui/vnc.c21
-rw-r--r--util/keyval.c11
-rw-r--r--util/qemu-config.c14
105 files changed, 977 insertions, 1265 deletions
diff --git a/block.c b/block.c
index 64412ee..8b9d457 100644
--- a/block.c
+++ b/block.c
@@ -217,7 +217,7 @@ void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
/* Stripping the explicit protocol prefix may result in a protocol
* prefix being (wrongly) detected (if the filename contains a colon) */
if (path_has_protocol(filename)) {
- QString *fat_filename;
+ GString *fat_filename;
/* This means there is some colon before the first slash; therefore,
* this cannot be an absolute path */
@@ -225,12 +225,13 @@ void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
/* And we can thus fix the protocol detection issue by prefixing it
* by "./" */
- fat_filename = qstring_from_str("./");
- qstring_append(fat_filename, filename);
+ fat_filename = g_string_new("./");
+ g_string_append(fat_filename, filename);
- assert(!path_has_protocol(qstring_get_str(fat_filename)));
+ assert(!path_has_protocol(fat_filename->str));
- qdict_put(options, "filename", fat_filename);
+ qdict_put(options, "filename",
+ qstring_from_gstring(fat_filename));
} else {
/* If no protocol prefix was detected, we can use the shortened
* filename as-is */
@@ -3977,7 +3978,7 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
new_backing_bs = NULL;
break;
case QTYPE_QSTRING:
- str = qobject_get_try_str(value);
+ str = qstring_get_str(qobject_to(QString, value));
new_backing_bs = bdrv_lookup_bs(NULL, str, errp);
if (new_backing_bs == NULL) {
return -EINVAL;
@@ -4240,8 +4241,8 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
}
if (child) {
- const char *str = qobject_get_try_str(new);
- if (!strcmp(child->bs->node_name, str)) {
+ if (!strcmp(child->bs->node_name,
+ qstring_get_str(qobject_to(QString, new)))) {
continue; /* Found child with this name, skip option */
}
}
@@ -6938,13 +6939,13 @@ void bdrv_refresh_filename(BlockDriverState *bs)
if (bs->exact_filename[0]) {
pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
} else {
- QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
+ GString *json = qobject_to_json(QOBJECT(bs->full_open_options));
if (snprintf(bs->filename, sizeof(bs->filename), "json:%s",
- qstring_get_str(json)) >= sizeof(bs->filename)) {
+ json->str) >= sizeof(bs->filename)) {
/* Give user a hint if we truncated things. */
strcpy(bs->filename + sizeof(bs->filename) - 4, "...");
}
- qobject_unref(json);
+ g_string_free(json, true);
}
}
diff --git a/block/gluster.c b/block/gluster.c
index 4f1448e..1f8699b 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -359,8 +359,8 @@ static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
return -EINVAL;
}
- gconf->server = g_new0(SocketAddressList, 1);
- gconf->server->value = gsconf = g_new0(SocketAddress, 1);
+ gsconf = g_new0(SocketAddress, 1);
+ QAPI_LIST_PREPEND(gconf->server, gsconf);
/* transport */
if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
diff --git a/block/qapi.c b/block/qapi.c
index 036da08..0ca206f 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -486,12 +486,7 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
ds->account_failed = stats->account_failed;
while ((ts = block_acct_interval_next(stats, ts))) {
- BlockDeviceTimedStatsList *timed_stats =
- g_malloc0(sizeof(*timed_stats));
BlockDeviceTimedStats *dev_stats = g_malloc0(sizeof(*dev_stats));
- timed_stats->next = ds->timed_stats;
- timed_stats->value = dev_stats;
- ds->timed_stats = timed_stats;
TimedAverage *rd = &ts->latency[BLOCK_ACCT_READ];
TimedAverage *wr = &ts->latency[BLOCK_ACCT_WRITE];
@@ -515,6 +510,8 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
block_acct_queue_depth(ts, BLOCK_ACCT_READ);
dev_stats->avg_wr_queue_depth =
block_acct_queue_depth(ts, BLOCK_ACCT_WRITE);
+
+ QAPI_LIST_PREPEND(ds->timed_stats, dev_stats);
}
bdrv_latency_histogram_stats(&stats->latency_histogram[BLOCK_ACCT_READ],
diff --git a/block/rbd.c b/block/rbd.c
index 9bd2bce..9071a00 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -232,7 +232,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
if (keypairs) {
qdict_put(options, "=keyvalue-pairs",
- qobject_to_json(QOBJECT(keypairs)));
+ qstring_from_gstring(qobject_to_json(QOBJECT(keypairs))));
}
done:
diff --git a/chardev/char.c b/chardev/char.c
index a9b8c5a..288efeb 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -776,15 +776,13 @@ static int qmp_query_chardev_foreach(Object *obj, void *data)
{
Chardev *chr = CHARDEV(obj);
ChardevInfoList **list = data;
- ChardevInfoList *info = g_malloc0(sizeof(*info));
+ ChardevInfo *value = g_malloc0(sizeof(*value));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->label = g_strdup(chr->label);
- info->value->filename = g_strdup(chr->filename);
- info->value->frontend_open = chr->be && chr->be->fe_open;
+ value->label = g_strdup(chr->label);
+ value->filename = g_strdup(chr->filename);
+ value->frontend_open = chr->be && chr->be->fe_open;
- info->next = *list;
- *list = info;
+ QAPI_LIST_PREPEND(*list, value);
return 0;
}
@@ -803,12 +801,10 @@ static void
qmp_prepend_backend(const char *name, void *opaque)
{
ChardevBackendInfoList **list = opaque;
- ChardevBackendInfoList *info = g_malloc0(sizeof(*info));
+ ChardevBackendInfo *value = g_new0(ChardevBackendInfo, 1);
- info->value = g_malloc0(sizeof(*info->value));
- info->value->name = g_strdup(name);
- info->next = *list;
- *list = info;
+ value->name = g_strdup(name);
+ QAPI_LIST_PREPEND(*list, value);
}
ChardevBackendInfoList *qmp_query_chardev_backends(Error **errp)
diff --git a/docs/devel/writing-qmp-commands.txt b/docs/devel/writing-qmp-commands.txt
index 2898468..258e63b 100644
--- a/docs/devel/writing-qmp-commands.txt
+++ b/docs/devel/writing-qmp-commands.txt
@@ -531,15 +531,11 @@ TimerAlarmMethodList *qmp_query_alarm_methods(Error **errp)
bool current = true;
for (p = alarm_timers; p->name; p++) {
- TimerAlarmMethodList *info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->method_name = g_strdup(p->name);
- info->value->current = current;
-
+ TimerAlarmMethod *value = g_malloc0(*value);
+ value->method_name = g_strdup(p->name);
+ value->current = current;
+ QAPI_LIST_PREPEND(method_list, value);
current = false;
-
- info->next = method_list;
- method_list = info;
}
return method_list;
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 87f1414..affffe0 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -215,7 +215,6 @@ MachineInfoList *qmp_query_machines(Error **errp)
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
- MachineInfoList *entry;
MachineInfo *info;
info = g_malloc0(sizeof(*info));
@@ -243,10 +242,7 @@ MachineInfoList *qmp_query_machines(Error **errp)
info->has_default_ram_id = true;
}
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = mach_list;
- mach_list = entry;
+ QAPI_LIST_PREPEND(mach_list, info);
}
g_slist_free(machines);
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 05dcaf0..de3b8f1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -504,11 +504,7 @@ static void machine_set_nvdimm_persistence(Object *obj, const char *value,
void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type)
{
- strList *item = g_new0(strList, 1);
-
- item->value = g_strdup(type);
- item->next = mc->allowed_dynamic_sysbus_devices;
- mc->allowed_dynamic_sysbus_devices = item;
+ QAPI_LIST_PREPEND(mc->allowed_dynamic_sysbus_devices, g_strdup(type));
}
static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque)
@@ -569,7 +565,6 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
for (i = 0; i < machine->possible_cpus->len; i++) {
Object *cpu;
- HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type);
@@ -582,9 +577,7 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
cpu_item->has_qom_path = true;
cpu_item->qom_path = object_get_canonical_path(cpu);
}
- list_item->value = cpu_item;
- list_item->next = head;
- head = list_item;
+ QAPI_LIST_PREPEND(head, cpu_item);
}
return head;
}
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f3b71fa..0e833a4 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -970,7 +970,7 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
};
static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
VirtIOGPU *g = opaque;
struct virtio_gpu_simple_resource *res;
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index 35d91af..b3fb9f8 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -386,7 +386,7 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
* reached
*/
static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
KVMS390FLICState *flic = opaque;
int len = FLIC_SAVE_INITIAL_SIZE;
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 1af1e6f..c53a023 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -127,13 +127,7 @@ RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
}
for (i = r->fp_ports - 1; i >= 0; i--) {
- RockerPortList *info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- struct fp_port *port = r->fp_port[i];
-
- fp_port_get_info(port, info);
- info->next = list;
- list = info;
+ QAPI_LIST_PREPEND(list, fp_port_get_info(r->fp_port[i]));
}
return list;
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 4aa7da7..cbeed65 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -51,14 +51,17 @@ bool fp_port_get_link_up(FpPort *port)
return !qemu_get_queue(port->nic)->link_down;
}
-void fp_port_get_info(FpPort *port, RockerPortList *info)
+RockerPort *fp_port_get_info(FpPort *port)
{
- info->value->name = g_strdup(port->name);
- info->value->enabled = port->enabled;
- info->value->link_up = fp_port_get_link_up(port);
- info->value->speed = port->speed;
- info->value->duplex = port->duplex;
- info->value->autoneg = port->autoneg;
+ RockerPort *value = g_malloc0(sizeof(*value));
+
+ value->name = g_strdup(port->name);
+ value->enabled = port->enabled;
+ value->link_up = fp_port_get_link_up(port);
+ value->speed = port->speed;
+ value->duplex = port->duplex;
+ value->autoneg = port->autoneg;
+ return value;
}
void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr)
diff --git a/hw/net/rocker/rocker_fp.h b/hw/net/rocker/rocker_fp.h
index dbe1dd3..7ff57aa 100644
--- a/hw/net/rocker/rocker_fp.h
+++ b/hw/net/rocker/rocker_fp.h
@@ -28,7 +28,7 @@ int fp_port_eg(FpPort *port, const struct iovec *iov, int iovcnt);
char *fp_port_get_name(FpPort *port);
bool fp_port_get_link_up(FpPort *port);
-void fp_port_get_info(FpPort *port, RockerPortList *info);
+RockerPort *fp_port_get_info(FpPort *port);
void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr);
void fp_port_set_macaddr(FpPort *port, MACAddr *macaddr);
uint8_t fp_port_get_learning(FpPort *port);
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 8e347d1..b3b8c5b 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -2296,7 +2296,6 @@ static void of_dpa_flow_fill(void *cookie, void *value, void *user_data)
struct of_dpa_flow_key *key = &flow->key;
struct of_dpa_flow_key *mask = &flow->mask;
struct of_dpa_flow_fill_context *flow_context = user_data;
- RockerOfDpaFlowList *new;
RockerOfDpaFlow *nflow;
RockerOfDpaFlowKey *nkey;
RockerOfDpaFlowMask *nmask;
@@ -2307,8 +2306,7 @@ static void of_dpa_flow_fill(void *cookie, void *value, void *user_data)
return;
}
- new = g_malloc0(sizeof(*new));
- nflow = new->value = g_malloc0(sizeof(*nflow));
+ nflow = g_malloc0(sizeof(*nflow));
nkey = nflow->key = g_malloc0(sizeof(*nkey));
nmask = nflow->mask = g_malloc0(sizeof(*nmask));
naction = nflow->action = g_malloc0(sizeof(*naction));
@@ -2424,8 +2422,7 @@ static void of_dpa_flow_fill(void *cookie, void *value, void *user_data)
naction->new_vlan_id = flow->action.apply.new_vlan_id;
}
- new->next = flow_context->list;
- flow_context->list = new;
+ QAPI_LIST_PREPEND(flow_context->list, nflow);
}
RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
@@ -2469,9 +2466,7 @@ static void of_dpa_group_fill(void *key, void *value, void *user_data)
{
struct of_dpa_group *group = value;
struct of_dpa_group_fill_context *flow_context = user_data;
- RockerOfDpaGroupList *new;
RockerOfDpaGroup *ngroup;
- struct uint32List *id;
int i;
if (flow_context->type != 9 &&
@@ -2479,8 +2474,7 @@ static void of_dpa_group_fill(void *key, void *value, void *user_data)
return;
}
- new = g_malloc0(sizeof(*new));
- ngroup = new->value = g_malloc0(sizeof(*ngroup));
+ ngroup = g_malloc0(sizeof(*ngroup));
ngroup->id = group->id;
@@ -2525,10 +2519,7 @@ static void of_dpa_group_fill(void *key, void *value, void *user_data)
ngroup->index = ROCKER_GROUP_INDEX_GET(group->id);
for (i = 0; i < group->l2_flood.group_count; i++) {
ngroup->has_group_ids = true;
- id = g_malloc0(sizeof(*id));
- id->value = group->l2_flood.group_ids[i];
- id->next = ngroup->group_ids;
- ngroup->group_ids = id;
+ QAPI_LIST_PREPEND(ngroup->group_ids, group->l2_flood.group_ids[i]);
}
break;
case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST:
@@ -2557,8 +2548,7 @@ static void of_dpa_group_fill(void *key, void *value, void *user_data)
break;
}
- new->next = flow_context->list;
- flow_context->list = new;
+ QAPI_LIST_PREPEND(flow_context->list, ngroup);
}
RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 044ac95..8356eee 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -437,17 +437,14 @@ static void rxfilter_notify(NetClientState *nc)
static intList *get_vlan_table(VirtIONet *n)
{
- intList *list, *entry;
+ intList *list;
int i, j;
list = NULL;
for (i = 0; i < MAX_VLAN >> 5; i++) {
for (j = 0; n->vlans[i] && j <= 0x1f; j++) {
if (n->vlans[i] & (1U << j)) {
- entry = g_malloc0(sizeof(*entry));
- entry->value = (i << 5) + j;
- entry->next = list;
- list = entry;
+ QAPI_LIST_PREPEND(list, (i << 5) + j);
}
}
}
@@ -460,7 +457,7 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
VirtIONet *n = qemu_get_nic_opaque(nc);
VirtIODevice *vdev = VIRTIO_DEVICE(n);
RxFilterInfo *info;
- strList *str_list, *entry;
+ strList *str_list;
int i;
info = g_malloc0(sizeof(*info));
@@ -491,19 +488,15 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
str_list = NULL;
for (i = 0; i < n->mac_table.first_multi; i++) {
- entry = g_malloc0(sizeof(*entry));
- entry->value = qemu_mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN);
- entry->next = str_list;
- str_list = entry;
+ QAPI_LIST_PREPEND(str_list,
+ qemu_mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN));
}
info->unicast_table = str_list;
str_list = NULL;
for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) {
- entry = g_malloc0(sizeof(*entry));
- entry->value = qemu_mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN);
- entry->next = str_list;
- str_list = entry;
+ QAPI_LIST_PREPEND(str_list,
+ qemu_mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN));
}
info->multicast_table = str_list;
info->vlan_table = get_vlan_table(n);
diff --git a/hw/nvram/eeprom93xx.c b/hw/nvram/eeprom93xx.c
index ca6f591..a1b9c78 100644
--- a/hw/nvram/eeprom93xx.c
+++ b/hw/nvram/eeprom93xx.c
@@ -104,7 +104,7 @@ static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size,
}
static int put_unused(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
fprintf(stderr, "uint16_from_uint8 is used only for backwards compatibility.\n");
fprintf(stderr, "Never should be used to write a new state.\n");
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 44cb274..9b8dcca 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -583,7 +583,7 @@ static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size,
}
static int put_unused(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n");
fprintf(stderr, "This functions shouldn't be called.\n");
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 36491ee..ae9331c 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -634,7 +634,7 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
}
static int put_msix_state(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
msix_save(pv, f);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d4349ea..dd589cd 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -559,7 +559,7 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
/* just put buffer */
static int put_pci_config_device(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
const uint8_t **v = pv;
assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
@@ -597,7 +597,7 @@ static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
}
static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int i;
PCIDevice *s = container_of(pv, PCIDevice, irq_state);
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index b00dce6..4786a44 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -699,7 +699,7 @@ void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
}
static int shpc_save(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
PCIDevice *d = container_of(pv, PCIDevice, shpc);
qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
diff --git a/hw/rdma/rdma_backend.c b/hw/rdma/rdma_backend.c
index 5de010b..6dcdfbb 100644
--- a/hw/rdma/rdma_backend.c
+++ b/hw/rdma/rdma_backend.c
@@ -78,7 +78,7 @@ static void clean_recv_mads(RdmaBackendDev *backend_dev)
unsigned long cqe_ctx_id;
do {
- cqe_ctx_id = rdma_protected_qlist_pop_int64(&backend_dev->
+ cqe_ctx_id = rdma_protected_gqueue_pop_int64(&backend_dev->
recv_mads_list);
if (cqe_ctx_id != -ENOENT) {
qatomic_inc(&backend_dev->rdma_dev_res->stats.missing_cqe);
@@ -597,7 +597,7 @@ static unsigned int save_mad_recv_buffer(RdmaBackendDev *backend_dev,
bctx->up_ctx = ctx;
bctx->sge = *sge;
- rdma_protected_qlist_append_int64(&backend_dev->recv_mads_list, bctx_id);
+ rdma_protected_gqueue_append_int64(&backend_dev->recv_mads_list, bctx_id);
return 0;
}
@@ -1111,7 +1111,7 @@ static void process_incoming_mad_req(RdmaBackendDev *backend_dev,
trace_mad_message("recv", msg->umad.mad, msg->umad_len);
- cqe_ctx_id = rdma_protected_qlist_pop_int64(&backend_dev->recv_mads_list);
+ cqe_ctx_id = rdma_protected_gqueue_pop_int64(&backend_dev->recv_mads_list);
if (cqe_ctx_id == -ENOENT) {
rdma_warn_report("No more free MADs buffers, waiting for a while");
sleep(THR_POLL_TO);
@@ -1185,7 +1185,7 @@ static int mad_init(RdmaBackendDev *backend_dev, CharBackend *mad_chr_be)
return -EIO;
}
- rdma_protected_qlist_init(&backend_dev->recv_mads_list);
+ rdma_protected_gqueue_init(&backend_dev->recv_mads_list);
enable_rdmacm_mux_async(backend_dev);
@@ -1205,7 +1205,7 @@ static void mad_fini(RdmaBackendDev *backend_dev)
{
disable_rdmacm_mux_async(backend_dev);
qemu_chr_fe_disconnect(backend_dev->rdmacm_mux.chr_be);
- rdma_protected_qlist_destroy(&backend_dev->recv_mads_list);
+ rdma_protected_gqueue_destroy(&backend_dev->recv_mads_list);
}
int rdma_backend_get_gid_index(RdmaBackendDev *backend_dev,
diff --git a/hw/rdma/rdma_backend_defs.h b/hw/rdma/rdma_backend_defs.h
index 0b55be3..4e6c0ad 100644
--- a/hw/rdma/rdma_backend_defs.h
+++ b/hw/rdma/rdma_backend_defs.h
@@ -43,7 +43,7 @@ typedef struct RdmaBackendDev {
struct ibv_context *context;
struct ibv_comp_channel *channel;
uint8_t port_num;
- RdmaProtectedQList recv_mads_list;
+ RdmaProtectedGQueue recv_mads_list;
RdmaCmMux rdmacm_mux;
} RdmaBackendDev;
diff --git a/hw/rdma/rdma_utils.c b/hw/rdma/rdma_utils.c
index 698ed47..98df58f 100644
--- a/hw/rdma/rdma_utils.c
+++ b/hw/rdma/rdma_utils.c
@@ -14,8 +14,6 @@
*/
#include "qemu/osdep.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qnum.h"
#include "trace.h"
#include "rdma_utils.h"
@@ -54,41 +52,46 @@ void rdma_pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len)
}
}
-void rdma_protected_qlist_init(RdmaProtectedQList *list)
+void rdma_protected_gqueue_init(RdmaProtectedGQueue *list)
{
qemu_mutex_init(&list->lock);
- list->list = qlist_new();
+ list->list = g_queue_new();
}
-void rdma_protected_qlist_destroy(RdmaProtectedQList *list)
+void rdma_protected_gqueue_destroy(RdmaProtectedGQueue *list)
{
if (list->list) {
- qlist_destroy_obj(QOBJECT(list->list));
+ g_queue_free_full(list->list, g_free);
qemu_mutex_destroy(&list->lock);
list->list = NULL;
}
}
-void rdma_protected_qlist_append_int64(RdmaProtectedQList *list, int64_t value)
+void rdma_protected_gqueue_append_int64(RdmaProtectedGQueue *list,
+ int64_t value)
{
qemu_mutex_lock(&list->lock);
- qlist_append_int(list->list, value);
+ g_queue_push_tail(list->list, g_memdup(&value, sizeof(value)));
qemu_mutex_unlock(&list->lock);
}
-int64_t rdma_protected_qlist_pop_int64(RdmaProtectedQList *list)
+int64_t rdma_protected_gqueue_pop_int64(RdmaProtectedGQueue *list)
{
- QObject *obj;
+ int64_t *valp;
+ int64_t val;
qemu_mutex_lock(&list->lock);
- obj = qlist_pop(list->list);
+
+ valp = g_queue_pop_head(list->list);
qemu_mutex_unlock(&list->lock);
- if (!obj) {
+ if (!valp) {
return -ENOENT;
}
- return qnum_get_uint(qobject_to(QNum, obj));
+ val = *valp;
+ g_free(valp);
+ return val;
}
void rdma_protected_gslist_init(RdmaProtectedGSList *list)
diff --git a/hw/rdma/rdma_utils.h b/hw/rdma/rdma_utils.h
index e7babe9..9fd0efd 100644
--- a/hw/rdma/rdma_utils.h
+++ b/hw/rdma/rdma_utils.h
@@ -28,10 +28,10 @@
#define rdma_info_report(fmt, ...) \
info_report("%s: " fmt, "rdma", ## __VA_ARGS__)
-typedef struct RdmaProtectedQList {
+typedef struct RdmaProtectedGQueue {
QemuMutex lock;
- QList *list;
-} RdmaProtectedQList;
+ GQueue *list;
+} RdmaProtectedGQueue;
typedef struct RdmaProtectedGSList {
QemuMutex lock;
@@ -40,10 +40,11 @@ typedef struct RdmaProtectedGSList {
void *rdma_pci_dma_map(PCIDevice *dev, dma_addr_t addr, dma_addr_t plen);
void rdma_pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len);
-void rdma_protected_qlist_init(RdmaProtectedQList *list);
-void rdma_protected_qlist_destroy(RdmaProtectedQList *list);
-void rdma_protected_qlist_append_int64(RdmaProtectedQList *list, int64_t value);
-int64_t rdma_protected_qlist_pop_int64(RdmaProtectedQList *list);
+void rdma_protected_gqueue_init(RdmaProtectedGQueue *list);
+void rdma_protected_gqueue_destroy(RdmaProtectedGQueue *list);
+void rdma_protected_gqueue_append_int64(RdmaProtectedGQueue *list,
+ int64_t value);
+int64_t rdma_protected_gqueue_pop_int64(RdmaProtectedGQueue *list);
void rdma_protected_gslist_init(RdmaProtectedGSList *list);
void rdma_protected_gslist_destroy(RdmaProtectedGSList *list);
void rdma_protected_gslist_append_int32(RdmaProtectedGSList *list,
diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c
index 006d75e..0922df5 100644
--- a/hw/rtc/twl92230.c
+++ b/hw/rtc/twl92230.c
@@ -746,7 +746,7 @@ static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
}
static int put_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int *v = pv;
qemu_put_be16(f, *v);
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index edb5c34..c349fb7 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1638,7 +1638,7 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
/* SCSI request list. For simplicity, pv points to the whole device */
static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
SCSIDevice *s = pv;
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 3238de6..4ca7d47 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -2227,7 +2227,7 @@ static int usbredir_post_load(void *priv, int version_id)
/* For usbredirparser migration */
static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
USBRedirDevice *dev = priv;
uint8_t *data;
@@ -2294,7 +2294,7 @@ static const VMStateInfo usbredir_parser_vmstate_info = {
/* For buffered packets (iso/irq) queue migration */
static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
struct endp_data *endp = priv;
USBRedirDevice *dev = endp->dev;
@@ -2421,7 +2421,8 @@ static const VMStateDescription usbredir_ep_vmstate = {
/* For PacketIdQueue migration */
static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field,
+ JSONWriter *vmdesc)
{
struct PacketIdQueue *q = priv;
USBRedirDevice *dev = q->dev;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index eff35fa..b308026 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2745,7 +2745,7 @@ static int get_extra_state(QEMUFile *f, void *pv, size_t size,
}
static int put_extra_state(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -2919,7 +2919,7 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
/* A wrapper for use as a VMState .put function */
static int virtio_device_put(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
return virtio_save(VIRTIO_DEVICE(opaque), f);
}
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 4d71dc8..075ee80 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -43,7 +43,7 @@ struct VMStateInfo {
const char *name;
int (*get)(QEMUFile *f, void *pv, size_t size, const VMStateField *field);
int (*put)(QEMUFile *f, void *pv, size_t size, const VMStateField *field,
- QJSON *vmdesc);
+ JSONWriter *vmdesc);
};
enum VMStateFlags {
@@ -1169,9 +1169,10 @@ extern const VMStateInfo vmstate_info_qlist;
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id);
int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, QJSON *vmdesc);
+ void *opaque, JSONWriter *vmdesc);
int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, QJSON *vmdesc, int version_id);
+ void *opaque, JSONWriter *vmdesc,
+ int version_id);
bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque);
diff --git a/include/qapi/qmp/json-writer.h b/include/qapi/qmp/json-writer.h
new file mode 100644
index 0000000..b70ba64
--- /dev/null
+++ b/include/qapi/qmp/json-writer.h
@@ -0,0 +1,35 @@
+/*
+ * JSON Writer
+ *
+ * Copyright (c) 2020 Red Hat Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef JSON_WRITER_H
+#define JSON_WRITER_H
+
+JSONWriter *json_writer_new(bool pretty);
+const char *json_writer_get(JSONWriter *);
+GString *json_writer_get_and_free(JSONWriter *);
+void json_writer_free(JSONWriter *);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JSONWriter, json_writer_free)
+
+void json_writer_start_object(JSONWriter *, const char *name);
+void json_writer_end_object(JSONWriter *);
+void json_writer_start_array(JSONWriter *, const char *name);
+void json_writer_end_array(JSONWriter *);
+void json_writer_bool(JSONWriter *, const char *name, bool val);
+void json_writer_null(JSONWriter *, const char *name);
+void json_writer_int64(JSONWriter *, const char *name, int64_t val);
+void json_writer_uint64(JSONWriter *, const char *name, uint64_t val);
+void json_writer_double(JSONWriter *, const char *name, double val);
+void json_writer_str(JSONWriter *, const char *name, const char *str);
+
+#endif
diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h
index 5f61e38..2f888d1 100644
--- a/include/qapi/qmp/qbool.h
+++ b/include/qapi/qmp/qbool.h
@@ -23,7 +23,5 @@ struct QBool {
QBool *qbool_from_bool(bool value);
bool qbool_get_bool(const QBool *qb);
-bool qbool_is_equal(const QObject *x, const QObject *y);
-void qbool_destroy_obj(QObject *obj);
#endif /* QBOOL_H */
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index da94234..9934539 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -39,10 +39,8 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value);
void qdict_del(QDict *qdict, const char *key);
int qdict_haskey(const QDict *qdict, const char *key);
QObject *qdict_get(const QDict *qdict, const char *key);
-bool qdict_is_equal(const QObject *x, const QObject *y);
const QDictEntry *qdict_first(const QDict *qdict);
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
-void qdict_destroy_obj(QObject *obj);
/* Helper to qdict_put_obj(), accepts any object */
#define qdict_put(qdict, key, obj) \
diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
index 5ebbe5a..593b40b 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qapi/qmp/qjson.h
@@ -25,7 +25,7 @@ QDict *qdict_from_vjsonf_nofail(const char *string, va_list ap)
QDict *qdict_from_jsonf_nofail(const char *string, ...)
GCC_FMT_ATTR(1, 2);
-QString *qobject_to_json(const QObject *obj);
-QString *qobject_to_json_pretty(const QObject *obj);
+GString *qobject_to_json(const QObject *obj);
+GString *qobject_to_json_pretty(const QObject *obj, bool pretty);
#endif /* QJSON_H */
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index 595b794..06e98ad 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -51,8 +51,6 @@ QObject *qlist_pop(QList *qlist);
QObject *qlist_peek(QList *qlist);
int qlist_empty(const QList *qlist);
size_t qlist_size(const QList *qlist);
-bool qlist_is_equal(const QObject *x, const QObject *y);
-void qlist_destroy_obj(QObject *obj);
static inline const QListEntry *qlist_first(const QList *qlist)
{
diff --git a/include/qapi/qmp/qnull.h b/include/qapi/qmp/qnull.h
index c142688..e84ecce 100644
--- a/include/qapi/qmp/qnull.h
+++ b/include/qapi/qmp/qnull.h
@@ -26,6 +26,4 @@ static inline QNull *qnull(void)
return qobject_ref(&qnull_);
}
-bool qnull_is_equal(const QObject *x, const QObject *y);
-
#endif /* QNULL_H */
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index bbae0a5..7f84e20 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -68,7 +68,4 @@ double qnum_get_double(QNum *qn);
char *qnum_to_string(QNum *qn);
-bool qnum_is_equal(const QObject *x, const QObject *y);
-void qnum_destroy_obj(QObject *obj);
-
#endif /* QNUM_H */
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index fcfd549..9003b71 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -64,14 +64,6 @@ QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
#define qobject_to(type, obj) \
((type *)qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)))
-/* Initialize an object to default values */
-static inline void qobject_init(QObject *obj, QType type)
-{
- assert(QTYPE_NONE < type && type < QTYPE__MAX);
- obj->base.refcnt = 1;
- obj->base.type = type;
-}
-
static inline void qobject_ref_impl(QObject *obj)
{
if (obj) {
@@ -90,6 +82,7 @@ bool qobject_is_equal(const QObject *x, const QObject *y);
/**
* qobject_destroy(): Free resources used by the object
+ * For use via qobject_unref() only!
*/
void qobject_destroy(QObject *obj);
diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
index e2e356e..1d8ba46 100644
--- a/include/qapi/qmp/qstring.h
+++ b/include/qapi/qmp/qstring.h
@@ -17,23 +17,13 @@
struct QString {
struct QObjectBase_ base;
- char *string;
- size_t length;
- size_t capacity;
+ const char *string;
};
QString *qstring_new(void);
QString *qstring_from_str(const char *str);
QString *qstring_from_substr(const char *str, size_t start, size_t end);
-size_t qstring_get_length(const QString *qstring);
+QString *qstring_from_gstring(GString *gstr);
const char *qstring_get_str(const QString *qstring);
-const char *qstring_get_try_str(const QString *qstring);
-const char *qobject_get_try_str(const QObject *qstring);
-void qstring_append_int(QString *qstring, int64_t value);
-void qstring_append(QString *qstring, const char *str);
-void qstring_append_chr(QString *qstring, int c);
-bool qstring_is_equal(const QObject *x, const QObject *y);
-char *qstring_free(QString *qstring, bool return_str);
-void qstring_destroy_obj(QObject *obj);
#endif /* QSTRING_H */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 6281eae..976b529 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -57,8 +57,8 @@ typedef struct IOMMUMemoryRegion IOMMUMemoryRegion;
typedef struct ISABus ISABus;
typedef struct ISADevice ISADevice;
typedef struct IsaDma IsaDma;
+typedef struct JSONWriter JSONWriter;
typedef struct MACAddr MACAddr;
-typedef struct ReservedRegion ReservedRegion;
typedef struct MachineClass MachineClass;
typedef struct MachineState MachineState;
typedef struct MemoryListener MemoryListener;
@@ -107,7 +107,6 @@ typedef struct QEMUSGList QEMUSGList;
typedef struct QemuSpin QemuSpin;
typedef struct QEMUTimer QEMUTimer;
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
-typedef struct QJSON QJSON;
typedef struct QList QList;
typedef struct QNull QNull;
typedef struct QNum QNum;
@@ -115,6 +114,7 @@ typedef struct QObject QObject;
typedef struct QString QString;
typedef struct RAMBlock RAMBlock;
typedef struct Range Range;
+typedef struct ReservedRegion ReservedRegion;
typedef struct SavedIOTLB SavedIOTLB;
typedef struct SHPCDevice SHPCDevice;
typedef struct SSIBus SSIBus;
diff --git a/migration/meson.build b/migration/meson.build
index 980e378..291adc1 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -6,7 +6,6 @@ migration_files = files(
'vmstate.c',
'qemu-file-channel.c',
'qemu-file.c',
- 'qjson.c',
)
softmmu_ss.add(migration_files)
diff --git a/migration/migration.c b/migration/migration.c
index f5d4a52..9c7ed12 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -406,12 +406,9 @@ int migration_incoming_enable_colo(void)
void migrate_add_address(SocketAddress *address)
{
MigrationIncomingState *mis = migration_incoming_get_current();
- SocketAddressList *addrs;
- addrs = g_new0(SocketAddressList, 1);
- addrs->next = mis->socket_address_list;
- mis->socket_address_list = addrs;
- addrs->value = QAPI_CLONE(SocketAddress, address);
+ QAPI_LIST_PREPEND(mis->socket_address_list,
+ QAPI_CLONE(SocketAddress, address));
}
static void qemu_start_incoming_migration(const char *uri, Error **errp)
@@ -1654,27 +1651,23 @@ void migrate_set_state(int *state, int old_state, int new_state)
}
}
-static MigrationCapabilityStatusList *migrate_cap_add(
- MigrationCapabilityStatusList *list,
- MigrationCapability index,
- bool state)
+static MigrationCapabilityStatus *migrate_cap_add(MigrationCapability index,
+ bool state)
{
- MigrationCapabilityStatusList *cap;
+ MigrationCapabilityStatus *cap;
- cap = g_new0(MigrationCapabilityStatusList, 1);
- cap->value = g_new0(MigrationCapabilityStatus, 1);
- cap->value->capability = index;
- cap->value->state = state;
- cap->next = list;
+ cap = g_new0(MigrationCapabilityStatus, 1);
+ cap->capability = index;
+ cap->state = state;
return cap;
}
void migrate_set_block_enabled(bool value, Error **errp)
{
- MigrationCapabilityStatusList *cap;
+ MigrationCapabilityStatusList *cap = NULL;
- cap = migrate_cap_add(NULL, MIGRATION_CAPABILITY_BLOCK, value);
+ QAPI_LIST_PREPEND(cap, migrate_cap_add(MIGRATION_CAPABILITY_BLOCK, value));
qmp_migrate_set_capabilities(cap, errp);
qapi_free_MigrationCapabilityStatusList(cap);
}
@@ -3869,7 +3862,7 @@ static bool migration_object_check(MigrationState *ms, Error **errp)
for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
if (ms->enabled_capabilities[i]) {
- head = migrate_cap_add(head, i, true);
+ QAPI_LIST_PREPEND(head, migrate_cap_add(i, true));
}
}
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index d99842e..ab482ad 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -145,14 +145,11 @@ static struct PostcopyBlocktimeContext *blocktime_context_new(void)
static uint32List *get_vcpu_blocktime_list(PostcopyBlocktimeContext *ctx)
{
MachineState *ms = MACHINE(qdev_get_machine());
- uint32List *list = NULL, *entry = NULL;
+ uint32List *list = NULL;
int i;
for (i = ms->smp.cpus - 1; i >= 0; i--) {
- entry = g_new0(uint32List, 1);
- entry->value = ctx->vcpu_blocktime[i];
- entry->next = list;
- list = entry;
+ QAPI_LIST_PREPEND(list, ctx->vcpu_blocktime[i]);
}
return list;
diff --git a/migration/qjson.c b/migration/qjson.c
deleted file mode 100644
index e9889bd..0000000
--- a/migration/qjson.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * A simple JSON writer
- *
- * Copyright Alexander Graf
- *
- * Authors:
- * Alexander Graf <agraf@suse.de>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-/*
- * Type QJSON lets you build JSON text. Its interface mirrors (a
- * subset of) abstract JSON syntax.
- *
- * It does *not* detect incorrect use. It happily produces invalid
- * JSON then. This is what migration wants.
- *
- * QAPI output visitors also produce JSON text. However, they do
- * assert their preconditions and invariants, and therefore abort on
- * incorrect use.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/qmp/qstring.h"
-#include "qjson.h"
-
-struct QJSON {
- QString *str;
- bool omit_comma;
-};
-
-static void json_emit_element(QJSON *json, const char *name)
-{
- /* Check whether we need to print a , before an element */
- if (json->omit_comma) {
- json->omit_comma = false;
- } else {
- qstring_append(json->str, ", ");
- }
-
- if (name) {
- qstring_append(json->str, "\"");
- qstring_append(json->str, name);
- qstring_append(json->str, "\" : ");
- }
-}
-
-void json_start_object(QJSON *json, const char *name)
-{
- json_emit_element(json, name);
- qstring_append(json->str, "{ ");
- json->omit_comma = true;
-}
-
-void json_end_object(QJSON *json)
-{
- qstring_append(json->str, " }");
- json->omit_comma = false;
-}
-
-void json_start_array(QJSON *json, const char *name)
-{
- json_emit_element(json, name);
- qstring_append(json->str, "[ ");
- json->omit_comma = true;
-}
-
-void json_end_array(QJSON *json)
-{
- qstring_append(json->str, " ]");
- json->omit_comma = false;
-}
-
-void json_prop_int(QJSON *json, const char *name, int64_t val)
-{
- json_emit_element(json, name);
- qstring_append_int(json->str, val);
-}
-
-void json_prop_str(QJSON *json, const char *name, const char *str)
-{
- json_emit_element(json, name);
- qstring_append_chr(json->str, '"');
- qstring_append(json->str, str);
- qstring_append_chr(json->str, '"');
-}
-
-const char *qjson_get_str(QJSON *json)
-{
- return qstring_get_str(json->str);
-}
-
-QJSON *qjson_new(void)
-{
- QJSON *json = g_new0(QJSON, 1);
-
- json->str = qstring_from_str("{ ");
- json->omit_comma = true;
- return json;
-}
-
-void qjson_finish(QJSON *json)
-{
- json_end_object(json);
-}
-
-void qjson_destroy(QJSON *json)
-{
- qobject_unref(json->str);
- g_free(json);
-}
diff --git a/migration/qjson.h b/migration/qjson.h
deleted file mode 100644
index 1786bb5..0000000
--- a/migration/qjson.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QEMU JSON writer
- *
- * Copyright Alexander Graf
- *
- * Authors:
- * Alexander Graf <agraf@suse.de>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-#ifndef QEMU_QJSON_H
-#define QEMU_QJSON_H
-
-QJSON *qjson_new(void);
-void qjson_destroy(QJSON *json);
-void json_prop_str(QJSON *json, const char *name, const char *str);
-void json_prop_int(QJSON *json, const char *name, int64_t val);
-void json_end_array(QJSON *json);
-void json_start_array(QJSON *json, const char *name);
-void json_end_object(QJSON *json);
-void json_start_object(QJSON *json, const char *name);
-const char *qjson_get_str(QJSON *json);
-void qjson_finish(QJSON *json);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(QJSON, qjson_destroy)
-
-#endif /* QEMU_QJSON_H */
diff --git a/migration/savevm.c b/migration/savevm.c
index 4a18c9d..27e8428 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -42,6 +42,7 @@
#include "postcopy-ram.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-migration.h"
+#include "qapi/qmp/json-writer.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "sysemu/cpus.h"
@@ -58,7 +59,6 @@
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
#include "sysemu/xen.h"
-#include "qjson.h"
#include "migration/colo.h"
#include "qemu/bitmap.h"
#include "net/announce.h"
@@ -209,7 +209,7 @@ static int get_timer(QEMUFile *f, void *pv, size_t size,
}
static int put_timer(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
QEMUTimer *v = pv;
timer_put(f, v);
@@ -406,7 +406,7 @@ static int get_capability(QEMUFile *f, void *pv, size_t size,
}
static int put_capability(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
MigrationCapability *capability = pv;
const char *capability_str = MigrationCapability_str(*capability);
@@ -884,7 +884,8 @@ static int vmstate_load(QEMUFile *f, SaveStateEntry *se)
return vmstate_load_state(f, se->vmsd, se->opaque, se->load_version_id);
}
-static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
+static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se,
+ JSONWriter *vmdesc)
{
int64_t old_offset, size;
@@ -893,18 +894,19 @@ static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se, QJSON *vmdes
size = qemu_ftell_fast(f) - old_offset;
if (vmdesc) {
- json_prop_int(vmdesc, "size", size);
- json_start_array(vmdesc, "fields");
- json_start_object(vmdesc, NULL);
- json_prop_str(vmdesc, "name", "data");
- json_prop_int(vmdesc, "size", size);
- json_prop_str(vmdesc, "type", "buffer");
- json_end_object(vmdesc);
- json_end_array(vmdesc);
+ json_writer_int64(vmdesc, "size", size);
+ json_writer_start_array(vmdesc, "fields");
+ json_writer_start_object(vmdesc, NULL);
+ json_writer_str(vmdesc, "name", "data");
+ json_writer_int64(vmdesc, "size", size);
+ json_writer_str(vmdesc, "type", "buffer");
+ json_writer_end_object(vmdesc);
+ json_writer_end_array(vmdesc);
}
}
-static int vmstate_save(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
+static int vmstate_save(QEMUFile *f, SaveStateEntry *se,
+ JSONWriter *vmdesc)
{
trace_vmstate_save(se->idstr, se->vmsd ? se->vmsd->name : "(old)");
if (!se->vmsd) {
@@ -1357,14 +1359,15 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
bool in_postcopy,
bool inactivate_disks)
{
- g_autoptr(QJSON) vmdesc = NULL;
+ g_autoptr(JSONWriter) vmdesc = NULL;
int vmdesc_len;
SaveStateEntry *se;
int ret;
- vmdesc = qjson_new();
- json_prop_int(vmdesc, "page_size", qemu_target_page_size());
- json_start_array(vmdesc, "devices");
+ vmdesc = json_writer_new(false);
+ json_writer_start_object(vmdesc, NULL);
+ json_writer_int64(vmdesc, "page_size", qemu_target_page_size());
+ json_writer_start_array(vmdesc, "devices");
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
@@ -1377,9 +1380,9 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
trace_savevm_section_start(se->idstr, se->section_id);
- json_start_object(vmdesc, NULL);
- json_prop_str(vmdesc, "name", se->idstr);
- json_prop_int(vmdesc, "instance_id", se->instance_id);
+ json_writer_start_object(vmdesc, NULL);
+ json_writer_str(vmdesc, "name", se->idstr);
+ json_writer_int64(vmdesc, "instance_id", se->instance_id);
save_section_header(f, se, QEMU_VM_SECTION_FULL);
ret = vmstate_save(f, se, vmdesc);
@@ -1390,7 +1393,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
trace_savevm_section_end(se->idstr, se->section_id, 0);
save_section_footer(f, se);
- json_end_object(vmdesc);
+ json_writer_end_object(vmdesc);
}
if (inactivate_disks) {
@@ -1409,14 +1412,14 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
qemu_put_byte(f, QEMU_VM_EOF);
}
- json_end_array(vmdesc);
- qjson_finish(vmdesc);
- vmdesc_len = strlen(qjson_get_str(vmdesc));
+ json_writer_end_array(vmdesc);
+ json_writer_end_object(vmdesc);
+ vmdesc_len = strlen(json_writer_get(vmdesc));
if (should_send_vmdesc()) {
qemu_put_byte(f, QEMU_VM_VMDESCRIPTION);
qemu_put_be32(f, vmdesc_len);
- qemu_put_buffer(f, (uint8_t *)qjson_get_str(vmdesc), vmdesc_len);
+ qemu_put_buffer(f, (uint8_t *)json_writer_get(vmdesc), vmdesc_len);
}
return 0;
diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c
index e22d41d..bf4d440 100644
--- a/migration/vmstate-types.c
+++ b/migration/vmstate-types.c
@@ -29,7 +29,7 @@ static int get_bool(QEMUFile *f, void *pv, size_t size,
}
static int put_bool(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
bool *v = pv;
qemu_put_byte(f, *v);
@@ -53,7 +53,7 @@ static int get_int8(QEMUFile *f, void *pv, size_t size,
}
static int put_int8(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int8_t *v = pv;
qemu_put_s8s(f, v);
@@ -77,7 +77,7 @@ static int get_int16(QEMUFile *f, void *pv, size_t size,
}
static int put_int16(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int16_t *v = pv;
qemu_put_sbe16s(f, v);
@@ -101,7 +101,7 @@ static int get_int32(QEMUFile *f, void *pv, size_t size,
}
static int put_int32(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int32_t *v = pv;
qemu_put_sbe32s(f, v);
@@ -178,7 +178,7 @@ static int get_int64(QEMUFile *f, void *pv, size_t size,
}
static int put_int64(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int64_t *v = pv;
qemu_put_sbe64s(f, v);
@@ -202,7 +202,7 @@ static int get_uint8(QEMUFile *f, void *pv, size_t size,
}
static int put_uint8(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
uint8_t *v = pv;
qemu_put_8s(f, v);
@@ -226,7 +226,7 @@ static int get_uint16(QEMUFile *f, void *pv, size_t size,
}
static int put_uint16(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
uint16_t *v = pv;
qemu_put_be16s(f, v);
@@ -250,7 +250,7 @@ static int get_uint32(QEMUFile *f, void *pv, size_t size,
}
static int put_uint32(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
uint32_t *v = pv;
qemu_put_be32s(f, v);
@@ -300,7 +300,7 @@ static int get_uint64(QEMUFile *f, void *pv, size_t size,
}
static int put_uint64(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
uint64_t *v = pv;
qemu_put_be64s(f, v);
@@ -325,7 +325,7 @@ static int get_nullptr(QEMUFile *f, void *pv, size_t size,
}
static int put_nullptr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
if (pv == NULL) {
@@ -432,7 +432,7 @@ static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
}
static int put_cpudouble(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
CPU_DoubleU *v = pv;
qemu_put_be32s(f, &v->l.upper);
@@ -457,7 +457,7 @@ static int get_buffer(QEMUFile *f, void *pv, size_t size,
}
static int put_buffer(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
uint8_t *v = pv;
qemu_put_buffer(f, v, size);
@@ -488,7 +488,7 @@ static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
}
static int put_unused_buffer(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
static const uint8_t buf[1024];
int block_len;
@@ -530,7 +530,7 @@ static int get_tmp(QEMUFile *f, void *pv, size_t size,
}
static int put_tmp(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
const VMStateDescription *vmsd = field->vmsd;
void *tmp = g_malloc(size);
@@ -573,7 +573,7 @@ static int get_bitmap(QEMUFile *f, void *pv, size_t size,
}
static int put_bitmap(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
unsigned long *bmp = pv;
int i, idx = 0;
@@ -637,7 +637,7 @@ static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
/* put for QTAILQ */
static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
const VMStateDescription *vmsd = field->vmsd;
/* offset of the QTAILQ entry in a QTAILQ element*/
@@ -670,7 +670,7 @@ struct put_gtree_data {
QEMUFile *f;
const VMStateDescription *key_vmsd;
const VMStateDescription *val_vmsd;
- QJSON *vmdesc;
+ JSONWriter *vmdesc;
int ret;
};
@@ -703,7 +703,7 @@ static gboolean put_gtree_elem(gpointer key, gpointer value, gpointer data)
}
static int put_gtree(QEMUFile *f, void *pv, size_t unused_size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
bool direct_key = (!field->start);
const VMStateDescription *key_vmsd = direct_key ? NULL : &field->vmsd[1];
@@ -819,7 +819,7 @@ const VMStateInfo vmstate_info_gtree = {
};
static int put_qlist(QEMUFile *f, void *pv, size_t unused_size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
const VMStateDescription *vmsd = field->vmsd;
/* offset of the QTAILQ entry in a QTAILQ element*/
diff --git a/migration/vmstate.c b/migration/vmstate.c
index e9d2aef..05f87cd 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -14,14 +14,14 @@
#include "migration.h"
#include "migration/vmstate.h"
#include "savevm.h"
+#include "qapi/qmp/json-writer.h"
#include "qemu-file.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "trace.h"
-#include "qjson.h"
static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, QJSON *vmdesc);
+ void *opaque, JSONWriter *vmdesc);
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
@@ -249,7 +249,8 @@ static bool vmsd_can_compress(const VMStateField *field)
return true;
}
-static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
+static void vmsd_desc_field_start(const VMStateDescription *vmsd,
+ JSONWriter *vmdesc,
const VMStateField *field, int i, int max)
{
char *name, *old_name;
@@ -270,25 +271,26 @@ static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
g_free(old_name);
}
- json_start_object(vmdesc, NULL);
- json_prop_str(vmdesc, "name", name);
+ json_writer_start_object(vmdesc, NULL);
+ json_writer_str(vmdesc, "name", name);
if (is_array) {
if (can_compress) {
- json_prop_int(vmdesc, "array_len", max);
+ json_writer_int64(vmdesc, "array_len", max);
} else {
- json_prop_int(vmdesc, "index", i);
+ json_writer_int64(vmdesc, "index", i);
}
}
- json_prop_str(vmdesc, "type", vmfield_get_type_name(field));
+ json_writer_str(vmdesc, "type", vmfield_get_type_name(field));
if (field->flags & VMS_STRUCT) {
- json_start_object(vmdesc, "struct");
+ json_writer_start_object(vmdesc, "struct");
}
g_free(name);
}
-static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
+static void vmsd_desc_field_end(const VMStateDescription *vmsd,
+ JSONWriter *vmdesc,
const VMStateField *field, size_t size, int i)
{
if (!vmdesc) {
@@ -297,11 +299,11 @@ static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
if (field->flags & VMS_STRUCT) {
/* We printed a struct in between, close its child object */
- json_end_object(vmdesc);
+ json_writer_end_object(vmdesc);
}
- json_prop_int(vmdesc, "size", size);
- json_end_object(vmdesc);
+ json_writer_int64(vmdesc, "size", size);
+ json_writer_end_object(vmdesc);
}
@@ -316,13 +318,13 @@ bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque)
int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, QJSON *vmdesc_id)
+ void *opaque, JSONWriter *vmdesc_id)
{
return vmstate_save_state_v(f, vmsd, opaque, vmdesc_id, vmsd->version_id);
}
int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, QJSON *vmdesc, int version_id)
+ void *opaque, JSONWriter *vmdesc, int version_id)
{
int ret = 0;
const VMStateField *field = vmsd->fields;
@@ -339,9 +341,9 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
}
if (vmdesc) {
- json_prop_str(vmdesc, "vmsd_name", vmsd->name);
- json_prop_int(vmdesc, "version", version_id);
- json_start_array(vmdesc, "fields");
+ json_writer_str(vmdesc, "vmsd_name", vmsd->name);
+ json_writer_int64(vmdesc, "version", version_id);
+ json_writer_start_array(vmdesc, "fields");
}
while (field->name) {
@@ -353,7 +355,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field);
int64_t old_offset, written_bytes;
- QJSON *vmdesc_loop = vmdesc;
+ JSONWriter *vmdesc_loop = vmdesc;
trace_vmstate_save_state_loop(vmsd->name, field->name, n_elems);
if (field->flags & VMS_POINTER) {
@@ -413,7 +415,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
}
if (vmdesc) {
- json_end_array(vmdesc);
+ json_writer_end_array(vmdesc);
}
ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
@@ -491,7 +493,7 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
}
static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, QJSON *vmdesc)
+ void *opaque, JSONWriter *vmdesc)
{
const VMStateDescription **sub = vmsd->subsections;
bool vmdesc_has_subsections = false;
@@ -507,11 +509,11 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
if (vmdesc) {
/* Only create subsection array when we have any */
if (!vmdesc_has_subsections) {
- json_start_array(vmdesc, "subsections");
+ json_writer_start_array(vmdesc, "subsections");
vmdesc_has_subsections = true;
}
- json_start_object(vmdesc, NULL);
+ json_writer_start_object(vmdesc, NULL);
}
qemu_put_byte(f, QEMU_VM_SUBSECTION);
@@ -525,14 +527,14 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
}
if (vmdesc) {
- json_end_object(vmdesc);
+ json_writer_end_object(vmdesc);
}
}
sub++;
}
if (vmdesc_has_subsections) {
- json_end_array(vmdesc);
+ json_writer_end_array(vmdesc);
}
return ret;
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 79c8432..0dd594f 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1255,7 +1255,8 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
const char *cap = qdict_get_str(qdict, "capability");
bool state = qdict_get_bool(qdict, "state");
Error *err = NULL;
- MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
+ MigrationCapabilityStatusList *caps = NULL;
+ MigrationCapabilityStatus *value;
int val;
val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
@@ -1263,14 +1264,14 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
goto end;
}
- caps->value = g_malloc0(sizeof(*caps->value));
- caps->value->capability = val;
- caps->value->state = state;
- caps->next = NULL;
+ value = g_malloc0(sizeof(*value));
+ value->capability = val;
+ value->state = state;
+ QAPI_LIST_PREPEND(caps, value);
qmp_migrate_set_capabilities(caps, &err);
+ qapi_free_MigrationCapabilityStatusList(caps);
end:
- qapi_free_MigrationCapabilityStatusList(caps);
hmp_handle_error(mon, err);
}
diff --git a/monitor/misc.c b/monitor/misc.c
index 6f5ae09..a5d4d4e 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -136,11 +136,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
handle_hmp_command(&hmp, command_line);
WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) {
- if (qstring_get_length(hmp.common.outbuf) > 0) {
- output = g_strdup(qstring_get_str(hmp.common.outbuf));
- } else {
- output = g_strdup("");
- }
+ output = g_strdup(hmp.common.outbuf->str);
}
out:
@@ -1434,33 +1430,26 @@ FdsetInfoList *qmp_query_fdsets(Error **errp)
QEMU_LOCK_GUARD(&mon_fdsets_lock);
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
- FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info));
- FdsetFdInfoList *fdsetfd_list = NULL;
+ FdsetInfo *fdset_info = g_malloc0(sizeof(*fdset_info));
- fdset_info->value = g_malloc0(sizeof(*fdset_info->value));
- fdset_info->value->fdset_id = mon_fdset->id;
+ fdset_info->fdset_id = mon_fdset->id;
QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
- FdsetFdInfoList *fdsetfd_info;
+ FdsetFdInfo *fdsetfd_info;
fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info));
- fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value));
- fdsetfd_info->value->fd = mon_fdset_fd->fd;
+ fdsetfd_info->fd = mon_fdset_fd->fd;
if (mon_fdset_fd->opaque) {
- fdsetfd_info->value->has_opaque = true;
- fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque);
+ fdsetfd_info->has_opaque = true;
+ fdsetfd_info->opaque = g_strdup(mon_fdset_fd->opaque);
} else {
- fdsetfd_info->value->has_opaque = false;
+ fdsetfd_info->has_opaque = false;
}
- fdsetfd_info->next = fdsetfd_list;
- fdsetfd_list = fdsetfd_info;
+ QAPI_LIST_PREPEND(fdset_info->fds, fdsetfd_info);
}
- fdset_info->value->fds = fdsetfd_list;
-
- fdset_info->next = fdset_list;
- fdset_list = fdset_info;
+ QAPI_LIST_PREPEND(fdset_list, fdset_info);
}
return fdset_list;
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index a613155..40903d6 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -105,7 +105,7 @@ struct Monitor {
* Members that are protected by the per-monitor lock
*/
QLIST_HEAD(, mon_fd_t) fds;
- QString *outbuf;
+ GString *outbuf;
guint out_watch;
/* Read under either BQL or mon_lock, written with BQL+mon_lock. */
int mux_out;
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 84222cd..1e4a6b3 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -29,7 +29,6 @@
#include "qapi/qapi-emit-events.h"
#include "qapi/qapi-visit-control.h"
#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "sysemu/qtest.h"
@@ -181,22 +180,19 @@ static void monitor_flush_locked(Monitor *mon)
return;
}
- buf = qstring_get_str(mon->outbuf);
- len = qstring_get_length(mon->outbuf);
+ buf = mon->outbuf->str;
+ len = mon->outbuf->len;
if (len && !mon->mux_out) {
rc = qemu_chr_fe_write(&mon->chr, (const uint8_t *) buf, len);
if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
/* all flushed or error */
- qobject_unref(mon->outbuf);
- mon->outbuf = qstring_new();
+ g_string_truncate(mon->outbuf, 0);
return;
}
if (rc > 0) {
/* partial write */
- QString *tmp = qstring_from_str(buf + rc);
- qobject_unref(mon->outbuf);
- mon->outbuf = tmp;
+ g_string_erase(mon->outbuf, 0, rc);
}
if (mon->out_watch == 0) {
mon->out_watch =
@@ -223,9 +219,9 @@ int monitor_puts(Monitor *mon, const char *str)
for (i = 0; str[i]; i++) {
c = str[i];
if (c == '\n') {
- qstring_append_chr(mon->outbuf, '\r');
+ g_string_append_c(mon->outbuf, '\r');
}
- qstring_append_chr(mon->outbuf, c);
+ g_string_append_c(mon->outbuf, c);
if (c == '\n') {
monitor_flush_locked(mon);
}
@@ -602,7 +598,7 @@ void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
}
qemu_mutex_init(&mon->mon_lock);
mon->is_qmp = is_qmp;
- mon->outbuf = qstring_new();
+ mon->outbuf = g_string_new(NULL);
mon->skip_flush = skip_flush;
mon->use_io_thread = use_io_thread;
}
@@ -616,7 +612,7 @@ void monitor_data_destroy(Monitor *mon)
} else {
readline_free(container_of(mon, MonitorHMP, common)->rs);
}
- qobject_unref(mon->outbuf);
+ g_string_free(mon->outbuf, true);
qemu_mutex_destroy(&mon->mon_lock);
}
diff --git a/monitor/qmp-cmds-control.c b/monitor/qmp-cmds-control.c
index a456762..17514f4 100644
--- a/monitor/qmp-cmds-control.c
+++ b/monitor/qmp-cmds-control.c
@@ -138,18 +138,18 @@ EventInfoList *qmp_query_events(Error **errp)
* QAPIEvent_str() and QAPIEvent_lookup[]. When the command goes,
* they should go, too.
*/
- EventInfoList *info, *ev_list = NULL;
+ EventInfoList *ev_list = NULL;
QAPIEvent e;
for (e = 0 ; e < QAPI_EVENT__MAX ; e++) {
const char *event_name = QAPIEvent_str(e);
+ EventInfo *info;
+
assert(event_name != NULL);
info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->name = g_strdup(event_name);
+ info->name = g_strdup(event_name);
- info->next = ev_list;
- ev_list = info;
+ QAPI_LIST_PREPEND(ev_list, info);
}
return ev_list;
diff --git a/monitor/qmp.c b/monitor/qmp.c
index b42f8c6..8f91af3 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -31,7 +31,6 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qstring.h"
#include "trace.h"
struct QMPRequest {
@@ -110,15 +109,15 @@ static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon)
void qmp_send_response(MonitorQMP *mon, const QDict *rsp)
{
const QObject *data = QOBJECT(rsp);
- QString *json;
+ GString *json;
- json = mon->pretty ? qobject_to_json_pretty(data) : qobject_to_json(data);
+ json = qobject_to_json_pretty(data, mon->pretty);
assert(json != NULL);
- qstring_append_chr(json, '\n');
- monitor_puts(&mon->common, qstring_get_str(json));
+ g_string_append_c(json, '\n');
+ monitor_puts(&mon->common, json->str);
- qobject_unref(json);
+ g_string_free(json, true);
}
/*
@@ -276,9 +275,15 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1;
qemu_mutex_unlock(&mon->qmp_queue_lock);
if (req_obj->req) {
- QDict *qdict = qobject_to(QDict, req_obj->req);
- QObject *id = qdict ? qdict_get(qdict, "id") : NULL;
- trace_monitor_qmp_cmd_in_band(qobject_get_try_str(id) ?: "");
+ if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) {
+ QDict *qdict = qobject_to(QDict, req_obj->req);
+ QObject *id = qdict ? qdict_get(qdict, "id") : NULL;
+ GString *id_json;
+
+ id_json = id ? qobject_to_json(id) : g_string_new(NULL);
+ trace_monitor_qmp_cmd_in_band(id_json->str);
+ g_string_free(id_json, true);
+ }
monitor_qmp_dispatch(mon, req_obj->req);
} else {
assert(req_obj->err);
@@ -308,26 +313,27 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
static void handle_qmp_command(void *opaque, QObject *req, Error *err)
{
MonitorQMP *mon = opaque;
- QObject *id = NULL;
- QDict *qdict;
+ QDict *qdict = qobject_to(QDict, req);
QMPRequest *req_obj;
assert(!req != !err);
- qdict = qobject_to(QDict, req);
- if (qdict) {
- id = qdict_get(qdict, "id");
- } /* else will fail qmp_dispatch() */
-
if (req && trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND)) {
- QString *req_json = qobject_to_json(req);
- trace_handle_qmp_command(mon, qstring_get_str(req_json));
- qobject_unref(req_json);
+ GString *req_json = qobject_to_json(req);
+ trace_handle_qmp_command(mon, req_json->str);
+ g_string_free(req_json, true);
}
if (qdict && qmp_is_oob(qdict)) {
/* OOB commands are executed immediately */
- trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(id) ?: "");
+ if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_OUT_OF_BAND)) {
+ QObject *id = qdict_get(qdict, "id");
+ GString *id_json;
+
+ id_json = id ? qobject_to_json(id) : g_string_new(NULL);
+ trace_monitor_qmp_cmd_out_of_band(id_json->str);
+ g_string_free(id_json, true);
+ }
monitor_qmp_dispatch(mon, req);
qobject_unref(req);
return;
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index b74aa4d..5506c93 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -258,7 +258,7 @@ static bool print_type_number(Visitor *v, const char *name, double *obj,
Error **errp)
{
StringOutputVisitor *sov = to_sov(v);
- string_output_set(sov, g_strdup_printf("%f", *obj));
+ string_output_set(sov, g_strdup_printf("%.17g", *obj));
return true;
}
diff --git a/qemu-img.c b/qemu-img.c
index 8bdea40..8597d06 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -33,7 +33,6 @@
#include "qapi/qobject-output-visitor.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
#include "qemu/cutils.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
@@ -627,18 +626,18 @@ fail:
static void dump_json_image_check(ImageCheck *check, bool quiet)
{
- QString *str;
+ GString *str;
QObject *obj;
Visitor *v = qobject_output_visitor_new(&obj);
visit_type_ImageCheck(v, NULL, &check, &error_abort);
visit_complete(v, &obj);
- str = qobject_to_json_pretty(obj);
+ str = qobject_to_json_pretty(obj, true);
assert(str != NULL);
- qprintf(quiet, "%s\n", qstring_get_str(str));
+ qprintf(quiet, "%s\n", str->str);
qobject_unref(obj);
visit_free(v);
- qobject_unref(str);
+ g_string_free(str, true);
}
static void dump_human_image_check(ImageCheck *check, bool quiet)
@@ -1652,14 +1651,13 @@ static void do_dirty_bitmap_merge(const char *dst_node, const char *dst_name,
Error **errp)
{
BlockDirtyBitmapMergeSource *merge_src;
- BlockDirtyBitmapMergeSourceList *list;
+ BlockDirtyBitmapMergeSourceList *list = NULL;
merge_src = g_new0(BlockDirtyBitmapMergeSource, 1);
merge_src->type = QTYPE_QDICT;
merge_src->u.external.node = g_strdup(src_node);
merge_src->u.external.name = g_strdup(src_name);
- list = g_new0(BlockDirtyBitmapMergeSourceList, 1);
- list->value = merge_src;
+ QAPI_LIST_PREPEND(list, merge_src);
qmp_block_dirty_bitmap_merge(dst_node, dst_name, list, errp);
qapi_free_BlockDirtyBitmapMergeSourceList(list);
}
@@ -2790,34 +2788,34 @@ static void dump_snapshots(BlockDriverState *bs)
static void dump_json_image_info_list(ImageInfoList *list)
{
- QString *str;
+ GString *str;
QObject *obj;
Visitor *v = qobject_output_visitor_new(&obj);
visit_type_ImageInfoList(v, NULL, &list, &error_abort);
visit_complete(v, &obj);
- str = qobject_to_json_pretty(obj);
+ str = qobject_to_json_pretty(obj, true);
assert(str != NULL);
- printf("%s\n", qstring_get_str(str));
+ printf("%s\n", str->str);
qobject_unref(obj);
visit_free(v);
- qobject_unref(str);
+ g_string_free(str, true);
}
static void dump_json_image_info(ImageInfo *info)
{
- QString *str;
+ GString *str;
QObject *obj;
Visitor *v = qobject_output_visitor_new(&obj);
visit_type_ImageInfo(v, NULL, &info, &error_abort);
visit_complete(v, &obj);
- str = qobject_to_json_pretty(obj);
+ str = qobject_to_json_pretty(obj, true);
assert(str != NULL);
- printf("%s\n", qstring_get_str(str));
+ printf("%s\n", str->str);
qobject_unref(obj);
visit_free(v);
- qobject_unref(str);
+ g_string_free(str, true);
}
static void dump_human_image_info_list(ImageInfoList *list)
@@ -5237,18 +5235,18 @@ out:
static void dump_json_block_measure_info(BlockMeasureInfo *info)
{
- QString *str;
+ GString *str;
QObject *obj;
Visitor *v = qobject_output_visitor_new(&obj);
visit_type_BlockMeasureInfo(v, NULL, &info, &error_abort);
visit_complete(v, &obj);
- str = qobject_to_json_pretty(obj);
+ str = qobject_to_json_pretty(obj, true);
assert(str != NULL);
- printf("%s\n", qstring_get_str(str));
+ printf("%s\n", str->str);
qobject_unref(obj);
visit_free(v);
- qobject_unref(str);
+ g_string_free(str, true);
}
static int img_measure(int argc, char **argv)
diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
index 749167e..2dda136 100644
--- a/qga/commands-posix-ssh.c
+++ b/qga/commands-posix-ssh.c
@@ -293,17 +293,12 @@ qmp_guest_ssh_get_authorized_keys(const char *username, Error **errp)
ret = g_new0(GuestAuthorizedKeys, 1);
for (i = 0; authkeys[i] != NULL; i++) {
- strList *new;
-
g_strstrip(authkeys[i]);
if (!authkeys[i][0] || authkeys[i][0] == '#') {
continue;
}
- new = g_new0(strList, 1);
- new->value = g_strdup(authkeys[i]);
- new->next = ret->keys;
- ret->keys = new;
+ QAPI_LIST_PREPEND(ret->keys, g_strdup(authkeys[i]));
}
return g_steal_pointer(&ret);
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index c089e38..849923b 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1036,7 +1036,6 @@ static void build_guest_fsinfo_for_real_device(char const *syspath,
{
GuestDiskAddress *disk;
GuestPCIAddress *pciaddr;
- GuestDiskAddressList *list = NULL;
bool has_hwinf;
#ifdef CONFIG_LIBUDEV
struct udev *udev = NULL;
@@ -1053,9 +1052,6 @@ static void build_guest_fsinfo_for_real_device(char const *syspath,
disk->pci_controller = pciaddr;
disk->bus_type = GUEST_DISK_BUS_TYPE_UNKNOWN;
- list = g_new0(GuestDiskAddressList, 1);
- list->value = disk;
-
#ifdef CONFIG_LIBUDEV
udev = udev_new();
udevice = udev_device_new_from_syspath(udev, syspath);
@@ -1089,10 +1085,9 @@ static void build_guest_fsinfo_for_real_device(char const *syspath,
}
if (has_hwinf || disk->has_dev || disk->has_serial) {
- list->next = fs->disk;
- fs->disk = list;
+ QAPI_LIST_PREPEND(fs->disk, disk);
} else {
- qapi_free_GuestDiskAddressList(list);
+ qapi_free_GuestDiskAddress(disk);
}
}
@@ -1288,7 +1283,6 @@ static void get_disk_deps(const char *disk_dir, GuestDiskInfo *disk)
disk->has_dependencies = true;
while ((dep = g_dir_read_name(dp_deps)) != NULL) {
g_autofree char *dep_dir = NULL;
- strList *dep_item = NULL;
char *dev_name;
/* Add dependent disks */
@@ -1296,10 +1290,7 @@ static void get_disk_deps(const char *disk_dir, GuestDiskInfo *disk)
dev_name = get_device_for_syspath(dep_dir);
if (dev_name != NULL) {
g_debug(" adding dependent device: %s", dev_name);
- dep_item = g_new0(strList, 1);
- dep_item->value = dev_name;
- dep_item->next = disk->dependencies;
- disk->dependencies = dep_item;
+ QAPI_LIST_PREPEND(disk->dependencies, dev_name);
}
}
g_dir_close(dp_deps);
@@ -1318,7 +1309,7 @@ static GuestDiskInfoList *get_disk_partitions(
const char *disk_name, const char *disk_dir,
const char *disk_dev)
{
- GuestDiskInfoList *item, *ret = list;
+ GuestDiskInfoList *ret = list;
struct dirent *de_disk;
DIR *dp_disk = NULL;
size_t len = strlen(disk_name);
@@ -1352,15 +1343,9 @@ static GuestDiskInfoList *get_disk_partitions(
partition->name = dev_name;
partition->partition = true;
/* Add parent disk as dependent for easier tracking of hierarchy */
- partition->dependencies = g_new0(strList, 1);
- partition->dependencies->value = g_strdup(disk_dev);
- partition->has_dependencies = true;
-
- item = g_new0(GuestDiskInfoList, 1);
- item->value = partition;
- item->next = ret;
- ret = item;
+ QAPI_LIST_PREPEND(partition->dependencies, g_strdup(disk_dev));
+ QAPI_LIST_PREPEND(ret, partition);
}
closedir(dp_disk);
@@ -1369,7 +1354,7 @@ static GuestDiskInfoList *get_disk_partitions(
GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
{
- GuestDiskInfoList *item, *ret = NULL;
+ GuestDiskInfoList *ret = NULL;
GuestDiskInfo *disk;
DIR *dp = NULL;
struct dirent *de = NULL;
@@ -1415,10 +1400,7 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
disk->partition = false;
disk->alias = get_alias_for_syspath(disk_dir);
disk->has_alias = (disk->alias != NULL);
- item = g_new0(GuestDiskInfoList, 1);
- item->value = disk;
- item->next = ret;
- ret = item;
+ QAPI_LIST_PREPEND(ret, disk);
/* Get address for non-virtual devices */
bool is_virtual = is_disk_virtual(disk_dir, &local_err);
@@ -1495,7 +1477,7 @@ GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
{
FsMountList mounts;
struct FsMount *mount;
- GuestFilesystemInfoList *new, *ret = NULL;
+ GuestFilesystemInfoList *ret = NULL;
Error *local_err = NULL;
QTAILQ_INIT(&mounts);
@@ -1508,10 +1490,7 @@ GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
QTAILQ_FOREACH(mount, &mounts, next) {
g_debug("Building guest fsinfo for '%s'", mount->dirname);
- new = g_malloc0(sizeof(*ret));
- new->value = build_guest_fsinfo(mount, &local_err);
- new->next = ret;
- ret = new;
+ QAPI_LIST_PREPEND(ret, build_guest_fsinfo(mount, &local_err));
if (local_err) {
error_propagate(errp, local_err);
qapi_free_GuestFilesystemInfoList(ret);
@@ -1777,7 +1756,6 @@ GuestFilesystemTrimResponse *
qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
{
GuestFilesystemTrimResponse *response;
- GuestFilesystemTrimResultList *list;
GuestFilesystemTrimResult *result;
int ret = 0;
FsMountList mounts;
@@ -1801,10 +1779,7 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
result = g_malloc0(sizeof(*result));
result->path = g_strdup(mount->dirname);
- list = g_malloc0(sizeof(*list));
- list->value = result;
- list->next = response->paths;
- response->paths = list;
+ QAPI_LIST_PREPEND(response->paths, result);
fd = qemu_open_old(mount->dirname, O_RDONLY);
if (fd == -1) {
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index ba1fd07..684639b 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -874,7 +874,7 @@ err_close:
static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
{
Error *local_err = NULL;
- GuestDiskAddressList *list = NULL, *cur_item = NULL;
+ GuestDiskAddressList *list = NULL;
GuestDiskAddress *disk = NULL;
int i;
HANDLE vol_h;
@@ -926,10 +926,8 @@ static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
error_free(local_err);
goto out;
}
- list = g_malloc0(sizeof(*list));
- list->value = disk;
+ QAPI_LIST_PREPEND(list, disk);
disk = NULL;
- list->next = NULL;
goto out;
} else {
error_setg_win32(errp, GetLastError(),
@@ -960,11 +958,8 @@ static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
error_propagate(errp, local_err);
goto out;
}
- cur_item = g_malloc0(sizeof(*list));
- cur_item->value = disk;
+ QAPI_LIST_PREPEND(list, disk);
disk = NULL;
- cur_item->next = list;
- list = cur_item;
}
@@ -982,7 +977,7 @@ out:
GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
{
ERRP_GUARD();
- GuestDiskInfoList *new = NULL, *ret = NULL;
+ GuestDiskInfoList *ret = NULL;
HDEVINFO dev_info;
SP_DEVICE_INTERFACE_DATA dev_iface_data;
int i;
@@ -1064,10 +1059,7 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
disk->has_address = true;
}
- new = g_malloc0(sizeof(GuestDiskInfoList));
- new->value = disk;
- new->next = ret;
- ret = new;
+ QAPI_LIST_PREPEND(ret, disk);
}
SetupDiDestroyDeviceInfoList(dev_info);
@@ -1165,7 +1157,7 @@ free:
GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
{
HANDLE vol_h;
- GuestFilesystemInfoList *new, *ret = NULL;
+ GuestFilesystemInfoList *ret = NULL;
char guid[256];
vol_h = FindFirstVolume(guid, sizeof(guid));
@@ -1183,10 +1175,7 @@ GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
error_free(local_err);
continue;
}
- new = g_malloc(sizeof(*ret));
- new->value = info;
- new->next = ret;
- ret = new;
+ QAPI_LIST_PREPEND(ret, info);
} while (FindNextVolume(vol_h, guid, sizeof(guid)));
if (GetLastError() != ERROR_NO_MORE_FILES) {
@@ -1330,7 +1319,6 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
do {
GuestFilesystemTrimResult *res;
- GuestFilesystemTrimResultList *list;
PWCHAR uc_path;
DWORD char_count = 0;
char *path, *out;
@@ -1369,11 +1357,7 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
res->path = path;
- list = g_new0(GuestFilesystemTrimResultList, 1);
- list->value = res;
- list->next = resp->paths;
-
- resp->paths = list;
+ QAPI_LIST_PREPEND(resp->paths, res);
memset(argv, 0, sizeof(argv));
argv[0] = (gchar *)"defrag.exe";
diff --git a/qga/commands.c b/qga/commands.c
index 3dcd5fb..e866fc7 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -66,17 +66,13 @@ static void qmp_command_info(const QmpCommand *cmd, void *opaque)
{
GuestAgentInfo *info = opaque;
GuestAgentCommandInfo *cmd_info;
- GuestAgentCommandInfoList *cmd_info_list;
cmd_info = g_new0(GuestAgentCommandInfo, 1);
cmd_info->name = g_strdup(qmp_command_name(cmd));
cmd_info->enabled = qmp_command_is_enabled(cmd);
cmd_info->success_response = qmp_has_success_response(cmd);
- cmd_info_list = g_new0(GuestAgentCommandInfoList, 1);
- cmd_info_list->value = cmd_info;
- cmd_info_list->next = info->supported_commands;
- info->supported_commands = cmd_info_list;
+ QAPI_LIST_PREPEND(info->supported_commands, cmd_info);
}
struct GuestAgentInfo *qmp_guest_info(Error **errp)
diff --git a/qga/main.c b/qga/main.c
index dea6a3a..e7f8f3b 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -22,7 +22,6 @@
#include "qapi/qmp/json-parser.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qstring.h"
#include "guest-agent-core.h"
#include "qga-qapi-init-commands.h"
#include "qapi/qmp/qerror.h"
@@ -528,8 +527,7 @@ fail:
static int send_response(GAState *s, const QDict *rsp)
{
- const char *buf;
- QString *payload_qstr, *response_qstr;
+ GString *response;
GIOStatus status;
g_assert(s->channel);
@@ -538,25 +536,19 @@ static int send_response(GAState *s, const QDict *rsp)
return 0;
}
- payload_qstr = qobject_to_json(QOBJECT(rsp));
- if (!payload_qstr) {
+ response = qobject_to_json(QOBJECT(rsp));
+ if (!response) {
return -EINVAL;
}
if (s->delimit_response) {
s->delimit_response = false;
- response_qstr = qstring_new();
- qstring_append_chr(response_qstr, QGA_SENTINEL_BYTE);
- qstring_append(response_qstr, qstring_get_str(payload_qstr));
- qobject_unref(payload_qstr);
- } else {
- response_qstr = payload_qstr;
+ g_string_prepend_c(response, QGA_SENTINEL_BYTE);
}
- qstring_append_chr(response_qstr, '\n');
- buf = qstring_get_str(response_qstr);
- status = ga_channel_write_all(s->channel, buf, strlen(buf));
- qobject_unref(response_qstr);
+ g_string_append_c(response, '\n');
+ status = ga_channel_write_all(s->channel, response->str, response->len);
+ g_string_free(response, true);
if (status != G_IO_STATUS_NORMAL) {
return -EIO;
}
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index c0f521b..d351039 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -130,7 +130,7 @@ static int cvt4hex(const char *s)
static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
{
const char *ptr = token->str;
- QString *str;
+ GString *str;
char quote;
const char *beg;
int cp, trailing;
@@ -140,7 +140,7 @@ static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
assert(*ptr == '"' || *ptr == '\'');
quote = *ptr++;
- str = qstring_new();
+ str = g_string_new(NULL);
while (*ptr != quote) {
assert(*ptr);
@@ -149,31 +149,31 @@ static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
beg = ptr++;
switch (*ptr++) {
case '"':
- qstring_append_chr(str, '"');
+ g_string_append_c(str, '"');
break;
case '\'':
- qstring_append_chr(str, '\'');
+ g_string_append_c(str, '\'');
break;
case '\\':
- qstring_append_chr(str, '\\');
+ g_string_append_c(str, '\\');
break;
case '/':
- qstring_append_chr(str, '/');
+ g_string_append_c(str, '/');
break;
case 'b':
- qstring_append_chr(str, '\b');
+ g_string_append_c(str, '\b');
break;
case 'f':
- qstring_append_chr(str, '\f');
+ g_string_append_c(str, '\f');
break;
case 'n':
- qstring_append_chr(str, '\n');
+ g_string_append_c(str, '\n');
break;
case 'r':
- qstring_append_chr(str, '\r');
+ g_string_append_c(str, '\r');
break;
case 't':
- qstring_append_chr(str, '\t');
+ g_string_append_c(str, '\t');
break;
case 'u':
cp = cvt4hex(ptr);
@@ -200,7 +200,7 @@ static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
(int)(ptr - beg), beg);
goto out;
}
- qstring_append(str, utf8_buf);
+ g_string_append(str, utf8_buf);
break;
default:
parse_error(ctxt, token, "invalid escape sequence in string");
@@ -225,14 +225,14 @@ static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
ptr = end;
len = mod_utf8_encode(utf8_buf, sizeof(utf8_buf), cp);
assert(len >= 0);
- qstring_append(str, utf8_buf);
+ g_string_append(str, utf8_buf);
}
}
- return str;
+ return qstring_from_gstring(str);
out:
- qobject_unref(str);
+ g_string_free(str, true);
return NULL;
}
diff --git a/qobject/json-writer.c b/qobject/json-writer.c
new file mode 100644
index 0000000..309a31d
--- /dev/null
+++ b/qobject/json-writer.c
@@ -0,0 +1,247 @@
+/*
+ * JSON Writer
+ *
+ * Copyright IBM, Corp. 2009
+ * Copyright (c) 2010-2020 Red Hat Inc.
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qmp/json-writer.h"
+#include "qemu/unicode.h"
+
+struct JSONWriter {
+ bool pretty;
+ bool need_comma;
+ GString *contents;
+ GByteArray *container_is_array;
+};
+
+JSONWriter *json_writer_new(bool pretty)
+{
+ JSONWriter *writer = g_new(JSONWriter, 1);
+
+ writer->pretty = pretty;
+ writer->need_comma = false;
+ writer->contents = g_string_new(NULL);
+ writer->container_is_array = g_byte_array_new();
+ return writer;
+}
+
+const char *json_writer_get(JSONWriter *writer)
+{
+ g_assert(!writer->container_is_array->len);
+ return writer->contents->str;
+}
+
+GString *json_writer_get_and_free(JSONWriter *writer)
+{
+ GString *contents = writer->contents;
+
+ writer->contents = NULL;
+ g_byte_array_free(writer->container_is_array, true);
+ g_free(writer);
+ return contents;
+}
+
+void json_writer_free(JSONWriter *writer)
+{
+ if (writer) {
+ g_string_free(json_writer_get_and_free(writer), true);
+ }
+}
+
+static void enter_container(JSONWriter *writer, bool is_array)
+{
+ unsigned depth = writer->container_is_array->len;
+
+ g_byte_array_set_size(writer->container_is_array, depth + 1);
+ writer->container_is_array->data[depth] = is_array;
+ writer->need_comma = false;
+}
+
+static void leave_container(JSONWriter *writer, bool is_array)
+{
+ unsigned depth = writer->container_is_array->len;
+
+ assert(depth);
+ assert(writer->container_is_array->data[depth - 1] == is_array);
+ g_byte_array_set_size(writer->container_is_array, depth - 1);
+ writer->need_comma = true;
+}
+
+static bool in_object(JSONWriter *writer)
+{
+ unsigned depth = writer->container_is_array->len;
+
+ return depth && !writer->container_is_array->data[depth - 1];
+}
+
+static void pretty_newline(JSONWriter *writer)
+{
+ if (writer->pretty) {
+ g_string_append_printf(writer->contents, "\n%*s",
+ writer->container_is_array->len * 4, "");
+ }
+}
+
+static void pretty_newline_or_space(JSONWriter *writer)
+{
+ if (writer->pretty) {
+ g_string_append_printf(writer->contents, "\n%*s",
+ writer->container_is_array->len * 4, "");
+ } else {
+ g_string_append_c(writer->contents, ' ');
+ }
+}
+
+static void quoted_str(JSONWriter *writer, const char *str)
+{
+ const char *ptr;
+ char *end;
+ int cp;
+
+ g_string_append_c(writer->contents, '"');
+
+ for (ptr = str; *ptr; ptr = end) {
+ cp = mod_utf8_codepoint(ptr, 6, &end);
+ switch (cp) {
+ case '\"':
+ g_string_append(writer->contents, "\\\"");
+ break;
+ case '\\':
+ g_string_append(writer->contents, "\\\\");
+ break;
+ case '\b':
+ g_string_append(writer->contents, "\\b");
+ break;
+ case '\f':
+ g_string_append(writer->contents, "\\f");
+ break;
+ case '\n':
+ g_string_append(writer->contents, "\\n");
+ break;
+ case '\r':
+ g_string_append(writer->contents, "\\r");
+ break;
+ case '\t':
+ g_string_append(writer->contents, "\\t");
+ break;
+ default:
+ if (cp < 0) {
+ cp = 0xFFFD; /* replacement character */
+ }
+ if (cp > 0xFFFF) {
+ /* beyond BMP; need a surrogate pair */
+ g_string_append_printf(writer->contents, "\\u%04X\\u%04X",
+ 0xD800 + ((cp - 0x10000) >> 10),
+ 0xDC00 + ((cp - 0x10000) & 0x3FF));
+ } else if (cp < 0x20 || cp >= 0x7F) {
+ g_string_append_printf(writer->contents, "\\u%04X", cp);
+ } else {
+ g_string_append_c(writer->contents, cp);
+ }
+ }
+ };
+
+ g_string_append_c(writer->contents, '"');
+}
+
+static void maybe_comma_name(JSONWriter *writer, const char *name)
+{
+ if (writer->need_comma) {
+ g_string_append_c(writer->contents, ',');
+ pretty_newline_or_space(writer);
+ } else {
+ if (writer->contents->len) {
+ pretty_newline(writer);
+ }
+ writer->need_comma = true;
+ }
+
+ if (in_object(writer)) {
+ quoted_str(writer, name);
+ g_string_append(writer->contents, ": ");
+ }
+}
+
+void json_writer_start_object(JSONWriter *writer, const char *name)
+{
+ maybe_comma_name(writer, name);
+ g_string_append_c(writer->contents, '{');
+ enter_container(writer, false);
+}
+
+void json_writer_end_object(JSONWriter *writer)
+{
+ leave_container(writer, false);
+ pretty_newline(writer);
+ g_string_append_c(writer->contents, '}');
+}
+
+void json_writer_start_array(JSONWriter *writer, const char *name)
+{
+ maybe_comma_name(writer, name);
+ g_string_append_c(writer->contents, '[');
+ enter_container(writer, true);
+}
+
+void json_writer_end_array(JSONWriter *writer)
+{
+ leave_container(writer, true);
+ pretty_newline(writer);
+ g_string_append_c(writer->contents, ']');
+}
+
+void json_writer_bool(JSONWriter *writer, const char *name, bool val)
+{
+ maybe_comma_name(writer, name);
+ g_string_append(writer->contents, val ? "true" : "false");
+}
+
+void json_writer_null(JSONWriter *writer, const char *name)
+{
+ maybe_comma_name(writer, name);
+ g_string_append(writer->contents, "null");
+}
+
+void json_writer_int64(JSONWriter *writer, const char *name, int64_t val)
+{
+ maybe_comma_name(writer, name);
+ g_string_append_printf(writer->contents, "%" PRId64, val);
+}
+
+void json_writer_uint64(JSONWriter *writer, const char *name, uint64_t val)
+{
+ maybe_comma_name(writer, name);
+ g_string_append_printf(writer->contents, "%" PRIu64, val);
+}
+
+void json_writer_double(JSONWriter *writer, const char *name, double val)
+{
+ maybe_comma_name(writer, name);
+
+ /*
+ * FIXME: g_string_append_printf() is locale dependent; but JSON
+ * requires numbers to be formatted as if in the C locale.
+ * Dependence on C locale is a pervasive issue in QEMU.
+ */
+ /*
+ * FIXME: This risks printing Inf or NaN, which are not valid
+ * JSON values.
+ */
+ g_string_append_printf(writer->contents, "%.17g", val);
+}
+
+void json_writer_str(JSONWriter *writer, const char *name, const char *str)
+{
+ maybe_comma_name(writer, name);
+ quoted_str(writer, str);
+}
diff --git a/qobject/meson.build b/qobject/meson.build
index bb63c06..4683a85 100644
--- a/qobject/meson.build
+++ b/qobject/meson.build
@@ -1,3 +1,4 @@
-util_ss.add(files('qnull.c', 'qnum.c', 'qstring.c', 'qdict.c', 'qlist.c', 'qbool.c',
- 'qlit.c', 'qjson.c', 'qobject.c', 'json-lexer.c', 'json-streamer.c', 'json-parser.c',
+util_ss.add(files('qnull.c', 'qnum.c', 'qstring.c', 'qdict.c',
+ 'qlist.c', 'qbool.c', 'qlit.c', 'qjson.c', 'qobject.c',
+ 'json-writer.c', 'json-lexer.c', 'json-streamer.c', 'json-parser.c',
'block-qdict.c'))
diff --git a/qobject/qbool.c b/qobject/qbool.c
index 06dfc43..16a600a 100644
--- a/qobject/qbool.c
+++ b/qobject/qbool.c
@@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qbool.h"
+#include "qobject-internal.h"
/**
* qbool_from_bool(): Create a new QBool from a bool
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 1079bd3..d844433 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -16,6 +16,7 @@
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qnull.h"
#include "qapi/qmp/qstring.h"
+#include "qobject-internal.h"
/**
* qdict_new(): Create a new QDict
diff --git a/qobject/qjson.c b/qobject/qjson.c
index f1f2c69..bcc376e 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -14,13 +14,13 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qmp/json-parser.h"
+#include "qapi/qmp/json-writer.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
-#include "qemu/unicode.h"
typedef struct JSONParsingState
{
@@ -149,144 +149,69 @@ QDict *qdict_from_jsonf_nofail(const char *string, ...)
return qdict;
}
-static void to_json(const QObject *obj, QString *str, int pretty, int indent);
-
-static void json_pretty_newline(QString *str, bool pretty, int indent)
-{
- int i;
-
- if (pretty) {
- qstring_append(str, "\n");
- for (i = 0; i < indent; i++) {
- qstring_append(str, " ");
- }
- }
-}
-
-static void to_json(const QObject *obj, QString *str, int pretty, int indent)
+static void to_json(JSONWriter *writer, const char *name,
+ const QObject *obj)
{
switch (qobject_type(obj)) {
case QTYPE_QNULL:
- qstring_append(str, "null");
+ json_writer_null(writer, name);
break;
case QTYPE_QNUM: {
QNum *val = qobject_to(QNum, obj);
- char *buffer = qnum_to_string(val);
- qstring_append(str, buffer);
- g_free(buffer);
+
+ switch (val->kind) {
+ case QNUM_I64:
+ json_writer_int64(writer, name, val->u.i64);
+ break;
+ case QNUM_U64:
+ json_writer_uint64(writer, name, val->u.u64);
+ break;
+ case QNUM_DOUBLE:
+ json_writer_double(writer, name, val->u.dbl);
+ break;
+ default:
+ abort();
+ }
break;
}
case QTYPE_QSTRING: {
QString *val = qobject_to(QString, obj);
- const char *ptr;
- int cp;
- char buf[16];
- char *end;
-
- ptr = qstring_get_str(val);
- qstring_append(str, "\"");
-
- for (; *ptr; ptr = end) {
- cp = mod_utf8_codepoint(ptr, 6, &end);
- switch (cp) {
- case '\"':
- qstring_append(str, "\\\"");
- break;
- case '\\':
- qstring_append(str, "\\\\");
- break;
- case '\b':
- qstring_append(str, "\\b");
- break;
- case '\f':
- qstring_append(str, "\\f");
- break;
- case '\n':
- qstring_append(str, "\\n");
- break;
- case '\r':
- qstring_append(str, "\\r");
- break;
- case '\t':
- qstring_append(str, "\\t");
- break;
- default:
- if (cp < 0) {
- cp = 0xFFFD; /* replacement character */
- }
- if (cp > 0xFFFF) {
- /* beyond BMP; need a surrogate pair */
- snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
- 0xD800 + ((cp - 0x10000) >> 10),
- 0xDC00 + ((cp - 0x10000) & 0x3FF));
- } else if (cp < 0x20 || cp >= 0x7F) {
- snprintf(buf, sizeof(buf), "\\u%04X", cp);
- } else {
- buf[0] = cp;
- buf[1] = 0;
- }
- qstring_append(str, buf);
- }
- };
-
- qstring_append(str, "\"");
+
+ json_writer_str(writer, name, qstring_get_str(val));
break;
}
case QTYPE_QDICT: {
QDict *val = qobject_to(QDict, obj);
- const char *comma = pretty ? "," : ", ";
- const char *sep = "";
const QDictEntry *entry;
- QString *qkey;
- qstring_append(str, "{");
+ json_writer_start_object(writer, name);
for (entry = qdict_first(val);
entry;
entry = qdict_next(val, entry)) {
- qstring_append(str, sep);
- json_pretty_newline(str, pretty, indent + 1);
-
- qkey = qstring_from_str(qdict_entry_key(entry));
- to_json(QOBJECT(qkey), str, pretty, indent + 1);
- qobject_unref(qkey);
-
- qstring_append(str, ": ");
- to_json(qdict_entry_value(entry), str, pretty, indent + 1);
- sep = comma;
+ to_json(writer, qdict_entry_key(entry), qdict_entry_value(entry));
}
- json_pretty_newline(str, pretty, indent);
- qstring_append(str, "}");
+ json_writer_end_object(writer);
break;
}
case QTYPE_QLIST: {
QList *val = qobject_to(QList, obj);
- const char *comma = pretty ? "," : ", ";
- const char *sep = "";
QListEntry *entry;
- qstring_append(str, "[");
+ json_writer_start_array(writer, name);
QLIST_FOREACH_ENTRY(val, entry) {
- qstring_append(str, sep);
- json_pretty_newline(str, pretty, indent + 1);
- to_json(qlist_entry_obj(entry), str, pretty, indent + 1);
- sep = comma;
+ to_json(writer, NULL, qlist_entry_obj(entry));
}
- json_pretty_newline(str, pretty, indent);
- qstring_append(str, "]");
+ json_writer_end_array(writer);
break;
}
case QTYPE_QBOOL: {
QBool *val = qobject_to(QBool, obj);
- if (qbool_get_bool(val)) {
- qstring_append(str, "true");
- } else {
- qstring_append(str, "false");
- }
+ json_writer_bool(writer, name, qbool_get_bool(val));
break;
}
default:
@@ -294,20 +219,15 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
}
}
-QString *qobject_to_json(const QObject *obj)
+GString *qobject_to_json_pretty(const QObject *obj, bool pretty)
{
- QString *str = qstring_new();
-
- to_json(obj, str, 0, 0);
+ JSONWriter *writer = json_writer_new(pretty);
- return str;
+ to_json(writer, NULL, obj);
+ return json_writer_get_and_free(writer);
}
-QString *qobject_to_json_pretty(const QObject *obj)
+GString *qobject_to_json(const QObject *obj)
{
- QString *str = qstring_new();
-
- to_json(obj, str, 1, 0);
-
- return str;
+ return qobject_to_json_pretty(obj, false);
}
diff --git a/qobject/qlist.c b/qobject/qlist.c
index 1be9536..60562a1 100644
--- a/qobject/qlist.c
+++ b/qobject/qlist.c
@@ -17,6 +17,7 @@
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
#include "qemu/queue.h"
+#include "qobject-internal.h"
/**
* qlist_new(): Create a new QList
diff --git a/qobject/qnull.c b/qobject/qnull.c
index 00870a1..b26b368 100644
--- a/qobject/qnull.c
+++ b/qobject/qnull.c
@@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qnull.h"
+#include "qobject-internal.h"
QNull qnull_ = {
.base = {
diff --git a/qobject/qnum.c b/qobject/qnum.c
index 7012fc5..5dd6693 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qnum.h"
+#include "qobject-internal.h"
/**
* qnum_from_int(): Create a new QNum from an int64_t
@@ -161,37 +162,14 @@ double qnum_get_double(QNum *qn)
char *qnum_to_string(QNum *qn)
{
- char *buffer;
- int len;
-
switch (qn->kind) {
case QNUM_I64:
return g_strdup_printf("%" PRId64, qn->u.i64);
case QNUM_U64:
return g_strdup_printf("%" PRIu64, qn->u.u64);
case QNUM_DOUBLE:
- /* FIXME: snprintf() is locale dependent; but JSON requires
- * numbers to be formatted as if in the C locale. Dependence
- * on C locale is a pervasive issue in QEMU. */
- /* FIXME: This risks printing Inf or NaN, which are not valid
- * JSON values. */
- /* FIXME: the default precision of 6 for %f often causes
- * rounding errors; we should be using DBL_DECIMAL_DIG (17),
- * and only rounding to a shorter number if the result would
- * still produce the same floating point value. */
- buffer = g_strdup_printf("%f" , qn->u.dbl);
- len = strlen(buffer);
- while (len > 0 && buffer[len - 1] == '0') {
- len--;
- }
-
- if (len && buffer[len - 1] == '.') {
- buffer[len - 1] = 0;
- } else {
- buffer[len] = 0;
- }
-
- return buffer;
+ /* 17 digits suffice for IEEE double */
+ return g_strdup_printf("%.17g", qn->u.dbl);
}
assert(0);
diff --git a/qobject/qobject-internal.h b/qobject/qobject-internal.h
new file mode 100644
index 0000000..b310c8e
--- /dev/null
+++ b/qobject/qobject-internal.h
@@ -0,0 +1,39 @@
+/*
+ * QObject internals
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QOBJECT_INTERNAL_H
+#define QOBJECT_INTERNAL_H
+
+#include "qapi/qmp/qobject.h"
+
+static inline void qobject_init(QObject *obj, QType type)
+{
+ assert(QTYPE_NONE < type && type < QTYPE__MAX);
+ obj->base.refcnt = 1;
+ obj->base.type = type;
+}
+
+void qbool_destroy_obj(QObject *obj);
+bool qbool_is_equal(const QObject *x, const QObject *y);
+
+void qdict_destroy_obj(QObject *obj);
+bool qdict_is_equal(const QObject *x, const QObject *y);
+
+void qlist_destroy_obj(QObject *obj);
+bool qlist_is_equal(const QObject *x, const QObject *y);
+
+bool qnull_is_equal(const QObject *x, const QObject *y);
+
+void qnum_destroy_obj(QObject *obj);
+bool qnum_is_equal(const QObject *x, const QObject *y);
+
+void qstring_destroy_obj(QObject *obj);
+bool qstring_is_equal(const QObject *x, const QObject *y);
+
+#endif
diff --git a/qobject/qobject.c b/qobject/qobject.c
index 878dd76..d7077b8 100644
--- a/qobject/qobject.c
+++ b/qobject/qobject.c
@@ -14,6 +14,7 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qstring.h"
+#include "qobject-internal.h"
QEMU_BUILD_BUG_MSG(
offsetof(QNull, base) != 0 ||
diff --git a/qobject/qstring.c b/qobject/qstring.c
index b66a2c3..b461389 100644
--- a/qobject/qstring.c
+++ b/qobject/qstring.c
@@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qstring.h"
+#include "qobject-internal.h"
/**
* qstring_new(): Create a new empty QString
@@ -24,14 +25,6 @@ QString *qstring_new(void)
}
/**
- * qstring_get_length(): Get the length of a QString
- */
-size_t qstring_get_length(const QString *qstring)
-{
- return qstring->length;
-}
-
-/**
* qstring_from_substr(): Create a new QString from a C string substring
*
* Return string reference
@@ -41,18 +34,9 @@ QString *qstring_from_substr(const char *str, size_t start, size_t end)
QString *qstring;
assert(start <= end);
-
qstring = g_malloc(sizeof(*qstring));
qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
-
- qstring->length = end - start;
- qstring->capacity = qstring->length;
-
- assert(qstring->capacity < SIZE_MAX);
- qstring->string = g_malloc(qstring->capacity + 1);
- memcpy(qstring->string, str + start, qstring->length);
- qstring->string[qstring->length] = 0;
-
+ qstring->string = g_strndup(str + start, end - start);
return qstring;
}
@@ -66,47 +50,22 @@ QString *qstring_from_str(const char *str)
return qstring_from_substr(str, 0, strlen(str));
}
-static void capacity_increase(QString *qstring, size_t len)
-{
- if (qstring->capacity < (qstring->length + len)) {
- assert(len <= SIZE_MAX - qstring->capacity);
- qstring->capacity += len;
- assert(qstring->capacity <= SIZE_MAX / 2);
- qstring->capacity *= 2; /* use exponential growth */
-
- qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
- }
-}
-
-/* qstring_append(): Append a C string to a QString
+/**
+ * qstring_from_gstring(): Convert a GString to a QString
+ *
+ * Return strong reference.
*/
-void qstring_append(QString *qstring, const char *str)
-{
- size_t len = strlen(str);
-
- capacity_increase(qstring, len);
- memcpy(qstring->string + qstring->length, str, len);
- qstring->length += len;
- qstring->string[qstring->length] = 0;
-}
-void qstring_append_int(QString *qstring, int64_t value)
+QString *qstring_from_gstring(GString *gstr)
{
- char num[32];
+ QString *qstring;
- snprintf(num, sizeof(num), "%" PRId64, value);
- qstring_append(qstring, num);
+ qstring = g_malloc(sizeof(*qstring));
+ qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
+ qstring->string = g_string_free(gstr, false);
+ return qstring;
}
-/**
- * qstring_append_chr(): Append a C char to a QString
- */
-void qstring_append_chr(QString *qstring, int c)
-{
- capacity_increase(qstring, 1);
- qstring->string[qstring->length++] = c;
- qstring->string[qstring->length] = 0;
-}
/**
* qstring_get_str(): Return a pointer to the stored string
@@ -120,27 +79,6 @@ const char *qstring_get_str(const QString *qstring)
}
/**
- * qstring_get_try_str(): Return a pointer to the stored string
- *
- * NOTE: will return NULL if qstring is not provided.
- */
-const char *qstring_get_try_str(const QString *qstring)
-{
- return qstring ? qstring_get_str(qstring) : NULL;
-}
-
-/**
- * qobject_get_try_str(): Return a pointer to the corresponding string
- *
- * NOTE: the string will only be returned if the object is valid, and
- * its type is QString, otherwise NULL is returned.
- */
-const char *qobject_get_try_str(const QObject *qstring)
-{
- return qstring_get_try_str(qobject_to(QString, qstring));
-}
-
-/**
* qstring_is_equal(): Test whether the two QStrings are equal
*/
bool qstring_is_equal(const QObject *x, const QObject *y)
@@ -150,32 +88,15 @@ bool qstring_is_equal(const QObject *x, const QObject *y)
}
/**
- * qstring_free(): Free the memory allocated by a QString object
- *
- * Return: if @return_str, return the underlying string, to be
- * g_free(), otherwise NULL is returned.
- */
-char *qstring_free(QString *qstring, bool return_str)
-{
- char *rv = NULL;
-
- if (return_str) {
- rv = qstring->string;
- } else {
- g_free(qstring->string);
- }
-
- g_free(qstring);
-
- return rv;
-}
-
-/**
* qstring_destroy_obj(): Free all memory allocated by a QString
* object
*/
void qstring_destroy_obj(QObject *obj)
{
+ QString *qs;
+
assert(obj != NULL);
- qstring_free(qobject_to(QString, obj), FALSE);
+ qs = qobject_to(QString, obj);
+ g_free((char *)qs->string);
+ g_free(qs);
}
diff --git a/qom/object.c b/qom/object.c
index f2ae6e6..5cd43fe 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1415,15 +1415,18 @@ char *object_property_get_str(Object *obj, const char *name,
Error **errp)
{
QObject *ret = object_property_get_qobject(obj, name, errp);
+ QString *qstring;
char *retval;
if (!ret) {
return NULL;
}
-
- retval = g_strdup(qobject_get_try_str(ret));
- if (!retval) {
+ qstring = qobject_to(QString, ret);
+ if (!qstring) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
+ retval = NULL;
+ } else {
+ retval = g_strdup(qstring_get_str(qstring));
}
qobject_unref(ret);
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index ed896fe..1e9ad6f 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -5,7 +5,6 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qstring.h"
#include "qapi/qobject-input-visitor.h"
#include "qom/object_interfaces.h"
#include "qemu/help_option.h"
@@ -207,7 +206,8 @@ char *object_property_help(const char *name, const char *type,
g_string_append(str, description);
}
if (defval) {
- g_autofree char *def_json = qstring_free(qobject_to_json(defval), TRUE);
+ g_autofree char *def_json = g_string_free(qobject_to_json(defval),
+ true);
g_string_append_printf(str, " (default: %s)", def_json);
}
diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index 8861a10..453fbfe 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -13,7 +13,6 @@
#include "qapi/qapi-commands-qom.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qstring.h"
#include "qom/object.h"
void hmp_qom_list(Monitor *mon, const QDict *qdict)
@@ -78,9 +77,9 @@ void hmp_qom_get(Monitor *mon, const QDict *qdict)
QObject *obj = qmp_qom_get(path, property, &err);
if (err == NULL) {
- QString *str = qobject_to_json_pretty(obj);
- monitor_printf(mon, "%s\n", qstring_get_str(str));
- qobject_unref(str);
+ GString *str = qobject_to_json_pretty(obj, true);
+ monitor_printf(mon, "%s\n", str->str);
+ g_string_free(str, true);
}
qobject_unref(obj);
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 2dd233f..b40ac39 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -46,14 +46,12 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
object_property_iter_init(&iter, obj);
while ((prop = object_property_iter_next(&iter))) {
- ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
+ ObjectPropertyInfo *value = g_malloc0(sizeof(ObjectPropertyInfo));
- entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
- entry->next = props;
- props = entry;
+ QAPI_LIST_PREPEND(props, value);
- entry->value->name = g_strdup(prop->name);
- entry->value->type = g_strdup(prop->type);
+ value->name = g_strdup(prop->name);
+ value->type = g_strdup(prop->type);
}
return props;
@@ -90,7 +88,7 @@ QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
static void qom_list_types_tramp(ObjectClass *klass, void *data)
{
- ObjectTypeInfoList *e, **pret = data;
+ ObjectTypeInfoList **pret = data;
ObjectTypeInfo *info;
ObjectClass *parent = object_class_get_parent(klass);
@@ -102,10 +100,7 @@ static void qom_list_types_tramp(ObjectClass *klass, void *data)
info->parent = g_strdup(object_class_get_name(parent));
}
- e = g_malloc0(sizeof(*e));
- e->value = info;
- e->next = *pret;
- *pret = e;
+ QAPI_LIST_PREPEND(*pret, info);
}
ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
@@ -150,7 +145,6 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
object_property_iter_init(&iter, obj);
while ((prop = object_property_iter_next(&iter))) {
ObjectPropertyInfo *info;
- ObjectPropertyInfoList *entry;
/* Skip Object and DeviceState properties */
if (strcmp(prop->name, "type") == 0 ||
@@ -176,10 +170,7 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
info->default_value = qobject_ref(prop->defval);
info->has_default_value = !!info->default_value;
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = prop_list;
- prop_list = entry;
+ QAPI_LIST_PREPEND(prop_list, info);
}
object_unref(obj);
@@ -217,7 +208,6 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
}
while ((prop = object_property_iter_next(&iter))) {
ObjectPropertyInfo *info;
- ObjectPropertyInfoList *entry;
info = g_malloc0(sizeof(*info));
info->name = g_strdup(prop->name);
@@ -225,10 +215,7 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
info->has_description = !!prop->description;
info->description = g_strdup(prop->description);
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = prop_list;
- prop_list = entry;
+ QAPI_LIST_PREPEND(prop_list, info);
}
object_unref(obj);
diff --git a/target/alpha/machine.c b/target/alpha/machine.c
index 9d20169..2b7c814 100644
--- a/target/alpha/machine.c
+++ b/target/alpha/machine.c
@@ -11,7 +11,7 @@ static int get_fpcr(QEMUFile *f, void *opaque, size_t size,
}
static int put_fpcr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
CPUAlphaState *env = opaque;
qemu_put_be64(f, cpu_alpha_load_fpcr(env));
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7b8bcd6..2d0d4cd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8283,7 +8283,6 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
const char *typename;
@@ -8293,10 +8292,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
strlen(typename) - strlen("-" TYPE_ARM_CPU));
info->q_typename = g_strdup(typename);
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = *cpu_list;
- *cpu_list = entry;
+ QAPI_LIST_PREPEND(*cpu_list, info);
}
CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
diff --git a/target/arm/machine.c b/target/arm/machine.c
index c5a2114..581852b 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -27,7 +27,7 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
}
static int put_fpscr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
@@ -573,7 +573,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
}
static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
@@ -608,7 +608,7 @@ static int get_power(QEMUFile *f, void *opaque, size_t size,
}
static int put_power(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ARMCPU *cpu = opaque;
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
index 169d8a6..198b14e 100644
--- a/target/arm/monitor.c
+++ b/target/arm/monitor.c
@@ -42,15 +42,6 @@ static GICCapability *gic_cap_new(int version)
return cap;
}
-static GICCapabilityList *gic_cap_list_add(GICCapabilityList *head,
- GICCapability *cap)
-{
- GICCapabilityList *item = g_new0(GICCapabilityList, 1);
- item->value = cap;
- item->next = head;
- return item;
-}
-
static inline void gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3)
{
#ifdef CONFIG_KVM
@@ -84,8 +75,8 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
gic_cap_kvm_probe(v2, v3);
- head = gic_cap_list_add(head, v2);
- head = gic_cap_list_add(head, v3);
+ QAPI_LIST_PREPEND(head, v2);
+ QAPI_LIST_PREPEND(head, v3);
return head;
}
diff --git a/target/avr/machine.c b/target/avr/machine.c
index e315442..de264f5 100644
--- a/target/avr/machine.c
+++ b/target/avr/machine.c
@@ -34,7 +34,7 @@ static int get_sreg(QEMUFile *f, void *opaque, size_t size,
}
static int put_sreg(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
CPUAVRState *env = opaque;
uint8_t sreg = cpu_get_sreg(env);
@@ -61,7 +61,7 @@ static int get_segment(QEMUFile *f, void *opaque, size_t size,
}
static int put_segment(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
uint32_t *ramp = opaque;
uint8_t temp = *ramp >> 16;
diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index b60b654..905991d 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -52,7 +52,7 @@ static int get_psw(QEMUFile *f, void *opaque, size_t size,
}
static int put_psw(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
CPUHPPAState *env = opaque;
qemu_put_betr(f, cpu_hppa_get_psw(env));
@@ -93,7 +93,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size,
}
static int put_tlb(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
hppa_tlb_entry *ent = opaque;
uint32_t val = 0;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0d20e15..35459a3 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5014,7 +5014,6 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
ObjectClass *oc = data;
X86CPUClass *cc = X86_CPU_CLASS(oc);
CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
info = g_malloc0(sizeof(*info));
@@ -5039,10 +5038,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
info->has_alias_of = !!info->alias_of;
}
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = *cpu_list;
- *cpu_list = entry;
+ QAPI_LIST_PREPEND(*cpu_list, info);
}
CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
diff --git a/target/microblaze/machine.c b/target/microblaze/machine.c
index c2074bb..d24def3 100644
--- a/target/microblaze/machine.c
+++ b/target/microblaze/machine.c
@@ -46,7 +46,7 @@ static int get_msr(QEMUFile *f, void *opaque, size_t size,
}
static int put_msr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
CPUMBState *env = container_of(opaque, CPUMBState, msr);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index aadc6f8..b2cd69f 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -543,7 +543,6 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
const char *typename;
@@ -553,10 +552,7 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data)
strlen(typename) - strlen("-" TYPE_MIPS_CPU));
info->q_typename = g_strdup(typename);
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = *cpu_list;
- *cpu_list = entry;
+ QAPI_LIST_PREPEND(*cpu_list, info);
}
CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
diff --git a/target/mips/machine.c b/target/mips/machine.c
index 5b23e3e..77afe65 100644
--- a/target/mips/machine.c
+++ b/target/mips/machine.c
@@ -31,7 +31,7 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size,
}
static int put_fpr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
int i;
fpr_t *v = pv;
@@ -156,7 +156,7 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size,
}
static int put_tlb(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
r4k_tlb_t *v = pv;
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index b92985d..6239725 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -55,7 +55,7 @@ static int get_sr(QEMUFile *f, void *opaque, size_t size,
}
static int put_sr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
CPUOpenRISCState *env = opaque;
qemu_put_be32(f, cpu_get_sr(env));
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index d9d911b..283db1d 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -134,7 +134,7 @@ static int get_avr(QEMUFile *f, void *pv, size_t size,
}
static int put_avr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ppc_avr_t *v = pv;
@@ -166,7 +166,7 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size,
}
static int put_fpr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ppc_vsr_t *v = pv;
@@ -197,7 +197,7 @@ static int get_vsr(QEMUFile *f, void *pv, size_t size,
}
static int put_vsr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ppc_vsr_t *v = pv;
@@ -455,7 +455,7 @@ static int get_vscr(QEMUFile *f, void *opaque, size_t size,
}
static int put_vscr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
PowerPCCPU *cpu = opaque;
qemu_put_be32(f, helper_mfvscr(&cpu->env));
@@ -580,7 +580,7 @@ static int get_slbe(QEMUFile *f, void *pv, size_t size,
}
static int put_slbe(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
ppc_slb_t *v = pv;
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index a4d0038..3c05a17 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -10566,7 +10566,6 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
ObjectClass *oc = data;
CpuDefinitionInfoList **first = user_data;
const char *typename;
- CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
typename = object_class_get_name(oc);
@@ -10574,10 +10573,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
info->name = g_strndup(typename,
strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = *first;
- *first = entry;
+ QAPI_LIST_PREPEND(*first, info);
}
CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
@@ -10593,7 +10589,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
ObjectClass *oc;
- CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
oc = ppc_cpu_class_by_name(alias->model);
@@ -10605,10 +10600,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
info->name = g_strdup(alias->alias);
info->q_typename = g_strdup(object_class_get_name(oc));
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = cpu_list;
- cpu_list = entry;
+ QAPI_LIST_PREPEND(cpu_list, info);
}
return cpu_list;
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index b5abff8..a23fd3e 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -427,7 +427,6 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
{
struct CpuDefinitionInfoListData *cpu_list_data = opaque;
CpuDefinitionInfoList **cpu_list = &cpu_list_data->list;
- CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
char *name = g_strdup(object_class_get_name(klass));
S390CPUClass *scc = S390_CPU_CLASS(klass);
@@ -454,10 +453,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
object_unref(obj);
}
- entry = g_new0(CpuDefinitionInfoList, 1);
- entry->value = info;
- entry->next = *cpu_list;
- *cpu_list = entry;
+ QAPI_LIST_PREPEND(*cpu_list, info);
}
CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
@@ -624,12 +620,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
static void list_add_feat(const char *name, void *opaque)
{
strList **last = (strList **) opaque;
- strList *entry;
- entry = g_new0(strList, 1);
- entry->value = g_strdup(name);
- entry->next = *last;
- *last = entry;
+ QAPI_LIST_PREPEND(*last, g_strdup(name));
}
CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa,
diff --git a/target/sparc/machine.c b/target/sparc/machine.c
index f38cf22..917375c 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -68,7 +68,7 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size,
}
static int put_psr(QEMUFile *f, void *opaque, size_t size,
- const VMStateField *field, QJSON *vmdesc)
+ const VMStateField *field, JSONWriter *vmdesc)
{
SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env;
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 9a02079..c845f91 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -35,17 +35,15 @@ static QString *from_json_str(const char *jstr, bool single, Error **errp)
static char *to_json_str(QString *str)
{
- QString *json = qobject_to_json(QOBJECT(str));
- char *jstr;
+ GString *json = qobject_to_json(QOBJECT(str));
if (!json) {
return NULL;
}
/* peel off double quotes */
- jstr = g_strndup(qstring_get_str(json) + 1,
- qstring_get_length(json) - 2);
- qobject_unref(json);
- return jstr;
+ g_string_truncate(json, json->len - 1);
+ g_string_erase(json, 0, 1);
+ return g_string_free(json, false);
}
static void escaped_string(void)
@@ -91,7 +89,7 @@ static void escaped_string(void)
for (j = 0; j < 2; j++) {
if (test_cases[i].utf8_out) {
cstr = from_json_str(test_cases[i].json_in, j, &error_abort);
- g_assert_cmpstr(qstring_get_try_str(cstr),
+ g_assert_cmpstr(qstring_get_str(cstr),
==, test_cases[i].utf8_out);
if (!test_cases[i].skip) {
jstr = to_json_str(cstr);
@@ -753,7 +751,7 @@ static void utf8_string(void)
/* Parse @json_in, expect @utf8_out */
if (utf8_out) {
str = from_json_str(json_in, j, &error_abort);
- g_assert_cmpstr(qstring_get_try_str(str), ==, utf8_out);
+ g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
qobject_unref(str);
} else {
str = from_json_str(json_in, j, NULL);
@@ -784,125 +782,129 @@ static void utf8_string(void)
/* Parse @json_out right back, unless it has replacements */
if (!strstr(json_out, "\\uFFFD")) {
str = from_json_str(json_out, j, &error_abort);
- g_assert_cmpstr(qstring_get_try_str(str), ==, utf8_in);
+ g_assert_cmpstr(qstring_get_str(str), ==, utf8_in);
qobject_unref(str);
}
}
}
}
-static void simple_number(void)
+static void int_number(void)
{
- int i;
struct {
const char *encoded;
int64_t decoded;
- int skip;
+ const char *reencoded;
} test_cases[] = {
{ "0", 0 },
{ "1234", 1234 },
{ "1", 1 },
{ "-32", -32 },
- { "-0", 0, .skip = 1 },
- { },
+ { "-0", 0, "0" },
+ {},
};
+ int i;
+ QNum *qnum;
+ int64_t ival;
+ uint64_t uval;
+ GString *str;
for (i = 0; test_cases[i].encoded; i++) {
- QNum *qnum;
- int64_t val;
-
qnum = qobject_to(QNum,
qobject_from_json(test_cases[i].encoded,
&error_abort));
g_assert(qnum);
- g_assert(qnum_get_try_int(qnum, &val));
- g_assert_cmpint(val, ==, test_cases[i].decoded);
- if (test_cases[i].skip == 0) {
- QString *str;
-
- str = qobject_to_json(QOBJECT(qnum));
- g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
- qobject_unref(str);
+ g_assert(qnum_get_try_int(qnum, &ival));
+ g_assert_cmpint(ival, ==, test_cases[i].decoded);
+ if (test_cases[i].decoded >= 0) {
+ g_assert(qnum_get_try_uint(qnum, &uval));
+ g_assert_cmpuint(uval, ==, (uint64_t)test_cases[i].decoded);
+ } else {
+ g_assert(!qnum_get_try_uint(qnum, &uval));
}
+ g_assert_cmpfloat(qnum_get_double(qnum), ==,
+ (double)test_cases[i].decoded);
+
+ str = qobject_to_json(QOBJECT(qnum));
+ g_assert_cmpstr(str->str, ==,
+ test_cases[i].reencoded ?: test_cases[i].encoded);
+ g_string_free(str, true);
qobject_unref(qnum);
}
}
-static void large_number(void)
+static void uint_number(void)
{
- const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
- const char *gtu64 = "18446744073709551616"; /* 2^64 */
- const char *lti64 = "-9223372036854775809"; /* -2^63 - 1 */
+ struct {
+ const char *encoded;
+ uint64_t decoded;
+ const char *reencoded;
+ } test_cases[] = {
+ { "9223372036854775808", (uint64_t)1 << 63 },
+ { "18446744073709551615", UINT64_MAX },
+ {},
+ };
+ int i;
QNum *qnum;
- QString *str;
- uint64_t val;
int64_t ival;
+ uint64_t uval;
+ GString *str;
- qnum = qobject_to(QNum, qobject_from_json(maxu64, &error_abort));
- g_assert(qnum);
- g_assert_cmpuint(qnum_get_uint(qnum), ==, 18446744073709551615U);
- g_assert(!qnum_get_try_int(qnum, &ival));
-
- str = qobject_to_json(QOBJECT(qnum));
- g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
- qobject_unref(str);
- qobject_unref(qnum);
-
- qnum = qobject_to(QNum, qobject_from_json(gtu64, &error_abort));
- g_assert(qnum);
- g_assert_cmpfloat(qnum_get_double(qnum), ==, 18446744073709552e3);
- g_assert(!qnum_get_try_uint(qnum, &val));
- g_assert(!qnum_get_try_int(qnum, &ival));
-
- str = qobject_to_json(QOBJECT(qnum));
- g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
- qobject_unref(str);
- qobject_unref(qnum);
+ for (i = 0; test_cases[i].encoded; i++) {
+ qnum = qobject_to(QNum,
+ qobject_from_json(test_cases[i].encoded,
+ &error_abort));
+ g_assert(qnum);
+ g_assert(qnum_get_try_uint(qnum, &uval));
+ g_assert_cmpuint(uval, ==, test_cases[i].decoded);
+ g_assert(!qnum_get_try_int(qnum, &ival));
+ g_assert_cmpfloat(qnum_get_double(qnum), ==,
+ (double)test_cases[i].decoded);
- qnum = qobject_to(QNum, qobject_from_json(lti64, &error_abort));
- g_assert(qnum);
- g_assert_cmpfloat(qnum_get_double(qnum), ==, -92233720368547758e2);
- g_assert(!qnum_get_try_uint(qnum, &val));
- g_assert(!qnum_get_try_int(qnum, &ival));
+ str = qobject_to_json(QOBJECT(qnum));
+ g_assert_cmpstr(str->str, ==,
+ test_cases[i].reencoded ?: test_cases[i].encoded);
+ g_string_free(str, true);
- str = qobject_to_json(QOBJECT(qnum));
- g_assert_cmpstr(qstring_get_str(str), ==, "-9223372036854775808");
- qobject_unref(str);
- qobject_unref(qnum);
+ qobject_unref(qnum);
+ }
}
static void float_number(void)
{
- int i;
struct {
const char *encoded;
double decoded;
- int skip;
+ const char *reencoded;
} test_cases[] = {
{ "32.43", 32.43 },
{ "0.222", 0.222 },
- { "-32.12313", -32.12313 },
- { "-32.20e-10", -32.20e-10, .skip = 1 },
- { },
+ { "-32.12313", -32.12313, "-32.123130000000003" },
+ { "-32.20e-10", -32.20e-10, "-3.22e-09" },
+ { "18446744073709551616", 0x1p64, "1.8446744073709552e+19" },
+ { "-9223372036854775809", -0x1p63, "-9.2233720368547758e+18" },
+ {},
};
+ int i;
+ QNum *qnum;
+ int64_t ival;
+ uint64_t uval;
+ GString *str;
for (i = 0; test_cases[i].encoded; i++) {
- QObject *obj;
- QNum *qnum;
-
- obj = qobject_from_json(test_cases[i].encoded, &error_abort);
- qnum = qobject_to(QNum, obj);
+ qnum = qobject_to(QNum,
+ qobject_from_json(test_cases[i].encoded,
+ &error_abort));
g_assert(qnum);
- g_assert(qnum_get_double(qnum) == test_cases[i].decoded);
+ g_assert_cmpfloat(qnum_get_double(qnum), ==, test_cases[i].decoded);
+ g_assert(!qnum_get_try_int(qnum, &ival));
+ g_assert(!qnum_get_try_uint(qnum, &uval));
- if (test_cases[i].skip == 0) {
- QString *str;
-
- str = qobject_to_json(obj);
- g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
- qobject_unref(str);
- }
+ str = qobject_to_json(QOBJECT(qnum));
+ g_assert_cmpstr(str->str, ==,
+ test_cases[i].reencoded ?: test_cases[i].encoded);
+ g_string_free(str, true);
qobject_unref(qnum);
}
@@ -913,7 +915,7 @@ static void keyword_literal(void)
QObject *obj;
QBool *qbool;
QNull *null;
- QString *str;
+ GString *str;
obj = qobject_from_json("true", &error_abort);
qbool = qobject_to(QBool, obj);
@@ -921,8 +923,8 @@ static void keyword_literal(void)
g_assert(qbool_get_bool(qbool) == true);
str = qobject_to_json(obj);
- g_assert(strcmp(qstring_get_str(str), "true") == 0);
- qobject_unref(str);
+ g_assert_cmpstr(str->str, ==, "true");
+ g_string_free(str, true);
qobject_unref(qbool);
@@ -932,8 +934,8 @@ static void keyword_literal(void)
g_assert(qbool_get_bool(qbool) == false);
str = qobject_to_json(obj);
- g_assert(strcmp(qstring_get_str(str), "false") == 0);
- qobject_unref(str);
+ g_assert_cmpstr(str->str, ==, "false");
+ g_string_free(str, true);
qobject_unref(qbool);
@@ -1019,9 +1021,8 @@ static void interpolation_valid(void)
/* string */
- qstr = qobject_to(QString,
- qobject_from_jsonf_nofail("%s", value_s));
- g_assert_cmpstr(qstring_get_try_str(qstr), ==, value_s);
+ qstr = qobject_to(QString, qobject_from_jsonf_nofail("%s", value_s));
+ g_assert_cmpstr(qstring_get_str(qstr), ==, value_s);
qobject_unref(qstr);
/* object */
@@ -1083,7 +1084,7 @@ static void simple_dict(void)
for (i = 0; test_cases[i].encoded; i++) {
QObject *obj;
- QString *str;
+ GString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
@@ -1091,10 +1092,10 @@ static void simple_dict(void)
str = qobject_to_json(obj);
qobject_unref(obj);
- obj = qobject_from_json(qstring_get_str(str), &error_abort);
+ obj = qobject_from_json(str->str, &error_abort);
g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
qobject_unref(obj);
- qobject_unref(str);
+ g_string_free(str, true);
}
}
@@ -1192,7 +1193,7 @@ static void simple_list(void)
for (i = 0; test_cases[i].encoded; i++) {
QObject *obj;
- QString *str;
+ GString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
@@ -1200,10 +1201,10 @@ static void simple_list(void)
str = qobject_to_json(obj);
qobject_unref(obj);
- obj = qobject_from_json(qstring_get_str(str), &error_abort);
+ obj = qobject_from_json(str->str, &error_abort);
g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
qobject_unref(obj);
- qobject_unref(str);
+ g_string_free(str, true);
}
}
@@ -1254,7 +1255,7 @@ static void simple_whitespace(void)
for (i = 0; test_cases[i].encoded; i++) {
QObject *obj;
- QString *str;
+ GString *str;
obj = qobject_from_json(test_cases[i].encoded, &error_abort);
g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
@@ -1262,11 +1263,11 @@ static void simple_whitespace(void)
str = qobject_to_json(obj);
qobject_unref(obj);
- obj = qobject_from_json(qstring_get_str(str), &error_abort);
+ obj = qobject_from_json(str->str, &error_abort);
g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
qobject_unref(obj);
- qobject_unref(str);
+ g_string_free(str, true);
}
}
@@ -1479,8 +1480,8 @@ int main(int argc, char **argv)
g_test_add_func("/literals/string/quotes", string_with_quotes);
g_test_add_func("/literals/string/utf8", utf8_string);
- g_test_add_func("/literals/number/simple", simple_number);
- g_test_add_func("/literals/number/large", large_number);
+ g_test_add_func("/literals/number/int", int_number);
+ g_test_add_func("/literals/number/uint", uint_number);
g_test_add_func("/literals/number/float", float_number);
g_test_add_func("/literals/keyword", keyword_literal);
diff --git a/tests/check-qnum.c b/tests/check-qnum.c
index 4105015..b85fca2 100644
--- a/tests/check-qnum.c
+++ b/tests/check-qnum.c
@@ -147,7 +147,13 @@ static void qnum_to_string_test(void)
qn = qnum_from_double(0.42);
tmp = qnum_to_string(qn);
- g_assert_cmpstr(tmp, ==, "0.42");
+ g_assert_cmpstr(tmp, ==, "0.41999999999999998");
+ g_free(tmp);
+ qobject_unref(qn);
+
+ qn = qnum_from_double(2.718281828459045);
+ tmp = qnum_to_string(qn);
+ g_assert_cmpstr(tmp, ==, "2.7182818284590451");
g_free(tmp);
qobject_unref(qn);
}
diff --git a/tests/check-qobject.c b/tests/check-qobject.c
index 6b6deae..c1713d1 100644
--- a/tests/check-qobject.c
+++ b/tests/check-qobject.c
@@ -155,8 +155,7 @@ static void qobject_is_equal_string_test(void)
str_case = qstring_from_str("Foo");
/* Should yield "foo" */
- str_built = qstring_from_substr("form", 0, 2);
- qstring_append_chr(str_built, 'o');
+ str_built = qstring_from_substr("buffoon", 3, 6);
check_unequal(str_base, str_whitespace_0, str_whitespace_1,
str_whitespace_2, str_whitespace_3, str_case);
diff --git a/tests/check-qstring.c b/tests/check-qstring.c
index 2d07992..4bf9772 100644
--- a/tests/check-qstring.c
+++ b/tests/check-qstring.c
@@ -47,21 +47,6 @@ static void qstring_get_str_test(void)
qobject_unref(qstring);
}
-static void qstring_append_chr_test(void)
-{
- int i;
- QString *qstring;
- const char *str = "qstring append char unit-test";
-
- qstring = qstring_new();
-
- for (i = 0; str[i]; i++)
- qstring_append_chr(qstring, str[i]);
-
- g_assert(strcmp(str, qstring_get_str(qstring)) == 0);
- qobject_unref(qstring);
-}
-
static void qstring_from_substr_test(void)
{
QString *qs;
@@ -90,7 +75,6 @@ int main(int argc, char **argv)
g_test_add_func("/public/from_str", qstring_from_str_test);
g_test_add_func("/public/get_str", qstring_get_str_test);
- g_test_add_func("/public/append_chr", qstring_append_chr_test);
g_test_add_func("/public/from_substr", qstring_from_substr_test);
g_test_add_func("/public/to_qstring", qobject_to_qstring_test);
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index e49f3a1..8e93b0a 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -652,27 +652,25 @@ void qmp_fd_vsend_fds(int fd, int *fds, size_t fds_num,
/* No need to send anything for an empty QObject. */
if (qobj) {
int log = getenv("QTEST_LOG") != NULL;
- QString *qstr = qobject_to_json(qobj);
- const char *str;
+ GString *str = qobject_to_json(qobj);
/*
* BUG: QMP doesn't react to input until it sees a newline, an
* object, or an array. Work-around: give it a newline.
*/
- qstring_append_chr(qstr, '\n');
- str = qstring_get_str(qstr);
+ g_string_append_c(str, '\n');
if (log) {
- fprintf(stderr, "%s", str);
+ fprintf(stderr, "%s", str->str);
}
/* Send QMP request */
if (fds && fds_num > 0) {
- socket_send_fds(fd, fds, fds_num, str, qstring_get_length(qstr));
+ socket_send_fds(fd, fds, fds_num, str->str, str->len);
} else {
- socket_send(fd, str, qstring_get_length(qstr));
+ socket_send(fd, str->str, str->len);
}
- qobject_unref(qstr);
+ g_string_free(str, true);
qobject_unref(qobj);
}
}
@@ -1197,9 +1195,9 @@ void qtest_qmp_assert_success(QTestState *qts, const char *fmt, ...)
g_assert(response);
if (!qdict_haskey(response, "return")) {
- QString *s = qobject_to_json_pretty(QOBJECT(response));
- g_test_message("%s", qstring_get_str(s));
- qobject_unref(s);
+ GString *s = qobject_to_json_pretty(QOBJECT(response), true);
+ g_test_message("%s", s->str);
+ g_string_free(s, true);
}
g_assert(qdict_haskey(response, "return"));
qobject_unref(response);
diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c
index 5e1e8b2..4944b3d 100644
--- a/tests/test-clone-visitor.c
+++ b/tests/test-clone-visitor.c
@@ -65,16 +65,13 @@ static void test_clone_alternate(void)
static void test_clone_list_union(void)
{
- uint8List *src, *dst;
+ uint8List *src = NULL, *dst;
uint8List *tmp = NULL;
int i;
/* Build list in reverse */
for (i = 10; i; i--) {
- src = g_new0(uint8List, 1);
- src->next = tmp;
- src->value = i;
- tmp = src;
+ QAPI_LIST_PREPEND(src, i);
}
dst = QAPI_CLONE(uint8List, src);
diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
index 1c856d9..b20ab8b 100644
--- a/tests/test-qobject-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -223,7 +223,8 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
const void *unused)
{
const char *value_str = "list value";
- TestStructList *p, *head = NULL;
+ TestStruct *value;
+ TestStructList *head = NULL;
const int max_items = 10;
bool value_bool = true;
int value_int = 10;
@@ -233,14 +234,12 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
/* Build the list in reverse order... */
for (i = 0; i < max_items; i++) {
- p = g_malloc0(sizeof(*p));
- p->value = g_malloc0(sizeof(*p->value));
- p->value->integer = value_int + (max_items - i - 1);
- p->value->boolean = value_bool;
- p->value->string = g_strdup(value_str);
-
- p->next = head;
- head = p;
+ value = g_malloc0(sizeof(*value));
+ value->integer = value_int + (max_items - i - 1);
+ value->boolean = value_bool;
+ value->string = g_strdup(value_str);
+
+ QAPI_LIST_PREPEND(head, value);
}
visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
@@ -270,26 +269,25 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
const void *unused)
{
- UserDefTwoList *p, *head = NULL;
+ UserDefTwo *value;
+ UserDefTwoList *head = NULL;
const char string[] = "foo bar";
int i, max_count = 1024;
for (i = 0; i < max_count; i++) {
- p = g_malloc0(sizeof(*p));
- p->value = g_malloc0(sizeof(*p->value));
-
- p->value->string0 = g_strdup(string);
- p->value->dict1 = g_new0(UserDefTwoDict, 1);
- p->value->dict1->string1 = g_strdup(string);
- p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
- p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
- p->value->dict1->dict2->userdef->string = g_strdup(string);
- p->value->dict1->dict2->userdef->integer = 42;
- p->value->dict1->dict2->string = g_strdup(string);
- p->value->dict1->has_dict3 = false;
-
- p->next = head;
- head = p;
+ value = g_malloc0(sizeof(*value));
+
+ value->string0 = g_strdup(string);
+ value->dict1 = g_new0(UserDefTwoDict, 1);
+ value->dict1->string1 = g_strdup(string);
+ value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
+ value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
+ value->dict1->dict2->userdef->string = g_strdup(string);
+ value->dict1->dict2->userdef->integer = 42;
+ value->dict1->dict2->string = g_strdup(string);
+ value->dict1->has_dict3 = false;
+
+ QAPI_LIST_PREPEND(head, value);
}
qapi_free_UserDefTwoList(head);
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 9f65814..0dae04b 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -130,13 +130,13 @@ static void test_visitor_out_bool(TestOutputVisitorData *data,
static void test_visitor_out_number(TestOutputVisitorData *data,
const void *unused)
{
- double value = 3.14;
+ double value = 3.1415926535897932;
char *str;
visit_type_number(data->ov, NULL, &value, &error_abort);
str = visitor_get(data);
- g_assert_cmpstr(str, ==, "3.140000");
+ g_assert_cmpstr(str, ==, "3.1415926535897931");
}
static void test_visitor_out_string(TestOutputVisitorData *data,
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 1c5a8b9..4629958 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -55,7 +55,6 @@ typedef struct PrimitiveType {
int16_t s16;
int32_t s32;
int64_t s64;
- intmax_t max;
} value;
enum PrimitiveTypeKind type;
const char *description;
@@ -307,25 +306,46 @@ static void test_primitives(gconstpointer opaque)
&error_abort);
g_assert(pt_copy != NULL);
- if (pt->type == PTYPE_STRING) {
+ switch (pt->type) {
+ case PTYPE_STRING:
g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string);
g_free((char *)pt_copy->value.string);
- } else if (pt->type == PTYPE_NUMBER) {
- GString *double_expected = g_string_new("");
- GString *double_actual = g_string_new("");
- /* we serialize with %f for our reference visitors, so rather than fuzzy
- * floating math to test "equality", just compare the formatted values
- */
- g_string_printf(double_expected, "%.6f", pt->value.number);
- g_string_printf(double_actual, "%.6f", pt_copy->value.number);
- g_assert_cmpstr(double_actual->str, ==, double_expected->str);
-
- g_string_free(double_expected, true);
- g_string_free(double_actual, true);
- } else if (pt->type == PTYPE_BOOLEAN) {
- g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max);
- } else {
- g_assert_cmpint(pt->value.max, ==, pt_copy->value.max);
+ break;
+ case PTYPE_BOOLEAN:
+ g_assert_cmpint(pt->value.boolean, ==, pt->value.boolean);
+ break;
+ case PTYPE_NUMBER:
+ g_assert_cmpfloat(pt->value.number, ==, pt_copy->value.number);
+ break;
+ case PTYPE_INTEGER:
+ g_assert_cmpint(pt->value.integer, ==, pt_copy->value.integer);
+ break;
+ case PTYPE_U8:
+ g_assert_cmpuint(pt->value.u8, ==, pt_copy->value.u8);
+ break;
+ case PTYPE_U16:
+ g_assert_cmpuint(pt->value.u16, ==, pt_copy->value.u16);
+ break;
+ case PTYPE_U32:
+ g_assert_cmpuint(pt->value.u32, ==, pt_copy->value.u32);
+ break;
+ case PTYPE_U64:
+ g_assert_cmpuint(pt->value.u64, ==, pt_copy->value.u64);
+ break;
+ case PTYPE_S8:
+ g_assert_cmpint(pt->value.s8, ==, pt_copy->value.s8);
+ break;
+ case PTYPE_S16:
+ g_assert_cmpint(pt->value.s16, ==, pt_copy->value.s16);
+ break;
+ case PTYPE_S32:
+ g_assert_cmpint(pt->value.s32, ==, pt_copy->value.s32);
+ break;
+ case PTYPE_S64:
+ g_assert_cmpint(pt->value.s64, ==, pt_copy->value.s64);
+ break;
+ case PTYPE_EOL:
+ g_assert_not_reached();
}
ops->cleanup(serialize_data);
@@ -351,135 +371,51 @@ static void test_primitive_lists(gconstpointer opaque)
for (i = 0; i < 32; i++) {
switch (pl.type) {
case PTYPE_STRING: {
- strList *tmp = g_new0(strList, 1);
- tmp->value = g_strdup(pt->value.string);
- if (pl.value.strings == NULL) {
- pl.value.strings = tmp;
- } else {
- tmp->next = pl.value.strings;
- pl.value.strings = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.strings, g_strdup(pt->value.string));
break;
}
case PTYPE_INTEGER: {
- intList *tmp = g_new0(intList, 1);
- tmp->value = pt->value.integer;
- if (pl.value.integers == NULL) {
- pl.value.integers = tmp;
- } else {
- tmp->next = pl.value.integers;
- pl.value.integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.integers, pt->value.integer);
break;
}
case PTYPE_S8: {
- int8List *tmp = g_new0(int8List, 1);
- tmp->value = pt->value.s8;
- if (pl.value.s8_integers == NULL) {
- pl.value.s8_integers = tmp;
- } else {
- tmp->next = pl.value.s8_integers;
- pl.value.s8_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.s8_integers, pt->value.s8);
break;
}
case PTYPE_S16: {
- int16List *tmp = g_new0(int16List, 1);
- tmp->value = pt->value.s16;
- if (pl.value.s16_integers == NULL) {
- pl.value.s16_integers = tmp;
- } else {
- tmp->next = pl.value.s16_integers;
- pl.value.s16_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.s16_integers, pt->value.s16);
break;
}
case PTYPE_S32: {
- int32List *tmp = g_new0(int32List, 1);
- tmp->value = pt->value.s32;
- if (pl.value.s32_integers == NULL) {
- pl.value.s32_integers = tmp;
- } else {
- tmp->next = pl.value.s32_integers;
- pl.value.s32_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.s32_integers, pt->value.s32);
break;
}
case PTYPE_S64: {
- int64List *tmp = g_new0(int64List, 1);
- tmp->value = pt->value.s64;
- if (pl.value.s64_integers == NULL) {
- pl.value.s64_integers = tmp;
- } else {
- tmp->next = pl.value.s64_integers;
- pl.value.s64_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.s64_integers, pt->value.s64);
break;
}
case PTYPE_U8: {
- uint8List *tmp = g_new0(uint8List, 1);
- tmp->value = pt->value.u8;
- if (pl.value.u8_integers == NULL) {
- pl.value.u8_integers = tmp;
- } else {
- tmp->next = pl.value.u8_integers;
- pl.value.u8_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.u8_integers, pt->value.u8);
break;
}
case PTYPE_U16: {
- uint16List *tmp = g_new0(uint16List, 1);
- tmp->value = pt->value.u16;
- if (pl.value.u16_integers == NULL) {
- pl.value.u16_integers = tmp;
- } else {
- tmp->next = pl.value.u16_integers;
- pl.value.u16_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.u16_integers, pt->value.u16);
break;
}
case PTYPE_U32: {
- uint32List *tmp = g_new0(uint32List, 1);
- tmp->value = pt->value.u32;
- if (pl.value.u32_integers == NULL) {
- pl.value.u32_integers = tmp;
- } else {
- tmp->next = pl.value.u32_integers;
- pl.value.u32_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.u32_integers, pt->value.u32);
break;
}
case PTYPE_U64: {
- uint64List *tmp = g_new0(uint64List, 1);
- tmp->value = pt->value.u64;
- if (pl.value.u64_integers == NULL) {
- pl.value.u64_integers = tmp;
- } else {
- tmp->next = pl.value.u64_integers;
- pl.value.u64_integers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.u64_integers, pt->value.u64);
break;
}
case PTYPE_NUMBER: {
- numberList *tmp = g_new0(numberList, 1);
- tmp->value = pt->value.number;
- if (pl.value.numbers == NULL) {
- pl.value.numbers = tmp;
- } else {
- tmp->next = pl.value.numbers;
- pl.value.numbers = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.numbers, pt->value.number);
break;
}
case PTYPE_BOOLEAN: {
- boolList *tmp = g_new0(boolList, 1);
- tmp->value = pt->value.boolean;
- if (pl.value.booleans == NULL) {
- pl.value.booleans = tmp;
- } else {
- tmp->next = pl.value.booleans;
- pl.value.booleans = tmp;
- }
+ QAPI_LIST_PREPEND(pl.value.booleans, pt->value.boolean);
break;
}
default:
@@ -704,10 +640,7 @@ static void test_nested_struct_list(gconstpointer opaque)
int i = 0;
for (i = 0; i < 8; i++) {
- tmp = g_new0(UserDefTwoList, 1);
- tmp->value = nested_struct_create();
- tmp->next = listp;
- listp = tmp;
+ QAPI_LIST_PREPEND(listp, nested_struct_create());
}
ops->serialize(listp, &serialize_data, visit_nested_struct_list,
@@ -790,10 +723,6 @@ static PrimitiveType pt_values[] = {
.value.boolean = 0,
},
/* number tests (double) */
- /* note: we format these to %.6f before comparing, since that's how
- * we serialize them and it doesn't make sense to check precision
- * beyond that.
- */
{
.description = "number_sanity1",
.type = PTYPE_NUMBER,
@@ -802,7 +731,7 @@ static PrimitiveType pt_values[] = {
{
.description = "number_sanity2",
.type = PTYPE_NUMBER,
- .value.number = 3.14159265,
+ .value.number = 3.141593,
},
{
.description = "number_min",
@@ -1028,15 +957,15 @@ static void qmp_deserialize(void **native_out, void *datap,
VisitorFunc visit, Error **errp)
{
QmpSerializeData *d = datap;
- QString *output_json;
+ GString *output_json;
QObject *obj_orig, *obj;
visit_complete(d->qov, &d->obj);
obj_orig = d->obj;
output_json = qobject_to_json(obj_orig);
- obj = qobject_from_json(qstring_get_str(output_json), &error_abort);
+ obj = qobject_from_json(output_json->str, &error_abort);
- qobject_unref(output_json);
+ g_string_free(output_json, true);
d->qiv = qobject_input_visitor_new(obj);
qobject_unref(obj_orig);
qobject_unref(obj);
diff --git a/trace/qmp.c b/trace/qmp.c
index 38246e1..85f81e4 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -92,39 +92,37 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name,
/* Get states (all errors checked above) */
trace_event_iter_init(&iter, name);
while ((ev = trace_event_iter_next(&iter)) != NULL) {
- TraceEventInfoList *elem;
+ TraceEventInfo *value;
bool is_vcpu = trace_event_is_vcpu(ev);
if (has_vcpu && !is_vcpu) {
continue;
}
- elem = g_new(TraceEventInfoList, 1);
- elem->value = g_new(TraceEventInfo, 1);
- elem->value->vcpu = is_vcpu;
- elem->value->name = g_strdup(trace_event_get_name(ev));
+ value = g_new(TraceEventInfo, 1);
+ value->vcpu = is_vcpu;
+ value->name = g_strdup(trace_event_get_name(ev));
if (!trace_event_get_state_static(ev)) {
- elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE;
+ value->state = TRACE_EVENT_STATE_UNAVAILABLE;
} else {
if (has_vcpu) {
if (is_vcpu) {
if (trace_event_get_vcpu_state_dynamic(cpu, ev)) {
- elem->value->state = TRACE_EVENT_STATE_ENABLED;
+ value->state = TRACE_EVENT_STATE_ENABLED;
} else {
- elem->value->state = TRACE_EVENT_STATE_DISABLED;
+ value->state = TRACE_EVENT_STATE_DISABLED;
}
}
/* else: already skipped above */
} else {
if (trace_event_get_state_dynamic(ev)) {
- elem->value->state = TRACE_EVENT_STATE_ENABLED;
+ value->state = TRACE_EVENT_STATE_ENABLED;
} else {
- elem->value->state = TRACE_EVENT_STATE_DISABLED;
+ value->state = TRACE_EVENT_STATE_DISABLED;
}
}
}
- elem->next = events;
- events = elem;
+ QAPI_LIST_PREPEND(events, value);
}
return events;
diff --git a/ui/input.c b/ui/input.c
index 4791b08..8ac407d 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -571,7 +571,7 @@ void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
MouseInfoList *qmp_query_mice(Error **errp)
{
MouseInfoList *mice_list = NULL;
- MouseInfoList *info;
+ MouseInfo *info;
QemuInputHandlerState *s;
bool current = true;
@@ -581,16 +581,14 @@ MouseInfoList *qmp_query_mice(Error **errp)
continue;
}
- info = g_new0(MouseInfoList, 1);
- info->value = g_new0(MouseInfo, 1);
- info->value->index = s->id;
- info->value->name = g_strdup(s->handler->name);
- info->value->absolute = s->handler->mask & INPUT_EVENT_MASK_ABS;
- info->value->current = current;
+ info = g_new0(MouseInfo, 1);
+ info->index = s->id;
+ info->name = g_strdup(s->handler->name);
+ info->absolute = s->handler->mask & INPUT_EVENT_MASK_ABS;
+ info->current = current;
current = false;
- info->next = mice_list;
- mice_list = info;
+ QAPI_LIST_PREPEND(mice_list, info);
}
return mice_list;
diff --git a/ui/vnc.c b/ui/vnc.c
index 34e6dc4..7452ac7 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -365,14 +365,11 @@ static VncDisplay *vnc_display_find(const char *id)
static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
{
- VncClientInfoList *cinfo, *prev = NULL;
+ VncClientInfoList *prev = NULL;
VncState *client;
QTAILQ_FOREACH(client, &vd->clients, next) {
- cinfo = g_new0(VncClientInfoList, 1);
- cinfo->value = qmp_query_vnc_client(client);
- cinfo->next = prev;
- prev = cinfo;
+ QAPI_LIST_PREPEND(prev, qmp_query_vnc_client(client));
}
return prev;
}
@@ -453,7 +450,6 @@ static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
int subauth,
VncServerInfo2List *prev)
{
- VncServerInfo2List *list;
VncServerInfo2 *info;
Error *err = NULL;
SocketAddress *addr;
@@ -476,10 +472,8 @@ static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
qmp_query_auth(auth, subauth, &info->auth,
&info->vencrypt, &info->has_vencrypt);
- list = g_new0(VncServerInfo2List, 1);
- list->value = info;
- list->next = prev;
- return list;
+ QAPI_LIST_PREPEND(prev, info);
+ return prev;
}
static void qmp_query_auth(int auth, int subauth,
@@ -554,7 +548,7 @@ static void qmp_query_auth(int auth, int subauth,
VncInfo2List *qmp_query_vnc_servers(Error **errp)
{
- VncInfo2List *item, *prev = NULL;
+ VncInfo2List *prev = NULL;
VncInfo2 *info;
VncDisplay *vd;
DeviceState *dev;
@@ -583,10 +577,7 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
vd->ws_subauth, info->server);
}
- item = g_new0(VncInfo2List, 1);
- item->value = info;
- item->next = prev;
- prev = item;
+ QAPI_LIST_PREPEND(prev, info);
}
return prev;
}
diff --git a/util/keyval.c b/util/keyval.c
index 7f625ad..be34928 100644
--- a/util/keyval.c
+++ b/util/keyval.c
@@ -189,7 +189,7 @@ static const char *keyval_parse_one(QDict *qdict, const char *params,
QDict *cur;
int ret;
QObject *next;
- QString *val;
+ GString *val;
key = params;
val_end = NULL;
@@ -263,7 +263,7 @@ static const char *keyval_parse_one(QDict *qdict, const char *params,
if (key == implied_key) {
assert(!*s);
- val = qstring_from_substr(params, 0, val_end - params);
+ val = g_string_new_len(params, val_end - params);
s = val_end;
if (*s == ',') {
s++;
@@ -276,7 +276,7 @@ static const char *keyval_parse_one(QDict *qdict, const char *params,
}
s++;
- val = qstring_new();
+ val = g_string_new(NULL);
for (;;) {
if (!*s) {
break;
@@ -286,11 +286,12 @@ static const char *keyval_parse_one(QDict *qdict, const char *params,
break;
}
}
- qstring_append_chr(val, *s++);
+ g_string_append_c(val, *s++);
}
}
- if (!keyval_parse_put(cur, key_in_cur, val, key, key_end, errp)) {
+ if (!keyval_parse_put(cur, key_in_cur, qstring_from_gstring(val),
+ key, key_end, errp)) {
return NULL;
}
return s;
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 725e3d7..e2a700b 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -55,7 +55,7 @@ QemuOpts *qemu_find_opts_singleton(const char *group)
static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
{
- CommandLineParameterInfoList *param_list = NULL, *entry;
+ CommandLineParameterInfoList *param_list = NULL;
CommandLineParameterInfo *info;
int i;
@@ -87,10 +87,7 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
info->q_default = g_strdup(desc[i].def_value_str);
}
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = param_list;
- param_list = entry;
+ QAPI_LIST_PREPEND(param_list, info);
}
return param_list;
@@ -246,7 +243,7 @@ CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option,
const char *option,
Error **errp)
{
- CommandLineOptionInfoList *conf_list = NULL, *entry;
+ CommandLineOptionInfoList *conf_list = NULL;
CommandLineOptionInfo *info;
int i;
@@ -262,10 +259,7 @@ CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option,
info->parameters =
query_option_descs(vm_config_groups[i]->desc);
}
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = conf_list;
- conf_list = entry;
+ QAPI_LIST_PREPEND(conf_list, info);
}
}