QAPI patches for 2018-06-22
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJbLQlmAAoJEDhwtADrkYZTSncQAK1jsP8crW+bgwRBPhwZgmv6 IEWXQc9OBlVD3yrSnMsqJuFOo9vak0EThBFUPBUNSN5rQZhuwBrOyKJRcxTSEilh h0Wq/HxCARRdJpcPXWo7UIXgNXrk5qoUzowc6m/6ReogOoycrA4YeOLdOoy98dUv 0a2U/EyKL/lWgioQhbnZWBEtFX1BFVztWUsG0AF6PGgbu7SZRGtw+IDQWzV7oRVN gsiKJYjTN7jjyxaM789TioiajMD1dFSN2V3BSqLv9LkaJ8dV69OVU5R6429EkzTF /BdahCtsTE7TTkXeqPqpOnrRXBYiCOeLTbi1Ub5De7wjtaLzfQW9ZolA1OxaSRWS AMvS92V2w6S97F0VkkfagGmqO6ypVXAjPr7a3yXHKig2DDMR5BWq10GXS7EHvn5a qVD4WbGxUFplxpyvbCAjZS/qV8hoDG8SsA58lUJP18z5Z6PJpCvk6bQl9XcOF+bc WqlcgW75Iu/ii1XZdzFylX1h9p4ox4roiZ9YBMKakb/oI8kfUHs4dL0Yz5A0aJKr /Vw/8TmokqkLI+PJX+6P4kGyrIVhB6x/iPDv1MXqjaEiO+tM6pMUfJvH8HtzTIay CJ0QNZQe2ksbV1gHZ4wGZwnGwOtOQVUmXChDVEcQbyOdlHAEGn9Zjbc1wq/wei8x VtA3kZn6CoIuih6vt6SO =Mo3y -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2018-06-22' into staging QAPI patches for 2018-06-22 # gpg: Signature made Fri 22 Jun 2018 15:36:22 BST # gpg: using RSA key 3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2018-06-22: MAINTAINERS: Update QAPI stanza for commitfb0bc835e5
qapi/introspect: Eliminate pointless variable in .visit_end() Revert commitd4e5ec877c
qapi: Open files with encoding='utf-8' qapi: remove empty flat union branches and types qapi: allow empty branches in flat unions tests: Add QDict clone-flatten test qdict: Make qdict_flatten() shallow-clone-friendly qapi/events: generate event enum in main module qapi/visit: remove useless prefix argument Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7ed14cbf3c
@ -1625,7 +1625,8 @@ F: tests/test-*-visitor.c
|
||||
F: tests/test-qapi-*.c
|
||||
F: tests/test-qmp-*.c
|
||||
F: tests/test-visitor-serialization.c
|
||||
F: scripts/qapi*
|
||||
F: scripts/qapi-gen.py
|
||||
F: scripts/qapi/*
|
||||
F: docs/devel/qapi*
|
||||
T: git git://repo.or.cz/qemu/armbru.git qapi-next
|
||||
|
||||
|
6
Makefile
6
Makefile
@ -20,8 +20,6 @@ ifneq ($(wildcard config-host.mak),)
|
||||
all:
|
||||
include config-host.mak
|
||||
|
||||
PYTHON_UTF8 = LC_ALL= LANG=C LC_CTYPE=en_US.UTF-8 $(PYTHON)
|
||||
|
||||
git-submodule-update:
|
||||
|
||||
.PHONY: git-submodule-update
|
||||
@ -576,7 +574,7 @@ qga/qapi-generated/qga-qapi-commands.h qga/qapi-generated/qga-qapi-commands.c \
|
||||
qga/qapi-generated/qga-qapi-doc.texi: \
|
||||
qga/qapi-generated/qapi-gen-timestamp ;
|
||||
qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
-o qga/qapi-generated -p "qga-" $<, \
|
||||
"GEN","$(@:%-timestamp=%)")
|
||||
@>$@
|
||||
@ -676,7 +674,7 @@ qapi/qapi-introspect.h qapi/qapi-introspect.c \
|
||||
qapi/qapi-doc.texi: \
|
||||
qapi-gen-timestamp ;
|
||||
qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
-o "qapi" -b $<, \
|
||||
"GEN","$(@:%-timestamp=%)")
|
||||
@>$@
|
||||
|
@ -4166,7 +4166,6 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
|
||||
switch (encrypt_info->format) {
|
||||
case Q_CRYPTO_BLOCK_FORMAT_QCOW:
|
||||
qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_AES;
|
||||
qencrypt->u.aes = encrypt_info->u.qcow;
|
||||
break;
|
||||
case Q_CRYPTO_BLOCK_FORMAT_LUKS:
|
||||
qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_LUKS;
|
||||
|
2
cpus.c
2
cpus.c
@ -2273,8 +2273,6 @@ CpuInfoFastList *qmp_query_cpus_fast(Error **errp)
|
||||
info->value->target = target;
|
||||
if (target == SYS_EMU_TARGET_S390X) {
|
||||
cpustate_to_cpuinfo_s390(&info->value->u.s390x, cpu);
|
||||
} else {
|
||||
/* do nothing for @CpuInfoOther */
|
||||
}
|
||||
|
||||
if (!cur_item) {
|
||||
|
@ -496,9 +496,11 @@ Resulting in these JSON objects:
|
||||
|
||||
Notice that in a flat union, the discriminator name is controlled by
|
||||
the user, but because it must map to a base member with enum type, the
|
||||
code generator can ensure that branches exist for all values of the
|
||||
enum (although the order of the keys need not match the declaration of
|
||||
the enum). In the resulting generated C data types, a flat union is
|
||||
code generator ensures that branches match the existing values of the
|
||||
enum. The order of the keys need not match the declaration of the enum.
|
||||
The keys need not cover all possible enum values. Omitted enum values
|
||||
are still valid branches that add no additional members to the data type.
|
||||
In the resulting generated C data types, a flat union is
|
||||
represented as a struct with the base members included directly, and
|
||||
then a union of structures for each branch of the struct.
|
||||
|
||||
|
@ -52,8 +52,7 @@
|
||||
{ 'union': 'ImageInfoSpecificQCow2Encryption',
|
||||
'base': 'ImageInfoSpecificQCow2EncryptionBase',
|
||||
'discriminator': 'format',
|
||||
'data': { 'aes': 'QCryptoBlockInfoQCow',
|
||||
'luks': 'QCryptoBlockInfoLUKS' } }
|
||||
'data': { 'luks': 'QCryptoBlockInfoLUKS' } }
|
||||
|
||||
##
|
||||
# @ImageInfoSpecificQCow2:
|
||||
@ -2877,16 +2876,6 @@
|
||||
'data': { 'type': 'SshHostKeyCheckHashType',
|
||||
'hash': 'str' }}
|
||||
|
||||
##
|
||||
# @SshHostKeyDummy:
|
||||
#
|
||||
# For those union branches that don't need additional fields.
|
||||
#
|
||||
# Since: 2.12
|
||||
##
|
||||
{ 'struct': 'SshHostKeyDummy',
|
||||
'data': {} }
|
||||
|
||||
##
|
||||
# @SshHostKeyCheck:
|
||||
#
|
||||
@ -2895,9 +2884,7 @@
|
||||
{ 'union': 'SshHostKeyCheck',
|
||||
'base': { 'mode': 'SshHostKeyCheckMode' },
|
||||
'discriminator': 'mode',
|
||||
'data': { 'none': 'SshHostKeyDummy',
|
||||
'hash': 'SshHostKeyHash',
|
||||
'known_hosts': 'SshHostKeyDummy' } }
|
||||
'data': { 'hash': 'SshHostKeyHash' } }
|
||||
|
||||
##
|
||||
# @BlockdevOptionsSsh:
|
||||
@ -4075,15 +4062,6 @@
|
||||
'*subformat': 'BlockdevVpcSubformat',
|
||||
'*force-size': 'bool' } }
|
||||
|
||||
##
|
||||
# @BlockdevCreateNotSupported:
|
||||
#
|
||||
# This is used for all drivers that don't support creating images.
|
||||
#
|
||||
# Since: 2.12
|
||||
##
|
||||
{ 'struct': 'BlockdevCreateNotSupported', 'data': {}}
|
||||
|
||||
##
|
||||
# @BlockdevCreateOptions:
|
||||
#
|
||||
@ -4098,44 +4076,20 @@
|
||||
'driver': 'BlockdevDriver' },
|
||||
'discriminator': 'driver',
|
||||
'data': {
|
||||
'blkdebug': 'BlockdevCreateNotSupported',
|
||||
'blkverify': 'BlockdevCreateNotSupported',
|
||||
'bochs': 'BlockdevCreateNotSupported',
|
||||
'cloop': 'BlockdevCreateNotSupported',
|
||||
'copy-on-read': 'BlockdevCreateNotSupported',
|
||||
'dmg': 'BlockdevCreateNotSupported',
|
||||
'file': 'BlockdevCreateOptionsFile',
|
||||
'ftp': 'BlockdevCreateNotSupported',
|
||||
'ftps': 'BlockdevCreateNotSupported',
|
||||
'gluster': 'BlockdevCreateOptionsGluster',
|
||||
'host_cdrom': 'BlockdevCreateNotSupported',
|
||||
'host_device': 'BlockdevCreateNotSupported',
|
||||
'http': 'BlockdevCreateNotSupported',
|
||||
'https': 'BlockdevCreateNotSupported',
|
||||
'iscsi': 'BlockdevCreateNotSupported',
|
||||
'luks': 'BlockdevCreateOptionsLUKS',
|
||||
'nbd': 'BlockdevCreateNotSupported',
|
||||
'nfs': 'BlockdevCreateOptionsNfs',
|
||||
'null-aio': 'BlockdevCreateNotSupported',
|
||||
'null-co': 'BlockdevCreateNotSupported',
|
||||
'nvme': 'BlockdevCreateNotSupported',
|
||||
'parallels': 'BlockdevCreateOptionsParallels',
|
||||
'qcow': 'BlockdevCreateOptionsQcow',
|
||||
'qcow2': 'BlockdevCreateOptionsQcow2',
|
||||
'qed': 'BlockdevCreateOptionsQed',
|
||||
'quorum': 'BlockdevCreateNotSupported',
|
||||
'raw': 'BlockdevCreateNotSupported',
|
||||
'rbd': 'BlockdevCreateOptionsRbd',
|
||||
'replication': 'BlockdevCreateNotSupported',
|
||||
'sheepdog': 'BlockdevCreateOptionsSheepdog',
|
||||
'ssh': 'BlockdevCreateOptionsSsh',
|
||||
'throttle': 'BlockdevCreateNotSupported',
|
||||
'vdi': 'BlockdevCreateOptionsVdi',
|
||||
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||
'vmdk': 'BlockdevCreateNotSupported',
|
||||
'vpc': 'BlockdevCreateOptionsVpc',
|
||||
'vvfat': 'BlockdevCreateNotSupported',
|
||||
'vxhs': 'BlockdevCreateNotSupported'
|
||||
'vpc': 'BlockdevCreateOptionsVpc'
|
||||
} }
|
||||
|
||||
##
|
||||
|
@ -297,16 +297,6 @@
|
||||
'uuid': 'str',
|
||||
'slots': [ 'QCryptoBlockInfoLUKSSlot' ] }}
|
||||
|
||||
##
|
||||
# @QCryptoBlockInfoQCow:
|
||||
#
|
||||
# Information about the QCow block encryption options
|
||||
#
|
||||
# Since: 2.7
|
||||
##
|
||||
{ 'struct': 'QCryptoBlockInfoQCow',
|
||||
'data': { }}
|
||||
|
||||
|
||||
##
|
||||
# @QCryptoBlockInfo:
|
||||
@ -318,5 +308,4 @@
|
||||
{ 'union': 'QCryptoBlockInfo',
|
||||
'base': 'QCryptoBlockInfoBase',
|
||||
'discriminator': 'format',
|
||||
'data': { 'qcow': 'QCryptoBlockInfoQCow',
|
||||
'luks': 'QCryptoBlockInfoLUKS' } }
|
||||
'data': { 'luks': 'QCryptoBlockInfoLUKS' } }
|
||||
|
@ -396,8 +396,7 @@
|
||||
'mips': 'CpuInfoMIPS',
|
||||
'tricore': 'CpuInfoTricore',
|
||||
's390': 'CpuInfoS390',
|
||||
'riscv': 'CpuInfoRISCV',
|
||||
'other': 'CpuInfoOther' } }
|
||||
'riscv': 'CpuInfoRISCV' } }
|
||||
|
||||
##
|
||||
# @CpuInfoX86:
|
||||
@ -467,16 +466,6 @@
|
||||
##
|
||||
{ 'struct': 'CpuInfoRISCV', 'data': { 'pc': 'int' } }
|
||||
|
||||
##
|
||||
# @CpuInfoOther:
|
||||
#
|
||||
# No additional information is available about the virtual CPU
|
||||
#
|
||||
# Since: 2.6
|
||||
#
|
||||
##
|
||||
{ 'struct': 'CpuInfoOther', 'data': { } }
|
||||
|
||||
##
|
||||
# @CpuS390State:
|
||||
#
|
||||
@ -578,38 +567,7 @@
|
||||
'arch' : 'CpuInfoArch',
|
||||
'target' : 'SysEmuTarget' },
|
||||
'discriminator' : 'target',
|
||||
'data' : { 'aarch64' : 'CpuInfoOther',
|
||||
'alpha' : 'CpuInfoOther',
|
||||
'arm' : 'CpuInfoOther',
|
||||
'cris' : 'CpuInfoOther',
|
||||
'hppa' : 'CpuInfoOther',
|
||||
'i386' : 'CpuInfoOther',
|
||||
'lm32' : 'CpuInfoOther',
|
||||
'm68k' : 'CpuInfoOther',
|
||||
'microblaze' : 'CpuInfoOther',
|
||||
'microblazeel' : 'CpuInfoOther',
|
||||
'mips' : 'CpuInfoOther',
|
||||
'mips64' : 'CpuInfoOther',
|
||||
'mips64el' : 'CpuInfoOther',
|
||||
'mipsel' : 'CpuInfoOther',
|
||||
'moxie' : 'CpuInfoOther',
|
||||
'nios2' : 'CpuInfoOther',
|
||||
'or1k' : 'CpuInfoOther',
|
||||
'ppc' : 'CpuInfoOther',
|
||||
'ppc64' : 'CpuInfoOther',
|
||||
'ppcemb' : 'CpuInfoOther',
|
||||
'riscv32' : 'CpuInfoOther',
|
||||
'riscv64' : 'CpuInfoOther',
|
||||
's390x' : 'CpuInfoS390',
|
||||
'sh4' : 'CpuInfoOther',
|
||||
'sh4eb' : 'CpuInfoOther',
|
||||
'sparc' : 'CpuInfoOther',
|
||||
'sparc64' : 'CpuInfoOther',
|
||||
'tricore' : 'CpuInfoOther',
|
||||
'unicore32' : 'CpuInfoOther',
|
||||
'x86_64' : 'CpuInfoOther',
|
||||
'xtensa' : 'CpuInfoOther',
|
||||
'xtensaeb' : 'CpuInfoOther' } }
|
||||
'data' : { 's390x' : 'CpuInfoS390' } }
|
||||
|
||||
##
|
||||
# @query-cpus-fast:
|
||||
|
@ -88,16 +88,6 @@
|
||||
##
|
||||
{ 'command': 'netdev_del', 'data': {'id': 'str'} }
|
||||
|
||||
##
|
||||
# @NetdevNoneOptions:
|
||||
#
|
||||
# Use it alone to have zero network devices.
|
||||
#
|
||||
# Since: 1.2
|
||||
##
|
||||
{ 'struct': 'NetdevNoneOptions',
|
||||
'data': { } }
|
||||
|
||||
##
|
||||
# @NetLegacyNicOptions:
|
||||
#
|
||||
@ -477,7 +467,6 @@
|
||||
'base': { 'id': 'str', 'type': 'NetClientDriver' },
|
||||
'discriminator': 'type',
|
||||
'data': {
|
||||
'none': 'NetdevNoneOptions',
|
||||
'nic': 'NetLegacyNicOptions',
|
||||
'user': 'NetdevUserOptions',
|
||||
'tap': 'NetdevTapOptions',
|
||||
@ -530,7 +519,6 @@
|
||||
'base': { 'type': 'NetLegacyOptionsType' },
|
||||
'discriminator': 'type',
|
||||
'data': {
|
||||
'none': 'NetdevNoneOptions',
|
||||
'nic': 'NetLegacyNicOptions',
|
||||
'user': 'NetdevUserOptions',
|
||||
'tap': 'NetdevTapOptions',
|
||||
|
19
qapi/ui.json
19
qapi/ui.json
@ -995,17 +995,6 @@
|
||||
'events' : [ 'InputEvent' ] } }
|
||||
|
||||
|
||||
##
|
||||
# @DisplayNoOpts:
|
||||
#
|
||||
# Empty struct for displays without config options.
|
||||
#
|
||||
# Since: 2.12
|
||||
#
|
||||
##
|
||||
{ 'struct' : 'DisplayNoOpts',
|
||||
'data' : { } }
|
||||
|
||||
##
|
||||
# @DisplayGTK:
|
||||
#
|
||||
@ -1068,10 +1057,4 @@
|
||||
'*window-close' : 'bool',
|
||||
'*gl' : 'DisplayGLMode' },
|
||||
'discriminator' : 'type',
|
||||
'data' : { 'default' : 'DisplayNoOpts',
|
||||
'none' : 'DisplayNoOpts',
|
||||
'gtk' : 'DisplayGTK',
|
||||
'sdl' : 'DisplayNoOpts',
|
||||
'egl-headless' : 'DisplayNoOpts',
|
||||
'curses' : 'DisplayNoOpts',
|
||||
'cocoa' : 'DisplayNoOpts' } }
|
||||
'data' : { 'gtk' : 'DisplayGTK' } }
|
||||
|
@ -114,19 +114,30 @@ static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char *prefix)
|
||||
|
||||
/*
|
||||
* Flatten non-empty QDict and QList recursively into @target,
|
||||
* copy other objects to @target
|
||||
* copy other objects to @target.
|
||||
* On the root level (if @qdict == @target), remove flattened
|
||||
* nested QDicts and QLists from @qdict.
|
||||
*
|
||||
* (Note that we do not need to remove entries from nested
|
||||
* dicts or lists. Their reference count is decremented on
|
||||
* the root level, so there are no leaks. In fact, if they
|
||||
* have a reference count greater than one, we are probably
|
||||
* well advised not to modify them altogether.)
|
||||
*/
|
||||
if (dict_val && qdict_size(dict_val)) {
|
||||
qdict_flatten_qdict(dict_val, target,
|
||||
new_key ? new_key : entry->key);
|
||||
qdict_del(qdict, entry->key);
|
||||
if (target == qdict) {
|
||||
qdict_del(qdict, entry->key);
|
||||
}
|
||||
} else if (list_val && !qlist_empty(list_val)) {
|
||||
qdict_flatten_qlist(list_val, target,
|
||||
new_key ? new_key : entry->key);
|
||||
qdict_del(qdict, entry->key);
|
||||
if (target == qdict) {
|
||||
qdict_del(qdict, entry->key);
|
||||
}
|
||||
} else if (target != qdict) {
|
||||
qdict_put_obj(target, new_key, qobject_ref(value));
|
||||
qdict_del(qdict, entry->key);
|
||||
}
|
||||
|
||||
g_free(new_key);
|
||||
|
@ -16,6 +16,7 @@ import errno
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
|
||||
builtin_types = {
|
||||
@ -340,7 +341,10 @@ class QAPISchemaParser(object):
|
||||
return None
|
||||
|
||||
try:
|
||||
fobj = open(incl_fname, 'r')
|
||||
if sys.version_info[0] >= 3:
|
||||
fobj = open(incl_fname, 'r', encoding='utf-8')
|
||||
else:
|
||||
fobj = open(incl_fname, 'r')
|
||||
except IOError as e:
|
||||
raise QAPISemError(info, '%s: %s' % (e.strerror, incl_fname))
|
||||
return QAPISchemaParser(fobj, previously_included, info)
|
||||
@ -779,13 +783,6 @@ def check_union(expr, info):
|
||||
"enum '%s'"
|
||||
% (key, enum_define['enum']))
|
||||
|
||||
# If discriminator is user-defined, ensure all values are covered
|
||||
if enum_define:
|
||||
for value in enum_define['data']:
|
||||
if value not in members.keys():
|
||||
raise QAPISemError(info, "Union '%s' data missing '%s' branch"
|
||||
% (name, value))
|
||||
|
||||
|
||||
def check_alternate(expr, info):
|
||||
name = expr['alternate']
|
||||
@ -1357,6 +1354,14 @@ class QAPISchemaObjectTypeVariants(object):
|
||||
self.tag_member = seen[c_name(self._tag_name)]
|
||||
assert self._tag_name == self.tag_member.name
|
||||
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
|
||||
if self._tag_name: # flat union
|
||||
# branches that are not explicitly covered get an empty type
|
||||
cases = set([v.name for v in self.variants])
|
||||
for val in self.tag_member.type.values:
|
||||
if val.name not in cases:
|
||||
v = QAPISchemaObjectTypeVariant(val.name, 'q_empty')
|
||||
v.set_owner(self.tag_member.owner)
|
||||
self.variants.append(v)
|
||||
for v in self.variants:
|
||||
v.check(schema)
|
||||
# Union names must match enum values; alternate names are
|
||||
@ -1492,7 +1497,11 @@ class QAPISchemaEvent(QAPISchemaEntity):
|
||||
class QAPISchema(object):
|
||||
def __init__(self, fname):
|
||||
self._fname = fname
|
||||
parser = QAPISchemaParser(open(fname, 'r'))
|
||||
if sys.version_info[0] >= 3:
|
||||
f = open(fname, 'r', encoding='utf-8')
|
||||
else:
|
||||
f = open(fname, 'r')
|
||||
parser = QAPISchemaParser(f)
|
||||
exprs = check_exprs(parser.exprs)
|
||||
self.docs = parser.docs
|
||||
self._entity_list = []
|
||||
@ -2006,7 +2015,10 @@ class QAPIGen(object):
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
|
||||
f = os.fdopen(fd, 'r+')
|
||||
if sys.version_info[0] >= 3:
|
||||
f = open(fd, 'r+', encoding='utf-8')
|
||||
else:
|
||||
f = os.fdopen(fd, 'r+')
|
||||
text = (self._top(fname) + self._preamble + self._body
|
||||
+ self._bottom(fname))
|
||||
oldtext = f.read(len(text) + 1)
|
||||
|
@ -180,8 +180,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
|
||||
types=types))
|
||||
|
||||
def visit_end(self):
|
||||
self._genh.add(gen_enum(self._enum_name, self._event_names))
|
||||
self._genc.add(gen_enum_lookup(self._enum_name, self._event_names))
|
||||
(genc, genh) = self._module[self._main_module]
|
||||
genh.add(gen_enum(self._enum_name, self._event_names))
|
||||
genc.add(gen_enum_lookup(self._enum_name, self._event_names))
|
||||
|
||||
def visit_event(self, name, info, arg_type, boxed):
|
||||
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
|
||||
|
@ -75,13 +75,10 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
|
||||
|
||||
def visit_end(self):
|
||||
# visit the types that are actually used
|
||||
qlits = self._qlits
|
||||
self._qlits = []
|
||||
for typ in self._used_types:
|
||||
typ.visit(self)
|
||||
# generate C
|
||||
# TODO can generate awfully long lines
|
||||
qlits.extend(self._qlits)
|
||||
name = c_name(self._prefix, protect=False) + 'qmp_schema_qlit'
|
||||
self._genh.add(mcgen('''
|
||||
#include "qapi/qmp/qlit.h"
|
||||
@ -93,7 +90,7 @@ extern const QLitObject %(c_name)s;
|
||||
const QLitObject %(c_name)s = %(c_string)s;
|
||||
''',
|
||||
c_name=c_name(name),
|
||||
c_string=to_qlit(qlits)))
|
||||
c_string=to_qlit(self._qlits)))
|
||||
self._schema = None
|
||||
self._qlits = []
|
||||
self._used_types = []
|
||||
|
@ -125,6 +125,8 @@ def gen_variants(variants):
|
||||
c_name=c_name(variants.tag_member.name))
|
||||
|
||||
for var in variants.variants:
|
||||
if var.type.name == 'q_empty':
|
||||
continue
|
||||
ret += mcgen('''
|
||||
%(c_type)s %(c_name)s;
|
||||
''',
|
||||
|
@ -81,15 +81,24 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
||||
c_name=c_name(variants.tag_member.name))
|
||||
|
||||
for var in variants.variants:
|
||||
ret += mcgen('''
|
||||
case_str = c_enum_const(variants.tag_member.type.name,
|
||||
var.name,
|
||||
variants.tag_member.type.prefix)
|
||||
if var.type.name == 'q_empty':
|
||||
# valid variant and nothing to do
|
||||
ret += mcgen('''
|
||||
case %(case)s:
|
||||
break;
|
||||
''',
|
||||
case=case_str)
|
||||
else:
|
||||
ret += mcgen('''
|
||||
case %(case)s:
|
||||
visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, &err);
|
||||
break;
|
||||
''',
|
||||
case=c_enum_const(variants.tag_member.type.name,
|
||||
var.name,
|
||||
variants.tag_member.type.prefix),
|
||||
c_type=var.type.c_name(), c_name=c_name(var.name))
|
||||
case=case_str,
|
||||
c_type=var.type.c_name(), c_name=c_name(var.name))
|
||||
|
||||
ret += mcgen('''
|
||||
default:
|
||||
@ -293,7 +302,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "%(visit)s.h"
|
||||
''',
|
||||
visit=visit, prefix=self._prefix))
|
||||
visit=visit))
|
||||
self._genh.preamble_add(mcgen('''
|
||||
#include "qapi/qapi-builtin-visit.h"
|
||||
#include "%(types)s.h"
|
||||
|
@ -499,7 +499,6 @@ qapi-schema += flat-union-base-any.json
|
||||
qapi-schema += flat-union-base-union.json
|
||||
qapi-schema += flat-union-clash-member.json
|
||||
qapi-schema += flat-union-empty.json
|
||||
qapi-schema += flat-union-incomplete-branch.json
|
||||
qapi-schema += flat-union-inline.json
|
||||
qapi-schema += flat-union-int-branch.json
|
||||
qapi-schema += flat-union-invalid-branch-key.json
|
||||
@ -679,13 +678,13 @@ tests/test-qapi-events.c tests/test-qapi-events.h \
|
||||
tests/test-qapi-introspect.c tests/test-qapi-introspect.h: \
|
||||
tests/test-qapi-gen-timestamp ;
|
||||
tests/test-qapi-gen-timestamp: $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
-o tests -p "test-" $<, \
|
||||
"GEN","$(@:%-timestamp=%)")
|
||||
@>$@
|
||||
|
||||
tests/qapi-schema/doc-good.test.texi: $(SRC_PATH)/tests/qapi-schema/doc-good.json $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
|
||||
-o tests/qapi-schema -p "doc-good-" $<, \
|
||||
"GEN","$@")
|
||||
@mv tests/qapi-schema/doc-good-qapi-doc.texi $@
|
||||
@ -979,7 +978,7 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
|
||||
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
|
||||
$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
|
||||
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
|
||||
$(PYTHON_UTF8) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
|
||||
$(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
|
||||
$^ >$*.test.out 2>$*.test.err; \
|
||||
echo $$? >$*.test.exit, \
|
||||
"TEST","$*.out")
|
||||
|
@ -125,6 +125,38 @@ static void qdict_flatten_test(void)
|
||||
qobject_unref(root);
|
||||
}
|
||||
|
||||
static void qdict_clone_flatten_test(void)
|
||||
{
|
||||
QDict *dict1 = qdict_new();
|
||||
QDict *dict2 = qdict_new();
|
||||
QDict *cloned_dict1;
|
||||
|
||||
/*
|
||||
* Test that we can clone and flatten
|
||||
* { "a": { "b": 42 } }
|
||||
* without modifying the clone.
|
||||
*/
|
||||
|
||||
qdict_put_int(dict2, "b", 42);
|
||||
qdict_put(dict1, "a", dict2);
|
||||
|
||||
cloned_dict1 = qdict_clone_shallow(dict1);
|
||||
|
||||
qdict_flatten(dict1);
|
||||
|
||||
g_assert(qdict_size(dict1) == 1);
|
||||
g_assert(qdict_get_int(dict1, "a.b") == 42);
|
||||
|
||||
g_assert(qdict_size(cloned_dict1) == 1);
|
||||
g_assert(qdict_get_qdict(cloned_dict1, "a") == dict2);
|
||||
|
||||
g_assert(qdict_size(dict2) == 1);
|
||||
g_assert(qdict_get_int(dict2, "b") == 42);
|
||||
|
||||
qobject_unref(dict1);
|
||||
qobject_unref(cloned_dict1);
|
||||
}
|
||||
|
||||
static void qdict_array_split_test(void)
|
||||
{
|
||||
QDict *test_dict = qdict_new();
|
||||
@ -674,6 +706,7 @@ int main(int argc, char **argv)
|
||||
|
||||
g_test_add_func("/public/defaults", qdict_defaults_test);
|
||||
g_test_add_func("/public/flatten", qdict_flatten_test);
|
||||
g_test_add_func("/public/clone_flatten", qdict_clone_flatten_test);
|
||||
g_test_add_func("/public/array_split", qdict_array_split_test);
|
||||
g_test_add_func("/public/array_entries", qdict_array_entries_test);
|
||||
g_test_add_func("/public/join", qdict_join_test);
|
||||
|
@ -1 +0,0 @@
|
||||
tests/qapi-schema/flat-union-incomplete-branch.json:6: Union 'TestUnion' data missing 'value2' branch
|
@ -1 +0,0 @@
|
||||
1
|
@ -1,9 +0,0 @@
|
||||
# we require all branches of the union to be covered
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
{ 'struct': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
{ 'union': 'TestUnion',
|
||||
'base': { 'type': 'TestEnum' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'value1': 'TestTypeA' } }
|
@ -39,7 +39,7 @@
|
||||
'*enum1': 'EnumOne' } } # intentional forward reference
|
||||
|
||||
{ 'enum': 'EnumOne',
|
||||
'data': [ 'value1', 'value2', 'value3' ] }
|
||||
'data': [ 'value1', 'value2', 'value3', 'value4' ] }
|
||||
|
||||
{ 'struct': 'UserDefZero',
|
||||
'data': { 'integer': 'int' } }
|
||||
@ -76,7 +76,9 @@
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1' : 'UserDefA',
|
||||
'value2' : 'UserDefB',
|
||||
'value3' : 'UserDefB' } }
|
||||
'value3' : 'UserDefB'
|
||||
# 'value4' defaults to empty
|
||||
} }
|
||||
|
||||
{ 'struct': 'UserDefUnionBase',
|
||||
'base': 'UserDefZero',
|
||||
|
@ -23,7 +23,7 @@ object UserDefOne
|
||||
base UserDefZero
|
||||
member string: str optional=False
|
||||
member enum1: EnumOne optional=True
|
||||
enum EnumOne ['value1', 'value2', 'value3']
|
||||
enum EnumOne ['value1', 'value2', 'value3', 'value4']
|
||||
object UserDefZero
|
||||
member integer: int optional=False
|
||||
object UserDefTwoDictDict
|
||||
@ -52,6 +52,7 @@ object UserDefFlatUnion
|
||||
case value1: UserDefA
|
||||
case value2: UserDefB
|
||||
case value3: UserDefB
|
||||
case value4: q_empty
|
||||
object UserDefUnionBase
|
||||
base UserDefZero
|
||||
member string: str optional=False
|
||||
|
Loading…
Reference in New Issue
Block a user