[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 29/54] qapi: add 'if' to enum members
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v2 29/54] qapi: add 'if' to enum members |
Date: |
Tue, 22 Aug 2017 15:22:30 +0200 |
Signed-off-by: Marc-André Lureau <address@hidden>
---
scripts/qapi.py | 33 +++++++++++++++++++++++++++------
tests/qapi-schema/enum-dict-member.err | 1 -
tests/qapi-schema/enum-dict-member.exit | 2 +-
tests/qapi-schema/enum-dict-member.json | 3 +--
tests/qapi-schema/enum-dict-member.out | 4 ++++
tests/qapi-schema/qapi-schema-test.json | 5 +++--
tests/qapi-schema/qapi-schema-test.out | 3 ++-
tests/qapi-schema/test-qapi.py | 4 +++-
8 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9d075440d3..9c7c01c11d 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -729,6 +729,10 @@ def check_event(expr, info):
allow_metas=meta)
+def enum_get_values(expr):
+ return [e if isinstance(e, str) else e['name'] for e in expr['data']]
+
+
def check_union(expr, info):
name = expr['union']
base = expr.get('base')
@@ -788,7 +792,7 @@ def check_union(expr, info):
# If the discriminator names an enum type, then all members
# of 'data' must also be members of the enum type.
if enum_define:
- if key not in enum_define['data']:
+ if key not in enum_get_values(enum_define):
raise QAPISemError(info,
"Discriminator value '%s' is not found in "
"enum '%s'"
@@ -796,7 +800,7 @@ def check_union(expr, info):
# If discriminator is user-defined, ensure all values are covered
if enum_define:
- for value in enum_define['data']:
+ for value in enum_get_values(enum_define):
if value not in members.keys():
raise QAPISemError(info, "Union '%s' data missing '%s' branch"
% (name, value))
@@ -827,7 +831,7 @@ def check_alternate(expr, info):
if qtype == 'QTYPE_QSTRING':
enum_expr = enum_types.get(value)
if enum_expr:
- for v in enum_expr['data']:
+ for v in enum_get_values(enum_expr):
if v in ['on', 'off']:
conflicting.add('QTYPE_QBOOL')
if re.match(r'[-+0-9.]', v): # lazy, could be tightened
@@ -857,6 +861,12 @@ def check_enum(expr, info):
raise QAPISemError(info,
"Enum '%s' requires a string for 'prefix'" % name)
for member in members:
+ if isinstance(member, dict):
+ if not 'name' in member:
+ raise QAPISemError(info, "Dictionary member of enum '%s' must "
+ "have a 'name' key" % name)
+ check_if(member, info)
+ member = member['name']
check_name(info, "Member of enum '%s'" % name, member,
enum_member=True)
@@ -1145,12 +1155,15 @@ class QAPISchemaEnumType(QAPISchemaType):
def member_names(self):
return [v.name for v in self.values]
+ def members(self):
+ return [(v.name, v.ifcond) for v in self.values]
+
def json_type(self):
return 'string'
def visit(self, visitor):
visitor.visit_enum_type(self.name, self.info,
- self.member_names(), self.prefix, self.ifcond)
+ self.members(), self.prefix, self.ifcond)
class QAPISchemaArrayType(QAPISchemaType):
@@ -1274,9 +1287,11 @@ class QAPISchemaObjectType(QAPISchemaType):
class QAPISchemaMember(object):
role = 'member'
- def __init__(self, name):
+ def __init__(self, name, ifcond=None):
assert isinstance(name, str)
+ assert ifcond is None or isinstance(ifcond, str)
self.name = name
+ self.ifcond = ifcond
self.owner = None
def set_owner(self, name):
@@ -1554,7 +1569,9 @@ class QAPISchema(object):
qtype_values, 'QTYPE'))
def _make_enum_members(self, values):
- return [QAPISchemaMember(v) for v in values]
+ return [QAPISchemaMember(v['name'], v.get('if')) if isinstance(v, dict)
+ else QAPISchemaMember(v)
+ for v in values]
def _make_implicit_enum_type(self, name, info, values, ifcond):
# See also QAPISchemaObjectTypeMember._pretty_owner()
@@ -1950,6 +1967,8 @@ static const char *const %(c_name)s_array[] = {
''',
c_name=c_name(name))
for value in values:
+ if isinstance(value, tuple):
+ value, ifcond = value
index = c_enum_const(name, value, prefix)
ret += mcgen('''
[%(index)s] = "%(value)s",
@@ -1980,6 +1999,8 @@ typedef enum %(c_name)s {
c_name=c_name(name))
for value in enum_values:
+ if isinstance(value, tuple):
+ value, ifcond = value
ret += mcgen('''
%(c_enum)s,
''',
diff --git a/tests/qapi-schema/enum-dict-member.err
b/tests/qapi-schema/enum-dict-member.err
index 8ca146ea59..e69de29bb2 100644
--- a/tests/qapi-schema/enum-dict-member.err
+++ b/tests/qapi-schema/enum-dict-member.err
@@ -1 +0,0 @@
-tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a
string name
diff --git a/tests/qapi-schema/enum-dict-member.exit
b/tests/qapi-schema/enum-dict-member.exit
index d00491fd7e..573541ac97 100644
--- a/tests/qapi-schema/enum-dict-member.exit
+++ b/tests/qapi-schema/enum-dict-member.exit
@@ -1 +1 @@
-1
+0
diff --git a/tests/qapi-schema/enum-dict-member.json
b/tests/qapi-schema/enum-dict-member.json
index 79672e0f09..b09a83061c 100644
--- a/tests/qapi-schema/enum-dict-member.json
+++ b/tests/qapi-schema/enum-dict-member.json
@@ -1,2 +1 @@
-# we reject any enum member that is not a string
-{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
+{ 'enum': 'TestEnum', 'data': [ { 'name': 'foo' }, { 'name': 'bar' } ]}
diff --git a/tests/qapi-schema/enum-dict-member.out
b/tests/qapi-schema/enum-dict-member.out
index e69de29bb2..cf8e3cce2b 100644
--- a/tests/qapi-schema/enum-dict-member.out
+++ b/tests/qapi-schema/enum-dict-member.out
@@ -0,0 +1,4 @@
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+ prefix QTYPE
+enum TestEnum ['foo', 'bar']
+object q_empty
diff --git a/tests/qapi-schema/qapi-schema-test.json
b/tests/qapi-schema/qapi-schema-test.json
index dc2c444fc1..ad2b405d83 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -194,7 +194,8 @@
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if': 'defined(TEST_IF_STRUCT)' }
-{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
+{ 'enum': 'TestIfEnum', 'data':
+ [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
'if': 'defined(TEST_IF_ENUM)' }
{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
@@ -203,7 +204,7 @@
{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct'
},
'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
-{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
+{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum'
},
'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
diff --git a/tests/qapi-schema/qapi-schema-test.out
b/tests/qapi-schema/qapi-schema-test.out
index fc5fd25f1b..211c367632 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -60,7 +60,7 @@ alternate TestIfAlternate
command TestIfCmd q_obj_TestIfCmd-arg -> None
gen=True success_response=True boxed=False
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
-enum TestIfEnum ['foo', 'bar']
+enum TestIfEnum ['foo', ('bar', 'defined(TEST_IF_ENUM_BAR)')]
if defined(TEST_IF_ENUM)
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
@@ -197,6 +197,7 @@ object q_obj_EVENT_D-arg
member enum3: EnumOne optional=True
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 17fd975812..70054848f0 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -18,7 +18,9 @@ import sys
class QAPISchemaTestVisitor(QAPISchemaVisitor):
def visit_enum_type(self, name, info, values, prefix, ifcond):
- print 'enum %s %s' % (name, values)
+ values = ', '.join(["'%s'" % v[0] if not v[1] else str(v)
+ for v in values])
+ print 'enum %s [%s]' % (name, values)
if prefix:
print ' prefix %s' % prefix
self._print_if(ifcond)
--
2.14.1.146.gd35faa819
- Re: [Qemu-devel] [PATCH v2 03/54] qobject: add literal qobject type, (continued)
[Qemu-devel] [PATCH v2 02/54] qdict: add qdict_put_null() helper, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 37/54] qapi: 'if' to alternate variant, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 32/54] qapi: add 'if' to struct members, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 08/54] hmp: use qapi_enum_parse() in hmp_migrate_set_capability, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 21/54] qapi-introspect: modify to_qlit() to generate #if code, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 29/54] qapi: add 'if' to enum members,
Marc-André Lureau <=
[Qemu-devel] [PATCH v2 43/54] qapi2texi: add 'If:' condition to struct members, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 30/54] qapi: add #if conditions on generated enum values, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 04/54] qlit: add qobject_form_qlit(), Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 38/54] qapi: add tests for invalid alternate, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 42/54] qapi2texi: add 'If:' condition to enum values, Marc-André Lureau, 2017/08/22
[Qemu-devel] [PATCH v2 11/54] quorum: use qapi_enum_parse() in quorum_open, Marc-André Lureau, 2017/08/22