[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v7 07/14] qapi: Move union tag quirks into subcl
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v7 07/14] qapi: Move union tag quirks into subclass |
Date: |
Thu, 08 Oct 2015 14:25:48 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) |
Eric Blake <address@hidden> writes:
> Right now, simple unions have a quirk of using 'kind' in the C
> struct to match the QMP wire name 'type'. This has resulted in
> messy clients each doing special cases. While we plan to
> eventually rename things to match, it is better in the meantime
> to consolidate the quirks into a special subclass, by adding a
> new member.c_name() function. This will also make it easier
> for reworking how alternate types are laid out in a future
> patch. Use the new c_name() function where possible.
>
> No change to generated code.
>
> Signed-off-by: Eric Blake <address@hidden>
>
> ---
> v7: new patch, but borrows idea of subclass from v6 10/12, as
> well as c_name() from 7/12
> ---
> scripts/qapi-commands.py | 8 ++++----
> scripts/qapi-types.py | 12 +++++-------
> scripts/qapi-visit.py | 17 +++++------------
> scripts/qapi.py | 15 +++++++++++++--
> 4 files changed, 27 insertions(+), 25 deletions(-)
My immediate reaction to the subclass idea was "instead of encapsulating
the flaw more nicely, why not fix it?" So gave that a try, see my other
reply.
That said, the diffstat shows the subclass idea doesn't take much code.
May make sense if we feel we shouldn't fix the flaw now.
> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
> index 43a893b..ff52ca9 100644
> --- a/scripts/qapi-commands.py
> +++ b/scripts/qapi-commands.py
> @@ -32,8 +32,8 @@ def gen_call(name, arg_type, ret_type):
> if arg_type:
> for memb in arg_type.members:
> if memb.optional:
> - argstr += 'has_%s, ' % c_name(memb.name)
> - argstr += '%s, ' % c_name(memb.name)
> + argstr += 'has_%s, ' % memb.c_name()
> + argstr += '%s, ' % memb.c_name()
>
> lhs = ''
> if ret_type:
Trap for the unwary: most of the time, c_name(FOO) is just fine. Except
when FOO is T.name, where T is a simple union's implicit tag member.
> @@ -77,11 +77,11 @@ def gen_marshal_vars(arg_type, ret_type):
> ret += mcgen('''
> bool has_%(c_name)s = false;
> ''',
> - c_name=c_name(memb.name))
> + c_name=memb.c_name())
> ret += mcgen('''
> %(c_type)s %(c_name)s = %(c_null)s;
> ''',
> - c_name=c_name(memb.name),
> + c_name=memb.c_name(),
> c_type=memb.type.c_type(),
> c_null=memb.type.c_null())
> ret += '\n'
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 227ea5c..34ea318 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -136,9 +136,10 @@ struct %(c_name)s {
> ''')
> else:
> ret += mcgen('''
> - %(c_type)s kind;
> + %(c_type)s %(c_name)s;
> ''',
> - c_type=c_name(variants.tag_member.type.name))
> + c_type=variants.tag_member.type.c_name(),
> + c_name=variants.tag_member.c_name())
My patch does
ret += gen_struct_field(variants.tag_member.name,
variants.tag_member.type,
False);
>
> # FIXME: What purpose does data serve, besides preventing a union that
> # has a branch named 'data'? We use it in qapi-visit.py to decide
> @@ -152,10 +153,7 @@ struct %(c_name)s {
> union { /* union tag is @%(c_name)s */
> void *data;
> ''',
> - # TODO ugly special case for simple union
> - # Use same tag name in C as on the wire to get rid of
> - # it, then: c_name=c_name(variants.tag_member.name)
> - c_name=c_name(variants.tag_name or 'kind'))
> + c_name=variants.tag_member.c_name())
>
> for var in variants.variants:
> # Ugly special case for simple union TODO get rid of it
> @@ -164,7 +162,7 @@ struct %(c_name)s {
> %(c_type)s %(c_name)s;
> ''',
> c_type=typ.c_type(),
> - c_name=c_name(var.name))
> + c_name=var.c_name())
>
> ret += mcgen('''
> };
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 56b8390..3f74302 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -196,7 +196,7 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj,
> const char *name, Error
> case=c_enum_const(variants.tag_member.type.name,
> var.name),
> c_type=var.type.c_name(),
> - c_name=c_name(var.name))
> + c_name=var.c_name())
>
> ret += mcgen('''
> default:
> @@ -249,10 +249,6 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj,
> const char *name, Error
> c_name=c_name(name))
> ret += gen_err_check(label='out_obj')
>
> - tag_key = variants.tag_member.name
> - if not variants.tag_name:
> - # we pointlessly use a different key for simple unions
> - tag_key = 'type'
> ret += mcgen('''
> visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
> if (err) {
> @@ -264,11 +260,8 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj,
> const char *name, Error
> switch ((*obj)->%(c_name)s) {
> ''',
> c_type=variants.tag_member.type.c_name(),
> - # TODO ugly special case for simple union
> - # Use same tag name in C as on the wire to get rid of
> - # it, then: c_name=c_name(variants.tag_member.name)
> - c_name=c_name(variants.tag_name or 'kind'),
> - name=tag_key)
> + c_name=variants.tag_member.c_name(),
> + name=variants.tag_member.name)
>
> for var in variants.variants:
> # TODO ugly special case for simple union
> @@ -283,13 +276,13 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s
> **obj, const char *name, Error
> visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "data", &err);
> ''',
> c_type=simple_union_type.c_name(),
> - c_name=c_name(var.name))
> + c_name=var.c_name())
> else:
> ret += mcgen('''
> visit_type_implicit_%(c_type)s(v, &(*obj)->%(c_name)s, &err);
> ''',
> c_type=var.type.c_name(),
> - c_name=c_name(var.name))
> + c_name=var.c_name())
> ret += mcgen('''
> break;
> ''')
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index eaa43b8..f5040da 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -984,7 +984,7 @@ class QAPISchemaObjectType(QAPISchemaType):
> members = []
> seen = {}
> for m in members:
> - assert c_name(m.name) not in seen
> + assert m.c_name() not in seen
> seen[m.name] = m
> for m in self.local_members:
> m.check(schema, members, seen)
> @@ -1031,6 +1031,17 @@ class QAPISchemaObjectTypeMember(object):
> all_members.append(self)
> seen[self.name] = self
>
> + def c_name(self):
> + return c_name(self.name)
> +
> +
> +# TODO Drop this class once we no longer have the 'type'/'kind' mismatch
> +class QAPISchemaObjectTypeUnionTag(QAPISchemaObjectTypeMember):
> + def c_name(self):
> + assert self.name == 'type'
> + assert self.type.is_implicit(QAPISchemaEnumType)
> + return 'kind'
> +
>
> class QAPISchemaObjectTypeVariants(object):
> def __init__(self, tag_name, tag_member, variants):
> @@ -1254,7 +1265,7 @@ class QAPISchema(object):
> def _make_implicit_tag(self, type_name, variants):
> typ = self._make_implicit_enum_type(type_name,
> [v.name for v in variants])
> - return QAPISchemaObjectTypeMember('type', typ, False)
> + return QAPISchemaObjectTypeUnionTag('type', typ, False)
>
> def _def_union_type(self, expr, info):
> name = expr['union']
- [Qemu-devel] [PATCH v7 00/14] post-introspection cleanups, subset B, Eric Blake, 2015/10/08
- [Qemu-devel] [PATCH v7 12/14] qapi: Move duplicate enum value checks to schema check(), Eric Blake, 2015/10/08
- [Qemu-devel] [PATCH v7 02/14] qapi: Prepare for errors during check(), Eric Blake, 2015/10/08
- [Qemu-devel] [PATCH v7 04/14] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/10/08
- [Qemu-devel] [PATCH v7 06/14] qapi: Create simple union type member earlier, Eric Blake, 2015/10/08
- [Qemu-devel] [PATCH v7 07/14] qapi: Move union tag quirks into subclass, Eric Blake, 2015/10/08
- [Qemu-devel] [PATCH v7 05/14] qapi: Lazy creation of array types, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v7 13/14] qapi: Add test for alternate branch 'kind' clash, Eric Blake, 2015/10/08