[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 3/4] qapi: Correctly handle downstream extens
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v2 3/4] qapi: Correctly handle downstream extensions in more locations |
Date: |
Wed, 29 Apr 2015 13:29:19 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Eric Blake <address@hidden> writes:
> Now that c_var() handles '.' in downstream extension names, fix
> the generator to support such names as additional types, enums,
> members within an enum, branches of a union or alternate, and
> in arrays.
>
> Signed-off-by: Eric Blake <address@hidden>
> ---
> scripts/qapi-commands.py | 4 ++--
> scripts/qapi-types.py | 27 ++++++++++++++-------------
> scripts/qapi-visit.py | 44 ++++++++++++++++++++++++--------------------
> scripts/qapi.py | 10 ++++++----
> 4 files changed, 46 insertions(+), 39 deletions(-)
>
> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
> index af1e1a1..84b66bc 100644
> --- a/scripts/qapi-commands.py
> +++ b/scripts/qapi-commands.py
> @@ -22,9 +22,9 @@ import errno
>
> def type_visitor(name):
> if type(name) == list:
> - return 'visit_type_%sList' % name[0]
> + return 'visit_type_%sList' % type_name(name[0])
> else:
> - return 'visit_type_%s' % name
> + return 'visit_type_%s' % type_name(name)
>
> def generate_command_decl(name, args, ret_type):
> arglist=""
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 8cf6349..b33b8fd 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -45,7 +45,7 @@ typedef struct %(name)sList
> struct %(name)sList *next;
> } %(name)sList;
> ''',
> - name=name)
> + name=c_var(name))
>
> def generate_fwd_enum_struct(name, members):
> return mcgen('''
> @@ -58,7 +58,7 @@ typedef struct %(name)sList
> struct %(name)sList *next;
> } %(name)sList;
> ''',
> - name=name)
> + name=c_var(name))
>
> def generate_struct_fields(members):
> ret = ''
> @@ -87,7 +87,7 @@ def generate_struct(expr):
> struct %(name)s
> {
> ''',
> - name=structname)
> + name=c_var(structname))
>
> if base:
> ret += generate_struct_fields({'base': base})
> @@ -115,7 +115,7 @@ def generate_enum_lookup(name, values):
> ret = mcgen('''
> const char *%(name)s_lookup[] = {
> ''',
> - name=name)
> + name=c_var(name))
> i = 0
> for value in values:
> index = generate_enum_full_value(name, value)
> @@ -134,6 +134,7 @@ const char *%(name)s_lookup[] = {
> return ret
>
> def generate_enum(name, values):
> + name = c_var(name)
> lookup_decl = mcgen('''
> extern const char *%(name)s_lookup[];
> ''',
> @@ -173,18 +174,18 @@ def generate_alternate_qtypes(expr):
> ret = mcgen('''
> const int %(name)s_qtypes[QTYPE_MAX] = {
> ''',
> - name=name)
> + name=c_var(name))
>
> for key in members:
> qtype = find_alternate_member_qtype(members[key])
> assert qtype, "Invalid alternate member"
>
> ret += mcgen('''
> - [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
> + [%(qtype)s] = %(value)s,
> ''',
> - qtype = qtype,
> - abbrev = de_camel_case(name).upper(),
> - enum = c_var(de_camel_case(key),False).upper())
> + qtype = qtype,
> + value = generate_enum_full_value("%sKind" %c_var(name),
> + key))
>
> ret += mcgen('''
> };
I fixed this one in my "[PATCH RFC 06/19] qapi: Use c_enum_const() in
generate_alternate_qtypes()".
You picked just my "[PATCH RFC 02/19] qapi: Fix C identifiers generated
for names containing '.'" into your series. Would you mind picking all
the related patches, i.e PATCH 02-07?
qapi: Fix C identifiers generated for names containing '.'
qapi: Rename _generate_enum_string() to camel_to_upper()
qapi: Rename generate_enum_full_value() to c_enum_const()
qapi: Simplify c_enum_const()
qapi: Use c_enum_const() in generate_alternate_qtypes()
qapi: Move camel_to_upper(), c_enum_const() to closely related code
> @@ -194,7 +195,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
>
> def generate_union(expr, meta):
>
> - name = expr[meta]
> + name = c_var(expr[meta])
> typeinfo = expr['data']
>
> base = expr.get('base')
> @@ -214,7 +215,7 @@ struct %(name)s
> void *data;
> ''',
> name=name,
> - discriminator_type_name=discriminator_type_name)
> + discriminator_type_name=c_var(discriminator_type_name))
>
> for key in typeinfo:
> ret += mcgen('''
> @@ -251,7 +252,7 @@ def generate_type_cleanup_decl(name):
> ret = mcgen('''
> void qapi_free_%(type)s(%(c_type)s obj);
> ''',
> - c_type=c_type(name),type=name)
> + c_type=c_type(name),type=c_var(name))
> return ret
>
> def generate_type_cleanup(name):
> @@ -272,7 +273,7 @@ void qapi_free_%(type)s(%(c_type)s obj)
> qapi_dealloc_visitor_cleanup(md);
> }
> ''',
> - c_type=c_type(name),type=name)
> + c_type=c_type(name),type=c_var(name))
> return ret
>
>
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index f24dcfa..d1d3fe6 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -44,12 +44,13 @@ static void visit_type_implicit_%(c_type)s(Visitor *m,
> %(c_type)s **obj, Error *
> c_type=type_name(type))
>
> def generate_visit_struct_fields(name, field_prefix, fn_prefix, members,
> base = None):
> + assert field_prefix == ""
Makes me wonder why we have a field_prefix parameter.
fn_prefix is also always ""...
> substructs = []
> ret = ''
> if not fn_prefix:
> - full_name = name
> + full_name = c_var(name)
> else:
... and therefore this this code is unreachable.
Just observing, not asking you to do anything here.
> - full_name = "%s_%s" % (name, fn_prefix)
> + full_name = "%s_%s" % (c_var(name), fn_prefix)
>
> if base:
> ret += generate_visit_implicit_struct(base)
> @@ -60,7 +61,7 @@ static void visit_type_%(full_name)s_fields(Visitor *m,
> %(name)s **obj, Error **
> {
> Error *err = NULL;
> ''',
> - name=name, full_name=full_name)
> + name=c_var(name), full_name=full_name)
> push_indent()
>
> if base:
> @@ -121,9 +122,9 @@ def generate_visit_struct_body(field_prefix, name,
> members):
> ''')
>
> if not field_prefix:
> - full_name = name
> + full_name = c_var(name)
> else:
> - full_name = "%s_%s" % (field_prefix, name)
> + full_name = "%s_%s" % (field_prefix, c_var(name))
>
> if len(field_prefix):
> ret += mcgen('''
> @@ -132,9 +133,9 @@ def generate_visit_struct_body(field_prefix, name,
> members):
> name=name)
> else:
> ret += mcgen('''
> - visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s),
> &err);
> + visit_start_struct(m, (void **)obj, "%(name)s", name,
> sizeof(%(c_name)s), &err);
> ''',
> - name=name)
> + name=name, c_name=c_var(name))
>
> ret += mcgen('''
> if (!err) {
> @@ -162,7 +163,7 @@ def generate_visit_struct(expr):
> void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error
> **errp)
> {
> ''',
> - name=name)
> + name=c_var(name))
>
> ret += generate_visit_struct_body("", name, members)
>
> @@ -171,7 +172,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj,
> const char *name, Error **e
> ''')
> return ret
>
> -def generate_visit_list(name, members):
> +def generate_visit_list(name, members, builtin=False):
> + if not builtin:
> + name = c_var(name)
Fun.
c_var() does two things:
(a) it protects certain words if protect=True
(b) it maps funny characters to '_'.
When builtin, (a) is unwanted, and (b) does nothing. That's why we need
the conditional.
A possible alternative could be c_var(name, not builtin). Matter of
taste.
Hmm, just saw what type_name() does. Why not just
name = type_name(name)
?
> return mcgen('''
>
> void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char
> *name, Error **errp)
> @@ -208,7 +211,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s *obj, const
> char *name, Error **er
> visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
> }
> ''',
> - name=name)
> + name=c_var(name))
>
> def generate_visit_alternate(name, members):
> ret = mcgen('''
> @@ -227,11 +230,11 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj,
> const char *name, Error **e
> }
> switch ((*obj)->kind) {
> ''',
> - name=name)
> + name=c_var(name))
>
> # For alternate, always use the default enum type automatically generated
> # as "'%sKind' % (name)"
> - disc_type = '%sKind' % (name)
> + disc_type = '%sKind' % c_var(name)
>
> for key in members:
> assert (members[key] in builtin_types.keys()
> @@ -277,12 +280,12 @@ def generate_visit_union(expr):
> if enum_define:
> # Use the enum type as discriminator
> ret = ""
> - disc_type = enum_define['enum_name']
> + disc_type = c_var(enum_define['enum_name'])
> else:
> # There will always be a discriminator in the C switch code, by
> default
> # it is an enum type generated silently as "'%sKind' % (name)"
> ret = generate_visit_enum('%sKind' % name, members.keys())
> - disc_type = '%sKind' % (name)
> + disc_type = '%sKind' % c_var(name)
>
> if base:
> assert discriminator
> @@ -306,7 +309,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj,
> const char *name, Error **e
> }
> if (*obj) {
> ''',
> - name=name)
> + name=c_var(name))
>
> if base:
> ret += mcgen('''
> @@ -315,7 +318,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj,
> const char *name, Error **e
> goto out_obj;
> }
> ''',
> - name=name)
> + name=c_var(name))
>
> if not discriminator:
> disc_key = "type"
> @@ -372,6 +375,7 @@ out:
> def generate_declaration(name, members, builtin_type=False):
> ret = ""
> if not builtin_type:
> + name = c_var(name)
> ret += mcgen('''
>
> void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error
> **errp);
> @@ -381,7 +385,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj,
> const char *name, Error **e
> ret += mcgen('''
> void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char
> *name, Error **errp);
> ''',
> - name=name)
> + name=name)
>
> return ret
>
> @@ -389,7 +393,7 @@ def generate_enum_declaration(name, members):
> ret = mcgen('''
> void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char
> *name, Error **errp);
> ''',
> - name=name)
> + name=c_var(name))
>
> return ret
>
> @@ -398,7 +402,7 @@ def generate_decl_enum(name, members):
>
> void visit_type_%(name)s(Visitor *m, %(name)s *obj, const char *name, Error
> **errp);
> ''',
> - name=name)
> + name=c_var(name))
>
> try:
> opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
> @@ -515,7 +519,7 @@ fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
> # over these cases
> if do_builtins:
> for typename in builtin_types.keys():
> - fdef.write(generate_visit_list(typename, None))
> + fdef.write(generate_visit_list(typename, None, builtin=True))
>
> for expr in exprs:
> if expr.has_key('struct'):
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 1d64c62..e706712 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -782,12 +782,14 @@ def c_var(name, protect=True):
> return name.translate(c_var_trans)
>
> def c_list_type(name):
> - return '%sList' % name
> + return '%sList' % type_name(name)
>
> def type_name(name):
> if type(name) == list:
> return c_list_type(name[0])
> - return name
> + if name in builtin_types.keys():
> + return name
> + return c_var(name)
>
> def add_name(name, info, meta, implicit = False):
> global all_names
> @@ -869,13 +871,13 @@ def c_type(name, is_param=False):
> elif type(name) == list:
> return '%s *%s' % (c_list_type(name[0]), eatspace)
> elif is_enum(name):
> - return name
> + return c_var(name)
> elif name == None or len(name) == 0:
> return 'void'
> elif name in events:
> return '%sEvent *%s' % (camel_case(name), eatspace)
> else:
> - return '%s *%s' % (name, eatspace)
> + return '%s *%s' % (c_var(name), eatspace)
>
> def is_c_ptr(name):
> suffix = "*" + eatspace
If it was my patch, I'd be tempted to split it up some. Matter of
taste, feel free to keep it a single patch.