QAPI patches

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJWNyfLAAoJEDhwtADrkYZTV1sP/3doWfI6jU70z+C8RkKM5cEr
 10T1G1cKAIRy4ji5CFzRY0/L8lQy6svBrwU6OZUKf9ZM+j2thG7IIibU8N/93DPE
 bXvcKgVvy873mfq9SoJM1OaqtqVoEepyKZ3snsYVTL5aiJ0E7I0tIcpohnKjxoRs
 kYcDdv3fID3bk9d9I9sSRYy7W2KL4aicR9x3WKYCVtxRIoZjAQZiJH44iuJUfA6z
 isxeghJEq2TP5bjBKf8/uMp2+nN8UJagWENf+aGaK1R5MFlHSMGuV1HyVJESZl0U
 pU8pdathbHx5UUigUQLhzpFDxiqs3fNDODplKe6cIs3zylQBO2djsMRw07/FjBCb
 QJqJCQrtKXfmCBxAIBa11X/rNeKfigm/GAOAZ1SF1Esk5J7CAX8qwFBlUlpR5OCM
 ycHzKm8T/zoZN7Hc0Ay/CdDlkRjNXpf51kg4qp14aPiZAcv8sRtWwv0qtIUdzCUM
 rsrgR0k1vvNp48u+9VeG7SV+PrurP8Mn1y5mthmwJkUJNUo/i1SPoOL/ZG71z4kD
 Otu5btrLPcJDrHf/nmXEtp1//eRrZPfBE8jHbNEMXMjqZ/wFKchWdJCnXDQ/yjE0
 OHp+EaThOvLvUtSnPYgPT7agJFbZZfjXvOheHeAi3dPl3zRdzLUeVAGOI0e2mCAq
 VPlkkpeIaVOFgzxjaGVL
 =XPNe
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-11-02' into staging

QAPI patches

# gpg: Signature made Mon 02 Nov 2015 09:07:23 GMT using RSA key ID EB918653
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>"
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>"

* remotes/armbru/tags/pull-qapi-2015-11-02: (25 commits)
  qapi: Simplify gen_struct_field()
  qapi: Reserve 'u' member name
  qapi: Finish converting to new qapi union layout
  tpm: Convert to new qapi union layout
  memory: Convert to new qapi union layout
  input: Convert to new qapi union layout
  char: Convert to new qapi union layout
  net: Convert to new qapi union layout
  sockets: Convert to new qapi union layout
  block: Convert to new qapi union layout
  tests: Convert to new qapi union layout
  qapi-visit: Convert to new qapi union layout
  qapi: Start converting to new qapi union layout
  qapi-visit: Remove redundant functions for flat union base
  qapi: Unbox base members
  qapi: Prefer typesafe upcasts to qapi base classes
  qapi-types: Refactor base fields output
  qapi-visit: Split off visit_type_FOO_fields forward decl
  vnc: Hoist allocation of VncBasicInfo to callers
  qapi: Reserve 'q_*' and 'has_*' member names
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-11-02 11:11:39 +00:00
commit 3d861a0109
74 changed files with 663 additions and 607 deletions

View File

