From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: armbru@redhat.com, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH v13 10/14] qapi: Track enum values by QAPISchemaMember, not string
Date: Fri, 20 Nov 2015 10:24:56 -0700 [thread overview]
Message-ID: <1448040300-968-11-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1448040300-968-1-git-send-email-eblake@redhat.com>
Rather than using just an array of strings, make enum.values be
an array of the new QAPISchemaMember type. Creating an enum
requires wrapping strings, and visiting an enum requires getting
at the name of each value. But using this type means we can
share the existing code for C name clash detection (although the
code is not yet active until a later commit removes the earlier
ad hoc parser checks). The ._pretty_owner() method needs to
learn about one more implicit type name: the generated enum
associated with a simple union.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
v13: new patch
---
scripts/qapi.py | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2748464..d1239c2 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -901,13 +901,17 @@ class QAPISchemaEnumType(QAPISchemaType):
def __init__(self, name, info, values, prefix):
QAPISchemaType.__init__(self, name, info)
for v in values:
- assert isinstance(v, str)
+ assert isinstance(v, QAPISchemaMember)
+ v.set_owner(name)
assert prefix is None or isinstance(prefix, str)
self.values = values
self.prefix = prefix
def check(self, schema):
- assert len(set(self.values)) == len(self.values)
+ # Check for collisions on the generated C enum values
+ seen = {}
+ for v in self.values:
+ v.check_clash(self.info, seen)
def is_implicit(self):
# See QAPISchema._make_implicit_enum_type()
@@ -917,15 +921,18 @@ class QAPISchemaEnumType(QAPISchemaType):
return c_name(self.name)
def c_null(self):
- return c_enum_const(self.name, (self.values + ['_MAX'])[0],
- self.prefix)
+ if self.values:
+ value = self.values[0].name
+ else:
+ value = '_MAX'
+ return c_enum_const(self.name, value, self.prefix)
def json_type(self):
return 'string'
def visit(self, visitor):
visitor.visit_enum_type(self.name, self.info,
- self.values, self.prefix)
+ [v.name for v in self.values], self.prefix)
class QAPISchemaArrayType(QAPISchemaType):
@@ -1049,6 +1056,8 @@ class QAPISchemaMember(object):
else:
assert owner.endswith('-wrapper')
return '(branch of %s)' % owner[:-8]
+ if owner.endswith('Kind'):
+ return '(branch of %s)' % owner[:-4]
return '(%s of %s)' % (self.role, owner)
def describe(self):
@@ -1094,12 +1103,13 @@ class QAPISchemaObjectTypeVariants(object):
self.tag_member = seen[c_name(self.tag_name)]
assert self.tag_name == self.tag_member.name
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
+ tag_values = [v.name for v in self.tag_member.type.values]
for v in self.variants:
v.check(schema)
# Union names must match enum values; alternate names are
# checked separately. Use 'seen' to tell the two apart.
if seen:
- assert v.name in self.tag_member.type.values
+ assert v.name in tag_values
assert isinstance(v.type, QAPISchemaObjectType)
v.type.check(schema)
@@ -1257,15 +1267,16 @@ class QAPISchema(object):
self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None,
[], None)
self._def_entity(self.the_empty_object_type)
- self._def_entity(QAPISchemaEnumType('QType', None,
- ['none', 'qnull', 'qint',
- 'qstring', 'qdict', 'qlist',
- 'qfloat', 'qbool'],
+ qtype_values = [QAPISchemaMember(name) for name in
+ ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist',
+ 'qfloat', 'qbool']]
+ self._def_entity(QAPISchemaEnumType('QType', None, qtype_values,
'QTYPE'))
def _make_implicit_enum_type(self, name, info, values):
name = name + 'Kind' # Use namespace reserved by add_name()
- self._def_entity(QAPISchemaEnumType(name, info, values, None))
+ self._def_entity(QAPISchemaEnumType(
+ name, info, [QAPISchemaMember(v) for v in values], None))
return name
def _make_array_type(self, element_type, info):
@@ -1288,7 +1299,8 @@ class QAPISchema(object):
name = expr['enum']
data = expr['data']
prefix = expr.get('prefix')
- self._def_entity(QAPISchemaEnumType(name, info, data, prefix))
+ self._def_entity(QAPISchemaEnumType(
+ name, info, [QAPISchemaMember(v) for v in data], prefix))
def _make_member(self, name, typ, info):
optional = False
--
2.4.3
next prev parent reply other threads:[~2015-11-20 17:25 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-20 17:24 [Qemu-devel] [PATCH v13 00/14] qapi member collision (post-introspection cleanups, subset D) Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 01/14] qobject: Simplify QObject Eric Blake
2015-11-26 14:27 ` Markus Armbruster
2015-11-26 15:06 ` Markus Armbruster
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 02/14] qobject: Rename qtype_code to QType Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 03/14] qapi: Convert QType into QAPI built-in enum type Eric Blake
2015-11-26 14:51 ` Markus Armbruster
2015-11-27 5:09 ` Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 04/14] qapi: Simplify visiting of alternate types Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 05/14] qapi: Inline _make_implicit_tag() Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 06/14] qapi: Fix alternates that accept 'number' but not 'int' Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 07/14] qapi: Simplify visits of optional fields Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 08/14] qapi: Shorter " Eric Blake
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 09/14] qapi: Prepare new QAPISchemaMember base class Eric Blake
2015-11-20 17:24 ` Eric Blake [this message]
2015-11-26 16:29 ` [Qemu-devel] [PATCH v13 10/14] qapi: Track enum values by QAPISchemaMember, not string Markus Armbruster
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 11/14] qapi: Populate info['name'] for each entity Eric Blake
2015-11-26 16:46 ` Markus Armbruster
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 12/14] qapi: Enforce (or whitelist) case conventions on qapi members Eric Blake
2015-11-27 9:03 ` Markus Armbruster
2015-12-01 22:35 ` Eric Blake
2015-12-02 8:20 ` Markus Armbruster
2015-12-02 15:47 ` Eric Blake
2015-11-27 9:42 ` Markus Armbruster
2015-12-01 16:12 ` Eric Blake
2015-12-02 10:55 ` Markus Armbruster
2015-11-20 17:24 ` [Qemu-devel] [PATCH v13 13/14] qapi: Move duplicate collision checks to schema check() Eric Blake
2015-11-20 17:25 ` [Qemu-devel] [PATCH v13 14/14] qapi: Detect base class loops Eric Blake
2015-11-27 9:56 ` [Qemu-devel] [PATCH v13 00/14] qapi member collision (post-introspection cleanups, subset D) Markus Armbruster
2015-12-01 16:28 ` Eric Blake
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=1448040300-968-11-git-send-email-eblake@redhat.com \
--to=eblake@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 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).