Re: [Qemu-devel] [PATCH V4 6/9] qapi script: support pre-defined enum type as discriminator in union

2013-12-13 Thread Eric Blake
On 12/10/2013 10:48 PM, Wenchao Xia wrote:
 By default, any union will automatically generate a enum type as
 [UnionName]Kind in C code, and it is duplicated when the discriminator
 is specified as a pre-defined enum type in schema. After this patch,
 the pre-defined enum type will be really used as the switch case
 condition in generated C code, if discriminator is an enum field.
 
 Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com
 ---
  docs/qapi-code-gen.txt |8 ++--
  scripts/qapi-types.py  |   18 ++
  scripts/qapi-visit.py  |   23 ---
  scripts/qapi.py|4 +++-
  4 files changed, 39 insertions(+), 14 deletions(-)
 
 diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
 index 0728f36..f00640b 100644
 --- a/docs/qapi-code-gen.txt
 +++ b/docs/qapi-code-gen.txt
 @@ -123,11 +123,15 @@ And it looks like this on the wire:
  
  Flat union types avoid the nesting on the wire. They are used whenever a
  specific field of the base type is declared as the discriminator ('type' is
 -then no longer generated). The discriminator must always be a string field.
 +then no longer generated). The discriminator can be a string field or a
 +predefined enum field. If it is a string field, a hidden enum type will be
 +generated as [UNION_NAME]Kind. If it is an enum field, compile time check

s/compile/a compile/

Minor enough that I'm okay giving:

Reviewed-by: Eric Blake ebl...@redhat.com

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH V4 6/9] qapi script: support pre-defined enum type as discriminator in union

2013-12-10 Thread Wenchao Xia
By default, any union will automatically generate a enum type as
[UnionName]Kind in C code, and it is duplicated when the discriminator
is specified as a pre-defined enum type in schema. After this patch,
the pre-defined enum type will be really used as the switch case
condition in generated C code, if discriminator is an enum field.

Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com
---
 docs/qapi-code-gen.txt |8 ++--
 scripts/qapi-types.py  |   18 ++
 scripts/qapi-visit.py  |   23 ---
 scripts/qapi.py|4 +++-
 4 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 0728f36..f00640b 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -123,11 +123,15 @@ And it looks like this on the wire:
 
 Flat union types avoid the nesting on the wire. They are used whenever a
 specific field of the base type is declared as the discriminator ('type' is
-then no longer generated). The discriminator must always be a string field.
+then no longer generated). The discriminator can be a string field or a
+predefined enum field. If it is a string field, a hidden enum type will be
+generated as [UNION_NAME]Kind. If it is an enum field, compile time check
+will be done to verify the correctness. It is recommended to use an enum field.
 The above example can then be modified as follows:
 
+ { 'enum': 'BlockdevDriver', 'data': [ 'raw', 'qcow2' ] }
  { 'type': 'BlockdevCommonOptions',
-   'data': { 'driver': 'str', 'readonly': 'bool' } }
+   'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } }
  { 'union': 'BlockdevOptions',
'base': 'BlockdevCommonOptions',
'discriminator': 'driver',
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 914f055..5031c4b 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -201,14 +201,21 @@ def generate_union(expr):
 base = expr.get('base')
 discriminator = expr.get('discriminator')
 
+enum_define = discriminator_find_enum_define(expr)
+if enum_define:
+discriminator_type_name = enum_define['enum_name']
+else:
+discriminator_type_name = '%sKind' % (name)
+
 ret = mcgen('''
 struct %(name)s
 {
-%(name)sKind kind;
+%(discriminator_type_name)s kind;
 union {
 void *data;
 ''',
-name=name)
+name=name,
+discriminator_type_name=discriminator_type_name)
 
 for key in typeinfo:
 ret += mcgen('''
@@ -389,8 +396,11 @@ for expr in exprs:
 fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
 elif expr.has_key('union'):
 ret += generate_fwd_struct(expr['union'], expr['data']) + \n
-ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
-fdef.write(generate_enum_lookup('%sKind' % expr['union'], 
expr['data'].keys()))
+enum_define = discriminator_find_enum_define(expr)
+if not enum_define:
+ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
+fdef.write(generate_enum_lookup('%sKind' % expr['union'],
+expr['data'].keys()))
 if expr.get('discriminator') == {}:
 fdef.write(generate_anon_union_qtypes(expr))
 else:
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 1b55924..3240921 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -277,10 +277,14 @@ def generate_visit_union(expr):
  (key, name))
 sys.exit(1)
 
-# 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())
-discriminator_type_name = '%sKind' % (name)
+# Use the predefined enum type as discriminator
+ret = 
+discriminator_type_name = 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())
+discriminator_type_name = '%sKind' % (name)
 
 if base:
 base_fields = find_struct(base)['data']
@@ -320,11 +324,12 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, 
const char *name, Error **
 else:
 desc_type = discriminator
 ret += mcgen('''
-visit_type_%(name)sKind(m, (*obj)-kind, %(type)s, err);
+visit_type_%(discriminator_type_name)s(m, (*obj)-kind, %(type)s, 
err);
 if (!err) {
 switch ((*obj)-kind) {
 ''',
- name=name, type=desc_type)
+ discriminator_type_name=discriminator_type_name,
+ type=desc_type)
 
 for key in members:
 if not discriminator:
@@ -538,7 +543,11 @@ for expr in exprs:
 ret +=