qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
To: qemu-devel@nongnu.org
Cc: eblake@redhat.com, armbru@redhat.com, mdroth@linux.vnet.ibm.com,
	Anton Nefedov <anton.nefedov@virtuozzo.com>
Subject: [Qemu-devel] [PATCH 1/2] qapi: allow flat unions with empty branches
Date: Fri, 11 May 2018 12:05:33 +0300	[thread overview]
Message-ID: <1526029534-35771-2-git-send-email-anton.nefedov@virtuozzo.com> (raw)
In-Reply-To: <1526029534-35771-1-git-send-email-anton.nefedov@virtuozzo.com>

The patch makes possible to avoid introducing dummy empty types
for the flat union branches that have no data.

Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
---
 scripts/qapi/common.py         | 18 ++++++++++++------
 scripts/qapi/doc.py            |  2 +-
 scripts/qapi/types.py          |  2 +-
 scripts/qapi/visit.py          | 12 +++++++-----
 tests/qapi-schema/test-qapi.py |  2 +-
 5 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index a032cec..ec5cf28 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -721,6 +721,7 @@ def check_union(expr, info):
     name = expr['union']
     base = expr.get('base')
     discriminator = expr.get('discriminator')
+    partial = expr.get('data-partial', False)
     members = expr['data']
 
     # Two types of unions, determined by discriminator.
@@ -783,7 +784,7 @@ def check_union(expr, info):
                                    % (key, enum_define['enum']))
 
     # If discriminator is user-defined, ensure all values are covered
-    if enum_define:
+    if enum_define and not partial:
         for value in enum_define['data']:
             if value not in members.keys():
                 raise QAPISemError(info, "Union '%s' data missing '%s' branch"
@@ -909,7 +910,7 @@ def check_exprs(exprs):
         elif 'union' in expr:
             meta = 'union'
             check_keys(expr_elem, 'union', ['data'],
-                       ['base', 'discriminator'])
+                       ['base', 'discriminator', 'data-partial'])
             union_types[expr[meta]] = expr
         elif 'alternate' in expr:
             meta = 'alternate'
@@ -1035,7 +1036,7 @@ class QAPISchemaVisitor(object):
     def visit_array_type(self, name, info, element_type):
         pass
 
-    def visit_object_type(self, name, info, base, members, variants):
+    def visit_object_type(self, name, info, base, members, variants, partial):
         pass
 
     def visit_object_type_flat(self, name, info, members, variants):
@@ -1192,7 +1193,8 @@ class QAPISchemaArrayType(QAPISchemaType):
 
 
 class QAPISchemaObjectType(QAPISchemaType):
-    def __init__(self, name, info, doc, base, local_members, variants):
+    def __init__(self, name, info, doc, base, local_members, variants,
+                 partial = False):
         # struct has local_members, optional base, and no variants
         # flat union has base, variants, and no local_members
         # simple union has local_members, variants, and no base
@@ -1209,6 +1211,7 @@ class QAPISchemaObjectType(QAPISchemaType):
         self.local_members = local_members
         self.variants = variants
         self.members = None
+        self.partial = partial
 
     def check(self, schema):
         if self.members is False:               # check for cycles
@@ -1269,7 +1272,8 @@ class QAPISchemaObjectType(QAPISchemaType):
 
     def visit(self, visitor):
         visitor.visit_object_type(self.name, self.info,
-                                  self.base, self.local_members, self.variants)
+                                  self.base, self.local_members, self.variants,
+                                  self.partial)
         visitor.visit_object_type_flat(self.name, self.info,
                                        self.members, self.variants)
 
@@ -1636,6 +1640,7 @@ class QAPISchema(object):
         name = expr['union']
         data = expr['data']
         base = expr.get('base')
+        partial = expr.get('data-partial', False)
         tag_name = expr.get('discriminator')
         tag_member = None
         if isinstance(base, dict):