@ -206,24 +206,24 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
saddr = g_new0(SocketAddress, 1); saddr = g_new0(SocketAddress, 1);
if (qdict_haskey(options, "path")) { if (qdict_haskey(options, "path")) {
saddr->kind = SOCKET_ADDRESS_KIND_UNIX; saddr->type = SOCKET_ADDRESS_KIND_UNIX;
saddr->q_unix = g_new0(UnixSocketAddress, 1); saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
saddr->q_unix->path = g_strdup(qdict_get_str(options, "path")); saddr->u.q_unix->path = g_strdup(qdict_get_str(options, "path"));
qdict_del(options, "path"); qdict_del(options, "path");
} else { } else {
saddr->kind = SOCKET_ADDRESS_KIND_INET; saddr->type = SOCKET_ADDRESS_KIND_INET;
saddr->inet = g_new0(InetSocketAddress, 1); saddr->u.inet = g_new0(InetSocketAddress, 1);
saddr->inet->host = g_strdup(qdict_get_str(options, "host")); saddr->u.inet->host = g_strdup(qdict_get_str(options, "host"));
if (!qdict_get_try_str(options, "port")) { if (!qdict_get_try_str(options, "port")) {
saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT); saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
} else { } else {
saddr->inet->port = g_strdup(qdict_get_str(options, "port")); saddr->u.inet->port = g_strdup(qdict_get_str(options, "port"));
} }
qdict_del(options, "host"); qdict_del(options, "host");
qdict_del(options, "port"); qdict_del(options, "port");
} }
s->client.is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX; s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
*export = g_strdup(qdict_get_try_str(options, "export")); *export = g_strdup(qdict_get_try_str(options, "export"));
if (*export) { if (*export) {

View File

@ -2738,18 +2738,16 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1); ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
*spec_info = (ImageInfoSpecific){ *spec_info = (ImageInfoSpecific){
.kind = IMAGE_INFO_SPECIFIC_KIND_QCOW2, .type = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
{ .u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
},
}; };
if (s->qcow_version == 2) { if (s->qcow_version == 2) {
*spec_info->qcow2 = (ImageInfoSpecificQCow2){ *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){
.compat = g_strdup("0.10"), .compat = g_strdup("0.10"),
.refcount_bits = s->refcount_bits, .refcount_bits = s->refcount_bits,
}; };
} else if (s->qcow_version == 3) { } else if (s->qcow_version == 3) {
*spec_info->qcow2 = (ImageInfoSpecificQCow2){ *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){
.compat = g_strdup("1.1"), .compat = g_strdup("1.1"),
.lazy_refcounts = s->compatible_features & .lazy_refcounts = s->compatible_features &
QCOW2_COMPAT_LAZY_REFCOUNTS, QCOW2_COMPAT_LAZY_REFCOUNTS,

View File

@ -2161,19 +2161,19 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
ImageInfoList **next; ImageInfoList **next;
*spec_info = (ImageInfoSpecific){ *spec_info = (ImageInfoSpecific){
.kind = IMAGE_INFO_SPECIFIC_KIND_VMDK, .type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
{ {
.vmdk = g_new0(ImageInfoSpecificVmdk, 1), .vmdk = g_new0(ImageInfoSpecificVmdk, 1),
}, },
}; };
*spec_info->vmdk = (ImageInfoSpecificVmdk) { *spec_info->u.vmdk = (ImageInfoSpecificVmdk) {
.create_type = g_strdup(s->create_type), .create_type = g_strdup(s->create_type),
.cid = s->cid, .cid = s->cid,
.parent_cid = s->parent_cid, .parent_cid = s->parent_cid,
}; };
next = &spec_info->vmdk->extents; next = &spec_info->u.vmdk->extents;
for (i = 0; i < s->num_extents; i++) { for (i = 0; i < s->num_extents; i++) {
*next = g_new0(ImageInfoList, 1); *next = g_new0(ImageInfoList, 1);
(*next)->value = vmdk_get_extent_info(&s->extents[i]); (*next)->value = vmdk_get_extent_info(&s->extents[i]);

View File

@ -1137,13 +1137,14 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
} }
} }
static void blockdev_do_action(int kind, void *data, Error **errp) static void blockdev_do_action(TransactionActionKind type, void *data,
Error **errp)
{ {
TransactionAction action; TransactionAction action;
TransactionActionList list; TransactionActionList list;
action.kind = kind; action.type = type;
action.data = data; action.u.data = data;
list.value = &action; list.value = &action;
list.next = NULL; list.next = NULL;
qmp_transaction(&list, errp); qmp_transaction(&list, errp);
@ -1388,9 +1389,9 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
InternalSnapshotState *state; InternalSnapshotState *state;
int ret1; int ret1;
g_assert(common->action->kind == g_assert(common->action->type ==
TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC); TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC);
internal = common->action->blockdev_snapshot_internal_sync; internal = common->action->u.blockdev_snapshot_internal_sync;
state = DO_UPCAST(InternalSnapshotState, common, common); state = DO_UPCAST(InternalSnapshotState, common, common);
/* 1. parse input */ /* 1. parse input */
@ -1536,22 +1537,22 @@ static void external_snapshot_prepare(BlkTransactionState *common,
TransactionAction *action = common->action; TransactionAction *action = common->action;
/* get parameters */ /* get parameters */
g_assert(action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC); g_assert(action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
has_device = action->blockdev_snapshot_sync->has_device; has_device = action->u.blockdev_snapshot_sync->has_device;
device = action->blockdev_snapshot_sync->device; device = action->u.blockdev_snapshot_sync->device;
has_node_name = action->blockdev_snapshot_sync->has_node_name; has_node_name = action->u.blockdev_snapshot_sync->has_node_name;
node_name = action->blockdev_snapshot_sync->node_name; node_name = action->u.blockdev_snapshot_sync->node_name;
has_snapshot_node_name = has_snapshot_node_name =
action->blockdev_snapshot_sync->has_snapshot_node_name; action->u.blockdev_snapshot_sync->has_snapshot_node_name;
snapshot_node_name = action->blockdev_snapshot_sync->snapshot_node_name; snapshot_node_name = action->u.blockdev_snapshot_sync->snapshot_node_name;
new_image_file = action->blockdev_snapshot_sync->snapshot_file; new_image_file = action->u.blockdev_snapshot_sync->snapshot_file;
if (action->blockdev_snapshot_sync->has_format) { if (action->u.blockdev_snapshot_sync->has_format) {
format = action->blockdev_snapshot_sync->format; format = action->u.blockdev_snapshot_sync->format;
} }
if (action->blockdev_snapshot_sync->has_mode) { if (action->u.blockdev_snapshot_sync->has_mode) {
mode = action->blockdev_snapshot_sync->mode; mode = action->u.blockdev_snapshot_sync->mode;
} }
/* start processing */ /* start processing */
@ -1681,8 +1682,8 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
DriveBackup *backup; DriveBackup *backup;
Error *local_err = NULL; Error *local_err = NULL;
assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP); assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
backup = common->action->drive_backup; backup = common->action->u.drive_backup;
blk = blk_by_name(backup->device); blk = blk_by_name(backup->device);
if (!blk) { if (!blk) {
@ -1754,8 +1755,8 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
BlockBackend *blk, *target; BlockBackend *blk, *target;
Error *local_err = NULL; Error *local_err = NULL;
assert(common->action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP); assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
backup = common->action->blockdev_backup; backup = common->action->u.blockdev_backup;
blk = blk_by_name(backup->device); blk = blk_by_name(backup->device);
if (!blk) { if (!blk) {
@ -1887,9 +1888,9 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
dev_info = dev_entry->value; dev_info = dev_entry->value;
dev_entry = dev_entry->next; dev_entry = dev_entry->next;
assert(dev_info->kind < ARRAY_SIZE(actions)); assert(dev_info->type < ARRAY_SIZE(actions));
ops = &actions[dev_info->kind]; ops = &actions[dev_info->type];
assert(ops->instance_size > 0); assert(ops->instance_size > 0);
state = g_malloc0(ops->instance_size); state = g_malloc0(ops->instance_size);

View File

@ -106,12 +106,15 @@ Types, commands, and events share a common namespace. Therefore,
generally speaking, type definitions should always use CamelCase for generally speaking, type definitions should always use CamelCase for
user-defined type names, while built-in types are lowercase. Type user-defined type names, while built-in types are lowercase. Type
definitions should not end in 'Kind', as this namespace is used for definitions should not end in 'Kind', as this namespace is used for
creating implicit C enums for visiting union types. Command names, creating implicit C enums for visiting union types, or in 'List', as
this namespace is used for creating array types. Command names,
and field names within a type, should be all lower case with words and field names within a type, should be all lower case with words
separated by a hyphen. However, some existing older commands and separated by a hyphen. However, some existing older commands and
complex types use underscore; when extending such expressions, complex types use underscore; when extending such expressions,
consistency is preferred over blindly avoiding underscore. Event consistency is preferred over blindly avoiding underscore. Event
names should be ALL_CAPS with words separated by underscore. names should be ALL_CAPS with words separated by underscore. Field
names cannot start with 'has-' or 'has_', as this is reserved for
tracking optional fields.
Any name (command, event, type, field, or enum value) beginning with Any name (command, event, type, field, or enum value) beginning with
"x-" is marked experimental, and may be withdrawn or changed "x-" is marked experimental, and may be withdrawn or changed
@ -122,9 +125,10 @@ vendor), even if the rest of the name uses dash (example:
__com.redhat_drive-mirror). Other than downstream extensions (with __com.redhat_drive-mirror). Other than downstream extensions (with
leading underscore and the use of dots), all names should begin with a leading underscore and the use of dots), all names should begin with a
letter, and contain only ASCII letters, digits, dash, and underscore. letter, and contain only ASCII letters, digits, dash, and underscore.
It is okay to reuse names that match C keywords; the generator will Names beginning with 'q_' are reserved for the generator: QMP names
rename a field named "default" in the QAPI to "q_default" in the that resemble C keywords or other problematic strings will be munged
generated C code. in C to use this prefix. For example, a field named "default" in
qapi becomes "q_default" in the generated C code.
In the rest of this document, usage lines are given for each In the rest of this document, usage lines are given for each
expression type, with literal strings written in lower case and expression type, with literal strings written in lower case and

26
hmp.c
View File

@ -569,8 +569,8 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
for (client = info->clients; client; client = client->next) { for (client = info->clients; client; client = client->next) {
monitor_printf(mon, "Client:\n"); monitor_printf(mon, "Client:\n");
monitor_printf(mon, " address: %s:%s\n", monitor_printf(mon, " address: %s:%s\n",
client->value->base->host, client->value->host,
client->value->base->service); client->value->service);
monitor_printf(mon, " x509_dname: %s\n", monitor_printf(mon, " x509_dname: %s\n",
client->value->x509_dname ? client->value->x509_dname ?
client->value->x509_dname : "none"); client->value->x509_dname : "none");
@ -638,7 +638,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict)
for (chan = info->channels; chan; chan = chan->next) { for (chan = info->channels; chan; chan = chan->next) {
monitor_printf(mon, "Channel:\n"); monitor_printf(mon, "Channel:\n");
monitor_printf(mon, " address: %s:%s%s\n", monitor_printf(mon, " address: %s:%s%s\n",
chan->value->base->host, chan->value->base->port, chan->value->host, chan->value->port,
chan->value->tls ? " [tls]" : ""); chan->value->tls ? " [tls]" : "");
monitor_printf(mon, " session: %" PRId64 "\n", monitor_printf(mon, " session: %" PRId64 "\n",
chan->value->connection_id); chan->value->connection_id);
@ -841,11 +841,11 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
c, TpmModel_lookup[ti->model]); c, TpmModel_lookup[ti->model]);
monitor_printf(mon, " \\ %s: type=%s", monitor_printf(mon, " \\ %s: type=%s",
ti->id, TpmTypeOptionsKind_lookup[ti->options->kind]); ti->id, TpmTypeOptionsKind_lookup[ti->options->type]);
switch (ti->options->kind) { switch (ti->options->type) {
case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
tpo = ti->options->passthrough; tpo = ti->options->u.passthrough;
monitor_printf(mon, "%s%s%s%s", monitor_printf(mon, "%s%s%s%s",
tpo->has_path ? ",path=" : "", tpo->has_path ? ",path=" : "",
tpo->has_path ? tpo->path : "", tpo->has_path ? tpo->path : "",
@ -1735,15 +1735,15 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
if (*endp != '\0') { if (*endp != '\0') {
goto err_out; goto err_out;
} }
keylist->value->kind = KEY_VALUE_KIND_NUMBER; keylist->value->type = KEY_VALUE_KIND_NUMBER;
keylist->value->number = value; keylist->value->u.number = value;
} else { } else {
int idx = index_from_key(keyname_buf); int idx = index_from_key(keyname_buf);
if (idx == Q_KEY_CODE_MAX) { if (idx == Q_KEY_CODE_MAX) {
goto err_out; goto err_out;
} }
keylist->value->kind = KEY_VALUE_KIND_QCODE; keylist->value->type = KEY_VALUE_KIND_QCODE;
keylist->value->qcode = idx; keylist->value->u.qcode = idx;
} }
if (!separator) { if (!separator) {
@ -1958,12 +1958,12 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
value = info->value; value = info->value;
if (value) { if (value) {
switch (value->kind) { switch (value->type) {
case MEMORY_DEVICE_INFO_KIND_DIMM: case MEMORY_DEVICE_INFO_KIND_DIMM:
di = value->dimm; di = value->u.dimm;
monitor_printf(mon, "Memory device [%s]: \"%s\"\n", monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
MemoryDeviceInfoKind_lookup[value->kind], MemoryDeviceInfoKind_lookup[value->type],
di->id ? di->id : ""); di->id ? di->id : "");
monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr);
monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); monitor_printf(mon, " slot: %" PRId64 "\n", di->slot);

View File

@ -842,13 +842,13 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
ChannelState *s = (ChannelState *)dev; ChannelState *s = (ChannelState *)dev;
int qcode, keycode; int qcode, keycode;
assert(evt->kind == INPUT_EVENT_KIND_KEY); assert(evt->type == INPUT_EVENT_KIND_KEY);
qcode = qemu_input_key_value_to_qcode(evt->key->key); qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode], trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
evt->key->down); evt->u.key->down);
if (qcode == Q_KEY_CODE_CAPS_LOCK) { if (qcode == Q_KEY_CODE_CAPS_LOCK) {
if (evt->key->down) { if (evt->u.key->down) {
s->caps_lock_mode ^= 1; s->caps_lock_mode ^= 1;
if (s->caps_lock_mode == 2) { if (s->caps_lock_mode == 2) {
return; /* Drop second press */ return; /* Drop second press */
@ -862,7 +862,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
} }
if (qcode == Q_KEY_CODE_NUM_LOCK) { if (qcode == Q_KEY_CODE_NUM_LOCK) {
if (evt->key->down) { if (evt->u.key->down) {
s->num_lock_mode ^= 1; s->num_lock_mode ^= 1;
if (s->num_lock_mode == 2) { if (s->num_lock_mode == 2) {
return; /* Drop second press */ return; /* Drop second press */
@ -876,7 +876,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
} }
keycode = qcode_to_keycode[qcode]; keycode = qcode_to_keycode[qcode];
if (!evt->key->down) { if (!evt->u.key->down) {
keycode |= 0x80; keycode |= 0x80;
} }
trace_escc_sunkbd_event_out(keycode); trace_escc_sunkbd_event_out(keycode);

View File

@ -119,33 +119,33 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
assert(hs->n < QUEUE_LENGTH); assert(hs->n < QUEUE_LENGTH);
e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK]; e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
switch (evt->kind) { switch (evt->type) {
case INPUT_EVENT_KIND_REL: case INPUT_EVENT_KIND_REL:
if (evt->rel->axis == INPUT_AXIS_X) { if (evt->u.rel->axis == INPUT_AXIS_X) {
e->xdx += evt->rel->value; e->xdx += evt->u.rel->value;
} else if (evt->rel->axis == INPUT_AXIS_Y) { } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
e->ydy += evt->rel->value; e->ydy += evt->u.rel->value;
} }
break; break;
case INPUT_EVENT_KIND_ABS: case INPUT_EVENT_KIND_ABS:
if (evt->rel->axis == INPUT_AXIS_X) { if (evt->u.rel->axis == INPUT_AXIS_X) {
e->xdx = evt->rel->value; e->xdx = evt->u.rel->value;
} else if (evt->rel->axis == INPUT_AXIS_Y) { } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
e->ydy = evt->rel->value; e->ydy = evt->u.rel->value;
} }
break; break;
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
if (evt->btn->down) { if (evt->u.btn->down) {
e->buttons_state |= bmap[evt->btn->button]; e->buttons_state |= bmap[evt->u.btn->button];
if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) { if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
e->dz--; e->dz--;
} else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) { } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
e->dz++; e->dz++;
} }
} else { } else {
e->buttons_state &= ~bmap[evt->btn->button]; e->buttons_state &= ~bmap[evt->u.btn->button];
} }
break; break;
@ -223,8 +223,8 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
int scancodes[3], i, count; int scancodes[3], i, count;
int slot; int slot;
count = qemu_input_key_value_to_scancode(evt->key->key, count = qemu_input_key_value_to_scancode(evt->u.key->key,
evt->key->down, evt->u.key->down,
scancodes); scancodes);
if (hs->n + count > QUEUE_LENGTH) { if (hs->n + count > QUEUE_LENGTH) {
fprintf(stderr, "usb-kbd: warning: key event queue full\n"); fprintf(stderr, "usb-kbd: warning: key event queue full\n");

View File

@ -183,8 +183,8 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
int scancodes[3], i, count; int scancodes[3], i, count;
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
count = qemu_input_key_value_to_scancode(evt->key->key, count = qemu_input_key_value_to_scancode(evt->u.key->key,
evt->key->down, evt->u.key->down,
scancodes); scancodes);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ps2_put_keycode(s, scancodes[i]); ps2_put_keycode(s, scancodes[i]);
@ -393,25 +393,25 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
return; return;
switch (evt->kind) { switch (evt->type) {
case INPUT_EVENT_KIND_REL: case INPUT_EVENT_KIND_REL:
if (evt->rel->axis == INPUT_AXIS_X) { if (evt->u.rel->axis == INPUT_AXIS_X) {
s->mouse_dx += evt->rel->value; s->mouse_dx += evt->u.rel->value;
} else if (evt->rel->axis == INPUT_AXIS_Y) { } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
s->mouse_dy -= evt->rel->value; s->mouse_dy -= evt->u.rel->value;
} }
break; break;
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
if (evt->btn->down) { if (evt->u.btn->down) {
s->mouse_buttons |= bmap[evt->btn->button]; s->mouse_buttons |= bmap[evt->u.btn->button];
if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) { if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
s->mouse_dz--; s->mouse_dz--;
} else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) { } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
s->mouse_dz++; s->mouse_dz++;
} }
} else { } else {
s->mouse_buttons &= ~bmap[evt->btn->button]; s->mouse_buttons &= ~bmap[evt->u.btn->button];
} }
break; break;

View File

@ -191,44 +191,45 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
virtio_input_event event; virtio_input_event event;
int qcode; int qcode;
switch (evt->kind) { switch (evt->type) {
case INPUT_EVENT_KIND_KEY: case INPUT_EVENT_KIND_KEY:
qcode = qemu_input_key_value_to_qcode(evt->key->key); qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
if (qcode && keymap_qcode[qcode]) { if (qcode && keymap_qcode[qcode]) {
event.type = cpu_to_le16(EV_KEY); event.type = cpu_to_le16(EV_KEY);
event.code = cpu_to_le16(keymap_qcode[qcode]); event.code = cpu_to_le16(keymap_qcode[qcode]);
event.value = cpu_to_le32(evt->key->down ? 1 : 0); event.value = cpu_to_le32(evt->u.key->down ? 1 : 0);
virtio_input_send(vinput, &event); virtio_input_send(vinput, &event);
} else { } else {
if (evt->key->down) { if (evt->u.key->down) {
fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__, fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,
qcode, QKeyCode_lookup[qcode]); qcode, QKeyCode_lookup[qcode]);
} }
} }
break; break;
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
if (keymap_button[evt->btn->button]) { if (keymap_button[evt->u.btn->button]) {
event.type = cpu_to_le16(EV_KEY); event.type = cpu_to_le16(EV_KEY);
event.code = cpu_to_le16(keymap_button[evt->btn->button]); event.code = cpu_to_le16(keymap_button[evt->u.btn->button]);
event.value = cpu_to_le32(evt->btn->down ? 1 : 0); event.value = cpu_to_le32(evt->u.btn->down ? 1 : 0);
virtio_input_send(vinput, &event); virtio_input_send(vinput, &event);
} else { } else {
if (evt->btn->down) { if (evt->u.btn->down) {
fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__, fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,
evt->btn->button, InputButton_lookup[evt->btn->button]); evt->u.btn->button,
InputButton_lookup[evt->u.btn->button]);
} }
} }
break; break;
case INPUT_EVENT_KIND_REL: case INPUT_EVENT_KIND_REL:
event.type = cpu_to_le16(EV_REL); event.type = cpu_to_le16(EV_REL);
event.code = cpu_to_le16(axismap_rel[evt->rel->axis]); event.code = cpu_to_le16(axismap_rel[evt->u.rel->axis]);
event.value = cpu_to_le32(evt->rel->value); event.value = cpu_to_le32(evt->u.rel->value);
virtio_input_send(vinput, &event); virtio_input_send(vinput, &event);
break; break;
case INPUT_EVENT_KIND_ABS: case INPUT_EVENT_KIND_ABS:
event.type = cpu_to_le16(EV_ABS); event.type = cpu_to_le16(EV_ABS);
event.code = cpu_to_le16(axismap_abs[evt->abs->axis]); event.code = cpu_to_le16(axismap_abs[evt->u.abs->axis]);
event.value = cpu_to_le32(evt->abs->value); event.value = cpu_to_le32(evt->u.abs->value);
virtio_input_send(vinput, &event); virtio_input_send(vinput, &event);
break; break;
default: default:

View File

@ -179,7 +179,7 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque)
NULL); NULL);
di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));
info->dimm = di; info->u.dimm = di;
elem->value = info; elem->value = info;
elem->next = NULL; elem->next = NULL;
**prev = elem; **prev = elem;
@ -203,9 +203,9 @@ ram_addr_t get_current_ram_size(void)
MemoryDeviceInfo *value = info->value; MemoryDeviceInfo *value = info->value;
if (value) { if (value) {
switch (value->kind) { switch (value->type) {
case MEMORY_DEVICE_INFO_KIND_DIMM: case MEMORY_DEVICE_INFO_KIND_DIMM:
size += value->dimm->size; size += value->u.dimm->size;
break; break;
default: default:
break; break;

View File

@ -187,8 +187,8 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
NetClientState *nc; NetClientState *nc;
DumpNetClient *dnc; DumpNetClient *dnc;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP); assert(opts->type == NET_CLIENT_OPTIONS_KIND_DUMP);
dump = opts->dump; dump = opts->u.dump;
assert(peer); assert(peer);

View File

@ -285,9 +285,9 @@ int net_init_hubport(const NetClientOptions *opts, const char *name,
{ {
const NetdevHubPortOptions *hubport; const NetdevHubPortOptions *hubport;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT); assert(opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT);
assert(!peer); assert(!peer);
hubport = opts->hubport; hubport = opts->u.hubport;
net_hub_add_port(hubport->hubid, name); net_hub_add_port(hubport->hubid, name);
return 0; return 0;

View File

@ -545,8 +545,8 @@ int net_init_l2tpv3(const NetClientOptions *opts,
s->queue_tail = 0; s->queue_tail = 0;
s->header_mismatch = false; s->header_mismatch = false;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_L2TPV3); assert(opts->type == NET_CLIENT_OPTIONS_KIND_L2TPV3);
l2tpv3 = opts->l2tpv3; l2tpv3 = opts->u.l2tpv3;
if (l2tpv3->has_ipv6 && l2tpv3->ipv6) { if (l2tpv3->has_ipv6 && l2tpv3->ipv6) {
s->ipv6 = l2tpv3->ipv6; s->ipv6 = l2tpv3->ipv6;

View File

@ -882,8 +882,8 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
NICInfo *nd; NICInfo *nd;
const NetLegacyNicOptions *nic; const NetLegacyNicOptions *nic;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_NIC); assert(opts->type == NET_CLIENT_OPTIONS_KIND_NIC);
nic = opts->nic; nic = opts->u.nic;
idx = nic_get_free_idx(); idx = nic_get_free_idx();
if (idx == -1 || nb_nics >= MAX_NICS) { if (idx == -1 || nb_nics >= MAX_NICS) {
@ -984,9 +984,9 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
opts = netdev->opts; opts = netdev->opts;
name = netdev->id; name = netdev->id;
if (opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP || if (opts->type == NET_CLIENT_OPTIONS_KIND_DUMP ||
opts->kind == NET_CLIENT_OPTIONS_KIND_NIC || opts->type == NET_CLIENT_OPTIONS_KIND_NIC ||
!net_client_init_fun[opts->kind]) { !net_client_init_fun[opts->type]) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
"a netdev backend type"); "a netdev backend type");
return -1; return -1;
@ -997,16 +997,16 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
/* missing optional values have been initialized to "all bits zero" */ /* missing optional values have been initialized to "all bits zero" */
name = net->has_id ? net->id : net->name; name = net->has_id ? net->id : net->name;
if (opts->kind == NET_CLIENT_OPTIONS_KIND_NONE) { if (opts->type == NET_CLIENT_OPTIONS_KIND_NONE) {
return 0; /* nothing to do */ return 0; /* nothing to do */
} }
if (opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT) { if (opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
"a net type"); "a net type");
return -1; return -1;
} }
if (!net_client_init_fun[opts->kind]) { if (!net_client_init_fun[opts->type]) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
"a net backend type (maybe it is not compiled " "a net backend type (maybe it is not compiled "
"into this binary)"); "into this binary)");
@ -1014,17 +1014,17 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
} }
/* Do not add to a vlan if it's a nic with a netdev= parameter. */ /* Do not add to a vlan if it's a nic with a netdev= parameter. */
if (opts->kind != NET_CLIENT_OPTIONS_KIND_NIC || if (opts->type != NET_CLIENT_OPTIONS_KIND_NIC ||
!opts->nic->has_netdev) { !opts->u.nic->has_netdev) {
peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL); peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
} }
} }
if (net_client_init_fun[opts->kind](opts, name, peer, errp) < 0) { if (net_client_init_fun[opts->type](opts, name, peer, errp) < 0) {
/* FIXME drop when all init functions store an Error */ /* FIXME drop when all init functions store an Error */
if (errp && !*errp) { if (errp && !*errp) {
error_setg(errp, QERR_DEVICE_INIT_FAILED, error_setg(errp, QERR_DEVICE_INIT_FAILED,
NetClientOptionsKind_lookup[opts->kind]); NetClientOptionsKind_lookup[opts->type]);
} }
return -1; return -1;
} }

View File

@ -746,8 +746,8 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
const NetdevUserOptions *user; const NetdevUserOptions *user;
const char **dnssearch; const char **dnssearch;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_USER); assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
user = opts->user; user = opts->u.user;
vnet = user->has_net ? g_strdup(user->net) : vnet = user->has_net ? g_strdup(user->net) :
user->has_ip ? g_strdup_printf("%s/24", user->ip) : user->has_ip ? g_strdup_printf("%s/24", user->ip) :

View File

@ -706,8 +706,8 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
Error *err = NULL; Error *err = NULL;
const NetdevSocketOptions *sock; const NetdevSocketOptions *sock;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_SOCKET); assert(opts->type == NET_CLIENT_OPTIONS_KIND_SOCKET);
sock = opts->socket; sock = opts->u.socket;
if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast + if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
sock->has_udp != 1) { sock->has_udp != 1) {

View File

@ -767,8 +767,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
/* FIXME error_setg(errp, ...) on failure */ /* FIXME error_setg(errp, ...) on failure */
const NetdevTapOptions *tap; const NetdevTapOptions *tap;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP); assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
tap = opts->tap; tap = opts->u.tap;
if (!tap->has_ifname) { if (!tap->has_ifname) {
error_report("tap: no interface name"); error_report("tap: no interface name");

View File

@ -565,8 +565,8 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,
TAPState *s; TAPState *s;
int fd, vnet_hdr; int fd, vnet_hdr;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_BRIDGE); assert(opts->type == NET_CLIENT_OPTIONS_KIND_BRIDGE);
bridge = opts->bridge; bridge = opts->u.bridge;
helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER; helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER;
br = bridge->has_br ? bridge->br : DEFAULT_BRIDGE_INTERFACE; br = bridge->has_br ? bridge->br : DEFAULT_BRIDGE_INTERFACE;
@ -728,8 +728,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
const char *vhostfdname; const char *vhostfdname;
char ifname[128]; char ifname[128];
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP); assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
tap = opts->tap; tap = opts->u.tap;
queues = tap->has_queues ? tap->queues : 1; queues = tap->has_queues ? tap->queues : 1;
vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL; vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;

View File

@ -115,8 +115,8 @@ int net_init_vde(const NetClientOptions *opts, const char *name,
/* FIXME error_setg(errp, ...) on failure */ /* FIXME error_setg(errp, ...) on failure */
const NetdevVdeOptions *vde; const NetdevVdeOptions *vde;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VDE); assert(opts->type == NET_CLIENT_OPTIONS_KIND_VDE);
vde = opts->vde; vde = opts->u.vde;
/* missing optional values have been initialized to "all bits zero" */ /* missing optional values have been initialized to "all bits zero" */
if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group, if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,

View File

