aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2018-12-13 16:37:11 +0400
committerMarkus Armbruster <armbru@redhat.com>2018-12-13 19:20:11 +0100
commit6cc32b0e14b3f91e15a9511d90b222abc1df391d (patch)
tree3b8cbbcd19be7c206ae11dd861328ce58dfd6034
parentea738b21685814dc54352858afabc2ff33ade53e (diff)
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: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-10-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
-rw-r--r--docs/devel/qapi-code-gen.txt9
-rw-r--r--scripts/qapi/common.py8
-rw-r--r--tests/Makefile.include1
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.err2
-rw-r--r--tests/qapi-schema/enum-if-invalid.err1
-rw-r--r--tests/qapi-schema/enum-if-invalid.exit1
-rw-r--r--tests/qapi-schema/enum-if-invalid.json3
-rw-r--r--tests/qapi-schema/enum-if-invalid.out0
-rw-r--r--tests/qapi-schema/qapi-schema-test.json5
-rw-r--r--tests/qapi-schema/qapi-schema-test.out2
-rw-r--r--tests/qapi-schema/test-qapi.py1
11 files changed, 27 insertions, 6 deletions
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 2c8b392b20..7ba9066eac 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -752,6 +752,15 @@ gets its generated code guarded like this:
#endif /* defined(HAVE_BAR) */
#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
compile with an arbitrary combination of conditions, since the
generators are unable to check it at this point.
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index b1cf33af21..a609ffcfee 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -871,7 +871,8 @@ def check_enum(expr, info):
for member in members:
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'],
enum_member=True)
@@ -1345,9 +1346,10 @@ class QAPISchemaObjectType(QAPISchemaType):
class QAPISchemaMember(object):
role = 'member'
- def __init__(self, name):
+ def __init__(self, name, ifcond=None):
assert isinstance(name, str)
self.name = name
+ self.ifcond = listify_cond(ifcond)
self.owner = None
def set_owner(self, name):
@@ -1656,7 +1658,7 @@ class QAPISchema(object):
qtype_values, 'QTYPE'))
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):
# See also QAPISchemaObjectTypeMember._pretty_owner()
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 2e894c1037..3c9eea27fd 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -384,6 +384,7 @@ qapi-schema += enum-bad-name.json
qapi-schema += enum-bad-prefix.json
qapi-schema += enum-clash-member.json
qapi-schema += enum-dict-member-unknown.json
+qapi-schema += enum-if-invalid.json
qapi-schema += enum-int-member.json
qapi-schema += enum-member-case.json
qapi-schema += enum-missing-data.json
diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err
index 76bd0471db..2aae618be0 100644
--- a/tests/qapi-schema/enum-dict-member-unknown.err
+++ b/tests/qapi-schema/enum-dict-member-unknown.err
@@ -1,2 +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'.
+Valid keys are 'if', 'name'.
diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err
new file mode 100644
index 0000000000..54c3cf887b
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-if-invalid.json:2: 'if' condition must be a string or a list of strings
diff --git a/tests/qapi-schema/enum-if-invalid.exit b/tests/qapi-schema/enum-if-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-if-invalid.json b/tests/qapi-schema/enum-if-invalid.json
new file mode 100644
index 0000000000..60bd0ef1d7
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.json
@@ -0,0 +1,3 @@
+# check invalid 'if' type
+{ 'enum': 'TestIfEnum', 'data':
+ [ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
diff --git a/tests/qapi-schema/enum-if-invalid.out b/tests/qapi-schema/enum-if-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.out
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 15388ae9a4..8bfaf5aedd 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -204,7 +204,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' },
@@ -219,7 +220,7 @@
{ 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' },
'if': 'defined(TEST_IF_ALT)' }
-{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
+{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
'returns': 'UserDefThree',
'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 06e80e5b04..d90d987651 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -272,6 +272,7 @@ object TestIfStruct
enum TestIfEnum
member foo
member bar
+ if ['defined(TEST_IF_ENUM_BAR)']
if ['defined(TEST_IF_ENUM)']
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
@@ -302,6 +303,7 @@ command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None
if ['defined(TEST_IF_ALT)']
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False
if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
command TestIfCmd q_obj_TestIfCmd-arg -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 641a18f06d..aadf252d9d 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -29,6 +29,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print(' prefix %s' % prefix)
for m in members:
print(' member %s' % m.name)
+ self._print_if(m.ifcond, indent=8)
self._print_if(ifcond)
def visit_object_type(self, name, info, ifcond, base, members, variants):