From 804007aaad8804ddf42f092b66bcf533f2fa99a9 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Sat, 22 Mar 2014 03:30:53 +0100 Subject: [PATCH 02/30] qapi: generate list struct and visit_list for enum RH-Author: Laszlo Ersek Message-id: <1395459071-19118-2-git-send-email-lersek@redhat.com> Patchwork-id: 58211 O-Subject: [RHEL-6.6 qemu-kvm PATCH 01/19] qapi: generate list struct and visit_list for enum Bugzilla: 1035162 RH-Acked-by: Paolo Bonzini RH-Acked-by: Dr. David Alan Gilbert (git) RH-Acked-by: Luiz Capitulino From: Amos Kong Currently, if we define an 'enum' and use it in one command's data, list struct for enum could not be generated, but it's used in qmp function. For example: KeyCodesList could not be generated. >>> qapi-schema.json: { 'enum': 'KeyCodes', 'data': [ 'shift', 'alt' ... ] } { 'command': 'sendkey', 'data': { 'keys': ['KeyCodes'], '*hold-time': 'int' } } >>> qmp-command.h: void qmp_sendkey(KeyCodesList * keys, bool has_hold_time, int64_t hold_time, Error **errp); This patch lets qapi generate list struct and visit_list for enum. Signed-off-by: Amos Kong Signed-off-by: Luiz Capitulino (cherry picked from commit b9c4b48d50057b6aee7c70879b240ff76f39c85b) RHEL-6 note: Since it's always extremely scary to touch the qapi generator, I created a cross-reference between RHEL-6 and upstream commits that touch the files "scripts/qapi-types.py" and "scripts/qapi-visit.py" (any one of them). The following list is ordered by the upstream commit "serial number", ie. the up# field: subject down# downhash up# uphash --------------------------------------------------------------- ----- -------- --- ------- qapi: add qapi-types.py code generator 01 197a85d 01 fb3182c qapi: add qapi-visit.py code generator 02 37bcd64 02 06d64c6 qapi: add code generation support for middle mode 03 d8d511a 03 776574d qapi: generate qapi_free_* functions for *List types 04 5db9665 04 75b96ac qapi: modify visitor code generation for list iteration 05 a560be0 05 e1bc2f7 qapi: Don't use c_var() on enum strings 06 885cad0 06 d2a80d6 qapi: Automatically generate a _MAX value for enums 07 73e27e3 07 303b54b qapi: allow a 'gen' key to suppress code generation 08 dc6205f 08 5dbee47 Fix qapi code generation wrt parallel build 09 b44869f 09 8d3bc51 Fix qapi code generation fix 10 56312c7 10 19bf7c8 qapi: complete implementation of unions 11 6b9b549 11 dc8fb6d qapi: add c_fun to escape function names 12 5e58df2 12 c9da228 qapi: shortcut visits on errors 13 3a356c0 13 b6f0474 qapi: allow freeing partially-allocated objects 14 1b7c9ac 14 69b5007 qapi: untangle next_list 15 9e69a7b 15 3a86a0f qapi: fix error propagation 16 9f92807 16 d195325 qapi: qapi-types.h: don't include qapi/qapi-types-core.h - - 17 b68a847 qapi: generate correct enum names for camel case enums 17 419fc51 18 f01f594 qapi: don't convert enum strings to lowercase 18 01c6969 19 ac4ff70 qapi: generate list struct and visit_list for enum 20 NEW 20 b9c4b48 qapi: Fix potential NULL pointer segfault 21 NEW 21 227ccf6 qapi: do not protect enum values from namespace pollution 19 b4eb443 22 eda50a6 qapi-types.h: Don't include qemu-common.h - - 23 da4fea0 qapi: move inclusions of qemu-common.h from headers to .c files - - 24 79ee7df qapi: move include files to include/qobject/ - - 25 7b1b5d1 qapi: qapi-types.py, native list support - - 26 c0afa9c qapi: qapi-visit.py, fix list handling for union types - - 27 c664aef qapi: qapi-visit.py, native list support - - 28 7c946bc qapi: pad GenericList value fields to 64 bits - - 29 a678e26 qapi-types.py: Implement 'base' for unions - - 30 e2503f5 qapi-visit.py: Split off generate_visit_struct_fields() - - 31 d131c89 qapi-visit.py: Implement 'base' for unions - - 32 0aef92b qapi: Flat unions with arbitrary discriminator - - 33 50f2bdc qapi: Anonymous unions - - 34 69dd62d qapi-types.py: Split off generate_struct_fields() - - 35 0153703 qapi-types.py: Fix enum struct sizes on i686 - - 36 02dc4bf qapi-types/visit.py: Pass whole expr dict for structs - - 37 14d3630 qapi-types/visit.py: Inheritance for structs - - 38 622f557 Adjust qapi-visit for python-2.4.3 - - 39 7b75d9d We are in pretty good shape. Thus far we only skipped upstream b68a847, and backported only eda50a6 out of order. This patch, and the next one (which I'm including just because it's so easy), are marked with NEW in the downhash column. The table shows that these two backports happen in order, and that they (together with the earlier, out-of-order backport of eda50a6) actually restore a global ordering, in sync with upstream. Signed-off-by: Laszlo Ersek --- scripts/qapi-types.py | 16 +++++++++++++++- scripts/qapi-visit.py | 14 +++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) Signed-off-by: Miroslav Rezanina --- scripts/qapi-types.py | 16 +++++++++++++++- scripts/qapi-visit.py | 14 +++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index 53fa0f6..86cb96b 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -28,6 +28,16 @@ typedef struct %(name)sList ''', name=name) +def generate_fwd_enum_struct(name, members): + return mcgen(''' +typedef struct %(name)sList +{ + %(name)s value; + struct %(name)sList *next; +} %(name)sList; +''', + name=name) + def generate_struct(structname, fieldname, members): ret = mcgen(''' struct %(name)s @@ -275,7 +285,8 @@ for expr in exprs: if expr.has_key('type'): ret += generate_fwd_struct(expr['type'], expr['data']) elif expr.has_key('enum'): - ret += generate_enum(expr['enum'], expr['data']) + ret += generate_enum(expr['enum'], expr['data']) + "\n" + ret += generate_fwd_enum_struct(expr['enum'], expr['data']) fdef.write(generate_enum_lookup(expr['enum'], expr['data'])) elif expr.has_key('union'): ret += generate_fwd_struct(expr['union'], expr['data']) + "\n" @@ -299,6 +310,9 @@ for expr in exprs: fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n") ret += generate_type_cleanup_decl(expr['union']) fdef.write(generate_type_cleanup(expr['union']) + "\n") + elif expr.has_key('enum'): + ret += generate_type_cleanup_decl(expr['enum'] + "List") + fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n") else: continue fdecl.write(ret) diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index efb44b7..e98f7a5 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -217,6 +217,16 @@ void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, return ret +def generate_enum_declaration(name, members, genlist=True): + ret = "" + if genlist: + ret += mcgen(''' +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp); +''', + name=name) + + return ret + def generate_decl_enum(name, members, genlist=True): return mcgen(''' @@ -335,10 +345,12 @@ for expr in exprs: ret += generate_declaration(expr['union'], expr['data']) fdecl.write(ret) elif expr.has_key('enum'): - ret = generate_visit_enum(expr['enum'], expr['data']) + ret = generate_visit_list(expr['enum'], expr['data']) + ret += generate_visit_enum(expr['enum'], expr['data']) fdef.write(ret) ret = generate_decl_enum(expr['enum'], expr['data']) + ret += generate_enum_declaration(expr['enum'], expr['data']) fdecl.write(ret) fdecl.write(''' -- 1.7.1