mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 14:53:54 -06:00
qapi: add a dictionary form with 'name' key for enum members
Desugar the enum NAME form to { 'name': NAME }. This will allow to add new enum members, such as 'if' in the following patch. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-7-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-8-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-9-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Harmless accidental move backed out, long line wrapped, patches squashed] Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
7e80d48001
commit
ea738b2168
12 changed files with 36 additions and 14 deletions
|
@ -740,6 +740,10 @@ def check_event(expr, info):
|
||||||
allow_metas=meta)
|
allow_metas=meta)
|
||||||
|
|
||||||
|
|
||||||
|
def enum_get_names(expr):
|
||||||
|
return [e['name'] for e in expr['data']]
|
||||||
|
|
||||||
|
|
||||||
def check_union(expr, info):
|
def check_union(expr, info):
|
||||||
name = expr['union']
|
name = expr['union']
|
||||||
base = expr.get('base')
|
base = expr.get('base')
|
||||||
|
@ -799,7 +803,7 @@ def check_union(expr, info):
|
||||||
# If the discriminator names an enum type, then all members
|
# If the discriminator names an enum type, then all members
|
||||||
# of 'data' must also be members of the enum type.
|
# of 'data' must also be members of the enum type.
|
||||||
if enum_define:
|
if enum_define:
|
||||||
if key not in enum_define['data']:
|
if key not in enum_get_names(enum_define):
|
||||||
raise QAPISemError(info,
|
raise QAPISemError(info,
|
||||||
"Discriminator value '%s' is not found in "
|
"Discriminator value '%s' is not found in "
|
||||||
"enum '%s'"
|
"enum '%s'"
|
||||||
|
@ -831,7 +835,7 @@ def check_alternate(expr, info):
|
||||||
if qtype == 'QTYPE_QSTRING':
|
if qtype == 'QTYPE_QSTRING':
|
||||||
enum_expr = enum_types.get(value)
|
enum_expr = enum_types.get(value)
|
||||||
if enum_expr:
|
if enum_expr:
|
||||||
for v in enum_expr['data']:
|
for v in enum_get_names(enum_expr):
|
||||||
if v in ['on', 'off']:
|
if v in ['on', 'off']:
|
||||||
conflicting.add('QTYPE_QBOOL')
|
conflicting.add('QTYPE_QBOOL')
|
||||||
if re.match(r'[-+0-9.]', v): # lazy, could be tightened
|
if re.match(r'[-+0-9.]', v): # lazy, could be tightened
|
||||||
|
@ -847,9 +851,15 @@ def check_alternate(expr, info):
|
||||||
types_seen[qt] = key
|
types_seen[qt] = key
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_enum(expr):
|
||||||
|
if isinstance(expr['data'], list):
|
||||||
|
expr['data'] = [m if isinstance(m, dict) else {'name': m}
|
||||||
|
for m in expr['data']]
|
||||||
|
|
||||||
|
|
||||||
def check_enum(expr, info):
|
def check_enum(expr, info):
|
||||||
name = expr['enum']
|
name = expr['enum']
|
||||||
members = expr.get('data')
|
members = expr['data']
|
||||||
prefix = expr.get('prefix')
|
prefix = expr.get('prefix')
|
||||||
|
|
||||||
if not isinstance(members, list):
|
if not isinstance(members, list):
|
||||||
|
@ -858,8 +868,11 @@ def check_enum(expr, info):
|
||||||
if prefix is not None and not isinstance(prefix, str):
|
if prefix is not None and not isinstance(prefix, str):
|
||||||
raise QAPISemError(info,
|
raise QAPISemError(info,
|
||||||
"Enum '%s' requires a string for 'prefix'" % name)
|
"Enum '%s' requires a string for 'prefix'" % name)
|
||||||
|
|
||||||
for member in members:
|
for member in members:
|
||||||
check_name(info, "Member of enum '%s'" % name, member,
|
source = "dictionary member of enum '%s'" % name
|
||||||
|
check_known_keys(info, source, member, ['name'], [])
|
||||||
|
check_name(info, "Member of enum '%s'" % name, member['name'],
|
||||||
enum_member=True)
|
enum_member=True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -937,6 +950,7 @@ def check_exprs(exprs):
|
||||||
if 'enum' in expr:
|
if 'enum' in expr:
|
||||||
meta = 'enum'
|
meta = 'enum'
|
||||||
check_keys(expr_elem, 'enum', ['data'], ['if', 'prefix'])
|
check_keys(expr_elem, 'enum', ['data'], ['if', 'prefix'])
|
||||||
|
normalize_enum(expr)
|
||||||
enum_types[expr[meta]] = expr
|
enum_types[expr[meta]] = expr
|
||||||
elif 'union' in expr:
|
elif 'union' in expr:
|
||||||
meta = 'union'
|
meta = 'union'
|
||||||
|
@ -1633,14 +1647,16 @@ class QAPISchema(object):
|
||||||
self.the_empty_object_type = QAPISchemaObjectType(
|
self.the_empty_object_type = QAPISchemaObjectType(
|
||||||
'q_empty', None, None, None, None, [], None)
|
'q_empty', None, None, None, None, [], None)
|
||||||
self._def_entity(self.the_empty_object_type)
|
self._def_entity(self.the_empty_object_type)
|
||||||
qtype_values = self._make_enum_members(['none', 'qnull', 'qnum',
|
|
||||||
'qstring', 'qdict', 'qlist',
|
qtypes = ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist',
|
||||||
'qbool'])
|
'qbool']
|
||||||
|
qtype_values = self._make_enum_members([{'name': n} for n in qtypes])
|
||||||
|
|
||||||
self._def_entity(QAPISchemaEnumType('QType', None, None, None,
|
self._def_entity(QAPISchemaEnumType('QType', None, None, None,
|
||||||
qtype_values, 'QTYPE'))
|
qtype_values, 'QTYPE'))
|
||||||
|
|
||||||
def _make_enum_members(self, values):
|
def _make_enum_members(self, values):
|
||||||
return [QAPISchemaMember(v) for v in values]
|
return [QAPISchemaMember(v['name']) for v in values]
|
||||||
|
|
||||||
def _make_implicit_enum_type(self, name, info, ifcond, values):
|
def _make_implicit_enum_type(self, name, info, ifcond, values):
|
||||||
# See also QAPISchemaObjectTypeMember._pretty_owner()
|
# See also QAPISchemaObjectTypeMember._pretty_owner()
|
||||||
|
@ -1740,8 +1756,8 @@ class QAPISchema(object):
|
||||||
else:
|
else:
|
||||||
variants = [self._make_simple_variant(key, value, info)
|
variants = [self._make_simple_variant(key, value, info)
|
||||||
for (key, value) in data.items()]
|
for (key, value) in data.items()]
|
||||||
typ = self._make_implicit_enum_type(name, info, ifcond,
|
enum = [{'name': v.name} for v in variants]
|
||||||
[v.name for v in variants])
|
typ = self._make_implicit_enum_type(name, info, ifcond, enum)
|
||||||
tag_member = QAPISchemaObjectTypeMember('type', typ, False)
|
tag_member = QAPISchemaObjectTypeMember('type', typ, False)
|
||||||
members = [tag_member]
|
members = [tag_member]
|
||||||
self._def_entity(
|
self._def_entity(
|
||||||
|
|
|
@ -379,10 +379,11 @@ qapi-schema += double-data.json
|
||||||
qapi-schema += double-type.json
|
qapi-schema += double-type.json
|
||||||
qapi-schema += duplicate-key.json
|
qapi-schema += duplicate-key.json
|
||||||
qapi-schema += empty.json
|
qapi-schema += empty.json
|
||||||
|
qapi-schema += enum-bad-member.json
|
||||||
qapi-schema += enum-bad-name.json
|
qapi-schema += enum-bad-name.json
|
||||||
qapi-schema += enum-bad-prefix.json
|
qapi-schema += enum-bad-prefix.json
|
||||||
qapi-schema += enum-clash-member.json
|
qapi-schema += enum-clash-member.json
|
||||||
qapi-schema += enum-dict-member.json
|
qapi-schema += enum-dict-member-unknown.json
|
||||||
qapi-schema += enum-int-member.json
|
qapi-schema += enum-int-member.json
|
||||||
qapi-schema += enum-member-case.json
|
qapi-schema += enum-member-case.json
|
||||||
qapi-schema += enum-missing-data.json
|
qapi-schema += enum-missing-data.json
|
||||||
|
|
1
tests/qapi-schema/enum-bad-member.err
Normal file
1
tests/qapi-schema/enum-bad-member.err
Normal file
|
@ -0,0 +1 @@
|
||||||
|
tests/qapi-schema/enum-bad-member.json:2: Member of enum 'MyEnum' requires a string name
|
2
tests/qapi-schema/enum-bad-member.json
Normal file
2
tests/qapi-schema/enum-bad-member.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# we reject any enum member that is not a string
|
||||||
|
{ 'enum': 'MyEnum', 'data': [ [ ] ] }
|
2
tests/qapi-schema/enum-dict-member-unknown.err
Normal file
2
tests/qapi-schema/enum-dict-member-unknown.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum'
|
||||||
|
Valid keys are 'name'.
|
1
tests/qapi-schema/enum-dict-member-unknown.exit
Normal file
1
tests/qapi-schema/enum-dict-member-unknown.exit
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1
|
2
tests/qapi-schema/enum-dict-member-unknown.json
Normal file
2
tests/qapi-schema/enum-dict-member-unknown.json
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# we reject any enum member that is not a string or a dict with 'name'
|
||||||
|
{ 'enum': 'MyEnum', 'data': [ { 'name': 'foo', 'bad-key': 'str' } ] }
|
0
tests/qapi-schema/enum-dict-member-unknown.out
Normal file
0
tests/qapi-schema/enum-dict-member-unknown.out
Normal file
|
@ -1 +0,0 @@
|
||||||
tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name
|
|
|
@ -1,2 +0,0 @@
|
||||||
# we reject any enum member that is not a string
|
|
||||||
{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
|
|
Loading…
Add table
Add a link
Reference in a new issue