@ -301,8 +301,8 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name,
const NetdevVhostUserOptions *vhost_user_opts; const NetdevVhostUserOptions *vhost_user_opts;
CharDriverState *chr; CharDriverState *chr;
assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER); assert(opts->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
vhost_user_opts = opts->vhost_user; vhost_user_opts = opts->u.vhost_user;
chr = net_vhost_parse_chardev(vhost_user_opts, errp); chr = net_vhost_parse_chardev(vhost_user_opts, errp);
if (!chr) { if (!chr) {

8
numa.c
View File

@ -226,9 +226,9 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
goto error; goto error;
} }
switch (object->kind) { switch (object->type) {
case NUMA_OPTIONS_KIND_NODE: case NUMA_OPTIONS_KIND_NODE:
numa_node_parse(object->node, opts, &err); numa_node_parse(object->u.node, opts, &err);
if (err) { if (err) {
goto error; goto error;
} }
@ -487,9 +487,9 @@ static void numa_stat_memory_devices(uint64_t node_mem[])
MemoryDeviceInfo *value = info->value; MemoryDeviceInfo *value = info->value;
if (value) { if (value) {
switch (value->kind) { switch (value->type) {
case MEMORY_DEVICE_INFO_KIND_DIMM: case MEMORY_DEVICE_INFO_KIND_DIMM:
node_mem[value->dimm->node] += value->dimm->size; node_mem[value->u.dimm->node] += value->u.dimm->size;
break; break;
default: default:
break; break;

View File

@ -2614,9 +2614,7 @@
# #
# @host: host part of the address # @host: host part of the address
# #
# @port: port part of the address, or lowest port if @to is present. # @port: port part of the address, or lowest port if @to is present
# Kernel selects a free port if omitted for listener addresses.
# #optional
# #
# @to: highest port to try # @to: highest port to try
# #
@ -2631,7 +2629,7 @@
{ 'struct': 'InetSocketAddress', { 'struct': 'InetSocketAddress',
'data': { 'data': {
'host': 'str', 'host': 'str',
'*port': 'str', 'port': 'str',
'*to': 'uint16', '*to': 'uint16',
'*ipv4': 'bool', '*ipv4': 'bool',
'*ipv6': 'bool' } } '*ipv6': 'bool' } }

View File

@ -97,18 +97,18 @@ static int SocketAddress_to_str(char *dest, int max_len,
const char *prefix, SocketAddress *addr, const char *prefix, SocketAddress *addr,
bool is_listen, bool is_telnet) bool is_listen, bool is_telnet)
{ {
switch (addr->kind) { switch (addr->type) {
case SOCKET_ADDRESS_KIND_INET: case SOCKET_ADDRESS_KIND_INET:
return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix, return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix,
is_telnet ? "telnet" : "tcp", addr->inet->host, is_telnet ? "telnet" : "tcp", addr->u.inet->host,
addr->inet->port, is_listen ? ",server" : ""); addr->u.inet->port, is_listen ? ",server" : "");
break; break;
case SOCKET_ADDRESS_KIND_UNIX: case SOCKET_ADDRESS_KIND_UNIX:
return snprintf(dest, max_len, "%sunix:%s%s", prefix, return snprintf(dest, max_len, "%sunix:%s%s", prefix,
addr->q_unix->path, is_listen ? ",server" : ""); addr->u.q_unix->path, is_listen ? ",server" : "");
break; break;
case SOCKET_ADDRESS_KIND_FD: case SOCKET_ADDRESS_KIND_FD:
return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->fd->str, return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->u.fd->str,
is_listen ? ",server" : ""); is_listen ? ",server" : "");
break; break;
default: default:
@ -661,7 +661,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
ChardevBackend *backend, ChardevBackend *backend,
ChardevReturn *ret, Error **errp) ChardevReturn *ret, Error **errp)
{ {
ChardevMux *mux = backend->mux; ChardevMux *mux = backend->u.mux;
CharDriverState *chr, *drv; CharDriverState *chr, *drv;
MuxDriver *d; MuxDriver *d;
@ -1070,7 +1070,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevHostdev *opts = backend->pipe; ChardevHostdev *opts = backend->u.pipe;
int fd_in, fd_out; int fd_in, fd_out;
char filename_in[CHR_MAX_FILENAME_SIZE]; char filename_in[CHR_MAX_FILENAME_SIZE];
char filename_out[CHR_MAX_FILENAME_SIZE]; char filename_out[CHR_MAX_FILENAME_SIZE];
@ -1148,7 +1148,7 @@ static CharDriverState *qemu_chr_open_stdio(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevStdio *opts = backend->stdio; ChardevStdio *opts = backend->u.stdio;
CharDriverState *chr; CharDriverState *chr;
struct sigaction act; struct sigaction act;
@ -2147,7 +2147,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevHostdev *opts = backend->pipe; ChardevHostdev *opts = backend->u.pipe;
const char *filename = opts->device; const char *filename = opts->device;
CharDriverState *chr; CharDriverState *chr;
WinCharState *s; WinCharState *s;
@ -3202,7 +3202,7 @@ static CharDriverState *qemu_chr_open_ringbuf(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevRingbuf *opts = backend->ringbuf; ChardevRingbuf *opts = backend->u.ringbuf;
CharDriverState *chr; CharDriverState *chr;
RingBufCharDriver *d; RingBufCharDriver *d;
@ -3477,16 +3477,16 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: file: no filename given"); error_setg(errp, "chardev: file: no filename given");
return; return;
} }
backend->file = g_new0(ChardevFile, 1); backend->u.file = g_new0(ChardevFile, 1);
backend->file->out = g_strdup(path); backend->u.file->out = g_strdup(path);
} }
static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
Error **errp) Error **errp)
{ {
backend->stdio = g_new0(ChardevStdio, 1); backend->u.stdio = g_new0(ChardevStdio, 1);
backend->stdio->has_signal = true; backend->u.stdio->has_signal = true;
backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true); backend->u.stdio->signal = qemu_opt_get_bool(opts, "signal", true);
} }
#ifdef HAVE_CHARDEV_SERIAL #ifdef HAVE_CHARDEV_SERIAL
@ -3499,8 +3499,8 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: serial/tty: no device path given"); error_setg(errp, "chardev: serial/tty: no device path given");
return; return;
} }
backend->serial = g_new0(ChardevHostdev, 1); backend->u.serial = g_new0(ChardevHostdev, 1);
backend->serial->device = g_strdup(device); backend->u.serial->device = g_strdup(device);
} }
#endif #endif
@ -3514,8 +3514,8 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: parallel: no device path given"); error_setg(errp, "chardev: parallel: no device path given");
return; return;
} }
backend->parallel = g_new0(ChardevHostdev, 1); backend->u.parallel = g_new0(ChardevHostdev, 1);
backend->parallel->device = g_strdup(device); backend->u.parallel->device = g_strdup(device);
} }
#endif #endif
@ -3528,8 +3528,8 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: pipe: no device path given"); error_setg(errp, "chardev: pipe: no device path given");
return; return;
} }
backend->pipe = g_new0(ChardevHostdev, 1); backend->u.pipe = g_new0(ChardevHostdev, 1);
backend->pipe->device = g_strdup(device); backend->u.pipe->device = g_strdup(device);
} }
static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
@ -3537,12 +3537,12 @@ static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
{ {
int val; int val;
backend->ringbuf = g_new0(ChardevRingbuf, 1); backend->u.ringbuf = g_new0(ChardevRingbuf, 1);
val = qemu_opt_get_size(opts, "size", 0); val = qemu_opt_get_size(opts, "size", 0);
if (val != 0) { if (val != 0) {
backend->ringbuf->has_size = true; backend->u.ringbuf->has_size = true;
backend->ringbuf->size = val; backend->u.ringbuf->size = val;
} }
} }
@ -3555,8 +3555,8 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: mux: no chardev given"); error_setg(errp, "chardev: mux: no chardev given");
return; return;
} }
backend->mux = g_new0(ChardevMux, 1); backend->u.mux = g_new0(ChardevMux, 1);
backend->mux->chardev = g_strdup(chardev); backend->u.mux->chardev = g_strdup(chardev);
} }
static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
@ -3583,37 +3583,37 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
} }
} }
backend->socket = g_new0(ChardevSocket, 1); backend->u.socket = g_new0(ChardevSocket, 1);
backend->socket->has_nodelay = true; backend->u.socket->has_nodelay = true;
backend->socket->nodelay = do_nodelay; backend->u.socket->nodelay = do_nodelay;
backend->socket->has_server = true; backend->u.socket->has_server = true;
backend->socket->server = is_listen; backend->u.socket->server = is_listen;
backend->socket->has_telnet = true; backend->u.socket->has_telnet = true;
backend->socket->telnet = is_telnet; backend->u.socket->telnet = is_telnet;
backend->socket->has_wait = true; backend->u.socket->has_wait = true;
backend->socket->wait = is_waitconnect; backend->u.socket->wait = is_waitconnect;
backend->socket->has_reconnect = true; backend->u.socket->has_reconnect = true;
backend->socket->reconnect = reconnect; backend->u.socket->reconnect = reconnect;
addr = g_new0(SocketAddress, 1); addr = g_new0(SocketAddress, 1);
if (path) { if (path) {
addr->kind = SOCKET_ADDRESS_KIND_UNIX; addr->type = SOCKET_ADDRESS_KIND_UNIX;
addr->q_unix = g_new0(UnixSocketAddress, 1); addr->u.q_unix = g_new0(UnixSocketAddress, 1);
addr->q_unix->path = g_strdup(path); addr->u.q_unix->path = g_strdup(path);
} else { } else {
addr->kind = SOCKET_ADDRESS_KIND_INET; addr->type = SOCKET_ADDRESS_KIND_INET;
addr->inet = g_new0(InetSocketAddress, 1); addr->u.inet = g_new0(InetSocketAddress, 1);
addr->inet->host = g_strdup(host); addr->u.inet->host = g_strdup(host);
addr->inet->port = g_strdup(port); addr->u.inet->port = g_strdup(port);
addr->inet->has_to = qemu_opt_get(opts, "to"); addr->u.inet->has_to = qemu_opt_get(opts, "to");
addr->inet->to = qemu_opt_get_number(opts, "to", 0); addr->u.inet->to = qemu_opt_get_number(opts, "to", 0);
addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4"); addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0); addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6"); addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0); addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
} }
backend->socket->addr = addr; backend->u.socket->addr = addr;
} }
static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
@ -3644,27 +3644,27 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
has_local = true; has_local = true;
} }
backend->udp = g_new0(ChardevUdp, 1); backend->u.udp = g_new0(ChardevUdp, 1);
addr = g_new0(SocketAddress, 1); addr = g_new0(SocketAddress, 1);
addr->kind = SOCKET_ADDRESS_KIND_INET; addr->type = SOCKET_ADDRESS_KIND_INET;
addr->inet = g_new0(InetSocketAddress, 1); addr->u.inet = g_new0(InetSocketAddress, 1);
addr->inet->host = g_strdup(host); addr->u.inet->host = g_strdup(host);
addr->inet->port = g_strdup(port); addr->u.inet->port = g_strdup(port);
addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4"); addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0); addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6"); addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0); addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
backend->udp->remote = addr; backend->u.udp->remote = addr;
if (has_local) { if (has_local) {
backend->udp->has_local = true; backend->u.udp->has_local = true;
addr = g_new0(SocketAddress, 1); addr = g_new0(SocketAddress, 1);
addr->kind = SOCKET_ADDRESS_KIND_INET; addr->type = SOCKET_ADDRESS_KIND_INET;
addr->inet = g_new0(InetSocketAddress, 1); addr->u.inet = g_new0(InetSocketAddress, 1);
addr->inet->host = g_strdup(localaddr); addr->u.inet->host = g_strdup(localaddr);
addr->inet->port = g_strdup(localport); addr->u.inet->port = g_strdup(localport);
backend->udp->local = addr; backend->u.udp->local = addr;
} }
} }
@ -3737,7 +3737,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
} }
chr = NULL; chr = NULL;
backend->kind = cd->kind; backend->type = cd->kind;
if (cd->parse) { if (cd->parse) {
cd->parse(opts, backend, &local_err); cd->parse(opts, backend, &local_err);
if (local_err) { if (local_err) {
@ -3754,9 +3754,9 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
qapi_free_ChardevBackend(backend); qapi_free_ChardevBackend(backend);
qapi_free_ChardevReturn(ret); qapi_free_ChardevReturn(ret);
backend = g_new0(ChardevBackend, 1); backend = g_new0(ChardevBackend, 1);
backend->mux = g_new0(ChardevMux, 1); backend->u.mux = g_new0(ChardevMux, 1);
backend->kind = CHARDEV_BACKEND_KIND_MUX; backend->type = CHARDEV_BACKEND_KIND_MUX;
backend->mux->chardev = g_strdup(bid); backend->u.mux->chardev = g_strdup(bid);
ret = qmp_chardev_add(id, backend, errp); ret = qmp_chardev_add(id, backend, errp);
if (!ret) { if (!ret) {
chr = qemu_chr_find(bid); chr = qemu_chr_find(bid);
@ -4048,7 +4048,7 @@ static CharDriverState *qmp_chardev_open_file(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevFile *file = backend->file; ChardevFile *file = backend->u.file;
HANDLE out; HANDLE out;
if (file->has_in) { if (file->has_in) {
@ -4070,7 +4070,7 @@ static CharDriverState *qmp_chardev_open_serial(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevHostdev *serial = backend->serial; ChardevHostdev *serial = backend->u.serial;
return qemu_chr_open_win_path(serial->device, errp); return qemu_chr_open_win_path(serial->device, errp);
} }
@ -4093,7 +4093,7 @@ static CharDriverState *qmp_chardev_open_file(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevFile *file = backend->file; ChardevFile *file = backend->u.file;
int flags, in = -1, out; int flags, in = -1, out;
flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY; flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
@ -4120,7 +4120,7 @@ static CharDriverState *qmp_chardev_open_serial(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevHostdev *serial = backend->serial; ChardevHostdev *serial = backend->u.serial;
int fd; int fd;
fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
@ -4138,7 +4138,7 @@ static CharDriverState *qmp_chardev_open_parallel(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevHostdev *parallel = backend->parallel; ChardevHostdev *parallel = backend->u.parallel;
int fd; int fd;
fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
@ -4183,7 +4183,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
{ {
CharDriverState *chr; CharDriverState *chr;
TCPCharDriver *s; TCPCharDriver *s;
ChardevSocket *sock = backend->socket; ChardevSocket *sock = backend->u.socket;
SocketAddress *addr = sock->addr; SocketAddress *addr = sock->addr;
bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;
bool is_listen = sock->has_server ? sock->server : true; bool is_listen = sock->has_server ? sock->server : true;
@ -4196,7 +4196,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
s->fd = -1; s->fd = -1;
s->listen_fd = -1; s->listen_fd = -1;
s->is_unix = addr->kind == SOCKET_ADDRESS_KIND_UNIX; s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX;
s->is_listen = is_listen; s->is_listen = is_listen;
s->is_telnet = is_telnet; s->is_telnet = is_telnet;
s->do_nodelay = do_nodelay; s->do_nodelay = do_nodelay;
@ -4250,7 +4250,7 @@ static CharDriverState *qmp_chardev_open_udp(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
ChardevUdp *udp = backend->udp; ChardevUdp *udp = backend->u.udp;
int fd; int fd;
fd = socket_dgram(udp->remote, udp->local, errp); fd = socket_dgram(udp->remote, udp->local, errp);
@ -4279,7 +4279,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
for (i = backends; i; i = i->next) { for (i = backends; i; i = i->next) {
cd = i->data; cd = i->data;
if (cd->kind == backend->kind) { if (cd->kind == backend->type) {
chr = cd->create(id, backend, ret, &local_err); chr = cd->create(id, backend, ret, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
@ -4297,9 +4297,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
chr->label = g_strdup(id); chr->label = g_strdup(id);
chr->avail_connections = chr->avail_connections =
(backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; (backend->type == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
if (!chr->filename) { if (!chr->filename) {
chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]); chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]);
} }
if (!chr->explicit_be_open) { if (!chr->explicit_be_open) {
qemu_chr_be_event(chr, CHR_EVENT_OPENED); qemu_chr_be_event(chr, CHR_EVENT_OPENED);

View File

@ -362,17 +362,17 @@ static SocketAddress *nbd_build_socket_address(const char *sockpath,
saddr = g_new0(SocketAddress, 1); saddr = g_new0(SocketAddress, 1);
if (sockpath) { if (sockpath) {
saddr->kind = SOCKET_ADDRESS_KIND_UNIX; saddr->type = SOCKET_ADDRESS_KIND_UNIX;
saddr->q_unix = g_new0(UnixSocketAddress, 1); saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
saddr->q_unix->path = g_strdup(sockpath); saddr->u.q_unix->path = g_strdup(sockpath);
} else { } else {
saddr->kind = SOCKET_ADDRESS_KIND_INET; saddr->type = SOCKET_ADDRESS_KIND_INET;
saddr->inet = g_new0(InetSocketAddress, 1); saddr->u.inet = g_new0(InetSocketAddress, 1);
saddr->inet->host = g_strdup(bindto); saddr->u.inet->host = g_strdup(bindto);
if (port) { if (port) {
saddr->inet->port = g_strdup(port); saddr->u.inet->port = g_strdup(port);
} else { } else {
saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT); saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
} }
} }

View File

@ -175,7 +175,9 @@ def gen_marshal(name, arg_type, ret_type):
ret += gen_marshal_input_visit(arg_type) ret += gen_marshal_input_visit(arg_type)
ret += gen_call(name, arg_type, ret_type) ret += gen_call(name, arg_type, ret_type)
if re.search('^ *goto out;', ret, re.MULTILINE): # 'goto out' produced by gen_marshal_input_visit->gen_visit_fields()
# for each arg_type member, and by gen_call() for ret_type
if (arg_type and arg_type.members) or ret_type:
ret += mcgen(''' ret += mcgen('''
out: out:

View File

@ -36,26 +36,37 @@ struct %(c_name)s {
c_name=c_name(name), c_type=element_type.c_type()) c_name=c_name(name), c_type=element_type.c_type())
def gen_struct_field(name, typ, optional): def gen_struct_field(member):
ret = '' ret = ''
if optional: if member.optional:
ret += mcgen(''' ret += mcgen('''
bool has_%(c_name)s; bool has_%(c_name)s;
''', ''',
c_name=c_name(name)) c_name=c_name(member.name))
ret += mcgen(''' ret += mcgen('''
%(c_type)s %(c_name)s; %(c_type)s %(c_name)s;
''', ''',
c_type=typ.c_type(), c_name=c_name(name)) c_type=member.type.c_type(), c_name=c_name(member.name))
return ret return ret
def gen_struct_fields(members): def gen_struct_fields(local_members, base=None):
ret = '' ret = ''
for memb in members: if base:
ret += gen_struct_field(memb.name, memb.type, memb.optional) ret += mcgen('''
/* Members inherited from %(c_name)s: */
''',
c_name=base.c_name())
for memb in base.members:
ret += gen_struct_field(memb)
ret += mcgen('''
/* Own members: */
''')
for memb in local_members:
ret += gen_struct_field(memb)
return ret return ret
@ -66,16 +77,13 @@ struct %(c_name)s {
''', ''',
c_name=c_name(name)) c_name=c_name(name))
if base: ret += gen_struct_fields(members, base)
ret += gen_struct_field('base', base, False)
ret += gen_struct_fields(members)
# Make sure that all structs have at least one field; this avoids # Make sure that all structs have at least one field; this avoids
# potential issues with attempting to malloc space for zero-length # potential issues with attempting to malloc space for zero-length
# structs in C, and also incompatibility with C++ (where an empty # structs in C, and also incompatibility with C++ (where an empty
# struct is size 1). # struct is size 1).
if not base and not members: if not (base and base.members) and not members:
ret += mcgen(''' ret += mcgen('''
char qapi_dummy_field_for_empty_struct; char qapi_dummy_field_for_empty_struct;
''') ''')
@ -87,6 +95,19 @@ struct %(c_name)s {
return ret return ret
def gen_upcast(name, base):
# C makes const-correctness ugly. We have to cast away const to let
# this function work for both const and non-const obj.
return mcgen('''
static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
{
return (%(base)s *)obj;
}
''',
c_name=c_name(name), base=base.c_name())
def gen_alternate_qtypes_decl(name): def gen_alternate_qtypes_decl(name):
return mcgen(''' return mcgen('''
@ -126,19 +147,9 @@ struct %(c_name)s {
''', ''',
c_name=c_name(name)) c_name=c_name(name))
if base: if base:
ret += mcgen(''' ret += gen_struct_fields([], base)
/* Members inherited from %(c_name)s: */
''',
c_name=c_name(base.name))
ret += gen_struct_fields(base.members)
ret += mcgen('''
/* Own members: */
''')
else: else:
ret += mcgen(''' ret += gen_struct_field(variants.tag_member)
%(c_type)s kind;
''',
c_type=c_name(variants.tag_member.type.name))
# FIXME: What purpose does data serve, besides preventing a union that # FIXME: What purpose does data serve, besides preventing a union that
# has a branch named 'data'? We use it in qapi-visit.py to decide # has a branch named 'data'? We use it in qapi-visit.py to decide
@ -152,10 +163,7 @@ struct %(c_name)s {
union { /* union tag is @%(c_name)s */ union { /* union tag is @%(c_name)s */
void *data; void *data;
''', ''',
# TODO ugly special case for simple union c_name=c_name(variants.tag_member.name))
# Use same tag name in C as on the wire to get rid of
# it, then: c_name=c_name(variants.tag_member.name)
c_name=c_name(variants.tag_name or 'kind'))
for var in variants.variants: for var in variants.variants:
# Ugly special case for simple union TODO get rid of it # Ugly special case for simple union TODO get rid of it
@ -167,7 +175,7 @@ struct %(c_name)s {
c_name=c_name(var.name)) c_name=c_name(var.name))
ret += mcgen(''' ret += mcgen('''
}; } u;
}; };
''') ''')
@ -265,6 +273,8 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl += gen_union(name, base, variants) self.decl += gen_union(name, base, variants)
else: else:
self.decl += gen_struct(name, base, members) self.decl += gen_struct(name, base, members)
if base:
self.decl += gen_upcast(name, base)
self._gen_type_cleanup(name) self._gen_type_cleanup(name)
def visit_alternate_type(self, name, info, variants): def visit_alternate_type(self, name, info, variants):

View File

@ -15,7 +15,12 @@
from qapi import * from qapi import *
import re import re
# visit_type_FOO_implicit() is emitted as needed; track if it has already
# been output.
implicit_structs_seen = set() implicit_structs_seen = set()
# visit_type_FOO_fields() is always emitted; track if a forward declaration
# or implementation has already been output.
struct_fields_seen = set() struct_fields_seen = set()
@ -29,19 +34,24 @@ void visit_type_%(c_name)s(Visitor *v, %(c_type)sobj, const char *name, Error **
c_name=c_name(name), c_type=c_type) c_name=c_name(name), c_type=c_type)
def gen_visit_implicit_struct(typ): def gen_visit_fields_decl(typ):
if typ in implicit_structs_seen:
return ''
implicit_structs_seen.add(typ)
ret = '' ret = ''
if typ.name not in struct_fields_seen: if typ.name not in struct_fields_seen:
# Need a forward declaration
ret += mcgen(''' ret += mcgen('''
static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s **obj, Error **errp); static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s **obj, Error **errp);
''', ''',
c_type=typ.c_name()) c_type=typ.c_name())
struct_fields_seen.add(typ.name)
return ret
def gen_visit_implicit_struct(typ):
if typ in implicit_structs_seen:
return ''
implicit_structs_seen.add(typ)
ret = gen_visit_fields_decl(typ)
ret += mcgen(''' ret += mcgen('''
@ -62,13 +72,12 @@ static void visit_type_implicit_%(c_type)s(Visitor *v, %(c_type)s **obj, Error *
def gen_visit_struct_fields(name, base, members): def gen_visit_struct_fields(name, base, members):
struct_fields_seen.add(name)
ret = '' ret = ''
if base: if base:
ret += gen_visit_implicit_struct(base) ret += gen_visit_fields_decl(base)
struct_fields_seen.add(name)
ret += mcgen(''' ret += mcgen('''
static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **errp) static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **errp)
@ -80,14 +89,15 @@ static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **e
if base: if base:
ret += mcgen(''' ret += mcgen('''
visit_type_implicit_%(c_type)s(v, &(*obj)->%(c_name)s, &err); visit_type_%(c_type)s_fields(v, (%(c_type)s **)obj, &err);
''', ''',
c_type=base.c_name(), c_name=c_name('base')) c_type=base.c_name())
ret += gen_err_check() ret += gen_err_check()
ret += gen_visit_fields(members, prefix='(*obj)->') ret += gen_visit_fields(members, prefix='(*obj)->')
if re.search('^ *goto out;', ret, re.MULTILINE): # 'goto out' produced for base, and by gen_visit_fields() for each member
if base or members:
ret += mcgen(''' ret += mcgen('''
out: out:
@ -179,18 +189,18 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
if (err) { if (err) {
goto out; goto out;
} }
visit_get_next_type(v, (int*) &(*obj)->kind, %(c_name)s_qtypes, name, &err); visit_get_next_type(v, (int*) &(*obj)->type, %(c_name)s_qtypes, name, &err);
if (err) { if (err) {
goto out_obj; goto out_obj;
} }
switch ((*obj)->kind) { switch ((*obj)->type) {
''', ''',
c_name=c_name(name)) c_name=c_name(name))
for var in variants.variants: for var in variants.variants:
ret += mcgen(''' ret += mcgen('''
case %(case)s: case %(case)s:
visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, name, &err); visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err);
break; break;
''', ''',
case=c_enum_const(variants.tag_member.type.name, case=c_enum_const(variants.tag_member.type.name,
@ -218,8 +228,7 @@ def gen_visit_union(name, base, variants):
ret = '' ret = ''
if base: if base:
members = [m for m in base.members if m != variants.tag_member] ret += gen_visit_fields_decl(base)
ret += gen_visit_struct_fields(name, None, members)
for var in variants.variants: for var in variants.variants:
# Ugly special case for simple union TODO get rid of it # Ugly special case for simple union TODO get rid of it
@ -244,31 +253,24 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
if base: if base:
ret += mcgen(''' ret += mcgen('''
visit_type_%(c_name)s_fields(v, obj, &err); visit_type_%(c_name)s_fields(v, (%(c_name)s **)obj, &err);
''', ''',
c_name=c_name(name)) c_name=base.c_name())
ret += gen_err_check(label='out_obj') else:
ret += mcgen('''
tag_key = variants.tag_member.name
if not variants.tag_name:
# we pointlessly use a different key for simple unions
tag_key = 'type'
ret += mcgen('''
visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err); visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
if (err) { ''',
goto out_obj; c_type=variants.tag_member.type.c_name(),
} c_name=c_name(variants.tag_member.name),
if (!visit_start_union(v, !!(*obj)->data, &err) || err) { name=variants.tag_member.name)
ret += gen_err_check(label='out_obj')
ret += mcgen('''
if (!visit_start_union(v, !!(*obj)->u.data, &err) || err) {
goto out_obj; goto out_obj;
} }
switch ((*obj)->%(c_name)s) { switch ((*obj)->%(c_name)s) {
''', ''',
c_type=variants.tag_member.type.c_name(), c_name=c_name(variants.tag_member.name))
# TODO ugly special case for simple union
# Use same tag name in C as on the wire to get rid of
# it, then: c_name=c_name(variants.tag_member.name)
c_name=c_name(variants.tag_name or 'kind'),
name=tag_key)
for var in variants.variants: for var in variants.variants:
# TODO ugly special case for simple union # TODO ugly special case for simple union
@ -280,13 +282,13 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
var.name)) var.name))
if simple_union_type: if simple_union_type:
ret += mcgen(''' ret += mcgen('''
visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "data", &err); visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, "data", &err);
''', ''',
c_type=simple_union_type.c_name(), c_type=simple_union_type.c_name(),
c_name=c_name(var.name)) c_name=c_name(var.name))
else: else:
ret += mcgen(''' ret += mcgen('''
visit_type_implicit_%(c_type)s(v, &(*obj)->%(c_name)s, &err); visit_type_implicit_%(c_type)s(v, &(*obj)->u.%(c_name)s, &err);
''', ''',
c_type=var.type.c_name(), c_type=var.type.c_name(),
c_name=c_name(var.name)) c_name=c_name(var.name))
@ -302,7 +304,7 @@ out_obj:
error_propagate(errp, err); error_propagate(errp, err);
err = NULL; err = NULL;
if (*obj) { if (*obj) {
visit_end_union(v, !!(*obj)->data, &err); visit_end_union(v, !!(*obj)->u.data, &err);
} }
error_propagate(errp, err); error_propagate(errp, err);
err = NULL; err = NULL;

View File

@ -172,7 +172,7 @@ class QAPISchemaParser(object):
if self.tok == '#': if self.tok == '#':
self.cursor = self.src.find('\n', self.cursor) self.cursor = self.src.find('\n', self.cursor)
elif self.tok in ['{', '}', ':', ',', '[', ']']: elif self.tok in "{}:,[]":
return return
elif self.tok == "'": elif self.tok == "'":
string = '' string = ''
@ -376,7 +376,9 @@ def check_name(expr_info, source, name, allow_optional=False,
# code always prefixes it with the enum name # code always prefixes it with the enum name
if enum_member: if enum_member:
membername = '_' + membername membername = '_' + membername
if not valid_name.match(membername): # Reserve the entire 'q_' namespace for c_name()
if not valid_name.match(membername) or \
c_name(membername, False).startswith('q_'):
raise QAPIExprError(expr_info, raise QAPIExprError(expr_info,
"%s uses invalid name '%s'" % (source, name)) "%s uses invalid name '%s'" % (source, name))
@ -390,10 +392,10 @@ def add_name(name, info, meta, implicit=False):
raise QAPIExprError(info, raise QAPIExprError(info,
"%s '%s' is already defined" "%s '%s' is already defined"
% (all_names[name], name)) % (all_names[name], name))
if not implicit and name[-4:] == 'Kind': if not implicit and (name.endswith('Kind') or name.endswith('List')):
raise QAPIExprError(info, raise QAPIExprError(info,
"%s '%s' should not end in 'Kind'" "%s '%s' should not end in '%s'"
% (meta, name)) % (meta, name, name[-4:]))
all_names[name] = meta all_names[name] = meta
@ -488,6 +490,10 @@ def check_type(expr_info, source, value, allow_array=False,
for (key, arg) in value.items(): for (key, arg) in value.items():
check_name(expr_info, "Member of %s" % source, key, check_name(expr_info, "Member of %s" % source, key,
allow_optional=allow_optional) allow_optional=allow_optional)
if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'):
raise QAPIExprError(expr_info,
"Member of %s uses reserved name '%s'"
% (source, key))
# Todo: allow dictionaries to represent default values of # Todo: allow dictionaries to represent default values of
# an optional argument. # an optional argument.
check_type(expr_info, "Member '%s' of %s" % (key, source), arg, check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
@ -542,7 +548,8 @@ def check_union(expr, expr_info):
base = expr.get('base') base = expr.get('base')
discriminator = expr.get('discriminator') discriminator = expr.get('discriminator')
members = expr['data'] members = expr['data']
values = {'MAX': '(automatic)', 'KIND': '(automatic)'} values = {'MAX': '(automatic)', 'KIND': '(automatic)',
'TYPE': '(automatic)'}
# Two types of unions, determined by discriminator. # Two types of unions, determined by discriminator.
@ -910,7 +917,7 @@ class QAPISchemaEnumType(QAPISchemaType):
def is_implicit(self): def is_implicit(self):
# See QAPISchema._make_implicit_enum_type() # See QAPISchema._make_implicit_enum_type()
return self.name[-4:] == 'Kind' return self.name.endswith('Kind')
def c_type(self, is_param=False): def c_type(self, is_param=False):
return c_name(self.name) return c_name(self.name)
@ -1196,9 +1203,7 @@ class QAPISchema(object):
return name return name
def _make_array_type(self, element_type, info): def _make_array_type(self, element_type, info):
# TODO fooList namespace is not reserved; user can create collisions, name = element_type + 'List' # Use namespace reserved by add_name()
# or abuse our type system with ['fooList'] for 2D array
name = element_type + 'List'
if not self.lookup_type(name): if not self.lookup_type(name):
self._def_entity(QAPISchemaArrayType(name, info, element_type)) self._def_entity(QAPISchemaArrayType(name, info, element_type))
return name return name

View File

@ -301,7 +301,7 @@ static CharDriverState *qemu_chr_open_spice_vmc(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
const char *type = backend->spicevmc->type; const char *type = backend->u.spicevmc->type;
const char **psubtype = spice_server_char_device_recognized_subtypes(); const char **psubtype = spice_server_char_device_recognized_subtypes();
for (; *psubtype != NULL; ++psubtype) { for (; *psubtype != NULL; ++psubtype) {
@ -324,7 +324,7 @@ static CharDriverState *qemu_chr_open_spice_port(const char *id,
ChardevReturn *ret, ChardevReturn *ret,
Error **errp) Error **errp)
{ {
const char *name = backend->spiceport->fqdn; const char *name = backend->u.spiceport->fqdn;
CharDriverState *chr; CharDriverState *chr;
SpiceCharDriver *s; SpiceCharDriver *s;
@ -362,8 +362,8 @@ static void qemu_chr_parse_spice_vmc(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: spice channel: no name given"); error_setg(errp, "chardev: spice channel: no name given");
return; return;
} }
backend->spicevmc = g_new0(ChardevSpiceChannel, 1); backend->u.spicevmc = g_new0(ChardevSpiceChannel, 1);
backend->spicevmc->type = g_strdup(name); backend->u.spicevmc->type = g_strdup(name);
} }
static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend, static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
@ -375,8 +375,8 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: spice port: no name given"); error_setg(errp, "chardev: spice port: no name given");
return; return;
} }
backend->spiceport = g_new0(ChardevSpicePort, 1); backend->u.spiceport = g_new0(ChardevSpicePort, 1);
backend->spiceport->fqdn = g_strdup(name); backend->u.spiceport->fqdn = g_strdup(name);
} }
static void register_types(void) static void register_types(void)

View File

@ -265,7 +265,6 @@ qapi-schema += enum-dict-member.json
qapi-schema += enum-int-member.json qapi-schema += enum-int-member.json
qapi-schema += enum-max-member.json qapi-schema += enum-max-member.json
qapi-schema += enum-missing-data.json qapi-schema += enum-missing-data.json
qapi-schema += enum-union-clash.json
qapi-schema += enum-wrong-data.json qapi-schema += enum-wrong-data.json
qapi-schema += escape-outside-string.json qapi-schema += escape-outside-string.json
qapi-schema += escape-too-big.json qapi-schema += escape-too-big.json
@ -316,12 +315,17 @@ qapi-schema += redefined-builtin.json
qapi-schema += redefined-command.json qapi-schema += redefined-command.json
qapi-schema += redefined-event.json qapi-schema += redefined-event.json
qapi-schema += redefined-type.json qapi-schema += redefined-type.json
qapi-schema += reserved-command-q.json
qapi-schema += reserved-member-has.json
qapi-schema += reserved-member-q.json
qapi-schema += reserved-member-u.json
qapi-schema += reserved-type-kind.json
qapi-schema += reserved-type-list.json
qapi-schema += returns-alternate.json qapi-schema += returns-alternate.json
qapi-schema += returns-array-bad.json qapi-schema += returns-array-bad.json
qapi-schema += returns-dict.json qapi-schema += returns-dict.json
qapi-schema += returns-unknown.json qapi-schema += returns-unknown.json
qapi-schema += returns-whitelist.json qapi-schema += returns-whitelist.json
qapi-schema += struct-base-clash-base.json
qapi-schema += struct-base-clash-deep.json qapi-schema += struct-base-clash-deep.json
qapi-schema += struct-base-clash.json qapi-schema += struct-base-clash.json
qapi-schema += struct-data-invalid.json qapi-schema += struct-data-invalid.json

View File

@ -1 +0,0 @@
tests/qapi-schema/enum-union-clash.json:2: enum 'UnionKind' should not end in 'Kind'

View File

@ -11,6 +11,10 @@
# An empty enum, although unusual, is currently acceptable # An empty enum, although unusual, is currently acceptable
{ 'enum': 'MyEnum', 'data': [ ] } { 'enum': 'MyEnum', 'data': [ ] }
# Likewise for an empty struct, including an empty base
{ 'struct': 'Empty1', 'data': { } }
{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
# for testing override of default naming heuristic # for testing override of default naming heuristic
{ 'enum': 'QEnumTwo', { 'enum': 'QEnumTwo',
'prefix': 'QENUM_TWO', 'prefix': 'QENUM_TWO',

View File

@ -81,6 +81,9 @@ event EVENT_A None
event EVENT_B None event EVENT_B None
event EVENT_C :obj-EVENT_C-arg event EVENT_C :obj-EVENT_C-arg
event EVENT_D :obj-EVENT_D-arg event EVENT_D :obj-EVENT_D-arg
object Empty1
object Empty2
base Empty1
enum EnumOne ['value1', 'value2', 'value3'] enum EnumOne ['value1', 'value2', 'value3']
object EventStructOne object EventStructOne
member struct1: UserDefOne optional=False member struct1: UserDefOne optional=False

View File

@ -0,0 +1 @@
tests/qapi-schema/reserved-command-q.json:5: 'command' uses invalid name 'q-unix'

View File

@ -0,0 +1,5 @@
# C entity name collision
# We reject names like 'q-unix', because they can collide with the mangled
# name for 'unix' in generated C.
{ 'command': 'unix' }
{ 'command': 'q-unix' }

View File

@ -0,0 +1 @@
tests/qapi-schema/reserved-member-has.json:5: Member of 'data' for command 'oops' uses reserved name 'has-a'

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,5 @@
# C member name collision
# We reject names like 'has-a', because they can collide with the flag
# for an optional 'a' in generated C.
# TODO we could munge the optional flag name to avoid the collision.
{ 'command': 'oops', 'data': { '*a': 'str', 'has-a': 'str' } }

View File

@ -0,0 +1 @@
tests/qapi-schema/reserved-member-q.json:4: Member of 'data' for struct 'Foo' uses invalid name 'q-unix'

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
# C member name collision
# We reject names like 'q-unix', because they can collide with the mangled
# name for 'unix' in generated C.
{ 'struct': 'Foo', 'data': { 'unix':'int', 'q-unix':'bool' } }

View File

View File

@ -0,0 +1 @@
tests/qapi-schema/reserved-member-u.json:7: Member of 'data' for struct 'Oops' uses reserved name 'u'

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,7 @@
# Potential C member name collision
# We reject use of 'u' as a member name, to allow it for internal use in
# putting union branch members in a separate namespace from QMP members.
# This is true even for non-unions, because it is possible to convert a
# struct to flat union while remaining backwards compatible in QMP.
# TODO - we could munge the member name to 'q_u' to avoid the collision
{ 'struct': 'Oops', 'data': { 'u': 'str' } }

View File

View File

@ -0,0 +1 @@
tests/qapi-schema/reserved-type-kind.json:2: enum 'UnionKind' should not end in 'Kind'

View File

@ -0,0 +1 @@
1

View File

@ -1,4 +1,2 @@
# we reject types that would conflict with implicit union enum # we reject types that would conflict with implicit union enum
{ 'enum': 'UnionKind', 'data': [ 'oops' ] } { 'enum': 'UnionKind', 'data': [ 'oops' ] }
{ 'union': 'Union',
'data': { 'a': 'int' } }

View File

View File

@ -0,0 +1 @@
tests/qapi-schema/reserved-type-list.json:5: struct 'FooList' should not end in 'List'

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,5 @@
# Potential C name collision
# We reserve names ending in 'List' for use by array types.
# TODO - we could choose array names to avoid collision with user types,
# in order to let this compile
{ 'struct': 'FooList', 'data': { 's': 'str' } }

View File

View File

@ -1 +0,0 @@
0

View File

@ -1,9 +0,0 @@
# Struct member 'base'
# FIXME: this parses, but then fails to compile due to a duplicate 'base'
# (one explicit in QMP, the other used to box the base class members).
# We should either reject the collision at parse time, or change the
# generated struct to allow this to compile.
{ 'struct': 'Base', 'data': {} }
{ 'struct': 'Sub',
'base': 'Base',
'data': { 'base': 'str' } }

View File

@ -1,5 +0,0 @@
object :empty
object Base
object Sub
base Base
member base: str optional=False

View File

@ -25,11 +25,9 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne)); UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
ud1c->string = strdup(ud1a->string); ud1c->string = strdup(ud1a->string);
ud1c->base = g_new0(UserDefZero, 1); ud1c->integer = ud1a->integer;
ud1c->base->integer = ud1a->base->integer;
ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0"); ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");
ud1d->base = g_new0(UserDefZero, 1); ud1d->integer = has_udb1 ? ud1b->integer : 0;
ud1d->base->integer = has_udb1 ? ud1b->base->integer : 0;
ret = g_new0(UserDefTwo, 1); ret = g_new0(UserDefTwo, 1);
ret->string0 = strdup("blah1"); ret->string0 = strdup("blah1");
@ -64,8 +62,8 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
{ {
__org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1); __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);
ret->kind = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
ret->__org_qemu_x_branch = strdup("blah1"); ret->u.__org_qemu_x_branch = strdup("blah1");
return ret; return ret;
} }
@ -176,20 +174,17 @@ static void test_dealloc_types(void)
UserDefOneList *ud1list; UserDefOneList *ud1list;
ud1test = g_malloc0(sizeof(UserDefOne)); ud1test = g_malloc0(sizeof(UserDefOne));
ud1test->base = g_new0(UserDefZero, 1); ud1test->integer = 42;
ud1test->base->integer = 42;
ud1test->string = g_strdup("hi there 42"); ud1test->string = g_strdup("hi there 42");
qapi_free_UserDefOne(ud1test); qapi_free_UserDefOne(ud1test);
ud1a = g_malloc0(sizeof(UserDefOne)); ud1a = g_malloc0(sizeof(UserDefOne));
ud1a->base = g_new0(UserDefZero, 1); ud1a->integer = 43;
ud1a->base->integer = 43;
ud1a->string = g_strdup("hi there 43"); ud1a->string = g_strdup("hi there 43");
ud1b = g_malloc0(sizeof(UserDefOne)); ud1b = g_malloc0(sizeof(UserDefOne));
ud1b->base = g_new0(UserDefZero, 1); ud1b->integer = 44;
ud1b->base->integer = 44;
ud1b->string = g_strdup("hi there 44"); ud1b->string = g_strdup("hi there 44");
ud1list = g_malloc0(sizeof(UserDefOneList)); ud1list = g_malloc0(sizeof(UserDefOneList));

View File

@ -179,9 +179,7 @@ static void test_event_c(TestEventData *data,
QDict *d, *d_data, *d_b; QDict *d, *d_data, *d_b;
UserDefOne b; UserDefOne b;
UserDefZero z; b.integer = 2;
z.integer = 2;
b.base = &z;
b.string = g_strdup("test1"); b.string = g_strdup("test1");
b.has_enum1 = false; b.has_enum1 = false;
@ -209,11 +207,9 @@ static void test_event_d(TestEventData *data,
{ {
UserDefOne struct1; UserDefOne struct1;
EventStructOne a; EventStructOne a;
UserDefZero z;
QDict *d, *d_data, *d_a, *d_struct1; QDict *d, *d_data, *d_a, *d_struct1;
z.integer = 2; struct1.integer = 2;
struct1.base = &z;
struct1.string = g_strdup("test1"); struct1.string = g_strdup("test1");
struct1.has_enum1 = true; struct1.has_enum1 = true;
struct1.enum1 = ENUM_ONE_VALUE1; struct1.enum1 = ENUM_ONE_VALUE1;

View File

@ -262,7 +262,7 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
check_and_free_str(udp->string0, "string0"); check_and_free_str(udp->string0, "string0");
check_and_free_str(udp->dict1->string1, "string1"); check_and_free_str(udp->dict1->string1, "string1");
g_assert_cmpint(udp->dict1->dict2->userdef->base->integer, ==, 42); g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
check_and_free_str(udp->dict1->dict2->userdef->string, "string"); check_and_free_str(udp->dict1->dict2->userdef->string, "string");
check_and_free_str(udp->dict1->dict2->string, "string2"); check_and_free_str(udp->dict1->dict2->string, "string2");
g_assert(udp->dict1->has_dict3 == false); g_assert(udp->dict1->has_dict3 == false);
@ -292,7 +292,7 @@ static void test_visitor_in_list(TestInputVisitorData *data,
snprintf(string, sizeof(string), "string%d", i); snprintf(string, sizeof(string), "string%d", i);
g_assert_cmpstr(item->value->string, ==, string); g_assert_cmpstr(item->value->string, ==, string);
g_assert_cmpint(item->value->base->integer, ==, 42 + i); g_assert_cmpint(item->value->integer, ==, 42 + i);
} }
qapi_free_UserDefOneList(head); qapi_free_UserDefOneList(head);
@ -347,6 +347,7 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
Visitor *v; Visitor *v;
Error *err = NULL; Error *err = NULL;
UserDefFlatUnion *tmp; UserDefFlatUnion *tmp;
UserDefUnionBase *base;
v = visitor_input_test_init(data, v = visitor_input_test_init(data,
"{ 'enum1': 'value1', " "{ 'enum1': 'value1', "
@ -359,7 +360,11 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1); g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
g_assert_cmpstr(tmp->string, ==, "str"); g_assert_cmpstr(tmp->string, ==, "str");
g_assert_cmpint(tmp->integer, ==, 41); g_assert_cmpint(tmp->integer, ==, 41);
g_assert_cmpint(tmp->value1->boolean, ==, true); g_assert_cmpint(tmp->u.value1->boolean, ==, true);
base = qapi_UserDefFlatUnion_base(tmp);
g_assert(&base->enum1 == &tmp->enum1);
qapi_free_UserDefFlatUnion(tmp); qapi_free_UserDefFlatUnion(tmp);
} }
@ -372,15 +377,15 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
v = visitor_input_test_init(data, "42"); v = visitor_input_test_init(data, "42");
visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_I); g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
g_assert_cmpint(tmp->i, ==, 42); g_assert_cmpint(tmp->u.i, ==, 42);
qapi_free_UserDefAlternate(tmp); qapi_free_UserDefAlternate(tmp);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "'string'"); v = visitor_input_test_init(data, "'string'");
visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_S); g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
g_assert_cmpstr(tmp->s, ==, "string"); g_assert_cmpstr(tmp->u.s, ==, "string");
qapi_free_UserDefAlternate(tmp); qapi_free_UserDefAlternate(tmp);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
@ -419,8 +424,8 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
* parse the same as ans */ * parse the same as ans */
v = visitor_input_test_init(data, "42"); v = visitor_input_test_init(data, "42");
visit_type_AltStrNum(v, &asn, NULL, &err); visit_type_AltStrNum(v, &asn, NULL, &err);
/* FIXME g_assert_cmpint(asn->kind, == ALT_STR_NUM_KIND_N); */ /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
/* FIXME g_assert_cmpfloat(asn->n, ==, 42); */ /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
g_assert(err); g_assert(err);
error_free(err); error_free(err);
err = NULL; err = NULL;
@ -429,29 +434,29 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
v = visitor_input_test_init(data, "42"); v = visitor_input_test_init(data, "42");
visit_type_AltNumStr(v, &ans, NULL, &error_abort); visit_type_AltNumStr(v, &ans, NULL, &error_abort);
g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N); g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
g_assert_cmpfloat(ans->n, ==, 42); g_assert_cmpfloat(ans->u.n, ==, 42);
qapi_free_AltNumStr(ans); qapi_free_AltNumStr(ans);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42"); v = visitor_input_test_init(data, "42");
visit_type_AltStrInt(v, &asi, NULL, &error_abort); visit_type_AltStrInt(v, &asi, NULL, &error_abort);
g_assert_cmpint(asi->kind, ==, ALT_STR_INT_KIND_I); g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
g_assert_cmpint(asi->i, ==, 42); g_assert_cmpint(asi->u.i, ==, 42);
qapi_free_AltStrInt(asi); qapi_free_AltStrInt(asi);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42"); v = visitor_input_test_init(data, "42");
visit_type_AltIntNum(v, &ain, NULL, &error_abort); visit_type_AltIntNum(v, &ain, NULL, &error_abort);
g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_I); g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
g_assert_cmpint(ain->i, ==, 42); g_assert_cmpint(ain->u.i, ==, 42);
qapi_free_AltIntNum(ain); qapi_free_AltIntNum(ain);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42"); v = visitor_input_test_init(data, "42");
visit_type_AltNumInt(v, &ani, NULL, &error_abort); visit_type_AltNumInt(v, &ani, NULL, &error_abort);
g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_I); g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
g_assert_cmpint(ani->i, ==, 42); g_assert_cmpint(ani->u.i, ==, 42);
qapi_free_AltNumInt(ani); qapi_free_AltNumInt(ani);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
@ -467,15 +472,15 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
v = visitor_input_test_init(data, "42.5"); v = visitor_input_test_init(data, "42.5");
visit_type_AltStrNum(v, &asn, NULL, &error_abort); visit_type_AltStrNum(v, &asn, NULL, &error_abort);
g_assert_cmpint(asn->kind, ==, ALT_STR_NUM_KIND_N); g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
g_assert_cmpfloat(asn->n, ==, 42.5); g_assert_cmpfloat(asn->u.n, ==, 42.5);
qapi_free_AltStrNum(asn); qapi_free_AltStrNum(asn);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5"); v = visitor_input_test_init(data, "42.5");
visit_type_AltNumStr(v, &ans, NULL, &error_abort); visit_type_AltNumStr(v, &ans, NULL, &error_abort);
g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N); g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
g_assert_cmpfloat(ans->n, ==, 42.5); g_assert_cmpfloat(ans->u.n, ==, 42.5);
qapi_free_AltNumStr(ans); qapi_free_AltNumStr(ans);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
@ -489,15 +494,15 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
v = visitor_input_test_init(data, "42.5"); v = visitor_input_test_init(data, "42.5");
visit_type_AltIntNum(v, &ain, NULL, &error_abort); visit_type_AltIntNum(v, &ain, NULL, &error_abort);
g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_N); g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
g_assert_cmpfloat(ain->n, ==, 42.5); g_assert_cmpfloat(ain->u.n, ==, 42.5);
qapi_free_AltIntNum(ain); qapi_free_AltIntNum(ain);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5"); v = visitor_input_test_init(data, "42.5");
visit_type_AltNumInt(v, &ani, NULL, &error_abort); visit_type_AltNumInt(v, &ani, NULL, &error_abort);
g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_N); g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
g_assert_cmpfloat(ani->n, ==, 42.5); g_assert_cmpfloat(ani->u.n, ==, 42.5);
qapi_free_AltNumInt(ani); qapi_free_AltNumInt(ani);
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
} }
@ -527,68 +532,68 @@ static void test_native_list_integer_helper(TestInputVisitorData *data,
visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err); visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
g_assert(cvalue != NULL); g_assert(cvalue != NULL);
g_assert_cmpint(cvalue->kind, ==, kind); g_assert_cmpint(cvalue->type, ==, kind);
switch (kind) { switch (kind) {
case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: { case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
intList *elem = NULL; intList *elem = NULL;
for (i = 0, elem = cvalue->integer; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.integer; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S8: { case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
int8List *elem = NULL; int8List *elem = NULL;
for (i = 0, elem = cvalue->s8; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S16: { case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
int16List *elem = NULL; int16List *elem = NULL;
for (i = 0, elem = cvalue->s16; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S32: { case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
int32List *elem = NULL; int32List *elem = NULL;
for (i = 0, elem = cvalue->s32; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S64: { case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
int64List *elem = NULL; int64List *elem = NULL;
for (i = 0, elem = cvalue->s64; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U8: { case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
uint8List *elem = NULL; uint8List *elem = NULL;
for (i = 0, elem = cvalue->u8; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U16: { case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
uint16List *elem = NULL; uint16List *elem = NULL;
for (i = 0, elem = cvalue->u16; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U32: { case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
uint32List *elem = NULL; uint32List *elem = NULL;
for (i = 0, elem = cvalue->u32; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U64: { case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
uint64List *elem = NULL; uint64List *elem = NULL;
for (i = 0, elem = cvalue->u64; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, i); g_assert_cmpint(elem->value, ==, i);
} }
break; break;
@ -690,9 +695,9 @@ static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err); visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
g_assert(cvalue != NULL); g_assert(cvalue != NULL);
g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN); g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
for (i = 0, elem = cvalue->boolean; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) {
g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0); g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
} }
@ -725,9 +730,9 @@ static void test_visitor_in_native_list_string(TestInputVisitorData *data,
visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err); visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
g_assert(cvalue != NULL); g_assert(cvalue != NULL);
g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING); g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
for (i = 0, elem = cvalue->string; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) {
gchar str[8]; gchar str[8];
sprintf(str, "%d", i); sprintf(str, "%d", i);
g_assert_cmpstr(elem->value, ==, str); g_assert_cmpstr(elem->value, ==, str);
@ -764,9 +769,9 @@ static void test_visitor_in_native_list_number(TestInputVisitorData *data,
visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err); visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
g_assert(cvalue != NULL); g_assert(cvalue != NULL);
g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER); g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
for (i = 0, elem = cvalue->number; elem; elem = elem->next, i++) { for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) {
GString *double_expected = g_string_new(""); GString *double_expected = g_string_new("");
GString *double_actual = g_string_new(""); GString *double_actual = g_string_new("");

View File

@ -250,16 +250,14 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2)); ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1); ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
ud2->dict1->dict2->userdef->string = g_strdup(string); ud2->dict1->dict2->userdef->string = g_strdup(string);
ud2->dict1->dict2->userdef->base = g_new0(UserDefZero, 1); ud2->dict1->dict2->userdef->integer = value;
ud2->dict1->dict2->userdef->base->integer = value;
ud2->dict1->dict2->string = g_strdup(strings[2]); ud2->dict1->dict2->string = g_strdup(strings[2]);
ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3)); ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
ud2->dict1->has_dict3 = true; ud2->dict1->has_dict3 = true;
ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1); ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
ud2->dict1->dict3->userdef->string = g_strdup(string); ud2->dict1->dict3->userdef->string = g_strdup(string);
ud2->dict1->dict3->userdef->base = g_new0(UserDefZero, 1); ud2->dict1->dict3->userdef->integer = value;
ud2->dict1->dict3->userdef->base->integer = value;
ud2->dict1->dict3->string = g_strdup(strings[3]); ud2->dict1->dict3->string = g_strdup(strings[3]);
visit_type_UserDefTwo(data->ov, &ud2, "unused", &err); visit_type_UserDefTwo(data->ov, &ud2, "unused", &err);
@ -301,8 +299,8 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
const void *unused) const void *unused)
{ {
EnumOne bad_values[] = { ENUM_ONE_MAX, -1 }; EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
UserDefZero b; UserDefOne u = {0};
UserDefOne u = { .base = &b }, *pu = &u; UserDefOne *pu = &u;
Error *err; Error *err;
int i; int i;
@ -416,8 +414,7 @@ static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1); p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1); p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
p->value->dict1->dict2->userdef->string = g_strdup(string); p->value->dict1->dict2->userdef->string = g_strdup(string);
p->value->dict1->dict2->userdef->base = g_new0(UserDefZero, 1); p->value->dict1->dict2->userdef->integer = 42;
p->value->dict1->dict2->userdef->base->integer = 42;
p->value->dict1->dict2->string = g_strdup(string); p->value->dict1->dict2->string = g_strdup(string);
p->value->dict1->has_dict3 = false; p->value->dict1->has_dict3 = false;
@ -490,9 +487,9 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion)); UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
tmp->enum1 = ENUM_ONE_VALUE1; tmp->enum1 = ENUM_ONE_VALUE1;
tmp->string = g_strdup("str"); tmp->string = g_strdup("str");
tmp->value1 = g_malloc0(sizeof(UserDefA)); tmp->u.value1 = g_malloc0(sizeof(UserDefA));
/* TODO when generator bug is fixed: tmp->integer = 41; */ tmp->integer = 41;
tmp->value1->boolean = true; tmp->u.value1->boolean = true;
visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &err); visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
@ -503,7 +500,7 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1"); g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str"); g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
/* TODO g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41); */ g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true); g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
qapi_free_UserDefFlatUnion(tmp); qapi_free_UserDefFlatUnion(tmp);
@ -517,8 +514,8 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
Error *err = NULL; Error *err = NULL;
UserDefAlternate *tmp = g_malloc0(sizeof(UserDefAlternate)); UserDefAlternate *tmp = g_malloc0(sizeof(UserDefAlternate));
tmp->kind = USER_DEF_ALTERNATE_KIND_I; tmp->type = USER_DEF_ALTERNATE_KIND_I;
tmp->i = 42; tmp->u.i = 42;
visit_type_UserDefAlternate(data->ov, &tmp, NULL, &err); visit_type_UserDefAlternate(data->ov, &tmp, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
@ -543,9 +540,9 @@ static void test_visitor_out_empty(TestOutputVisitorData *data,
static void init_native_list(UserDefNativeListUnion *cvalue) static void init_native_list(UserDefNativeListUnion *cvalue)
{ {
int i; int i;
switch (cvalue->kind) { switch (cvalue->type) {
case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: { case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
intList **list = &cvalue->integer; intList **list = &cvalue->u.integer;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(intList, 1); *list = g_new0(intList, 1);
(*list)->value = i; (*list)->value = i;
@ -555,7 +552,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S8: { case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
int8List **list = &cvalue->s8; int8List **list = &cvalue->u.s8;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(int8List, 1); *list = g_new0(int8List, 1);
(*list)->value = i; (*list)->value = i;
@ -565,7 +562,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S16: { case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
int16List **list = &cvalue->s16; int16List **list = &cvalue->u.s16;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(int16List, 1); *list = g_new0(int16List, 1);
(*list)->value = i; (*list)->value = i;
@ -575,7 +572,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S32: { case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
int32List **list = &cvalue->s32; int32List **list = &cvalue->u.s32;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(int32List, 1); *list = g_new0(int32List, 1);
(*list)->value = i; (*list)->value = i;
@ -585,7 +582,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_S64: { case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
int64List **list = &cvalue->s64; int64List **list = &cvalue->u.s64;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(int64List, 1); *list = g_new0(int64List, 1);
(*list)->value = i; (*list)->value = i;
@ -595,7 +592,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U8: { case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
uint8List **list = &cvalue->u8; uint8List **list = &cvalue->u.u8;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(uint8List, 1); *list = g_new0(uint8List, 1);
(*list)->value = i; (*list)->value = i;
@ -605,7 +602,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U16: { case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
uint16List **list = &cvalue->u16; uint16List **list = &cvalue->u.u16;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(uint16List, 1); *list = g_new0(uint16List, 1);
(*list)->value = i; (*list)->value = i;
@ -615,7 +612,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U32: { case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
uint32List **list = &cvalue->u32; uint32List **list = &cvalue->u.u32;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(uint32List, 1); *list = g_new0(uint32List, 1);
(*list)->value = i; (*list)->value = i;
@ -625,7 +622,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_U64: { case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
uint64List **list = &cvalue->u64; uint64List **list = &cvalue->u.u64;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(uint64List, 1); *list = g_new0(uint64List, 1);
(*list)->value = i; (*list)->value = i;
@ -635,7 +632,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: { case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
boolList **list = &cvalue->boolean; boolList **list = &cvalue->u.boolean;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(boolList, 1); *list = g_new0(boolList, 1);
(*list)->value = (i % 3 == 0); (*list)->value = (i % 3 == 0);
@ -645,7 +642,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: { case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
strList **list = &cvalue->string; strList **list = &cvalue->u.string;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(strList, 1); *list = g_new0(strList, 1);
(*list)->value = g_strdup_printf("%d", i); (*list)->value = g_strdup_printf("%d", i);
@ -655,7 +652,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
break; break;
} }
case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: { case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
numberList **list = &cvalue->number; numberList **list = &cvalue->u.number;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*list = g_new0(numberList, 1); *list = g_new0(numberList, 1);
(*list)->value = (double)i / 3; (*list)->value = (double)i / 3;
@ -764,14 +761,14 @@ static void test_native_list(TestOutputVisitorData *data,
Error *err = NULL; Error *err = NULL;
QObject *obj; QObject *obj;
cvalue->kind = kind; cvalue->type = kind;
init_native_list(cvalue); init_native_list(cvalue);
visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &err); visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &err);
g_assert(err == NULL); g_assert(err == NULL);
obj = qmp_output_get_qobject(data->qov); obj = qmp_output_get_qobject(data->qov);
check_native_list(obj, cvalue->kind); check_native_list(obj, cvalue->type);
qapi_free_UserDefNativeListUnion(cvalue); qapi_free_UserDefNativeListUnion(cvalue);
qobject_decref(obj); qobject_decref(obj);
} }

View File

@ -258,15 +258,13 @@ static UserDefTwo *nested_struct_create(void)
udnp->dict1->string1 = strdup("test_string1"); udnp->dict1->string1 = strdup("test_string1");
udnp->dict1->dict2 = g_malloc0(sizeof(*udnp->dict1->dict2)); udnp->dict1->dict2 = g_malloc0(sizeof(*udnp->dict1->dict2));
udnp->dict1->dict2->userdef = g_new0(UserDefOne, 1); udnp->dict1->dict2->userdef = g_new0(UserDefOne, 1);
udnp->dict1->dict2->userdef->base = g_new0(UserDefZero, 1); udnp->dict1->dict2->userdef->integer = 42;
udnp->dict1->dict2->userdef->base->integer = 42;
udnp->dict1->dict2->userdef->string = strdup("test_string"); udnp->dict1->dict2->userdef->string = strdup("test_string");
udnp->dict1->dict2->string = strdup("test_string2"); udnp->dict1->dict2->string = strdup("test_string2");
udnp->dict1->dict3 = g_malloc0(sizeof(*udnp->dict1->dict3)); udnp->dict1->dict3 = g_malloc0(sizeof(*udnp->dict1->dict3));
udnp->dict1->has_dict3 = true; udnp->dict1->has_dict3 = true;
udnp->dict1->dict3->userdef = g_new0(UserDefOne, 1); udnp->dict1->dict3->userdef = g_new0(UserDefOne, 1);
udnp->dict1->dict3->userdef->base = g_new0(UserDefZero, 1); udnp->dict1->dict3->userdef->integer = 43;
udnp->dict1->dict3->userdef->base->integer = 43;
udnp->dict1->dict3->userdef->string = strdup("test_string"); udnp->dict1->dict3->userdef->string = strdup("test_string");
udnp->dict1->dict3->string = strdup("test_string3"); udnp->dict1->dict3->string = strdup("test_string3");
return udnp; return udnp;
@ -278,15 +276,15 @@ static void nested_struct_compare(UserDefTwo *udnp1, UserDefTwo *udnp2)
g_assert(udnp2); g_assert(udnp2);
g_assert_cmpstr(udnp1->string0, ==, udnp2->string0); g_assert_cmpstr(udnp1->string0, ==, udnp2->string0);
g_assert_cmpstr(udnp1->dict1->string1, ==, udnp2->dict1->string1); g_assert_cmpstr(udnp1->dict1->string1, ==, udnp2->dict1->string1);
g_assert_cmpint(udnp1->dict1->dict2->userdef->base->integer, ==, g_assert_cmpint(udnp1->dict1->dict2->userdef->integer, ==,
udnp2->dict1->dict2->userdef->base->integer); udnp2->dict1->dict2->userdef->integer);
g_assert_cmpstr(udnp1->dict1->dict2->userdef->string, ==, g_assert_cmpstr(udnp1->dict1->dict2->userdef->string, ==,
udnp2->dict1->dict2->userdef->string); udnp2->dict1->dict2->userdef->string);
g_assert_cmpstr(udnp1->dict1->dict2->string, ==, g_assert_cmpstr(udnp1->dict1->dict2->string, ==,
udnp2->dict1->dict2->string); udnp2->dict1->dict2->string);
g_assert(udnp1->dict1->has_dict3 == udnp2->dict1->has_dict3); g_assert(udnp1->dict1->has_dict3 == udnp2->dict1->has_dict3);
g_assert_cmpint(udnp1->dict1->dict3->userdef->base->integer, ==, g_assert_cmpint(udnp1->dict1->dict3->userdef->integer, ==,
udnp2->dict1->dict3->userdef->base->integer); udnp2->dict1->dict3->userdef->integer);
g_assert_cmpstr(udnp1->dict1->dict3->userdef->string, ==, g_assert_cmpstr(udnp1->dict1->dict3->userdef->string, ==,
udnp2->dict1->dict3->userdef->string); udnp2->dict1->dict3->userdef->string);
g_assert_cmpstr(udnp1->dict1->dict3->string, ==, g_assert_cmpstr(udnp1->dict1->dict3->string, ==,

4
tpm.c
View File

@ -260,9 +260,9 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
switch (drv->ops->type) { switch (drv->ops->type) {
case TPM_TYPE_PASSTHROUGH: case TPM_TYPE_PASSTHROUGH:
res->options->kind = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH; res->options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;
tpo = g_new0(TPMPassthroughOptions, 1); tpo = g_new0(TPMPassthroughOptions, 1);
res->options->passthrough = tpo; res->options->u.passthrough = tpo;
if (drv->path) { if (drv->path) {
tpo->path = g_strdup(drv->path); tpo->path = g_strdup(drv->path);
tpo->has_path = true; tpo->has_path = true;

View File

@ -2016,7 +2016,7 @@ static VcHandler *vc_handler = text_console_init;
static CharDriverState *vc_init(const char *id, ChardevBackend *backend, static CharDriverState *vc_init(const char *id, ChardevBackend *backend,
ChardevReturn *ret, Error **errp) ChardevReturn *ret, Error **errp)
{ {
return vc_handler(backend->vc, errp); return vc_handler(backend->u.vc, errp);
} }
void register_vc_handler(VcHandler *handler) void register_vc_handler(VcHandler *handler)
@ -2057,30 +2057,30 @@ static void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend,
{ {
int val; int val;
backend->vc = g_new0(ChardevVC, 1); backend->u.vc = g_new0(ChardevVC, 1);
val = qemu_opt_get_number(opts, "width", 0); val = qemu_opt_get_number(opts, "width", 0);
if (val != 0) { if (val != 0) {
backend->vc->has_width = true; backend->u.vc->has_width = true;
backend->vc->width = val; backend->u.vc->width = val;
} }
val = qemu_opt_get_number(opts, "height", 0); val = qemu_opt_get_number(opts, "height", 0);
if (val != 0) { if (val != 0) {
backend->vc->has_height = true; backend->u.vc->has_height = true;
backend->vc->height = val; backend->u.vc->height = val;
} }
val = qemu_opt_get_number(opts, "cols", 0); val = qemu_opt_get_number(opts, "cols", 0);
if (val != 0) { if (val != 0) {
backend->vc->has_cols = true; backend->u.vc->has_cols = true;
backend->vc->cols = val; backend->u.vc->cols = val;
} }
val = qemu_opt_get_number(opts, "rows", 0); val = qemu_opt_get_number(opts, "rows", 0);
if (val != 0) { if (val != 0) {
backend->vc->has_rows = true; backend->u.vc->has_rows = true;
backend->vc->rows = val; backend->u.vc->rows = val;
} }
} }

View File

@ -139,11 +139,11 @@ static int number_to_qcode[0x100];
int qemu_input_key_value_to_number(const KeyValue *value) int qemu_input_key_value_to_number(const KeyValue *value)
{ {
if (value->kind == KEY_VALUE_KIND_QCODE) { if (value->type == KEY_VALUE_KIND_QCODE) {
return qcode_to_number[value->qcode]; return qcode_to_number[value->u.qcode];
} else { } else {
assert(value->kind == KEY_VALUE_KIND_NUMBER); assert(value->type == KEY_VALUE_KIND_NUMBER);
return value->number; return value->u.number;
} }
} }
@ -166,11 +166,11 @@ int qemu_input_key_number_to_qcode(uint8_t nr)
int qemu_input_key_value_to_qcode(const KeyValue *value) int qemu_input_key_value_to_qcode(const KeyValue *value)
{ {
if (value->kind == KEY_VALUE_KIND_QCODE) { if (value->type == KEY_VALUE_KIND_QCODE) {
return value->qcode; return value->u.qcode;
} else { } else {
assert(value->kind == KEY_VALUE_KIND_NUMBER); assert(value->type == KEY_VALUE_KIND_NUMBER);
return qemu_input_key_number_to_qcode(value->number); return qemu_input_key_number_to_qcode(value->u.number);
} }
} }
@ -180,8 +180,8 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
int keycode = qemu_input_key_value_to_number(value); int keycode = qemu_input_key_value_to_number(value);
int count = 0; int count = 0;
if (value->kind == KEY_VALUE_KIND_QCODE && if (value->type == KEY_VALUE_KIND_QCODE &&
value->qcode == Q_KEY_CODE_PAUSE) { value->u.qcode == Q_KEY_CODE_PAUSE) {
/* specific case */ /* specific case */
int v = down ? 0 : 0x80; int v = down ? 0 : 0x80;
codes[count++] = 0xe1; codes[count++] = 0xe1;

View File

@ -113,8 +113,8 @@ static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
if (!entry || !entry->put_kbd) { if (!entry || !entry->put_kbd) {
return; return;
} }
count = qemu_input_key_value_to_scancode(evt->key->key, count = qemu_input_key_value_to_scancode(evt->u.key->key,
evt->key->down, evt->u.key->down,
scancodes); scancodes);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
entry->put_kbd(entry->opaque, scancodes[i]); entry->put_kbd(entry->opaque, scancodes[i]);
@ -150,21 +150,22 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
}; };
QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev; QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
switch (evt->kind) { switch (evt->type) {
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
if (evt->btn->down) { if (evt->u.btn->down) {
s->buttons |= bmap[evt->btn->button]; s->buttons |= bmap[evt->u.btn->button];
} else { } else {
s->buttons &= ~bmap[evt->btn->button]; s->buttons &= ~bmap[evt->u.btn->button];
} }
if (evt->btn->down && evt->btn->button == INPUT_BUTTON_WHEEL_UP) { if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_X],
s->axis[INPUT_AXIS_Y], s->axis[INPUT_AXIS_Y],
-1, -1,
s->buttons); s->buttons);
} }
if (evt->btn->down && evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) { if (evt->u.btn->down &&
evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_X],
s->axis[INPUT_AXIS_Y], s->axis[INPUT_AXIS_Y],
@ -173,10 +174,10 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
} }
break; break;
case INPUT_EVENT_KIND_ABS: case INPUT_EVENT_KIND_ABS:
s->axis[evt->abs->axis] = evt->abs->value; s->axis[evt->u.abs->axis] = evt->u.abs->value;
break; break;
case INPUT_EVENT_KIND_REL: case INPUT_EVENT_KIND_REL:
s->axis[evt->rel->axis] += evt->rel->value; s->axis[evt->u.rel->axis] += evt->u.rel->value;
break; break;
default: default:
break; break;

View File

@ -147,10 +147,10 @@ void qmp_x_input_send_event(bool has_console, int64_t console,
for (e = events; e != NULL; e = e->next) { for (e = events; e != NULL; e = e->next) {
InputEvent *event = e->value; InputEvent *event = e->value;
if (!qemu_input_find_handler(1 << event->kind, con)) { if (!qemu_input_find_handler(1 << event->type, con)) {
error_setg(errp, "Input handler not found for " error_setg(errp, "Input handler not found for "
"event type %s", "event type %s",
InputEventKind_lookup[event->kind]); InputEventKind_lookup[event->type]);
return; return;
} }
} }
@ -168,22 +168,22 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt)
{ {
switch (graphic_rotate) { switch (graphic_rotate) {
case 90: case 90:
if (evt->abs->axis == INPUT_AXIS_X) { if (evt->u.abs->axis == INPUT_AXIS_X) {
evt->abs->axis = INPUT_AXIS_Y; evt->u.abs->axis = INPUT_AXIS_Y;
} else if (evt->abs->axis == INPUT_AXIS_Y) { } else if (evt->u.abs->axis == INPUT_AXIS_Y) {
evt->abs->axis = INPUT_AXIS_X; evt->u.abs->axis = INPUT_AXIS_X;
evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value; evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
} }
break; break;
case 180: case 180:
evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value; evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
break; break;
case 270: case 270:
if (evt->abs->axis == INPUT_AXIS_X) { if (evt->u.abs->axis == INPUT_AXIS_X) {
evt->abs->axis = INPUT_AXIS_Y; evt->u.abs->axis = INPUT_AXIS_Y;
evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value; evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
} else if (evt->abs->axis == INPUT_AXIS_Y) { } else if (evt->u.abs->axis == INPUT_AXIS_Y) {
evt->abs->axis = INPUT_AXIS_X; evt->u.abs->axis = INPUT_AXIS_X;
} }
break; break;
} }
@ -197,18 +197,18 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
if (src) { if (src) {
idx = qemu_console_get_index(src); idx = qemu_console_get_index(src);
} }
switch (evt->kind) { switch (evt->type) {
case INPUT_EVENT_KIND_KEY: case INPUT_EVENT_KIND_KEY:
switch (evt->key->key->kind) { switch (evt->u.key->key->type) {
case KEY_VALUE_KIND_NUMBER: case KEY_VALUE_KIND_NUMBER:
qcode = qemu_input_key_number_to_qcode(evt->key->key->number); qcode = qemu_input_key_number_to_qcode(evt->u.key->key->u.number);
name = QKeyCode_lookup[qcode]; name = QKeyCode_lookup[qcode];
trace_input_event_key_number(idx, evt->key->key->number, trace_input_event_key_number(idx, evt->u.key->key->u.number,
name, evt->key->down); name, evt->u.key->down);
break; break;
case KEY_VALUE_KIND_QCODE: case KEY_VALUE_KIND_QCODE:
name = QKeyCode_lookup[evt->key->key->qcode]; name = QKeyCode_lookup[evt->u.key->key->u.qcode];
trace_input_event_key_qcode(idx, name, evt->key->down); trace_input_event_key_qcode(idx, name, evt->u.key->down);
break; break;
case KEY_VALUE_KIND_MAX: case KEY_VALUE_KIND_MAX:
/* keep gcc happy */ /* keep gcc happy */
@ -216,16 +216,16 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
} }
break; break;
case INPUT_EVENT_KIND_BTN: case INPUT_EVENT_KIND_BTN:
name = InputButton_lookup[evt->btn->button]; name = InputButton_lookup[evt->u.btn->button];
trace_input_event_btn(idx, name, evt->btn->down); trace_input_event_btn(idx, name, evt->u.btn->down);
break; break;
case INPUT_EVENT_KIND_REL: case INPUT_EVENT_KIND_REL:
name = InputAxis_lookup[evt->rel->axis]; name = InputAxis_lookup[evt->u.rel->axis];
trace_input_event_rel(idx, name, evt->rel->value); trace_input_event_rel(idx, name, evt->u.rel->value);
break; break;
case INPUT_EVENT_KIND_ABS: case INPUT_EVENT_KIND_ABS:
name = InputAxis_lookup[evt->abs->axis]; name = InputAxis_lookup[evt->u.abs->axis];
trace_input_event_abs(idx, name, evt->abs->value); trace_input_event_abs(idx, name, evt->u.abs->value);
break; break;
case INPUT_EVENT_KIND_MAX: case INPUT_EVENT_KIND_MAX:
/* keep gcc happy */ /* keep gcc happy */
@ -311,12 +311,12 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
qemu_input_event_trace(src, evt); qemu_input_event_trace(src, evt);
/* pre processing */ /* pre processing */
if (graphic_rotate && (evt->kind == INPUT_EVENT_KIND_ABS)) { if (graphic_rotate && (evt->type == INPUT_EVENT_KIND_ABS)) {
qemu_input_transform_abs_rotate(evt); qemu_input_transform_abs_rotate(evt);
} }
/* send event */ /* send event */
s = qemu_input_find_handler(1 << evt->kind, src); s = qemu_input_find_handler(1 << evt->type, src);
if (!s) { if (!s) {
return; return;
} }
@ -348,10 +348,10 @@ void qemu_input_event_sync(void)
InputEvent *qemu_input_event_new_key(KeyValue *key, bool down) InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
{ {
InputEvent *evt = g_new0(InputEvent, 1); InputEvent *evt = g_new0(InputEvent, 1);
evt->key = g_new0(InputKeyEvent, 1); evt->u.key = g_new0(InputKeyEvent, 1);
evt->kind = INPUT_EVENT_KIND_KEY; evt->type = INPUT_EVENT_KIND_KEY;
evt->key->key = key; evt->u.key->key = key;
evt->key->down = down; evt->u.key->down = down;
return evt; return evt;
} }
@ -372,16 +372,16 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down) void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
{ {
KeyValue *key = g_new0(KeyValue, 1); KeyValue *key = g_new0(KeyValue, 1);
key->kind = KEY_VALUE_KIND_NUMBER; key->type = KEY_VALUE_KIND_NUMBER;
key->number = num; key->u.number = num;
qemu_input_event_send_key(src, key, down); qemu_input_event_send_key(src, key, down);
} }
void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down) void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
{ {
KeyValue *key = g_new0(KeyValue, 1); KeyValue *key = g_new0(KeyValue, 1);
key->kind = KEY_VALUE_KIND_QCODE; key->type = KEY_VALUE_KIND_QCODE;
key->qcode = q; key->u.qcode = q;
qemu_input_event_send_key(src, key, down); qemu_input_event_send_key(src, key, down);
} }
@ -398,10 +398,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms)
InputEvent *qemu_input_event_new_btn(InputButton btn, bool down) InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
{ {
InputEvent *evt = g_new0(InputEvent, 1); InputEvent *evt = g_new0(InputEvent, 1);
evt->btn = g_new0(InputBtnEvent, 1); evt->u.btn = g_new0(InputBtnEvent, 1);
evt->kind = INPUT_EVENT_KIND_BTN; evt->type = INPUT_EVENT_KIND_BTN;
evt->btn->button = btn; evt->u.btn->button = btn;
evt->btn->down = down; evt->u.btn->down = down;
return evt; return evt;
} }
@ -451,8 +451,8 @@ InputEvent *qemu_input_event_new_move(InputEventKind kind,
InputEvent *evt = g_new0(InputEvent, 1); InputEvent *evt = g_new0(InputEvent, 1);
InputMoveEvent *move = g_new0(InputMoveEvent, 1); InputMoveEvent *move = g_new0(InputMoveEvent, 1);
evt->kind = kind; evt->type = kind;
evt->data = move; evt->u.data = move;
move->axis = axis; move->axis = axis;
move->value = value; move->value = value;
return evt; return evt;

View File

@ -200,8 +200,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
{ {
SpiceServerInfo *server = g_malloc0(sizeof(*server)); SpiceServerInfo *server = g_malloc0(sizeof(*server));
SpiceChannel *client = g_malloc0(sizeof(*client)); SpiceChannel *client = g_malloc0(sizeof(*client));
server->base = g_malloc0(sizeof(*server->base));
client->base = g_malloc0(sizeof(*client->base));
/* /*
* Spice server might have called us from spice worker thread * Spice server might have called us from spice worker thread
@ -218,9 +216,11 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
} }
if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
add_addr_info(client->base, (struct sockaddr *)&info->paddr_ext, add_addr_info(qapi_SpiceChannel_base(client),
(struct sockaddr *)&info->paddr_ext,
info->plen_ext); info->plen_ext);
add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext, add_addr_info(qapi_SpiceServerInfo_base(server),
(struct sockaddr *)&info->laddr_ext,
info->llen_ext); info->llen_ext);
} else { } else {
error_report("spice: %s, extended address is expected", error_report("spice: %s, extended address is expected",
@ -229,7 +229,9 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
switch (event) { switch (event) {
case SPICE_CHANNEL_EVENT_CONNECTED: case SPICE_CHANNEL_EVENT_CONNECTED:
qapi_event_send_spice_connected(server->base, client->base, &error_abort); qapi_event_send_spice_connected(qapi_SpiceServerInfo_base(server),
qapi_SpiceChannel_base(client),
&error_abort);
break; break;
case SPICE_CHANNEL_EVENT_INITIALIZED: case SPICE_CHANNEL_EVENT_INITIALIZED:
if (auth) { if (auth) {
@ -242,7 +244,9 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
break; break;
case SPICE_CHANNEL_EVENT_DISCONNECTED: case SPICE_CHANNEL_EVENT_DISCONNECTED:
channel_list_del(info); channel_list_del(info);
qapi_event_send_spice_disconnected(server->base, client->base, &error_abort); qapi_event_send_spice_disconnected(qapi_SpiceServerInfo_base(server),
qapi_SpiceChannel_base(client),
&error_abort);
break; break;
default: default:
break; break;
@ -378,16 +382,15 @@ static SpiceChannelList *qmp_query_spice_channels(void)
chan = g_malloc0(sizeof(*chan)); chan = g_malloc0(sizeof(*chan));
chan->value = g_malloc0(sizeof(*chan->value)); chan->value = g_malloc0(sizeof(*chan->value));
chan->value->base = g_malloc0(sizeof(*chan->value->base));
paddr = (struct sockaddr *)&item->info->paddr_ext; paddr = (struct sockaddr *)&item->info->paddr_ext;
plen = item->info->plen_ext; plen = item->info->plen_ext;
getnameinfo(paddr, plen, getnameinfo(paddr, plen,
host, sizeof(host), port, sizeof(port), host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV); NI_NUMERICHOST | NI_NUMERICSERV);
chan->value->base->host = g_strdup(host); chan->value->host = g_strdup(host);
chan->value->base->port = g_strdup(port); chan->value->port = g_strdup(port);
chan->value->base->family = inet_netfamily(paddr->sa_family); chan->value->family = inet_netfamily(paddr->sa_family);
chan->value->connection_id = item->info->connection_id; chan->value->connection_id = item->info->connection_id;
chan->value->channel_type = item->info->type; chan->value->channel_type = item->info->type;

114
ui/vnc.c
View File

@ -156,10 +156,11 @@ char *vnc_socket_remote_addr(const char *format, int fd) {
return addr_to_string(format, &sa, salen); return addr_to_string(format, &sa, salen);
} }
static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa, static void vnc_init_basic_info(struct sockaddr_storage *sa,
socklen_t salen) socklen_t salen,
VncBasicInfo *info,
Error **errp)
{ {
VncBasicInfo *info;
char host[NI_MAXHOST]; char host[NI_MAXHOST];
char serv[NI_MAXSERV]; char serv[NI_MAXSERV];
int err; int err;
@ -168,42 +169,44 @@ static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
host, sizeof(host), host, sizeof(host),
serv, sizeof(serv), serv, sizeof(serv),
NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
VNC_DEBUG("Cannot resolve address %d: %s\n", error_setg(errp, "Cannot resolve address: %s",
err, gai_strerror(err)); gai_strerror(err));
return NULL; return;
} }
info = g_malloc0(sizeof(VncBasicInfo));
info->host = g_strdup(host); info->host = g_strdup(host);
info->service = g_strdup(serv); info->service = g_strdup(serv);
info->family = inet_netfamily(sa->ss_family); info->family = inet_netfamily(sa->ss_family);
return info;
} }
static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd) static void vnc_init_basic_info_from_server_addr(int fd, VncBasicInfo *info,
Error **errp)
{ {
struct sockaddr_storage sa; struct sockaddr_storage sa;
socklen_t salen; socklen_t salen;
salen = sizeof(sa); salen = sizeof(sa);
if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) { if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
return NULL; error_setg_errno(errp, errno, "getsockname failed");
return;
} }
return vnc_basic_info_get(&sa, salen); vnc_init_basic_info(&sa, salen, info, errp);
} }
static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd) static void vnc_init_basic_info_from_remote_addr(int fd, VncBasicInfo *info,
Error **errp)
{ {
struct sockaddr_storage sa; struct sockaddr_storage sa;
socklen_t salen; socklen_t salen;
salen = sizeof(sa); salen = sizeof(sa);
if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) { if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
return NULL; error_setg_errno(errp, errno, "getpeername failed");
return;
} }
return vnc_basic_info_get(&sa, salen); vnc_init_basic_info(&sa, salen, info, errp);
} }
static const char *vnc_auth_name(VncDisplay *vd) { static const char *vnc_auth_name(VncDisplay *vd) {
@ -256,15 +259,18 @@ static const char *vnc_auth_name(VncDisplay *vd) {
static VncServerInfo *vnc_server_info_get(VncDisplay *vd) static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
{ {
VncServerInfo *info; VncServerInfo *info;
VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock); Error *err = NULL;
if (!bi) {
return NULL;
}
info = g_malloc(sizeof(*info)); info = g_malloc(sizeof(*info));
info->base = bi; vnc_init_basic_info_from_server_addr(vd->lsock,
qapi_VncServerInfo_base(info), &err);
info->has_auth = true; info->has_auth = true;
info->auth = g_strdup(vnc_auth_name(vd)); info->auth = g_strdup(vnc_auth_name(vd));
if (err) {
qapi_free_VncServerInfo(info);
info = NULL;
error_free(err);
}
return info; return info;
} }
@ -291,11 +297,16 @@ static void vnc_client_cache_auth(VncState *client)
static void vnc_client_cache_addr(VncState *client) static void vnc_client_cache_addr(VncState *client)
{ {
VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock); Error *err = NULL;
if (bi) { client->info = g_malloc0(sizeof(*client->info));
client->info = g_malloc0(sizeof(*client->info)); vnc_init_basic_info_from_remote_addr(client->csock,
client->info->base = bi; qapi_VncClientInfo_base(client->info),
&err);
if (err) {
qapi_free_VncClientInfo(client->info);
client->info = NULL;
error_free(err);
} }
} }
@ -306,7 +317,6 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
if (!vs->info) { if (!vs->info) {
return; return;
} }
g_assert(vs->info->base);
si = vnc_server_info_get(vs->vd); si = vnc_server_info_get(vs->vd);
if (!si) { if (!si) {
@ -315,7 +325,8 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
switch (event) { switch (event) {
case QAPI_EVENT_VNC_CONNECTED: case QAPI_EVENT_VNC_CONNECTED:
qapi_event_send_vnc_connected(si, vs->info->base, &error_abort); qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
&error_abort);
break; break;
case QAPI_EVENT_VNC_INITIALIZED: case QAPI_EVENT_VNC_INITIALIZED:
qapi_event_send_vnc_initialized(si, vs->info, &error_abort); qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
@ -350,11 +361,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
} }
info = g_malloc0(sizeof(*info)); info = g_malloc0(sizeof(*info));
info->base = g_malloc0(sizeof(*info->base)); info->host = g_strdup(host);
info->base->host = g_strdup(host); info->service = g_strdup(serv);
info->base->service = g_strdup(serv); info->family = inet_netfamily(sa.ss_family);
info->base->family = inet_netfamily(sa.ss_family); info->websocket = client->websocket;
info->base->websocket = client->websocket;
if (client->tls) { if (client->tls) {
info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls); info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
@ -3514,9 +3524,9 @@ void vnc_display_open(const char *id, Error **errp)
} }
if (strncmp(vnc, "unix:", 5) == 0) { if (strncmp(vnc, "unix:", 5) == 0) {
saddr->kind = SOCKET_ADDRESS_KIND_UNIX; saddr->type = SOCKET_ADDRESS_KIND_UNIX;
saddr->q_unix = g_new0(UnixSocketAddress, 1); saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
saddr->q_unix->path = g_strdup(vnc + 5); saddr->u.q_unix->path = g_strdup(vnc + 5);
if (vs->ws_enabled) { if (vs->ws_enabled) {
error_setg(errp, "UNIX sockets not supported with websock"); error_setg(errp, "UNIX sockets not supported with websock");
@ -3524,12 +3534,12 @@ void vnc_display_open(const char *id, Error **errp)
} }
} else { } else {
unsigned long long baseport; unsigned long long baseport;
saddr->kind = SOCKET_ADDRESS_KIND_INET; saddr->type = SOCKET_ADDRESS_KIND_INET;
saddr->inet = g_new0(InetSocketAddress, 1); saddr->u.inet = g_new0(InetSocketAddress, 1);
if (vnc[0] == '[' && vnc[hlen - 1] == ']') { if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
saddr->inet->host = g_strndup(vnc + 1, hlen - 2); saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
} else { } else {
saddr->inet->host = g_strndup(vnc, hlen); saddr->u.inet->host = g_strndup(vnc, hlen);
} }
if (parse_uint_full(h + 1, &baseport, 10) < 0) { if (parse_uint_full(h + 1, &baseport, 10) < 0) {
error_setg(errp, "can't convert to a number: %s", h + 1); error_setg(errp, "can't convert to a number: %s", h + 1);
@ -3540,28 +3550,28 @@ void vnc_display_open(const char *id, Error **errp)
error_setg(errp, "port %s out of range", h + 1); error_setg(errp, "port %s out of range", h + 1);
goto fail; goto fail;
} }
saddr->inet->port = g_strdup_printf( saddr->u.inet->port = g_strdup_printf(
"%d", (int)baseport + 5900); "%d", (int)baseport + 5900);
if (to) { if (to) {
saddr->inet->has_to = true; saddr->u.inet->has_to = true;
saddr->inet->to = to; saddr->u.inet->to = to;
} }
saddr->inet->ipv4 = saddr->inet->has_ipv4 = has_ipv4; saddr->u.inet->ipv4 = saddr->u.inet->has_ipv4 = has_ipv4;
saddr->inet->ipv6 = saddr->inet->has_ipv6 = has_ipv6; saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
if (vs->ws_enabled) { if (vs->ws_enabled) {
wsaddr->kind = SOCKET_ADDRESS_KIND_INET; wsaddr->type = SOCKET_ADDRESS_KIND_INET;
wsaddr->inet = g_new0(InetSocketAddress, 1); wsaddr->u.inet = g_new0(InetSocketAddress, 1);
wsaddr->inet->host = g_strdup(saddr->inet->host); wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
wsaddr->inet->port = g_strdup(websocket); wsaddr->u.inet->port = g_strdup(websocket);
if (to) { if (to) {
wsaddr->inet->has_to = true; wsaddr->u.inet->has_to = true;
wsaddr->inet->to = to; wsaddr->u.inet->to = to;
} }
wsaddr->inet->ipv4 = wsaddr->inet->has_ipv4 = has_ipv4; wsaddr->u.inet->ipv4 = wsaddr->u.inet->has_ipv4 = has_ipv4;
wsaddr->inet->ipv6 = wsaddr->inet->has_ipv6 = has_ipv6; wsaddr->u.inet->ipv6 = wsaddr->u.inet->has_ipv6 = has_ipv6;
} }
} }
} else { } else {
@ -3760,7 +3770,7 @@ void vnc_display_open(const char *id, Error **errp)
if (csock < 0) { if (csock < 0) {
goto fail; goto fail;
} }
vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX; vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
vnc_connect(vs, csock, false, false); vnc_connect(vs, csock, false, false);
} else { } else {
/* listen for connects */ /* listen for connects */
@ -3768,7 +3778,7 @@ void vnc_display_open(const char *id, Error **errp)
if (vs->lsock < 0) { if (vs->lsock < 0) {
goto fail; goto fail;
} }
vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX; vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
if (vs->ws_enabled) { if (vs->ws_enabled) {
vs->lwebsock = socket_listen(wsaddr, errp); vs->lwebsock = socket_listen(wsaddr, errp);
if (vs->lwebsock < 0) { if (vs->lwebsock < 0) {

View File

@ -918,23 +918,23 @@ SocketAddress *socket_parse(const char *str, Error **errp)
error_setg(errp, "invalid Unix socket address"); error_setg(errp, "invalid Unix socket address");
goto fail; goto fail;
} else { } else {
addr->kind = SOCKET_ADDRESS_KIND_UNIX; addr->type = SOCKET_ADDRESS_KIND_UNIX;
addr->q_unix = g_new(UnixSocketAddress, 1); addr->u.q_unix = g_new(UnixSocketAddress, 1);
addr->q_unix->path = g_strdup(str + 5); addr->u.q_unix->path = g_strdup(str + 5);
} }
} else if (strstart(str, "fd:", NULL)) { } else if (strstart(str, "fd:", NULL)) {
if (str[3] == '\0') { if (str[3] == '\0') {
error_setg(errp, "invalid file descriptor address"); error_setg(errp, "invalid file descriptor address");
goto fail; goto fail;
} else { } else {
addr->kind = SOCKET_ADDRESS_KIND_FD; addr->type = SOCKET_ADDRESS_KIND_FD;
addr->fd = g_new(String, 1); addr->u.fd = g_new(String, 1);
addr->fd->str = g_strdup(str + 3); addr->u.fd->str = g_strdup(str + 3);
} }
} else { } else {
addr->kind = SOCKET_ADDRESS_KIND_INET; addr->type = SOCKET_ADDRESS_KIND_INET;
addr->inet = inet_parse(str, errp); addr->u.inet = inet_parse(str, errp);
if (addr->inet == NULL) { if (addr->u.inet == NULL) {
goto fail; goto fail;
} }
} }
@ -952,19 +952,19 @@ int socket_connect(SocketAddress *addr, Error **errp,
int fd; int fd;
opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
switch (addr->kind) { switch (addr->type) {
case SOCKET_ADDRESS_KIND_INET: case SOCKET_ADDRESS_KIND_INET:
inet_addr_to_opts(opts, addr->inet); inet_addr_to_opts(opts, addr->u.inet);
fd = inet_connect_opts(opts, errp, callback, opaque); fd = inet_connect_opts(opts, errp, callback, opaque);
break; break;
case SOCKET_ADDRESS_KIND_UNIX: case SOCKET_ADDRESS_KIND_UNIX:
qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort); qemu_opt_set(opts, "path", addr->u.q_unix->path, &error_abort);
fd = unix_connect_opts(opts, errp, callback, opaque); fd = unix_connect_opts(opts, errp, callback, opaque);
break; break;
case SOCKET_ADDRESS_KIND_FD: case SOCKET_ADDRESS_KIND_FD:
fd = monitor_get_fd(cur_mon, addr->fd->str, errp); fd = monitor_get_fd(cur_mon, addr->u.fd->str, errp);
if (fd >= 0 && callback) { if (fd >= 0 && callback) {
qemu_set_nonblock(fd); qemu_set_nonblock(fd);
callback(fd, NULL, opaque); callback(fd, NULL, opaque);
@ -984,19 +984,19 @@ int socket_listen(SocketAddress *addr, Error **errp)
int fd; int fd;
opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
switch (addr->kind) { switch (addr->type) {
case SOCKET_ADDRESS_KIND_INET: case SOCKET_ADDRESS_KIND_INET:
inet_addr_to_opts(opts, addr->inet); inet_addr_to_opts(opts, addr->u.inet);
fd = inet_listen_opts(opts, 0, errp); fd = inet_listen_opts(opts, 0, errp);
break; break;
case SOCKET_ADDRESS_KIND_UNIX: case SOCKET_ADDRESS_KIND_UNIX:
qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort); qemu_opt_set(opts, "path", addr->u.q_unix->path, &error_abort);
fd = unix_listen_opts(opts, errp); fd = unix_listen_opts(opts, errp);
break; break;
case SOCKET_ADDRESS_KIND_FD: case SOCKET_ADDRESS_KIND_FD:
fd = monitor_get_fd(cur_mon, addr->fd->str, errp); fd = monitor_get_fd(cur_mon, addr->u.fd->str, errp);
break; break;
default: default:
@ -1012,12 +1012,12 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
int fd; int fd;
opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort); opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
switch (remote->kind) { switch (remote->type) {
case SOCKET_ADDRESS_KIND_INET: case SOCKET_ADDRESS_KIND_INET:
inet_addr_to_opts(opts, remote->inet); inet_addr_to_opts(opts, remote->u.inet);
if (local) { if (local) {
qemu_opt_set(opts, "localaddr", local->inet->host, &error_abort); qemu_opt_set(opts, "localaddr", local->u.inet->host, &error_abort);
qemu_opt_set(opts, "localport", local->inet->port, &error_abort); qemu_opt_set(opts, "localport", local->u.inet->port, &error_abort);
} }
fd = inet_dgram_opts(opts, errp); fd = inet_dgram_opts(opts, errp);
break; break;
@ -1052,14 +1052,14 @@ socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
} }
addr = g_new0(SocketAddress, 1); addr = g_new0(SocketAddress, 1);
addr->kind = SOCKET_ADDRESS_KIND_INET; addr->type = SOCKET_ADDRESS_KIND_INET;
addr->inet = g_new0(InetSocketAddress, 1); addr->u.inet = g_new0(InetSocketAddress, 1);
addr->inet->host = g_strdup(host); addr->u.inet->host = g_strdup(host);
addr->inet->port = g_strdup(serv); addr->u.inet->port = g_strdup(serv);
if (sa->ss_family == AF_INET) { if (sa->ss_family == AF_INET) {
addr->inet->has_ipv4 = addr->inet->ipv4 = true; addr->u.inet->has_ipv4 = addr->u.inet->ipv4 = true;
} else { } else {
addr->inet->has_ipv6 = addr->inet->ipv6 = true; addr->u.inet->has_ipv6 = addr->u.inet->ipv6 = true;
} }
return addr; return addr;
@ -1076,11 +1076,11 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
struct sockaddr_un *su = (struct sockaddr_un *)sa; struct sockaddr_un *su = (struct sockaddr_un *)sa;
addr = g_new0(SocketAddress, 1); addr = g_new0(SocketAddress, 1);
addr->kind = SOCKET_ADDRESS_KIND_UNIX; addr->type = SOCKET_ADDRESS_KIND_UNIX;
addr->q_unix = g_new0(UnixSocketAddress, 1); addr->u.q_unix = g_new0(UnixSocketAddress, 1);
if (su->sun_path[0]) { if (su->sun_path[0]) {
addr->q_unix->path = g_strndup(su->sun_path, addr->u.q_unix->path = g_strndup(su->sun_path,
sizeof(su->sun_path)); sizeof(su->sun_path));
} }
return addr; return addr;