提交 6cc32b0e 编写于 作者: M Marc-André Lureau 提交者: Markus Armbruster

qapi: add 'if' to enum members

QAPISchemaMember gains .ifcond for enum members: inherited classes,
such as QAPISchemaObjectTypeMember, will thus have an ifcond member
after this (those different types will also use the .ifcond to store
the condition and generate conditional code in the following patches).

The generated code remains unconditional for now. Later patches
generate the conditionals.
Signed-off-by: NMarc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: NMarkus Armbruster <armbru@redhat.com>
Message-Id: <20181213123724.4866-10-marcandre.lureau@redhat.com>
Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
上级 ea738b21
...@@ -752,6 +752,15 @@ gets its generated code guarded like this: ...@@ -752,6 +752,15 @@ gets its generated code guarded like this:
#endif /* defined(HAVE_BAR) */ #endif /* defined(HAVE_BAR) */
#endif /* defined(CONFIG_FOO) */ #endif /* defined(CONFIG_FOO) */
An enum value can be replaced by a dictionary with a 'name' and a 'if'
key.
Example: a conditional 'bar' enum member.
{ 'enum': 'IfEnum', 'data':
[ 'foo',
{ 'name' : 'bar', 'if': 'defined(IFCOND)' } ] }
Please note that you are responsible to ensure that the C code will Please note that you are responsible to ensure that the C code will
compile with an arbitrary combination of conditions, since the compile with an arbitrary combination of conditions, since the
generators are unable to check it at this point. generators are unable to check it at this point.
......
...@@ -871,7 +871,8 @@ def check_enum(expr, info): ...@@ -871,7 +871,8 @@ def check_enum(expr, info):
for member in members: for member in members:
source = "dictionary member of enum '%s'" % name source = "dictionary member of enum '%s'" % name
check_known_keys(info, source, member, ['name'], []) check_known_keys(info, source, member, ['name'], ['if'])
check_if(member, info)
check_name(info, "Member of enum '%s'" % name, member['name'], check_name(info, "Member of enum '%s'" % name, member['name'],
enum_member=True) enum_member=True)
...@@ -1345,9 +1346,10 @@ class QAPISchemaObjectType(QAPISchemaType): ...@@ -1345,9 +1346,10 @@ class QAPISchemaObjectType(QAPISchemaType):
class QAPISchemaMember(object): class QAPISchemaMember(object):
role = 'member' role = 'member'
def __init__(self, name): def __init__(self, name, ifcond=None):
assert isinstance(name, str) assert isinstance(name, str)
self.name = name self.name = name
self.ifcond = listify_cond(ifcond)
self.owner = None self.owner = None
def set_owner(self, name): def set_owner(self, name):
...@@ -1656,7 +1658,7 @@ class QAPISchema(object): ...@@ -1656,7 +1658,7 @@ class QAPISchema(object):
qtype_values, 'QTYPE')) qtype_values, 'QTYPE'))
def _make_enum_members(self, values): def _make_enum_members(self, values):
return [QAPISchemaMember(v['name']) for v in values] return [QAPISchemaMember(v['name'], v.get('if')) 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()
......
...@@ -384,6 +384,7 @@ qapi-schema += enum-bad-name.json ...@@ -384,6 +384,7 @@ 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-unknown.json qapi-schema += enum-dict-member-unknown.json
qapi-schema += enum-if-invalid.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
......
tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum' tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum'
Valid keys are 'name'. Valid keys are 'if', 'name'.
tests/qapi-schema/enum-if-invalid.json:2: 'if' condition must be a string or a list of strings
# check invalid 'if' type
{ 'enum': 'TestIfEnum', 'data':
[ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
...@@ -204,7 +204,8 @@ ...@@ -204,7 +204,8 @@
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' }, { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if': 'defined(TEST_IF_STRUCT)' } '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)' } 'if': 'defined(TEST_IF_ENUM)' }
{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' }, { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
...@@ -219,7 +220,7 @@ ...@@ -219,7 +220,7 @@
{ 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' }, { 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' },
'if': 'defined(TEST_IF_ALT)' } 'if': 'defined(TEST_IF_ALT)' }
{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' }, { 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
'returns': 'UserDefThree', 'returns': 'UserDefThree',
'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } 'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] }
......
...@@ -272,6 +272,7 @@ object TestIfStruct ...@@ -272,6 +272,7 @@ object TestIfStruct
enum TestIfEnum enum TestIfEnum
member foo member foo
member bar member bar
if ['defined(TEST_IF_ENUM_BAR)']
if ['defined(TEST_IF_ENUM)'] if ['defined(TEST_IF_ENUM)']
object q_obj_TestStruct-wrapper object q_obj_TestStruct-wrapper
member data: TestStruct optional=False member data: TestStruct optional=False
...@@ -302,6 +303,7 @@ command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None ...@@ -302,6 +303,7 @@ command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None
if ['defined(TEST_IF_ALT)'] if ['defined(TEST_IF_ALT)']
object q_obj_TestIfCmd-arg object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False
if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
command TestIfCmd q_obj_TestIfCmd-arg -> UserDefThree command TestIfCmd q_obj_TestIfCmd-arg -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False gen=True success_response=True boxed=False oob=False preconfig=False
......
...@@ -29,6 +29,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): ...@@ -29,6 +29,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print(' prefix %s' % prefix) print(' prefix %s' % prefix)
for m in members: for m in members:
print(' member %s' % m.name) print(' member %s' % m.name)
self._print_if(m.ifcond, indent=8)
self._print_if(ifcond) self._print_if(ifcond)
def visit_object_type(self, name, info, ifcond, base, members, variants): def visit_object_type(self, name, info, ifcond, base, members, variants):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册