aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/qapi-types.py42
-rw-r--r--scripts/qapi-visit.py47
-rw-r--r--scripts/qapi.py15
3 files changed, 104 insertions, 0 deletions
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 84d46fb863..5ee46ea1b3 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -150,6 +150,40 @@ typedef enum %(name)s
return lookup_decl + enum_decl
+def generate_anon_union_qtypes(expr):
+
+ name = expr['union']
+ members = expr['data']
+
+ ret = mcgen('''
+const int %(name)s_qtypes[QTYPE_MAX] = {
+''',
+ name=name)
+
+ for key in members:
+ qapi_type = members[key]
+ if builtin_type_qtypes.has_key(qapi_type):
+ qtype = builtin_type_qtypes[qapi_type]
+ elif find_struct(qapi_type):
+ qtype = "QTYPE_QDICT"
+ elif find_union(qapi_type):
+ qtype = "QTYPE_QDICT"
+ else:
+ assert False, "Invalid anonymous union member"
+
+ ret += mcgen('''
+ [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
+''',
+ qtype = qtype,
+ abbrev = de_camel_case(name).upper(),
+ enum = c_fun(de_camel_case(key),False).upper())
+
+ ret += mcgen('''
+};
+''')
+ return ret
+
+
def generate_union(expr):
name = expr['union']
@@ -190,6 +224,12 @@ struct %(name)s
ret += mcgen('''
};
''')
+ if discriminator == {}:
+ ret += mcgen('''
+extern const int %(name)s_qtypes[];
+''',
+ name=name)
+
return ret
@@ -342,6 +382,8 @@ for expr in exprs:
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()))
+ if expr.get('discriminator') == {}:
+ fdef.write(generate_anon_union_qtypes(expr))
else:
continue
fdecl.write(ret)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 87d5f15164..597cca4b66 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -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:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3a54c7fc7c..38c808e256 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -17,6 +17,21 @@ builtin_types = [
'uint8', 'uint16', 'uint32', 'uint64'
]
+builtin_type_qtypes = {
+ 'str': 'QTYPE_QSTRING',
+ 'int': 'QTYPE_QINT',
+ 'number': 'QTYPE_QFLOAT',
+ 'bool': 'QTYPE_QBOOL',
+ 'int8': 'QTYPE_QINT',
+ 'int16': 'QTYPE_QINT',
+ 'int32': 'QTYPE_QINT',
+ 'int64': 'QTYPE_QINT',
+ 'uint8': 'QTYPE_QINT',
+ 'uint16': 'QTYPE_QINT',
+ 'uint32': 'QTYPE_QINT',
+ 'uint64': 'QTYPE_QINT',
+}
+
def tokenize(data):
while len(data):
ch = data[0]