qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, mdroth@linux.vnet.ibm.com, armbru@redhat.com,
	lcapitulino@redhat.com, Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH V7 04/11] qapi script: check correctness of discriminator values in union
Date: Thu, 20 Feb 2014 00:54:48 -0500	[thread overview]
Message-ID: <1392875695-15627-5-git-send-email-xiawenc@linux.vnet.ibm.com> (raw)
In-Reply-To: <1392875695-15627-1-git-send-email-xiawenc@linux.vnet.ibm.com>

It will check whether base is set, whether discriminator is found
in base, whether the values specified are written correctly, and
whether all enum values are covered, when discriminator is a
pre-defined enum type. Exprs now have addtional info inside qapi.py
to form better error message.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 scripts/qapi.py |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index c504eb4..8af8cfd 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -50,6 +50,15 @@ class QAPISchemaError(Exception):
     def __str__(self):
         return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
 
+class QAPIExprError(Exception):
+    def __init__(self, expr_elem, msg):
+        self.fp = expr_elem['fp']
+        self.line = expr_elem['line']
+        self.msg = msg
+
+    def __str__(self):
+        return "%s:%s: %s" % (self.fp.name, self.line, self.msg)
+
 class QAPISchema:
 
     def __init__(self, fp):
@@ -64,7 +73,11 @@ class QAPISchema:
         self.accept()
 
         while self.tok != None:
-            self.exprs.append(self.get_expr(False))
+            line = self.line
+            expr_elem = {'expr': self.get_expr(False),
+                         'fp': fp,
+                         'line': line}
+            self.exprs.append(expr_elem)
 
     def accept(self):
         while True:
@@ -162,6 +175,66 @@ class QAPISchema:
             raise QAPISchemaError(self, 'Expected "{", "[" or string')
         return expr
 
+# This function can be used to check whether "base" is valid
+def find_base_fields(base):
+    base_struct_define = find_struct(base)
+    if not base_struct_define:
+        return None
+    return base_struct_define.get('data')
+
+# Return the discriminator enum define, if discriminator is specified in
+# @expr_elem["expr"] and it is a pre-defined enum type
+def discriminator_find_enum_define(expr_elem):
+    expr = expr_elem['expr']
+    discriminator = expr.get('discriminator')
+    base = expr.get('base')
+
+    # Only support discriminator when base present
+    if not (discriminator and base):
+        return None
+
+    base_fields = find_base_fields(base)
+
+    if not base_fields:
+        raise QAPIExprError(expr_elem,
+                            "Base '%s' is not a valid type"
+                            % base)
+
+    discriminator_type = base_fields.get(discriminator)
+
+    if not discriminator_type:
+        raise QAPIExprError(expr_elem,
+                            "Discriminator '%s' not found in schema"
+                            % discriminator)
+
+    return find_enum(discriminator_type)
+
+def check_union(expr_elem):
+    # If discriminator is specified and it is a pre-defined enum in schema,
+    # check its correctness
+    enum_define = discriminator_find_enum_define(expr_elem)
+    name = expr_elem['expr']['union']
+    members = expr_elem['expr']['data']
+    if enum_define:
+        for key in members:
+            if not key in enum_define['enum_values']:
+                raise QAPIExprError(expr_elem,
+                                    "Discriminator value '%s' is not found in "
+                                    "enum '%s'" %
+                                    (key, enum_define["enum_name"]))
+        for key in enum_define['enum_values']:
+            if not key in members:
+                raise QAPIExprError(expr_elem,
+                                    "Enum value '%s' is not covered by a "
+                                    "branch of union '%s'" %
+                                    (key, name))
+
+def check_exprs(schema):
+    for expr_elem in schema.exprs:
+        expr = expr_elem['expr']
+        if expr.has_key('union'):
+            check_union(expr_elem)
+
 def parse_schema(fp):
     try:
         schema = QAPISchema(fp)
@@ -171,7 +244,8 @@ def parse_schema(fp):
 
     exprs = []
 
-    for expr in schema.exprs:
+    for expr_elem in schema.exprs:
+        expr = expr_elem['expr']
         if expr.has_key('enum'):
             add_enum(expr['enum'], expr['data'])
         elif expr.has_key('union'):
@@ -181,6 +255,12 @@ def parse_schema(fp):
             add_struct(expr)
         exprs.append(expr)
 
+    try:
+        check_exprs(schema)
+    except QAPIExprError, e:
+        print >>sys.stderr, e
+        exit(1)
+
     return exprs
 
 def parse_args(typeinfo):
-- 
1.7.1

  parent reply	other threads:[~2014-02-20  5:55 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-20  5:54 [Qemu-devel] [PATCH V7 00/11] qapi script: support enum as discriminator and better enum name Wenchao Xia
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 01/11] qapi script: remember enum values Wenchao Xia
2014-02-20 12:05   ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 02/11] qapi script: add check for duplicated key Wenchao Xia
2014-02-20 12:05   ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 03/11] qapi-script: remember line number in schema parsing Wenchao Xia
2014-02-20 12:22   ` Markus Armbruster
2014-02-21  0:10     ` Wenchao Xia
2014-02-21 13:04       ` Markus Armbruster
2014-02-20  5:54 ` Wenchao Xia [this message]
2014-02-20 14:43   ` [Qemu-devel] [PATCH V7 04/11] qapi script: check correctness of discriminator values in union Markus Armbruster
2014-02-20 15:26     ` Eric Blake
2014-02-21  8:21       ` Markus Armbruster
2014-02-21 13:49         ` Eric Blake
2014-02-21 14:08           ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 05/11] qapi script: code move for generate_enum_name() Wenchao Xia
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 06/11] qapi script: use same function to generate enum string Wenchao Xia
2014-02-20 15:20   ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 07/11] qapi script: support pre-defined enum type as discriminator in union Wenchao Xia
2014-02-20 16:38   ` Markus Armbruster
2014-02-21  0:17     ` Wenchao Xia
2014-02-21  8:13       ` Markus Armbruster
2014-02-21 13:56         ` Eric Blake
2014-02-21 14:39           ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 08/11] qapi: convert BlockdevOptions to use enum discriminator Wenchao Xia
2014-02-20 17:59   ` Eric Blake
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 09/11] qapi script: do not allow string discriminator Wenchao Xia
2014-02-20 16:50   ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 10/11] qapi script: do not add "_" for every capitalized char in enum Wenchao Xia
2014-02-20 16:54   ` Markus Armbruster
2014-02-20 17:53     ` Eric Blake
2014-02-21  8:21       ` Markus Armbruster
2014-02-20  5:54 ` [Qemu-devel] [PATCH V7 11/11] qapi test: add error path test for union Wenchao Xia

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=1392875695-15627-5-git-send-email-xiawenc@linux.vnet.ibm.com \
    --to=xiawenc@linux.vnet.ibm.com \
    --cc=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@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).