QAPI patches patches for 2020-12-19

-----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAl/dynUSHGFybWJydUBy
 ZWRoYXQuY29tAAoJEDhwtADrkYZT3igP/3bWwsKR5vKVsDUTmMfrhcgaFvQiaYoG
 F29Bond8Xy0Zd0gl7OWh/5jKL0vGlrEVPrKfYLUjMnfkeRec/pOkIB2oOmIxpnPs
 9zi4kh2hQ3dEoRBuvSnnZzedetYPTuCpWMIjlztkgfxgcimqm8TPNVSxRaSApjC3
 Y8108wGwBWVf2C0rhKO9E2xA51uo6khy05i1psUtqUlC+PuDQ/OwzQHM2dnWdDB6
 kUwBDK17nhL6WwsYqCyKLSiDModReYfDiY8GS5MDLo74dzwXiatEefCR7+sbM4xq
 eX/SBoqoeS1jLPNuCryNeGNKvNA2KAbEJTnbQA2NxBXHgZ9/1SxVZFxuPp4nDMSQ
 N7BDuDI8YtJE479RjT/ZzRG65xadGBSe/HXkXM9mZwh1zitop8SVZ9fArFBHvNzw
 Y5zAv3fQd54+87psffg4dYFK0wGmqTabLEEuVzM8KIVqcAdYA2yC2b2EHy+vsxuq
 GMkr0WaA6Sq2gthXmzdTjmUPuHdan/NIhuV6d66SbPNH2oH31piptFxuznyFWSKV
 isciFFdUrkg5QrF8DSt2nmdwMFf8QGbszqP8QIGMzhJCCS9GXIiGG8f149++q8X8
 HO1lFAdLQJdrDwCYmfx36tOvi2rS/rcoTGgvg66UX3xKko1ruoxR1ZWcS54obJN6
 vEQDZ+PxubDg
 =vGLy
 -----END PGP SIGNATURE-----

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>
master
Peter Maydell 2021-01-01 14:33:03 +00:00
commit 1f7c02797f
105 changed files with 975 additions and 1263 deletions

23
block.c
View File

@ -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);
}
}

View File

@ -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")) {

View File

@ -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],

View File

@ -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:

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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) \

View File

@ -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 */

View File

@ -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)
{

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -6,7 +6,6 @@ migration_files = files(
'vmstate.c',
'qemu-file-channel.c',
'qemu-file.c',
'qjson.c',
)
softmmu_ss.add(migration_files)

View File

@ -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));
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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*/

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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) {

View File

@ -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";

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

247
qobject/json-writer.c Normal file
View File

@ -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);
}

View File

@ -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'))

View File

@ -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

View File

@ -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

View File

@ -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();
JSONWriter *writer = json_writer_new(pretty);
to_json(obj, str, 0, 0);
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);
}

View File

@ -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

View File

@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qnull.h"
#include "qobject-internal.h"
QNull qnull_ = {
.base = {

View File

@ -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);

View File

@ -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

View File

@ -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 ||

View File

@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/qstring.h"
#include "qobject-internal.h"
/**
* qstring_new(): Create a new empty QString
@ -23,14 +24,6 @@ QString *qstring_new(void)
return qstring_from_str("");
}
/**
* 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
*
@ -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,48 +50,23 @@ 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
*/
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)
{
char num[32];
snprintf(num, sizeof(num), "%" PRId64, value);
qstring_append(qstring, num);
}
/**
* qstring_append_chr(): Append a C char to a QString
* qstring_from_gstring(): Convert a GString to a QString
*
* Return strong reference.
*/
void qstring_append_chr(QString *qstring, int c)
QString *qstring_from_gstring(GString *gstr)
{
capacity_increase(qstring, 1);
qstring->string[qstring->length++] = c;
qstring->string[qstring->length] = 0;
QString *qstring;
qstring = g_malloc(sizeof(*qstring));
qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
qstring->string = g_string_free(gstr, false);
return qstring;
}
/**
* qstring_get_str(): Return a pointer to the stored string
*
@ -119,27 +78,6 @@ const char *qstring_get_str(const QString *qstring)
return qstring->string;
}
/**
* 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
*/
@ -149,33 +87,16 @@ bool qstring_is_equal(const QObject *x, const QObject *y)
qobject_to(QString, y)->string);
}
/**
* 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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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));
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);
str = qobject_to_json(QOBJECT(qnum));
g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
qobject_unref(str);
qobject_unref(qnum);
str = qobject_to_json(QOBJECT(qnum));
g_assert_cmpstr(str->str, ==,
test_cases[i].reencoded ?: test_cases[i].encoded);
g_string_free(str, true);
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);
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(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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
value = g_malloc0(sizeof(*value));
value->integer = value_int + (max_items - i - 1);
value->boolean = value_bool;
value->string = g_strdup(value_str);
p->next = head;
head = p;
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));
value = g_malloc0(sizeof(*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;
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;
p->next = head;
head = p;
QAPI_LIST_PREPEND(head, value);
}
qapi_free_UserDefTwoList(head);

View File

@ -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,

View File

@ -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);

Some files were not shown because too many files have changed in this diff Show More