|
|
9ae3a8 |
From fafd52c6d2c32e24ae83b4d534c6e2f72f53795d Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 9 Sep 2013 14:28:16 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 25/38] qapi: Anonymous unions
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1378736903-18489-26-git-send-email-kwolf@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 54212
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.0 qemu-kvm PATCH 25/32] qapi: Anonymous unions
|
|
|
9ae3a8 |
Bugzilla: 1005818
|
|
|
9ae3a8 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Bugzilla: 1005818
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The discriminator for anonymous unions is the data type. This allows to
|
|
|
9ae3a8 |
have a union type that allows both of these:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
{ 'file': 'my_existing_block_device_id' }
|
|
|
9ae3a8 |
{ 'file': { 'filename': '/tmp/mydisk.qcow2', 'read-only': true } }
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Unions like this are specified in the schema with an empty dict as
|
|
|
9ae3a8 |
discriminator. For this example you could take:
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
{ 'union': 'BlockRef',
|
|
|
9ae3a8 |
'discriminator': {},
|
|
|
9ae3a8 |
'data': { 'definition': 'BlockOptions',
|
|
|
9ae3a8 |
'reference': 'str' } }
|
|
|
9ae3a8 |
{ 'type': 'ExampleObject',
|
|
|
9ae3a8 |
'data: { 'file': 'BlockRef' } }
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 69dd62dfd60631ba69201d8a197fde1ece4b4df3)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
docs/qapi-code-gen.txt | 25 ++++++++++++++++++++++++
|
|
|
9ae3a8 |
include/qapi/qmp/qobject.h | 1 +
|
|
|
9ae3a8 |
include/qapi/visitor-impl.h | 2 ++
|
|
|
9ae3a8 |
include/qapi/visitor.h | 3 +++
|
|
|
9ae3a8 |
qapi/qapi-visit-core.c | 9 +++++++++
|
|
|
9ae3a8 |
qapi/qmp-input-visitor.c | 14 ++++++++++++++
|
|
|
9ae3a8 |
qobject/qjson.c | 2 ++
|
|
|
9ae3a8 |
scripts/qapi-types.py | 42 ++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
scripts/qapi-visit.py | 47 +++++++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
scripts/qapi.py | 15 +++++++++++++++
|
|
|
9ae3a8 |
10 files changed, 160 insertions(+)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
docs/qapi-code-gen.txt | 25 ++++++++++++++++++++++
|
|
|
9ae3a8 |
include/qapi/qmp/qobject.h | 1 +
|
|
|
9ae3a8 |
include/qapi/visitor-impl.h | 2 +
|
|
|
9ae3a8 |
include/qapi/visitor.h | 3 ++
|
|
|
9ae3a8 |
qapi/qapi-visit-core.c | 9 ++++++++
|
|
|
9ae3a8 |
qapi/qmp-input-visitor.c | 14 ++++++++++++
|
|
|
9ae3a8 |
qobject/qjson.c | 2 +
|
|
|
9ae3a8 |
scripts/qapi-types.py | 42 ++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
scripts/qapi-visit.py | 47 +++++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
scripts/qapi.py | 15 +++++++++++++
|
|
|
9ae3a8 |
10 files changed, 160 insertions(+), 0 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
|
|
|
9ae3a8 |
index 11f19cf..0ce045c 100644
|
|
|
9ae3a8 |
--- a/docs/qapi-code-gen.txt
|
|
|
9ae3a8 |
+++ b/docs/qapi-code-gen.txt
|
|
|
9ae3a8 |
@@ -125,6 +125,31 @@ Resulting in this JSON object:
|
|
|
9ae3a8 |
"lazy-refcounts": true }
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+A special type of unions are anonymous unions. They don't form a dictionary in
|
|
|
9ae3a8 |
+the wire format but allow the direct use of different types in their place. As
|
|
|
9ae3a8 |
+they aren't structured, they don't have any explicit discriminator but use
|
|
|
9ae3a8 |
+the (QObject) data type of their value as an implicit discriminator. This means
|
|
|
9ae3a8 |
+that they are restricted to using only one discriminator value per QObject
|
|
|
9ae3a8 |
+type. For example, you cannot have two different complex types in an anonymous
|
|
|
9ae3a8 |
+union, or two different integer types.
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+Anonymous unions are declared using an empty dictionary as their discriminator.
|
|
|
9ae3a8 |
+The discriminator values never appear on the wire, they are only used in the
|
|
|
9ae3a8 |
+generated C code. Anonymous unions cannot have a base type.
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ { 'union': 'BlockRef',
|
|
|
9ae3a8 |
+ 'discriminator': {},
|
|
|
9ae3a8 |
+ 'data': { 'definition': 'BlockdevOptions',
|
|
|
9ae3a8 |
+ 'reference': 'str' } }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+This example allows using both of the following example objects:
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ { "file": "my_existing_block_device_id" }
|
|
|
9ae3a8 |
+ { "file": { "driver": "file",
|
|
|
9ae3a8 |
+ "readonly": false,
|
|
|
9ae3a8 |
+ 'filename': "/tmp/mydisk.qcow2" } }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
=== Commands ===
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Commands are defined by using a list containing three members. The first
|
|
|
9ae3a8 |
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
|
|
|
9ae3a8 |
index 9124649..d0bbc7c 100644
|
|
|
9ae3a8 |
--- a/include/qapi/qmp/qobject.h
|
|
|
9ae3a8 |
+++ b/include/qapi/qmp/qobject.h
|
|
|
9ae3a8 |
@@ -44,6 +44,7 @@ typedef enum {
|
|
|
9ae3a8 |
QTYPE_QFLOAT,
|
|
|
9ae3a8 |
QTYPE_QBOOL,
|
|
|
9ae3a8 |
QTYPE_QERROR,
|
|
|
9ae3a8 |
+ QTYPE_MAX,
|
|
|
9ae3a8 |
} qtype_code;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
struct QObject;
|
|
|
9ae3a8 |
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
|
|
|
9ae3a8 |
index 5c1297f..f3fa420 100644
|
|
|
9ae3a8 |
--- a/include/qapi/visitor-impl.h
|
|
|
9ae3a8 |
+++ b/include/qapi/visitor-impl.h
|
|
|
9ae3a8 |
@@ -32,6 +32,8 @@ struct Visitor
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
void (*type_enum)(Visitor *v, int *obj, const char *strings[],
|
|
|
9ae3a8 |
const char *kind, const char *name, Error **errp);
|
|
|
9ae3a8 |
+ void (*get_next_type)(Visitor *v, int *kind, const int *qobjects,
|
|
|
9ae3a8 |
+ const char *name, Error **errp);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
|
|
9ae3a8 |
void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
|
|
|
9ae3a8 |
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
|
|
|
9ae3a8 |
index a1cdd81..aa9e771 100644
|
|
|
9ae3a8 |
--- a/include/qapi/visitor.h
|
|
|
9ae3a8 |
+++ b/include/qapi/visitor.h
|
|
|
9ae3a8 |
@@ -13,6 +13,7 @@
|
|
|
9ae3a8 |
#ifndef QAPI_VISITOR_CORE_H
|
|
|
9ae3a8 |
#define QAPI_VISITOR_CORE_H
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+#include "qapi/qmp/qobject.h"
|
|
|
9ae3a8 |
#include "qapi/error.h"
|
|
|
9ae3a8 |
#include <stdlib.h>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -39,6 +40,8 @@ void visit_end_list(Visitor *v, Error **errp);
|
|
|
9ae3a8 |
void visit_start_optional(Visitor *v, bool *present, const char *name,
|
|
|
9ae3a8 |
Error **errp);
|
|
|
9ae3a8 |
void visit_end_optional(Visitor *v, Error **errp);
|
|
|
9ae3a8 |
+void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
|
|
|
9ae3a8 |
+ const char *name, Error **errp);
|
|
|
9ae3a8 |
void visit_type_enum(Visitor *v, int *obj, const char *strings[],
|
|
|
9ae3a8 |
const char *kind, const char *name, Error **errp);
|
|
|
9ae3a8 |
void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
|
|
9ae3a8 |
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
|
|
|
9ae3a8 |
index 9b4d51b..d6a4012 100644
|
|
|
9ae3a8 |
--- a/qapi/qapi-visit-core.c
|
|
|
9ae3a8 |
+++ b/qapi/qapi-visit-core.c
|
|
|
9ae3a8 |
@@ -12,6 +12,7 @@
|
|
|
9ae3a8 |
*/
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#include "qemu-common.h"
|
|
|
9ae3a8 |
+#include "qapi/qmp/qobject.h"
|
|
|
9ae3a8 |
#include "qapi/qmp/qerror.h"
|
|
|
9ae3a8 |
#include "qapi/visitor.h"
|
|
|
9ae3a8 |
#include "qapi/visitor-impl.h"
|
|
|
9ae3a8 |
@@ -98,6 +99,14 @@ void visit_end_optional(Visitor *v, Error **errp)
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
|
|
|
9ae3a8 |
+ const char *name, Error **errp)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ if (!error_is_set(errp) && v->get_next_type) {
|
|
|
9ae3a8 |
+ v->get_next_type(v, obj, qtypes, name, errp);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
void visit_type_enum(Visitor *v, int *obj, const char *strings[],
|
|
|
9ae3a8 |
const char *kind, const char *name, Error **errp)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
|
|
|
9ae3a8 |
index 70864a1..bf42c04 100644
|
|
|
9ae3a8 |
--- a/qapi/qmp-input-visitor.c
|
|
|
9ae3a8 |
+++ b/qapi/qmp-input-visitor.c
|
|
|
9ae3a8 |
@@ -208,6 +208,19 @@ static void qmp_input_end_list(Visitor *v, Error **errp)
|
|
|
9ae3a8 |
qmp_input_pop(qiv, errp);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,
|
|
|
9ae3a8 |
+ const char *name, Error **errp)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ QmpInputVisitor *qiv = to_qiv(v);
|
|
|
9ae3a8 |
+ QObject *qobj = qmp_input_get_object(qiv, name, false);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (!qobj) {
|
|
|
9ae3a8 |
+ error_set(errp, QERR_MISSING_PARAMETER, name ? name : "null");
|
|
|
9ae3a8 |
+ return;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ *kind = qobjects[qobject_type(qobj)];
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
|
|
|
9ae3a8 |
Error **errp)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
@@ -317,6 +330,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
|
|
|
9ae3a8 |
v->visitor.type_str = qmp_input_type_str;
|
|
|
9ae3a8 |
v->visitor.type_number = qmp_input_type_number;
|
|
|
9ae3a8 |
v->visitor.start_optional = qmp_input_start_optional;
|
|
|
9ae3a8 |
+ v->visitor.get_next_type = qmp_input_get_next_type;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
qmp_input_push(v, obj, NULL);
|
|
|
9ae3a8 |
qobject_incref(obj);
|
|
|
9ae3a8 |
diff --git a/qobject/qjson.c b/qobject/qjson.c
|
|
|
9ae3a8 |
index 19085a1..6cf2511 100644
|
|
|
9ae3a8 |
--- a/qobject/qjson.c
|
|
|
9ae3a8 |
+++ b/qobject/qjson.c
|
|
|
9ae3a8 |
@@ -260,6 +260,8 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
|
|
|
9ae3a8 |
/* XXX: should QError be emitted? */
|
|
|
9ae3a8 |
case QTYPE_NONE:
|
|
|
9ae3a8 |
break;
|
|
|
9ae3a8 |
+ case QTYPE_MAX:
|
|
|
9ae3a8 |
+ abort();
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
|
|
|
9ae3a8 |
index 3d9af3c..20f4bdf 100644
|
|
|
9ae3a8 |
--- a/scripts/qapi-types.py
|
|
|
9ae3a8 |
+++ b/scripts/qapi-types.py
|
|
|
9ae3a8 |
@@ -144,6 +144,40 @@ typedef enum %(name)s
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
return lookup_decl + enum_decl
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+def generate_anon_union_qtypes(expr):
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ name = expr['union']
|
|
|
9ae3a8 |
+ members = expr['data']
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ ret = mcgen('''
|
|
|
9ae3a8 |
+const int %(name)s_qtypes[QTYPE_MAX] = {
|
|
|
9ae3a8 |
+''',
|
|
|
9ae3a8 |
+ name=name)
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ for key in members:
|
|
|
9ae3a8 |
+ qapi_type = members[key]
|
|
|
9ae3a8 |
+ if builtin_type_qtypes.has_key(qapi_type):
|
|
|
9ae3a8 |
+ qtype = builtin_type_qtypes[qapi_type]
|
|
|
9ae3a8 |
+ elif find_struct(qapi_type):
|
|
|
9ae3a8 |
+ qtype = "QTYPE_QDICT"
|
|
|
9ae3a8 |
+ elif find_union(qapi_type):
|
|
|
9ae3a8 |
+ qtype = "QTYPE_QDICT"
|
|
|
9ae3a8 |
+ else:
|
|
|
9ae3a8 |
+ assert False, "Invalid anonymous union member"
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ ret += mcgen('''
|
|
|
9ae3a8 |
+ [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
|
|
|
9ae3a8 |
+''',
|
|
|
9ae3a8 |
+ qtype = qtype,
|
|
|
9ae3a8 |
+ abbrev = de_camel_case(name).upper(),
|
|
|
9ae3a8 |
+ enum = c_fun(de_camel_case(key),False).upper())
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ ret += mcgen('''
|
|
|
9ae3a8 |
+};
|
|
|
9ae3a8 |
+''')
|
|
|
9ae3a8 |
+ return ret
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
def generate_union(expr):
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
name = expr['union']
|
|
|
9ae3a8 |
@@ -184,6 +218,12 @@ struct %(name)s
|
|
|
9ae3a8 |
ret += mcgen('''
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
''')
|
|
|
9ae3a8 |
+ if discriminator == {}:
|
|
|
9ae3a8 |
+ ret += mcgen('''
|
|
|
9ae3a8 |
+extern const int %(name)s_qtypes[];
|
|
|
9ae3a8 |
+''',
|
|
|
9ae3a8 |
+ name=name)
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
return ret
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
@@ -336,6 +376,8 @@ for expr in exprs:
|
|
|
9ae3a8 |
ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
|
|
|
9ae3a8 |
ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
|
|
|
9ae3a8 |
fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
|
|
|
9ae3a8 |
+ if expr.get('discriminator') == {}:
|
|
|
9ae3a8 |
+ fdef.write(generate_anon_union_qtypes(expr))
|
|
|
9ae3a8 |
else:
|
|
|
9ae3a8 |
continue
|
|
|
9ae3a8 |
fdecl.write(ret)
|
|
|
9ae3a8 |
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
|
|
|
9ae3a8 |
index b1c1ad6..367cf7a 100644
|
|
|
9ae3a8 |
--- a/scripts/qapi-visit.py
|
|
|
9ae3a8 |
+++ b/scripts/qapi-visit.py
|
|
|
9ae3a8 |
@@ -176,6 +176,49 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
|
|
|
9ae3a8 |
''',
|
|
|
9ae3a8 |
name=name)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+def generate_visit_anon_union(name, members):
|
|
|
9ae3a8 |
+ ret = mcgen('''
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ Error *err = NULL;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (!error_is_set(errp)) {
|
|
|
9ae3a8 |
+ visit_start_implicit_struct(m, (void**) obj, sizeof(%(name)s), &err;;
|
|
|
9ae3a8 |
+ visit_get_next_type(m, (int*) &(*obj)->kind, %(name)s_qtypes, name, &err;;
|
|
|
9ae3a8 |
+ switch ((*obj)->kind) {
|
|
|
9ae3a8 |
+''',
|
|
|
9ae3a8 |
+ name=name)
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ for key in members:
|
|
|
9ae3a8 |
+ assert (members[key] in builtin_types
|
|
|
9ae3a8 |
+ or find_struct(members[key])
|
|
|
9ae3a8 |
+ or find_union(members[key])), "Invalid anonymous union member"
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ ret += mcgen('''
|
|
|
9ae3a8 |
+ case %(abbrev)s_KIND_%(enum)s:
|
|
|
9ae3a8 |
+ visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err;;
|
|
|
9ae3a8 |
+ break;
|
|
|
9ae3a8 |
+''',
|
|
|
9ae3a8 |
+ abbrev = de_camel_case(name).upper(),
|
|
|
9ae3a8 |
+ enum = c_fun(de_camel_case(key),False).upper(),
|
|
|
9ae3a8 |
+ c_type = type_name(members[key]),
|
|
|
9ae3a8 |
+ c_name = c_fun(key))
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ ret += mcgen('''
|
|
|
9ae3a8 |
+ default:
|
|
|
9ae3a8 |
+ abort();
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ error_propagate(errp, err);
|
|
|
9ae3a8 |
+ err = NULL;
|
|
|
9ae3a8 |
+ visit_end_implicit_struct(m, &err;;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+''')
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ return ret
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
def generate_visit_union(expr):
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
name = expr['union']
|
|
|
9ae3a8 |
@@ -184,6 +227,10 @@ def generate_visit_union(expr):
|
|
|
9ae3a8 |
base = expr.get('base')
|
|
|
9ae3a8 |
discriminator = expr.get('discriminator')
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ if discriminator == {}:
|
|
|
9ae3a8 |
+ assert not base
|
|
|
9ae3a8 |
+ return generate_visit_anon_union(name, members)
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
ret = generate_visit_enum('%sKind' % name, members.keys())
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if base:
|
|
|
9ae3a8 |
diff --git a/scripts/qapi.py b/scripts/qapi.py
|
|
|
9ae3a8 |
index 3a54c7f..38c808e 100644
|
|
|
9ae3a8 |
--- a/scripts/qapi.py
|
|
|
9ae3a8 |
+++ b/scripts/qapi.py
|
|
|
9ae3a8 |
@@ -17,6 +17,21 @@ builtin_types = [
|
|
|
9ae3a8 |
'uint8', 'uint16', 'uint32', 'uint64'
|
|
|
9ae3a8 |
]
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+builtin_type_qtypes = {
|
|
|
9ae3a8 |
+ 'str': 'QTYPE_QSTRING',
|
|
|
9ae3a8 |
+ 'int': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'number': 'QTYPE_QFLOAT',
|
|
|
9ae3a8 |
+ 'bool': 'QTYPE_QBOOL',
|
|
|
9ae3a8 |
+ 'int8': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'int16': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'int32': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'int64': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'uint8': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'uint16': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'uint32': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+ 'uint64': 'QTYPE_QINT',
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
def tokenize(data):
|
|
|
9ae3a8 |
while len(data):
|
|
|
9ae3a8 |
ch = data[0]
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.1
|
|
|
9ae3a8 |
|