[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 15/54] qapi: add 'if' to top-level expressions
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v2 15/54] qapi: add 'if' to top-level expressions |
Date: |
Tue, 22 Aug 2017 15:22:16 +0200 |
Accept 'if' key in top-level elements, accepted as string or list of
string type. The following patches will modify the test visitor to
check the value is correctly saved, and generate #if/#endif code (as a
single #if/endif line or a series for a list).
Example of 'if' key:
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if':
'defined(TEST_IF_STRUCT)' }
A following patch for qapi-code-gen.txt will provide more complete
documentation for 'if' usage.
Signed-off-by: Marc-André Lureau <address@hidden>
---
scripts/qapi.py | 13 +++++++++++++
tests/test-qmp-commands.c | 6 ++++++
tests/qapi-schema/qapi-schema-test.json | 20 ++++++++++++++++++++
tests/qapi-schema/qapi-schema-test.out | 22 ++++++++++++++++++++++
4 files changed, 61 insertions(+)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 73adb90379..a94d93ada4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -639,6 +639,16 @@ def add_name(name, info, meta, implicit=False):
all_names[name] = meta
+def check_if(expr, info):
+ ifcond = expr.get('if')
+ if not ifcond or isinstance(ifcond, str):
+ return
+ if (not isinstance(ifcond, list) or
+ any([not isinstance(elt, str) for elt in ifcond])):
+ raise QAPISemError(info, "'if' condition requires a string or "
+ "a list of string")
+
+
def check_type(info, source, value, allow_array=False,
allow_dict=False, allow_optional=False,
allow_metas=[]):
@@ -865,6 +875,7 @@ def check_keys(expr_elem, meta, required, optional=[]):
expr = expr_elem['expr']
info = expr_elem['info']
name = expr[meta]
+ optional = optional + ['if'] # all top-level elem accept if
if not isinstance(name, str):
raise QAPISemError(info, "'%s' key must have a string value" % meta)
required = required + [meta]
@@ -880,6 +891,8 @@ def check_keys(expr_elem, meta, required, optional=[]):
raise QAPISemError(info,
"'%s' of %s '%s' should only use true value"
% (key, meta, name))
+ if key == 'if':
+ check_if(expr, info)
for key in required:
if key not in expr:
raise QAPISemError(info, "Key '%s' is missing from %s '%s'"
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 904c89d4d4..9b9a7ffee7 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -10,6 +10,12 @@
static QmpCommandList qmp_commands;
+/* #if defined(TEST_IF_CMD) */
+void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
+{
+}
+/* #endif */
+
void qmp_user_def_cmd(Error **errp)
{
}
diff --git a/tests/qapi-schema/qapi-schema-test.json
b/tests/qapi-schema/qapi-schema-test.json
index c72dbd8050..dc2c444fc1 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -188,3 +188,23 @@
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
'returns': '__org.qemu_x-Union1' }
+
+# test 'if' condition handling
+
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+ 'if': 'defined(TEST_IF_STRUCT)' }
+
+{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
+ 'if': 'defined(TEST_IF_ENUM)' }
+
+{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
+ 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
+
+{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct'
},
+ 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
+
+{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
+ 'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
+
+{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
+ 'if': 'defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)' }
diff --git a/tests/qapi-schema/qapi-schema-test.out
b/tests/qapi-schema/qapi-schema-test.out
index 3b1e9082d3..7fbaea19bc 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -52,6 +52,22 @@ enum QEnumTwo ['value1', 'value2']
prefix QENUM_TWO
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+alternate TestIfAlternate
+ tag type
+ case foo: int
+ case bar: TestStruct
+command TestIfCmd q_obj_TestIfCmd-arg -> None
+ gen=True success_response=True boxed=False
+enum TestIfEnum ['foo', 'bar']
+event TestIfEvent q_obj_TestIfEvent-arg
+ boxed=False
+object TestIfStruct
+ member foo: int optional=False
+object TestIfUnion
+ member type: TestIfUnionKind optional=False
+ tag type
+ case foo: q_obj_TestStruct-wrapper
+enum TestIfUnionKind ['foo']
object TestStruct
member integer: int optional=False
member boolean: bool optional=False
@@ -172,6 +188,12 @@ object q_obj_EVENT_D-arg
member b: str optional=False
member c: str optional=True
member enum3: EnumOne optional=True
+object q_obj_TestIfCmd-arg
+ member foo: TestIfStruct optional=False
+object q_obj_TestIfEvent-arg
+ member foo: TestIfStruct optional=False
+object q_obj_TestStruct-wrapper
+ member data: TestStruct optional=False
object q_obj_UserDefFlatUnion2-base
member integer: int optional=True
member string: str optional=False
--
2.14.1.146.gd35faa819
- [Qemu-devel] [PATCH v2 00/54] qapi: add #if pre-processor conditions to generated code, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 07/54] tpm: simplify driver registration & lookup, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 26/54] qapi-types: refactor variants handling, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 15/54] qapi: add 'if' to top-level expressions,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v2 36/54] qapi: add #if conditions to generated variants, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 28/54] qapi: do not define enumeration value explicitely, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 34/54] qapi: add #if conditions to generated struct members, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 20/54] qapi-introspect: modify to_qlit() to take an optional suffix, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 18/54] qapi: add 'ifcond' to visitor methods, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 39/54] qapi: add #if conditions to generated alternate variants, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 10/54] block: use qemu_enum_parse() in blkdebug_debug_breakpoint, Marc-André Lureau, 2017/08/22
- [Qemu-devel] [PATCH v2 24/54] qapi-event: add #if conditions to events, Marc-André Lureau, 2017/08/22