mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-28 21:03:54 -06:00
qapi: Anonymous unions
The discriminator for anonymous unions is the data type. This allows to have a union type that allows both of these: { 'file': 'my_existing_block_device_id' } { 'file': { 'filename': '/tmp/mydisk.qcow2', 'read-only': true } } Unions like this are specified in the schema with an empty dict as discriminator. For this example you could take: { 'union': 'BlockRef', 'discriminator': {}, 'data': { 'definition': 'BlockOptions', 'reference': 'str' } } { 'type': 'ExampleObject', 'data: { 'file': 'BlockRef' } } Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
ea66c6d881
commit
69dd62dfd6
10 changed files with 160 additions and 0 deletions
|
@ -176,6 +176,49 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
|
|||
''',
|
||||
name=name)
|
||||
|
||||
def generate_visit_anon_union(name, members):
|
||||
ret = mcgen('''
|
||||
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
|
||||
if (!error_is_set(errp)) {
|
||||
visit_start_implicit_struct(m, (void**) obj, sizeof(%(name)s), &err);
|
||||
visit_get_next_type(m, (int*) &(*obj)->kind, %(name)s_qtypes, name, &err);
|
||||
switch ((*obj)->kind) {
|
||||
''',
|
||||
name=name)
|
||||
|
||||
for key in members:
|
||||
assert (members[key] in builtin_types
|
||||
or find_struct(members[key])
|
||||
or find_union(members[key])), "Invalid anonymous union member"
|
||||
|
||||
ret += mcgen('''
|
||||
case %(abbrev)s_KIND_%(enum)s:
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
|
||||
break;
|
||||
''',
|
||||
abbrev = de_camel_case(name).upper(),
|
||||
enum = c_fun(de_camel_case(key),False).upper(),
|
||||
c_type = type_name(members[key]),
|
||||
c_name = c_fun(key))
|
||||
|
||||
ret += mcgen('''
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
error_propagate(errp, err);
|
||||
err = NULL;
|
||||
visit_end_implicit_struct(m, &err);
|
||||
}
|
||||
}
|
||||
''')
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def generate_visit_union(expr):
|
||||
|
||||
name = expr['union']
|
||||
|
@ -184,6 +227,10 @@ def generate_visit_union(expr):
|
|||
base = expr.get('base')
|
||||
discriminator = expr.get('discriminator')
|
||||
|
||||
if discriminator == {}:
|
||||
assert not base
|
||||
return generate_visit_anon_union(name, members)
|
||||
|
||||
ret = generate_visit_enum('%sKind' % name, members.keys())
|
||||
|
||||
if base:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue