qapi: Support downstream structs

Enhance the testsuite to cover downstream structs, including struct
members and base structs.  Update the generator to mangle the
struct names in the appropriate places.

Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Eric Blake 2015-05-14 06:50:57 -06:00 committed by Markus Armbruster
parent fce384b8e5
commit 83a02706bb
4 changed files with 18 additions and 9 deletions

View File

@ -45,7 +45,7 @@ def generate_fwd_struct(name, members, builtin_type=False):
struct %(name)sList *next; struct %(name)sList *next;
} %(name)sList; } %(name)sList;
''', ''',
name=name) name=c_name(name))
def generate_fwd_enum_struct(name, members): def generate_fwd_enum_struct(name, members):
return mcgen(''' return mcgen('''
@ -87,7 +87,7 @@ def generate_struct(expr):
struct %(name)s struct %(name)s
{ {
''', ''',
name=structname) name=c_name(structname))
if base: if base:
ret += generate_struct_fields({'base': base}) ret += generate_struct_fields({'base': base})

View File

@ -56,7 +56,7 @@ def generate_visit_struct_fields(name, members, base = None):
{ {
Error *err = NULL; Error *err = NULL;
''', ''',
name=name) name=c_name(name))
push_indent() push_indent()
if base: if base:
@ -111,16 +111,16 @@ def generate_visit_struct_body(name, members):
ret = mcgen(''' ret = mcgen('''
Error *err = NULL; Error *err = NULL;
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);
if (!err) { if (!err) {
if (*obj) { if (*obj) {
visit_type_%(name)s_fields(m, obj, errp); visit_type_%(c_name)s_fields(m, obj, errp);
} }
visit_end_struct(m, &err); visit_end_struct(m, &err);
} }
error_propagate(errp, err); error_propagate(errp, err);
''', ''',
name=name) name=name, c_name=c_name(name))
return ret return ret
@ -137,7 +137,7 @@ def generate_visit_struct(expr):
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp) void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp)
{ {
''', ''',
name=name) name=c_name(name))
ret += generate_visit_struct_body(name, members) ret += generate_visit_struct_body(name, members)
@ -347,6 +347,7 @@ def generate_visit_union(expr):
def generate_declaration(name, members, builtin_type=False): def generate_declaration(name, members, builtin_type=False):
ret = "" ret = ""
if not builtin_type: if not builtin_type:
name = c_name(name)
ret += mcgen(''' ret += mcgen('''
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp); void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp);

View File

@ -110,3 +110,7 @@
# test that we correctly compile downstream extensions # test that we correctly compile downstream extensions
{ 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] } { 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] }
{ 'struct': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member2': 'str' } }

View File

@ -23,7 +23,9 @@
OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]), OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]), OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]),
OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]), OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]),
OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])])] OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])]),
OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))])]
[{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']}, [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
{'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']}, {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
{'enum_name': 'UserDefAlternateKind', 'enum_values': None}, {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
@ -39,4 +41,6 @@
OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]), OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]), OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]), OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])] OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))])]