All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Michael Roth" <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH 09/26] qapi: add 'if' condition on struct member
Date: Thu, 27 Jul 2017 17:41:09 +0200	[thread overview]
Message-ID: <20170727154126.11339-10-marcandre.lureau@redhat.com> (raw)
In-Reply-To: <20170727154126.11339-1-marcandre.lureau@redhat.com>

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi.py                           | 18 ++++++++++++++----
 scripts/qapi-introspect.py                |  2 ++
 scripts/qapi-types.py                     |  2 ++
 scripts/qapi-visit.py                     |  2 ++
 tests/Makefile.include                    |  2 ++
 tests/qapi-schema/qapi-schema-test.json   |  9 ++++++---
 tests/qapi-schema/qapi-schema-test.out    |  4 +++-
 tests/qapi-schema/struct-if-invalid.err   |  1 +
 tests/qapi-schema/struct-if-invalid.exit  |  1 +
 tests/qapi-schema/struct-if-invalid.json  |  3 +++
 tests/qapi-schema/struct-if-invalid.out   |  0
 tests/qapi-schema/struct-member-type.err  |  0
 tests/qapi-schema/struct-member-type.exit |  1 +
 tests/qapi-schema/struct-member-type.json |  1 +
 tests/qapi-schema/struct-member-type.out  |  5 +++++
 tests/qapi-schema/test-qapi.py            |  3 ++-
 16 files changed, 45 insertions(+), 9 deletions(-)
 create mode 100644 tests/qapi-schema/struct-if-invalid.err
 create mode 100644 tests/qapi-schema/struct-if-invalid.exit
 create mode 100644 tests/qapi-schema/struct-if-invalid.json
 create mode 100644 tests/qapi-schema/struct-if-invalid.out
 create mode 100644 tests/qapi-schema/struct-member-type.err
 create mode 100644 tests/qapi-schema/struct-member-type.exit
 create mode 100644 tests/qapi-schema/struct-member-type.json
 create mode 100644 tests/qapi-schema/struct-member-type.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 93d07283e6..1eb40590fb 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -678,7 +678,13 @@ def check_type(info, source, value, allow_array=False,
         return
 
     if not allow_dict:
-        raise QAPISemError(info, "%s should be a type name" % source)
+        if isinstance(value, dict) and 'type' in value:
+            check_type(info, source, value['type'], allow_array,
+                       allow_dict, allow_optional, allow_metas)
+            check_if(value, info)
+            return
+        else:
+            raise QAPISemError(info, "%s should be a type name" % source)
 
     if not isinstance(value, OrderedDict):
         raise QAPISemError(info,
@@ -1333,8 +1339,8 @@ class QAPISchemaMember(object):
 
 
 class QAPISchemaObjectTypeMember(QAPISchemaMember):
-    def __init__(self, name, typ, optional):
-        QAPISchemaMember.__init__(self, name)
+    def __init__(self, name, typ, optional, ifcond=None):
+        QAPISchemaMember.__init__(self, name, ifcond)
         assert isinstance(typ, str)
         assert isinstance(optional, bool)
         self._type_name = typ
@@ -1611,13 +1617,17 @@ class QAPISchema(object):
 
     def _make_member(self, name, typ, info):
         optional = False
+        ifcond = None
         if name.startswith('*'):
             name = name[1:]
             optional = True
+        if isinstance(typ, dict):
+            ifcond = typ.get('if')
+            typ = typ['type']
         if isinstance(typ, list):
             assert len(typ) == 1
             typ = self._make_array_type(typ[0], info)
-        return QAPISchemaObjectTypeMember(name, typ, optional)
+        return QAPISchemaObjectTypeMember(name, typ, optional, ifcond)
 
     def _make_members(self, data, info):
         return [self._make_member(key, value, info)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index ecfb0f2752..98b320a79e 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -130,6 +130,8 @@ const QLitObject %(c_name)s = %(c_string)s;
         ret = {'name': member.name, 'type': self._use_type(member.type)}
         if member.optional:
             ret['default'] = None
+        if member.ifcond:
+            ret = (ret, member.ifcond)
         return ret
 
     def _gen_variants(self, tag_name, variants):
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index d0d2eb917c..659fb1da86 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -41,6 +41,7 @@ struct %(c_name)s {
 def gen_struct_members(members):
     ret = ''
     for memb in members:
+        ret += gen_if(memb.ifcond)
         if memb.optional:
             ret += mcgen('''
     bool has_%(c_name)s;
@@ -50,6 +51,7 @@ def gen_struct_members(members):
     %(c_type)s %(c_name)s;
 ''',
                      c_type=memb.type.c_type(), c_name=c_name(memb.name))
+        ret += gen_endif(memb.ifcond)
     return ret
 
 
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 335407d078..f400cef13c 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -53,6 +53,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
                      c_type=base.c_name())
 
     for memb in members:
+        ret += gen_if(memb.ifcond)
         if memb.optional:
             ret += mcgen('''
     if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) {
@@ -72,6 +73,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
             ret += mcgen('''
     }
 ''')
+        ret += gen_endif(memb.ifcond)
 
     if variants:
         ret += mcgen('''
diff --git a/tests/Makefile.include b/tests/Makefile.include
index cb5daf0009..816cc5c5e3 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -489,7 +489,9 @@ qapi-schema += returns-whitelist.json
 qapi-schema += struct-base-clash-deep.json
 qapi-schema += struct-base-clash.json
 qapi-schema += struct-data-invalid.json
+qapi-schema += struct-if-invalid.json
 qapi-schema += struct-member-invalid.json
+qapi-schema += struct-member-type.json
 qapi-schema += trailing-comma-list.json
 qapi-schema += trailing-comma-object.json
 qapi-schema += type-bypass-bad-gen.json
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index ad2b405d83..bb515280d2 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -191,7 +191,8 @@
 
 # test 'if' condition handling
 
-{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+{ 'struct': 'TestIfStruct', 'data':
+  { 'foo': 'int', 'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} },
   'if': 'defined(TEST_IF_STRUCT)' }
 
 { 'enum': 'TestIfEnum', 'data':
@@ -204,8 +205,10 @@
 { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
   'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
 
-{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
+{ 'command': 'TestIfCmd', 'data':
+  { 'foo': 'TestIfStruct', 'bar': { 'type': 'TestIfEnum', 'if': 'TEST_IF_CMD_BAR' } },
   'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
 
-{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
+{ 'event': 'TestIfEvent', 'data':
+  { 'foo': 'TestIfStruct', 'bar': { 'type': 'TestIfEnum', 'if': 'TEST_IF_EVT_BAR' } },
   '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 211c367632..b17c32a45f 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -67,6 +67,7 @@ event TestIfEvent q_obj_TestIfEvent-arg
     if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
 object TestIfStruct
     member foo: int optional=False
+    member bar: int optional=False if=defined(TEST_IF_STRUCT_BAR)
     if defined(TEST_IF_STRUCT)
 object TestIfUnion
     member type: TestIfUnionKind optional=False
@@ -197,10 +198,11 @@ 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
+    member bar: TestIfEnum optional=False if=TEST_IF_CMD_BAR
     if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
 object q_obj_TestIfEvent-arg
     member foo: TestIfStruct optional=False
+    member bar: TestIfEnum optional=False if=TEST_IF_EVT_BAR
     if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
 object q_obj_TestStruct-wrapper
     member data: TestStruct optional=False
diff --git a/tests/qapi-schema/struct-if-invalid.err b/tests/qapi-schema/struct-if-invalid.err
new file mode 100644
index 0000000000..42245262a9
--- /dev/null
+++ b/tests/qapi-schema/struct-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-if-invalid.json:2: Member 'bar' of 'data' for struct 'TestIfStruct' should be a type name
diff --git a/tests/qapi-schema/struct-if-invalid.exit b/tests/qapi-schema/struct-if-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/struct-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-if-invalid.json b/tests/qapi-schema/struct-if-invalid.json
new file mode 100644
index 0000000000..466cdb61e1
--- /dev/null
+++ b/tests/qapi-schema/struct-if-invalid.json
@@ -0,0 +1,3 @@
+# check missing 'type'
+{ 'struct': 'TestIfStruct', 'data':
+  { 'foo': 'int', 'bar': { 'if': 'defined(TEST_IF_STRUCT_BAR)' } } }
diff --git a/tests/qapi-schema/struct-if-invalid.out b/tests/qapi-schema/struct-if-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/struct-member-type.err b/tests/qapi-schema/struct-member-type.err
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/struct-member-type.exit b/tests/qapi-schema/struct-member-type.exit
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/tests/qapi-schema/struct-member-type.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/struct-member-type.json b/tests/qapi-schema/struct-member-type.json
new file mode 100644
index 0000000000..07de38fa4a
--- /dev/null
+++ b/tests/qapi-schema/struct-member-type.json
@@ -0,0 +1 @@
+{ 'struct': 'foo', 'data': { 'a': { 'type': 'str' } } }
diff --git a/tests/qapi-schema/struct-member-type.out b/tests/qapi-schema/struct-member-type.out
new file mode 100644
index 0000000000..2ea68909a9
--- /dev/null
+++ b/tests/qapi-schema/struct-member-type.out
@@ -0,0 +1,5 @@
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+    prefix QTYPE
+object foo
+    member a: str optional=False
+object q_empty
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 70054848f0..5d2f67a1d3 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -31,7 +31,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
             print '    base %s' % base.name
         for m in members:
             print '    member %s: %s optional=%s' % \
-                (m.name, m.type.name, m.optional)
+                (m.name, m.type.name, m.optional) + \
+                (' if=%s' % m.ifcond if m.ifcond else '')
         self._print_variants(variants)
         self._print_if(ifcond)
 
-- 
2.14.0.rc0.1.g40ca67566

  parent reply	other threads:[~2017-07-27 15:51 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-27 15:41 [Qemu-devel] [PATCH 00/26] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 01/26] qapi: fix type_seen key error Marc-André Lureau
2017-08-15 14:40   ` Markus Armbruster
2017-08-17 23:17     ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 02/26] qobject: replace dump_qobject() by qobject_to_string() Marc-André Lureau
2017-08-16  9:02   ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 03/26] qboject: add literal qobject type Marc-André Lureau
2017-08-16  8:59   ` Markus Armbruster
2017-08-22 11:16     ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 04/26] qapi: generate a literal qobject for introspection Marc-André Lureau
2017-08-16 10:21   ` Markus Armbruster
2017-08-22 11:17     ` Marc-André Lureau
2017-08-17 11:48   ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 05/26] visitor: pass size of strings array to enum visitor Marc-André Lureau
2017-08-16 12:54   ` Markus Armbruster
2017-08-22 11:17     ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 06/26] qapi2texi: minor python code simplification Marc-André Lureau
2017-08-16 12:55   ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 07/26] qapi: add 'if' condition on top-level schema elements Marc-André Lureau
2017-08-16 15:43   ` Markus Armbruster
2017-08-17  5:50     ` Markus Armbruster
2017-08-22 11:17     ` Marc-André Lureau
2017-08-22 16:52       ` Markus Armbruster
2017-08-23 12:45         ` Eduardo Habkost
2017-08-17 11:51   ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 08/26] qapi: add 'if' condition on enum member values Marc-André Lureau
2017-07-27 15:41 ` Marc-André Lureau [this message]
2017-07-27 15:41 ` [Qemu-devel] [PATCH 10/26] qapi: add 'if' condition on union variant Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 11/26] qapi: add 'if' condition on alternate variant Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 12/26] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 13/26] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 14/26] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 15/26] qapi2texi: add condition to variants Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 16/26] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
2017-07-28 19:00   ` Dr. David Alan Gilbert
2017-08-17  6:32     ` Markus Armbruster
2017-08-17  9:33       ` Dr. David Alan Gilbert
2017-08-17  7:04   ` Markus Armbruster
2017-08-17  8:56     ` Markus Armbruster
2017-08-23 15:07       ` Gerd Hoffmann
2017-08-23 17:35         ` Eduardo Habkost
2017-08-23 15:09     ` Gerd Hoffmann
2017-08-29 10:42     ` Daniel P. Berrange
2017-08-29 10:46       ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 17/26] qapi: add conditions to SPICE " Marc-André Lureau
2017-08-17  8:10   ` Markus Armbruster
2017-08-17  8:43     ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 18/26] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
2017-08-17  9:16   ` Markus Armbruster
2017-08-22 11:18     ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 19/26] build-sys: move qapi variables in qapi.mak Marc-André Lureau
2017-08-17  9:19   ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 20/26] tests/qmp-test: add query-qmp-schema test Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 21/26] build-sys: make qemu qapi objects per-target Marc-André Lureau
2017-08-17 11:44   ` Markus Armbruster
2017-08-22 11:18     ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 22/26] qapi: make rtc-reset-reinjection depend on TARGET_I386 Marc-André Lureau
2017-08-17 11:57   ` Markus Armbruster
2017-08-22 11:18     ` Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 23/26] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
2017-08-17 12:13   ` Markus Armbruster
2017-07-27 15:41 ` [Qemu-devel] [PATCH 24/26] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 25/26] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
2017-07-27 15:41 ` [Qemu-devel] [PATCH 26/26] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
2017-08-17 12:30   ` Markus Armbruster
2017-08-17 12:43     ` Marc-André Lureau
2017-08-17 13:55 ` [Qemu-devel] [PATCH 00/26] qapi: add #if pre-processor conditions to generated code Markus Armbruster
2017-08-22 11:22   ` Marc-André Lureau
2017-08-22 16:58     ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170727154126.11339-10-marcandre.lureau@redhat.com \
    --to=marcandre.lureau@redhat.com \
    --cc=armbru@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.