QAPI patches
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWH0puAAoJEDhwtADrkYZT6/cP/3EfS/0TVI6tiU1pz/qm6SMy yFYeYw1WIHw9/x7esRMGZ977QfmuL1YhZ0sD4lmpIMcXwuzTd0/tuO0AydH7ffZj daL/rKSiQjdPCbebHol6rAFWHOxRBqz1g2jDgIM9FB4dEjqzbUydV7/9Mmo5b44v Hss0/neKn6zVHognv4aB/FMmjjsbzqgvHcour7T+rVIF9qial/hA2I6ioM2kCnt4 jbkLUYYhb/rPNTlxjvT4vNsDfTiHScTeow6gRzd5LL5f1K7nTmRzqalsyZpRgpl+ mDIrbPExN4O6gDZkKDk3pmwAI+vPTVNP868tSjqNJmUeCdUmT9EQ8LagZCbt0b/e aViwkRmuDv+FNPfkmgmhXY0RTaX9QDT3vwWSjOzLGvrFj66UfbepXfBWlOZnl7DQ KJU33CnEjkbu/viiCat4HjCGt1kF11s+YPlYWGXgyo1QkF54o8OmKGTjZOaEze+R gvIdtbBKYSwnyMbPo26OrwvTDBYfZ+F5j2MCpuDEgwE0CtKbtAOCc87PMRtunDoh xloQ3F6fuItC9dPUGDcDxvN9RG3uPNcOUU4aoS0/y7CHlHqlxOJz6AIlm57vO67B T/PAd1uW6T/yFJWCub0iAHCkvmui639eIz2VyPfuJJb2YAiWivULsLplOzS1cYE4 N7J7BPGEATvaCCmmRPjd =CoJX -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-10-15' into staging QAPI patches # gpg: Signature made Thu 15 Oct 2015 07:40:46 BST 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-10-15: qapi: Track location that created an implicit type qapi: Create simple union type member earlier qapi: Lazy creation of array types qapi: Don't use info as witness of implicit object type qapi: Drop redundant args-member-array test qapi: Drop redundant flat-union-reverse-define test qapi: Drop redundant returns-int test qapi: Move empty-enum to compile-time test qapi: Drop redundant alternate-good test qapi: Prepare for errors during check() qapi: Use predicate callback to determine visit filtering qapi: Fix regression with '-netdev help' Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
61f7901bb8
@ -3415,6 +3415,17 @@
|
||||
'cpuid-register': 'X86CPURegister32',
|
||||
'features': 'int' } }
|
||||
|
||||
##
|
||||
# @DummyForceArrays
|
||||
#
|
||||
# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally
|
||||
#
|
||||
# Since 2.5
|
||||
##
|
||||
{ 'struct': 'DummyForceArrays',
|
||||
'data': { 'unused': ['X86CPUFeatureWordInfo'] } }
|
||||
|
||||
|
||||
##
|
||||
# @RxState:
|
||||
#
|
||||
|
@ -54,7 +54,6 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
|
||||
self._jsons = []
|
||||
self._used_types = []
|
||||
self._name_map = {}
|
||||
return QAPISchemaType # don't visit types for now
|
||||
|
||||
def visit_end(self):
|
||||
# visit the types that are actually used
|
||||
@ -82,6 +81,10 @@ const char %(c_name)s[] = %(c_string)s;
|
||||
self._used_types = None
|
||||
self._name_map = None
|
||||
|
||||
def visit_needed(self, entity):
|
||||
# Ignore types on first pass; visit_end() will pick up used types
|
||||
return not isinstance(entity, QAPISchemaType)
|
||||
|
||||
def _name(self, name):
|
||||
if self._unmask:
|
||||
return name
|
||||
|
@ -233,6 +233,11 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
||||
self.decl = self._btin + self.decl
|
||||
self._btin = None
|
||||
|
||||
def visit_needed(self, entity):
|
||||
# Visit everything except implicit objects
|
||||
return not (entity.is_implicit() and
|
||||
isinstance(entity, QAPISchemaObjectType))
|
||||
|
||||
def _gen_type_cleanup(self, name):
|
||||
self.decl += gen_type_cleanup_decl(name)
|
||||
self.defn += gen_type_cleanup(name)
|
||||
@ -254,14 +259,13 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
||||
self._gen_type_cleanup(name)
|
||||
|
||||
def visit_object_type(self, name, info, base, members, variants):
|
||||
if info:
|
||||
self._fwdecl += gen_fwd_object_or_array(name)
|
||||
if variants:
|
||||
assert not members # not implemented
|
||||
self.decl += gen_union(name, base, variants)
|
||||
else:
|
||||
self.decl += gen_struct(name, base, members)
|
||||
self._gen_type_cleanup(name)
|
||||
self._fwdecl += gen_fwd_object_or_array(name)
|
||||
if variants:
|
||||
assert not members # not implemented
|
||||
self.decl += gen_union(name, base, variants)
|
||||
else:
|
||||
self.decl += gen_struct(name, base, members)
|
||||
self._gen_type_cleanup(name)
|
||||
|
||||
def visit_alternate_type(self, name, info, variants):
|
||||
self._fwdecl += gen_fwd_object_or_array(name)
|
||||
|
@ -301,7 +301,9 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
|
||||
out_obj:
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
visit_end_union(v, !!(*obj)->data, &err);
|
||||
if (*obj) {
|
||||
visit_end_union(v, !!(*obj)->data, &err);
|
||||
}
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
visit_end_struct(v, &err);
|
||||
@ -333,6 +335,11 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
||||
self.decl = self._btin + self.decl
|
||||
self._btin = None
|
||||
|
||||
def visit_needed(self, entity):
|
||||
# Visit everything except implicit objects
|
||||
return not (entity.is_implicit() and
|
||||
isinstance(entity, QAPISchemaObjectType))
|
||||
|
||||
def visit_enum_type(self, name, info, values, prefix):
|
||||
self.decl += gen_visit_decl(name, scalar=True)
|
||||
self.defn += gen_visit_enum(name)
|
||||
@ -349,13 +356,12 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
||||
self.defn += defn
|
||||
|
||||
def visit_object_type(self, name, info, base, members, variants):
|
||||
if info:
|
||||
self.decl += gen_visit_decl(name)
|
||||
if variants:
|
||||
assert not members # not implemented
|
||||
self.defn += gen_visit_union(name, base, variants)
|
||||
else:
|
||||
self.defn += gen_visit_struct(name, base, members)
|
||||
self.decl += gen_visit_decl(name)
|
||||
if variants:
|
||||
assert not members # not implemented
|
||||
self.defn += gen_visit_union(name, base, variants)
|
||||
else:
|
||||
self.defn += gen_visit_struct(name, base, members)
|
||||
|
||||
def visit_alternate_type(self, name, info, variants):
|
||||
self.decl += gen_visit_decl(name)
|
||||
|
149
scripts/qapi.py
149
scripts/qapi.py
@ -56,9 +56,6 @@ returns_whitelist = [
|
||||
'guest-set-vcpus',
|
||||
'guest-sync',
|
||||
'guest-sync-delimited',
|
||||
|
||||
# From qapi-schema-test:
|
||||
'user_def_cmd3',
|
||||
]
|
||||
|
||||
enum_types = []
|
||||
@ -103,6 +100,7 @@ class QAPISchemaError(Exception):
|
||||
class QAPIExprError(Exception):
|
||||
def __init__(self, expr_info, msg):
|
||||
Exception.__init__(self)
|
||||
assert expr_info
|
||||
self.info = expr_info
|
||||
self.msg = msg
|
||||
|
||||
@ -792,6 +790,11 @@ class QAPISchemaEntity(object):
|
||||
def __init__(self, name, info):
|
||||
assert isinstance(name, str)
|
||||
self.name = name
|
||||
# For explicitly defined entities, info points to the (explicit)
|
||||
# definition. For builtins (and their arrays), info is None.
|
||||
# For implicitly defined entities, info points to a place that
|
||||
# triggered the implicit definition (there may be more than one
|
||||
# such place).
|
||||
self.info = info
|
||||
|
||||
def c_name(self):
|
||||
@ -800,6 +803,9 @@ class QAPISchemaEntity(object):
|
||||
def check(self, schema):
|
||||
pass
|
||||
|
||||
def is_implicit(self):
|
||||
return not self.info
|
||||
|
||||
def visit(self, visitor):
|
||||
pass
|
||||
|
||||
@ -811,6 +817,10 @@ class QAPISchemaVisitor(object):
|
||||
def visit_end(self):
|
||||
pass
|
||||
|
||||
def visit_needed(self, entity):
|
||||
# Default to visiting everything
|
||||
return True
|
||||
|
||||
def visit_builtin_type(self, name, info, json_type):
|
||||
pass
|
||||
|
||||
@ -898,6 +908,10 @@ class QAPISchemaEnumType(QAPISchemaType):
|
||||
def check(self, schema):
|
||||
assert len(set(self.values)) == len(self.values)
|
||||
|
||||
def is_implicit(self):
|
||||
# See QAPISchema._make_implicit_enum_type()
|
||||
return self.name[-4:] == 'Kind'
|
||||
|
||||
def c_type(self, is_param=False):
|
||||
return c_name(self.name)
|
||||
|
||||
@ -924,6 +938,9 @@ class QAPISchemaArrayType(QAPISchemaType):
|
||||
self.element_type = schema.lookup_type(self._element_type_name)
|
||||
assert self.element_type
|
||||
|
||||
def is_implicit(self):
|
||||
return True
|
||||
|
||||
def json_type(self):
|
||||
return 'array'
|
||||
|
||||
@ -960,6 +977,7 @@ class QAPISchemaObjectType(QAPISchemaType):
|
||||
members = []
|
||||
seen = {}
|
||||
for m in members:
|
||||
assert c_name(m.name) not in seen
|
||||
seen[m.name] = m
|
||||
for m in self.local_members:
|
||||
m.check(schema, members, seen)
|
||||
@ -967,12 +985,16 @@ class QAPISchemaObjectType(QAPISchemaType):
|
||||
self.variants.check(schema, members, seen)
|
||||
self.members = members
|
||||
|
||||
def is_implicit(self):
|
||||
# See QAPISchema._make_implicit_object_type()
|
||||
return self.name[0] == ':'
|
||||
|
||||
def c_name(self):
|
||||
assert self.info
|
||||
assert not self.is_implicit()
|
||||
return QAPISchemaType.c_name(self)
|
||||
|
||||
def c_type(self, is_param=False):
|
||||
assert self.info
|
||||
assert not self.is_implicit()
|
||||
return QAPISchemaType.c_type(self)
|
||||
|
||||
def json_type(self):
|
||||
@ -1004,18 +1026,18 @@ class QAPISchemaObjectTypeMember(object):
|
||||
|
||||
|
||||
class QAPISchemaObjectTypeVariants(object):
|
||||
def __init__(self, tag_name, tag_enum, variants):
|
||||
assert tag_name is None or isinstance(tag_name, str)
|
||||
assert tag_enum is None or isinstance(tag_enum, str)
|
||||
def __init__(self, tag_name, tag_member, variants):
|
||||
# Flat unions pass tag_name but not tag_member.
|
||||
# Simple unions and alternates pass tag_member but not tag_name.
|
||||
# After check(), tag_member is always set, and tag_name remains
|
||||
# a reliable witness of being used by a flat union.
|
||||
assert bool(tag_member) != bool(tag_name)
|
||||
assert (isinstance(tag_name, str) or
|
||||
isinstance(tag_member, QAPISchemaObjectTypeMember))
|
||||
for v in variants:
|
||||
assert isinstance(v, QAPISchemaObjectTypeVariant)
|
||||
self.tag_name = tag_name
|
||||
if tag_name:
|
||||
assert not tag_enum
|
||||
self.tag_member = None
|
||||
else:
|
||||
self.tag_member = QAPISchemaObjectTypeMember('type', tag_enum,
|
||||
False)
|
||||
self.tag_member = tag_member
|
||||
self.variants = variants
|
||||
|
||||
def check(self, schema, members, seen):
|
||||
@ -1040,7 +1062,8 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
|
||||
# This function exists to support ugly simple union special cases
|
||||
# TODO get rid of them, and drop the function
|
||||
def simple_union_type(self):
|
||||
if isinstance(self.type, QAPISchemaObjectType) and not self.type.info:
|
||||
if (self.type.is_implicit() and
|
||||
isinstance(self.type, QAPISchemaObjectType)):
|
||||
assert len(self.type.members) == 1
|
||||
assert not self.type.variants
|
||||
return self.type.members[0].type
|
||||
@ -1112,15 +1135,19 @@ class QAPISchema(object):
|
||||
def __init__(self, fname):
|
||||
try:
|
||||
self.exprs = check_exprs(QAPISchemaParser(open(fname, "r")).exprs)
|
||||
self._entity_dict = {}
|
||||
self._predefining = True
|
||||
self._def_predefineds()
|
||||
self._predefining = False
|
||||
self._def_exprs()
|
||||
self.check()
|
||||
except (QAPISchemaError, QAPIExprError), err:
|
||||
print >>sys.stderr, err
|
||||
exit(1)
|
||||
self._entity_dict = {}
|
||||
self._def_predefineds()
|
||||
self._def_exprs()
|
||||
self.check()
|
||||
|
||||
def _def_entity(self, ent):
|
||||
# Only the predefined types are allowed to not have info
|
||||
assert ent.info or self._predefining
|
||||
assert ent.name not in self._entity_dict
|
||||
self._entity_dict[ent.name] = ent
|
||||
|
||||
@ -1136,7 +1163,12 @@ class QAPISchema(object):
|
||||
def _def_builtin_type(self, name, json_type, c_type, c_null):
|
||||
self._def_entity(QAPISchemaBuiltinType(name, json_type,
|
||||
c_type, c_null))
|
||||
self._make_array_type(name) # TODO really needed?
|
||||
# TODO As long as we have QAPI_TYPES_BUILTIN to share multiple
|
||||
# qapi-types.h from a single .c, all arrays of builtins must be
|
||||
# declared in the first file whether or not they are used. Nicer
|
||||
# would be to use lazy instantiation, while figuring out how to
|
||||
# avoid compilation issues with multiple qapi-types.h.
|
||||
self._make_array_type(name, None)
|
||||
|
||||
def _def_predefineds(self):
|
||||
for t in [('str', 'string', 'char' + pointer_suffix, 'NULL'),
|
||||
@ -1158,23 +1190,25 @@ class QAPISchema(object):
|
||||
[], None)
|
||||
self._def_entity(self.the_empty_object_type)
|
||||
|
||||
def _make_implicit_enum_type(self, name, values):
|
||||
name = name + 'Kind'
|
||||
self._def_entity(QAPISchemaEnumType(name, None, values, None))
|
||||
def _make_implicit_enum_type(self, name, info, values):
|
||||
name = name + 'Kind' # Use namespace reserved by add_name()
|
||||
self._def_entity(QAPISchemaEnumType(name, info, values, None))
|
||||
return name
|
||||
|
||||
def _make_array_type(self, element_type):
|
||||
def _make_array_type(self, element_type, info):
|
||||
# TODO fooList namespace is not reserved; user can create collisions,
|
||||
# or abuse our type system with ['fooList'] for 2D array
|
||||
name = element_type + 'List'
|
||||
if not self.lookup_type(name):
|
||||
self._def_entity(QAPISchemaArrayType(name, None, element_type))
|
||||
self._def_entity(QAPISchemaArrayType(name, info, element_type))
|
||||
return name
|
||||
|
||||
def _make_implicit_object_type(self, name, role, members):
|
||||
def _make_implicit_object_type(self, name, info, role, members):
|
||||
if not members:
|
||||
return None
|
||||
name = ':obj-%s-%s' % (name, role)
|
||||
if not self.lookup_entity(name, QAPISchemaObjectType):
|
||||
self._def_entity(QAPISchemaObjectType(name, None, None,
|
||||
self._def_entity(QAPISchemaObjectType(name, info, None,
|
||||
members, None))
|
||||
return name
|
||||
|
||||
@ -1183,20 +1217,19 @@ class QAPISchema(object):
|
||||
data = expr['data']
|
||||
prefix = expr.get('prefix')
|
||||
self._def_entity(QAPISchemaEnumType(name, info, data, prefix))
|
||||
self._make_array_type(name) # TODO really needed?
|
||||
|
||||
def _make_member(self, name, typ):
|
||||
def _make_member(self, name, typ, info):
|
||||
optional = False
|
||||
if name.startswith('*'):
|
||||
name = name[1:]
|
||||
optional = True
|
||||
if isinstance(typ, list):
|
||||
assert len(typ) == 1
|
||||
typ = self._make_array_type(typ[0])
|
||||
typ = self._make_array_type(typ[0], info)
|
||||
return QAPISchemaObjectTypeMember(name, typ, optional)
|
||||
|
||||
def _make_members(self, data):
|
||||
return [self._make_member(key, value)
|
||||
def _make_members(self, data, info):
|
||||
return [self._make_member(key, value, info)
|
||||
for (key, value) in data.iteritems()]
|
||||
|
||||
def _def_struct_type(self, expr, info):
|
||||
@ -1204,58 +1237,56 @@ class QAPISchema(object):
|
||||
base = expr.get('base')
|
||||
data = expr['data']
|
||||
self._def_entity(QAPISchemaObjectType(name, info, base,
|
||||
self._make_members(data),
|
||||
self._make_members(data, info),
|
||||
None))
|
||||
self._make_array_type(name) # TODO really needed?
|
||||
|
||||
def _make_variant(self, case, typ):
|
||||
return QAPISchemaObjectTypeVariant(case, typ)
|
||||
|
||||
def _make_simple_variant(self, case, typ):
|
||||
def _make_simple_variant(self, case, typ, info):
|
||||
if isinstance(typ, list):
|
||||
assert len(typ) == 1
|
||||
typ = self._make_array_type(typ[0])
|
||||
typ = self._make_implicit_object_type(typ, 'wrapper',
|
||||
[self._make_member('data', typ)])
|
||||
typ = self._make_array_type(typ[0], info)
|
||||
typ = self._make_implicit_object_type(
|
||||
typ, info, 'wrapper', [self._make_member('data', typ, info)])
|
||||
return QAPISchemaObjectTypeVariant(case, typ)
|
||||
|
||||
def _make_tag_enum(self, type_name, variants):
|
||||
return self._make_implicit_enum_type(type_name,
|
||||
[v.name for v in variants])
|
||||
def _make_implicit_tag(self, type_name, info, variants):
|
||||
typ = self._make_implicit_enum_type(type_name, info,
|
||||
[v.name for v in variants])
|
||||
return QAPISchemaObjectTypeMember('type', typ, False)
|
||||
|
||||
def _def_union_type(self, expr, info):
|
||||
name = expr['union']
|
||||
data = expr['data']
|
||||
base = expr.get('base')
|
||||
tag_name = expr.get('discriminator')
|
||||
tag_enum = None
|
||||
tag_member = None
|
||||
if tag_name:
|
||||
variants = [self._make_variant(key, value)
|
||||
for (key, value) in data.iteritems()]
|
||||
else:
|
||||
variants = [self._make_simple_variant(key, value)
|
||||
variants = [self._make_simple_variant(key, value, info)
|
||||
for (key, value) in data.iteritems()]
|
||||
tag_enum = self._make_tag_enum(name, variants)
|
||||
tag_member = self._make_implicit_tag(name, info, variants)
|
||||
self._def_entity(
|
||||
QAPISchemaObjectType(name, info, base,
|
||||
self._make_members(OrderedDict()),
|
||||
self._make_members(OrderedDict(), info),
|
||||
QAPISchemaObjectTypeVariants(tag_name,
|
||||
tag_enum,
|
||||
tag_member,
|
||||
variants)))
|
||||
self._make_array_type(name) # TODO really needed?
|
||||
|
||||
def _def_alternate_type(self, expr, info):
|
||||
name = expr['alternate']
|
||||
data = expr['data']
|
||||
variants = [self._make_variant(key, value)
|
||||
for (key, value) in data.iteritems()]
|
||||
tag_enum = self._make_tag_enum(name, variants)
|
||||
tag_member = self._make_implicit_tag(name, info, variants)
|
||||
self._def_entity(
|
||||
QAPISchemaAlternateType(name, info,
|
||||
QAPISchemaObjectTypeVariants(None,
|
||||
tag_enum,
|
||||
tag_member,
|
||||
variants)))
|
||||
self._make_array_type(name) # TODO really needed?
|
||||
|
||||
def _def_command(self, expr, info):
|
||||
name = expr['command']
|
||||
@ -1264,11 +1295,11 @@ class QAPISchema(object):
|
||||
gen = expr.get('gen', True)
|
||||
success_response = expr.get('success-response', True)
|
||||
if isinstance(data, OrderedDict):
|
||||
data = self._make_implicit_object_type(name, 'arg',
|
||||
self._make_members(data))
|
||||
data = self._make_implicit_object_type(
|
||||
name, info, 'arg', self._make_members(data, info))
|
||||
if isinstance(rets, list):
|
||||
assert len(rets) == 1
|
||||
rets = self._make_array_type(rets[0])
|
||||
rets = self._make_array_type(rets[0], info)
|
||||
self._def_entity(QAPISchemaCommand(name, info, data, rets, gen,
|
||||
success_response))
|
||||
|
||||
@ -1276,8 +1307,8 @@ class QAPISchema(object):
|
||||
name = expr['event']
|
||||
data = expr.get('data')
|
||||
if isinstance(data, OrderedDict):
|
||||
data = self._make_implicit_object_type(name, 'arg',
|
||||
self._make_members(data))
|
||||
data = self._make_implicit_object_type(
|
||||
name, info, 'arg', self._make_members(data, info))
|
||||
self._def_entity(QAPISchemaEvent(name, info, data))
|
||||
|
||||
def _def_exprs(self):
|
||||
@ -1304,10 +1335,10 @@ class QAPISchema(object):
|
||||
ent.check(self)
|
||||
|
||||
def visit(self, visitor):
|
||||
ignore = visitor.visit_begin(self)
|
||||
for name in sorted(self._entity_dict.keys()):
|
||||
if not ignore or not isinstance(self._entity_dict[name], ignore):
|
||||
self._entity_dict[name].visit(visitor)
|
||||
visitor.visit_begin(self)
|
||||
for (name, entity) in sorted(self._entity_dict.items()):
|
||||
if visitor.visit_needed(entity):
|
||||
entity.visit(visitor)
|
||||
visitor.visit_end()
|
||||
|
||||
|
||||
|
@ -230,7 +230,6 @@ qapi-schema += alternate-clash.json
|
||||
qapi-schema += alternate-conflict-dict.json
|
||||
qapi-schema += alternate-conflict-string.json
|
||||
qapi-schema += alternate-empty.json
|
||||
qapi-schema += alternate-good.json
|
||||
qapi-schema += alternate-nested.json
|
||||
qapi-schema += alternate-unknown.json
|
||||
qapi-schema += args-alternate.json
|
||||
@ -240,7 +239,6 @@ qapi-schema += args-array-unknown.json
|
||||
qapi-schema += args-int.json
|
||||
qapi-schema += args-invalid.json
|
||||
qapi-schema += args-member-array-bad.json
|
||||
qapi-schema += args-member-array.json
|
||||
qapi-schema += args-member-unknown.json
|
||||
qapi-schema += args-name-clash.json
|
||||
qapi-schema += args-union.json
|
||||
@ -261,7 +259,6 @@ qapi-schema += enum-bad-name.json
|
||||
qapi-schema += enum-bad-prefix.json
|
||||
qapi-schema += enum-clash-member.json
|
||||
qapi-schema += enum-dict-member.json
|
||||
qapi-schema += enum-empty.json
|
||||
qapi-schema += enum-int-member.json
|
||||
qapi-schema += enum-max-member.json
|
||||
qapi-schema += enum-missing-data.json
|
||||
@ -288,7 +285,6 @@ qapi-schema += flat-union-invalid-branch-key.json
|
||||
qapi-schema += flat-union-invalid-discriminator.json
|
||||
qapi-schema += flat-union-no-base.json
|
||||
qapi-schema += flat-union-optional-discriminator.json
|
||||
qapi-schema += flat-union-reverse-define.json
|
||||
qapi-schema += flat-union-string-discriminator.json
|
||||
qapi-schema += funny-char.json
|
||||
qapi-schema += ident-with-escape.json
|
||||
@ -320,7 +316,6 @@ qapi-schema += redefined-type.json
|
||||
qapi-schema += returns-alternate.json
|
||||
qapi-schema += returns-array-bad.json
|
||||
qapi-schema += returns-dict.json
|
||||
qapi-schema += returns-int.json
|
||||
qapi-schema += returns-unknown.json
|
||||
qapi-schema += returns-whitelist.json
|
||||
qapi-schema += struct-base-clash-base.json
|
||||
|
@ -1 +0,0 @@
|
||||
0
|
@ -1,9 +0,0 @@
|
||||
# Working example of alternate
|
||||
{ 'struct': 'Data',
|
||||
'data': { '*number': 'int', '*name': 'str' } }
|
||||
{ 'enum': 'Enum',
|
||||
'data': [ 'hello', 'world' ] }
|
||||
{ 'alternate': 'Alt',
|
||||
'data': { 'value': 'int',
|
||||
'string': 'Enum',
|
||||
'struct': 'Data' } }
|
@ -1,10 +0,0 @@
|
||||
object :empty
|
||||
alternate Alt
|
||||
case value: int
|
||||
case string: Enum
|
||||
case struct: Data
|
||||
enum AltKind ['value', 'string', 'struct']
|
||||
object Data
|
||||
member number: int optional=True
|
||||
member name: str optional=True
|
||||
enum Enum ['hello', 'world']
|
@ -1 +0,0 @@
|
||||
0
|
@ -1,4 +0,0 @@
|
||||
# valid array members
|
||||
{ 'enum': 'abc', 'data': [ 'a', 'b', 'c' ] }
|
||||
{ 'struct': 'def', 'data': { 'array': [ 'abc' ] } }
|
||||
{ 'command': 'okay', 'data': { 'member1': [ 'int' ], 'member2': [ 'def' ] } }
|
@ -1,9 +0,0 @@
|
||||
object :empty
|
||||
object :obj-okay-arg
|
||||
member member1: intList optional=False
|
||||
member member2: defList optional=False
|
||||
enum abc ['a', 'b', 'c']
|
||||
object def
|
||||
member array: abcList optional=False
|
||||
command okay :obj-okay-arg -> None
|
||||
gen=True success_response=True
|
@ -1 +0,0 @@
|
||||
0
|
@ -1,2 +0,0 @@
|
||||
# An empty enum, although unusual, is currently acceptable
|
||||
{ 'enum': 'MyEnum', 'data': [ ] }
|
@ -1,2 +0,0 @@
|
||||
object :empty
|
||||
enum MyEnum []
|
@ -1 +0,0 @@
|
||||
0
|
@ -1,17 +0,0 @@
|
||||
{ 'union': 'TestUnion',
|
||||
'base': 'TestBase',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1': 'TestTypeA',
|
||||
'value2': 'TestTypeB' } }
|
||||
|
||||
{ 'struct': 'TestBase',
|
||||
'data': { 'enum1': 'TestEnum' } }
|
||||
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
|
||||
{ 'struct': 'TestTypeA',
|
||||
'data': { 'string': 'str' } }
|
||||
|
||||
{ 'struct': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
@ -1,13 +0,0 @@
|
||||
object :empty
|
||||
object TestBase
|
||||
member enum1: TestEnum optional=False
|
||||
enum TestEnum ['value1', 'value2']
|
||||
object TestTypeA
|
||||
member string: str optional=False
|
||||
object TestTypeB
|
||||
member integer: int optional=False
|
||||
object TestUnion
|
||||
base TestBase
|
||||
tag enum1
|
||||
case value1: TestTypeA
|
||||
case value2: TestTypeB
|
@ -1,10 +1,15 @@
|
||||
# *-*- Mode: Python -*-*
|
||||
|
||||
# This file is a stress test of supported qapi constructs that must
|
||||
# parse and compile correctly.
|
||||
|
||||
# for testing enums
|
||||
{ 'enum': 'EnumOne',
|
||||
'data': [ 'value1', 'value2', 'value3' ] }
|
||||
{ 'struct': 'NestedEnumsOne',
|
||||
'data': { 'enum1': 'EnumOne', '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } }
|
||||
'data': { 'enum1': 'EnumOne', # Intentional forward reference
|
||||
'*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } }
|
||||
|
||||
# An empty enum, although unusual, is currently acceptable
|
||||
{ 'enum': 'MyEnum', 'data': [ ] }
|
||||
|
||||
# for testing override of default naming heuristic
|
||||
{ 'enum': 'QEnumTwo',
|
||||
@ -14,7 +19,11 @@
|
||||
# for testing nested structs
|
||||
{ 'struct': 'UserDefOne',
|
||||
'base': 'UserDefZero', # intentional forward reference
|
||||
'data': { 'string': 'str', '*enum1': 'EnumOne' } }
|
||||
'data': { 'string': 'str',
|
||||
'*enum1': 'EnumOne' } } # intentional forward reference
|
||||
|
||||
{ 'enum': 'EnumOne',
|
||||
'data': [ 'value1', 'value2', 'value3' ] }
|
||||
|
||||
{ 'struct': 'UserDefZero',
|
||||
'data': { 'integer': 'int' } }
|
||||
@ -31,6 +40,10 @@
|
||||
'data': { 'string0': 'str',
|
||||
'dict1': 'UserDefTwoDict' } }
|
||||
|
||||
# dummy struct to force generation of array types not otherwise mentioned
|
||||
{ 'struct': 'ForceArrays',
|
||||
'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'] } }
|
||||
|
||||
# for testing unions
|
||||
# Among other things, test that a name collision between branches does
|
||||
# not cause any problems (since only one branch can be in use at a time),
|
||||
@ -98,9 +111,10 @@
|
||||
{ 'command': 'user_def_cmd2',
|
||||
'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'},
|
||||
'returns': 'UserDefTwo' }
|
||||
{ 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' },
|
||||
|
||||
# Returning a non-dictionary requires a name from the whitelist
|
||||
{ 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' },
|
||||
'returns': 'int' }
|
||||
# note: command name 'guest-sync' chosen to avoid "cannot use built-in" error
|
||||
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
|
||||
|
||||
# For testing integer range flattening in opts-visitor. The following schema
|
||||
|
@ -17,6 +17,9 @@ object :obj-anyList-wrapper
|
||||
member data: anyList optional=False
|
||||
object :obj-boolList-wrapper
|
||||
member data: boolList optional=False
|
||||
object :obj-guest-get-time-arg
|
||||
member a: int optional=False
|
||||
member b: int optional=True
|
||||
object :obj-guest-sync-arg
|
||||
member arg: any optional=False
|
||||
object :obj-int16List-wrapper
|
||||
@ -50,9 +53,6 @@ object :obj-user_def_cmd1-arg
|
||||
object :obj-user_def_cmd2-arg
|
||||
member ud1a: UserDefOne optional=False
|
||||
member ud1b: UserDefOne optional=True
|
||||
object :obj-user_def_cmd3-arg
|
||||
member a: int optional=False
|
||||
member b: int optional=True
|
||||
alternate AltIntNum
|
||||
case i: int
|
||||
case n: number
|
||||
@ -86,6 +86,10 @@ object EventStructOne
|
||||
member struct1: UserDefOne optional=False
|
||||
member string: str optional=False
|
||||
member enum2: EnumOne optional=True
|
||||
object ForceArrays
|
||||
member unused1: UserDefOneList optional=False
|
||||
member unused2: UserDefTwoList optional=False
|
||||
enum MyEnum []
|
||||
object NestedEnumsOne
|
||||
member enum1: EnumOne optional=False
|
||||
member enum2: EnumOne optional=True
|
||||
@ -183,6 +187,8 @@ object __org.qemu_x-Union2
|
||||
case __org.qemu_x-value: __org.qemu_x-Struct2
|
||||
command __org.qemu_x-command :obj-__org.qemu_x-command-arg -> __org.qemu_x-Union1
|
||||
gen=True success_response=True
|
||||
command guest-get-time :obj-guest-get-time-arg -> int
|
||||
gen=True success_response=True
|
||||
command guest-sync :obj-guest-sync-arg -> any
|
||||
gen=True success_response=True
|
||||
command user_def_cmd None -> None
|
||||
@ -191,5 +197,3 @@ command user_def_cmd1 :obj-user_def_cmd1-arg -> None
|
||||
gen=True success_response=True
|
||||
command user_def_cmd2 :obj-user_def_cmd2-arg -> UserDefTwo
|
||||
gen=True success_response=True
|
||||
command user_def_cmd3 :obj-user_def_cmd3-arg -> int
|
||||
gen=True success_response=True
|
||||
|
@ -1 +0,0 @@
|
||||
0
|
@ -1,3 +0,0 @@
|
||||
# It is okay (although not extensible) to return a non-dictionary
|
||||
# But to make it work, the name must be in a whitelist
|
||||
{ 'command': 'guest-get-time', 'returns': 'int' }
|
@ -1,3 +0,0 @@
|
||||
object :empty
|
||||
command guest-get-time None -> int
|
||||
gen=True success_response=True
|
@ -46,7 +46,7 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t qmp_user_def_cmd3(int64_t a, bool has_b, int64_t b, Error **errp)
|
||||
int64_t qmp_guest_get_time(int64_t a, bool has_b, int64_t b, Error **errp)
|
||||
{
|
||||
return a + (has_b ? b : 0);
|
||||
}
|
||||
@ -160,7 +160,7 @@ static void test_dispatch_cmd_io(void)
|
||||
|
||||
qdict_put(args3, "a", qint_from_int(66));
|
||||
qdict_put(req, "arguments", args3);
|
||||
qdict_put(req, "execute", qstring_from_str("user_def_cmd3"));
|
||||
qdict_put(req, "execute", qstring_from_str("guest-get-time"));
|
||||
|
||||
ret3 = qobject_to_qint(test_qmp_dispatch(req));
|
||||
assert(qint_get_int(ret3) == 66);
|
||||
|
Loading…
Reference in New Issue
Block a user