@@ -1656,7 +1661,8 @@ class QAPISchema(object):
             QAPISchemaObjectType(name, info, doc, base, members,
                                  QAPISchemaObjectTypeVariants(tag_name,
                                                               tag_member,
-                                                              variants)))
+                                                              variants),
+                                 partial))
 
     def _def_alternate_type(self, expr, info, doc):
         name = expr['alternate']
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 9b312b2..40dffc4 100644
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -211,7 +211,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
                                body=texi_entity(doc, 'Values',
                                                 member_func=texi_enum_value)))
 
-    def visit_object_type(self, name, info, base, members, variants):
+    def visit_object_type(self, name, info, base, members, variants, partial):
         doc = self.cur_doc
         if base and base.is_implicit():
             base = None
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 64d9c0f..e805509 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -215,7 +215,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
         self._genh.add(gen_array(name, element_type))
         self._gen_type_cleanup(name)
 
-    def visit_object_type(self, name, info, base, members, variants):
+    def visit_object_type(self, name, info, base, members, variants, partial):
         # Nothing to do for the special empty builtin
         if name == 'q_empty':
             return
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 5d72d89..3ee64bb 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -34,7 +34,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
                  c_name=c_name(name))
 
 
-def gen_visit_object_members(name, base, members, variants):
+def gen_visit_object_members(name, base, members, variants, partial):
     ret = mcgen('''
 
 void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
@@ -93,9 +93,10 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
 
         ret += mcgen('''
     default:
-        abort();
+        %(action)s
     }
-''')
+''',
+                     action="break;" if partial else "abort();")
 
     # 'goto out' produced for base, for each member, and if variants were
     # present
@@ -309,12 +310,13 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
         self._genh.add(gen_visit_decl(name))
         self._genc.add(gen_visit_list(name, element_type))
 
-    def visit_object_type(self, name, info, base, members, variants):
+    def visit_object_type(self, name, info, base, members, variants, partial):
         # Nothing to do for the special empty builtin
         if name == 'q_empty':
             return
         self._genh.add(gen_visit_members_decl(name))
-        self._genc.add(gen_visit_object_members(name, base, members, variants))
+        self._genc.add(gen_visit_object_members(name, base, members, variants,
+                                                partial))
         # TODO Worth changing the visitor signature, so we could
         # directly use rather than repeat type.is_implicit()?
         if not name.startswith('q_'):
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index c1a144b..95cd575 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -28,7 +28,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
         if prefix:
             print('    prefix %s' % prefix)
 
-    def visit_object_type(self, name, info, base, members, variants):
+    def visit_object_type(self, name, info, base, members, variants, partial):
         print('object %s' % name)
         if base:
             print('    base %s' % base.name)
-- 
2.7.4

  reply	other threads:[~2018-05-11  9:06 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-11  9:05 [Qemu-devel] [PATCH 0/2] qapi: allow flat unions with empty branches Anton Nefedov
2018-05-11  9:05 ` Anton Nefedov [this message]
2018-05-14 18:08   ` [Qemu-devel] [PATCH 1/2] " Markus Armbruster
2018-05-14 19:34     ` Eric Blake
2018-05-15  7:01       ` Markus Armbruster
2018-05-15 15:20         ` Eric Blake
2018-05-15 17:40           ` Markus Armbruster
2018-05-16 15:05             ` Anton Nefedov
2018-05-17  8:05               ` Markus Armbruster
2018-05-17 13:21                 ` Eric Blake
2018-05-18  6:45                   ` Markus Armbruster
2018-05-18  8:16                     ` Anton Nefedov
2018-05-11  9:05 ` [Qemu-devel] [PATCH 2/2] qapi: avoid empty CpuInfoOther type Anton Nefedov

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=1526029534-35771-2-git-send-email-anton.nefedov@virtuozzo.com \
    --to=anton.nefedov@virtuozzo.com \
    --cc=armbru@redhat.com \
    --cc=eblake@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).