[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/20] qapi: complete implementation of unions
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 10/20] qapi: complete implementation of unions |
Date: |
Mon, 12 Mar 2012 16:19:41 +0100 |
From: Paolo Bonzini <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
Acked-by: Luiz Capitulino <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
qapi-schema-test.json | 10 ++++++++++
scripts/qapi-types.py | 6 ++++++
scripts/qapi-visit.py | 31 ++++++++++++++++++++++++++++++-
test-qmp-input-visitor.c | 18 ++++++++++++++++++
test-qmp-output-visitor.c | 34 ++++++++++++++++++++++++++++++++++
5 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/qapi-schema-test.json b/qapi-schema-test.json
index 2b38919..8c7f9f7 100644
--- a/qapi-schema-test.json
+++ b/qapi-schema-test.json
@@ -22,6 +22,16 @@
'dict2': { 'userdef1': 'UserDefOne', 'string2': 'str' },
'*dict3': { 'userdef2': 'UserDefOne', 'string3': 'str'
} } } }
+# for testing unions
+{ 'type': 'UserDefA',
+ 'data': { 'boolean': 'bool' } }
+
+{ 'type': 'UserDefB',
+ 'data': { 'integer': 'int' } }
+
+{ 'union': 'UserDefUnion',
+ 'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
+
# testing commands
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index b56225b..727fb77 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -117,6 +117,7 @@ struct %(name)s
{
%(name)sKind kind;
union {
+ void *data;
''',
name=name)
@@ -269,6 +270,7 @@ for expr in exprs:
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()))
else:
continue
fdecl.write(ret)
@@ -283,6 +285,10 @@ for expr in exprs:
fdef.write(generate_type_cleanup(expr['type']) + "\n")
elif expr.has_key('union'):
ret += generate_union(expr['union'], expr['data'])
+ ret += generate_type_cleanup_decl(expr['union'] + "List")
+ fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
+ ret += generate_type_cleanup_decl(expr['union'])
+ fdef.write(generate_type_cleanup(expr['union']) + "\n")
else:
continue
fdecl.write(ret)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 5160d83..54117d4 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -110,10 +110,38 @@ def generate_visit_union(name, members):
void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error
**errp)
{
-}
+ Error *err = NULL;
+
+ visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s),
&err);
+ visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto end;
+ }
+ switch ((*obj)->kind) {
''',
name=name)
+ for key in members:
+ ret += mcgen('''
+ case %(abbrev)s_KIND_%(enum)s:
+ visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", errp);
+ break;
+''',
+ abbrev = de_camel_case(name).upper(),
+ enum = de_camel_case(key).upper(),
+ c_type=members[key],
+ c_name=c_var(key))
+
+ ret += mcgen('''
+ default:
+ abort();
+ }
+end:
+ visit_end_struct(m, errp);
+}
+''')
+
return ret
def generate_declaration(name, members, genlist=True):
@@ -242,6 +270,7 @@ for expr in exprs:
fdecl.write(ret)
elif expr.has_key('union'):
ret = generate_visit_union(expr['union'], expr['data'])
+ ret += generate_visit_list(expr['union'], expr['data'])
fdef.write(ret)
ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
diff --git a/test-qmp-input-visitor.c b/test-qmp-input-visitor.c
index 926db5c..1996e49 100644
--- a/test-qmp-input-visitor.c
+++ b/test-qmp-input-visitor.c
@@ -234,6 +234,22 @@ static void test_visitor_in_list(TestInputVisitorData
*data,
qapi_free_UserDefOneList(head);
}
+static void test_visitor_in_union(TestInputVisitorData *data,
+ const void *unused)
+{
+ Visitor *v;
+ Error *err = NULL;
+ UserDefUnion *tmp;
+
+ v = visitor_input_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42
} }");
+
+ visit_type_UserDefUnion(v, &tmp, NULL, &err);
+ g_assert(err == NULL);
+ g_assert_cmpint(tmp->kind, ==, USER_DEF_UNION_KIND_B);
+ g_assert_cmpint(tmp->b->integer, ==, 42);
+ qapi_free_UserDefUnion(tmp);
+}
+
static void input_visitor_test_add(const char *testpath,
TestInputVisitorData *data,
void (*test_func)(TestInputVisitorData
*data, const void *user_data))
@@ -264,6 +280,8 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_struct_nested);
input_visitor_test_add("/visitor/input/list",
&in_visitor_data, test_visitor_in_list);
+ input_visitor_test_add("/visitor/input/union",
+ &in_visitor_data, test_visitor_in_union);
g_test_run();
diff --git a/test-qmp-output-visitor.c b/test-qmp-output-visitor.c
index 5452cd4..4d6c4d4 100644
--- a/test-qmp-output-visitor.c
+++ b/test-qmp-output-visitor.c
@@ -380,6 +380,38 @@ static void
test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
qapi_free_UserDefNestedList(head);
}
+static void test_visitor_out_union(TestOutputVisitorData *data,
+ const void *unused)
+{
+ QObject *arg, *qvalue;
+ QDict *qdict, *value;
+
+ Error *err = NULL;
+
+ UserDefUnion *tmp = g_malloc0(sizeof(UserDefUnion));
+ tmp->kind = USER_DEF_UNION_KIND_A;
+ tmp->a = g_malloc0(sizeof(UserDefA));
+ tmp->a->boolean = true;
+
+ visit_type_UserDefUnion(data->ov, &tmp, NULL, &err);
+ g_assert(err == NULL);
+ arg = qmp_output_get_qobject(data->qov);
+
+ g_assert(qobject_type(arg) == QTYPE_QDICT);
+ qdict = qobject_to_qdict(arg);
+
+ g_assert_cmpstr(qdict_get_str(qdict, "type"), ==, "a");
+
+ qvalue = qdict_get(qdict, "data");
+ g_assert(data != NULL);
+ g_assert(qobject_type(qvalue) == QTYPE_QDICT);
+ value = qobject_to_qdict(qvalue);
+ g_assert_cmpint(qdict_get_bool(value, "boolean"), ==, true);
+
+ qapi_free_UserDefUnion(tmp);
+ QDECREF(qdict);
+}
+
static void output_visitor_test_add(const char *testpath,
TestOutputVisitorData *data,
void (*test_func)(TestOutputVisitorData
*data, const void *user_data))
@@ -416,6 +448,8 @@ int main(int argc, char **argv)
&out_visitor_data, test_visitor_out_list);
output_visitor_test_add("/visitor/output/list-qapi-free",
&out_visitor_data,
test_visitor_out_list_qapi_free);
+ output_visitor_test_add("/visitor/output/union",
+ &out_visitor_data, test_visitor_out_union);
g_test_run();
--
1.7.6.5
- [Qemu-devel] [PULL 00/20] Block patches, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 08/20] Add 'make check-block', Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 05/20] qcow2: Add error messages in qcow2_truncate, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 06/20] qemu-iotests: Mark some tests as quick, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 02/20] qed: do not evict in-use L2 table cache entries, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 01/20] Group snapshot: Fix format name for backing file, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 16/20] qcow2: Reduce number of I/O requests, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 03/20] qcow2: Add some tracing, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 17/20] coroutine: adding sigaltstack method (.c source), Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 18/20] coroutine: adding configure choose mechanism for coroutine backend, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 10/20] qapi: complete implementation of unions,
Kevin Wolf <=
- [Qemu-devel] [PATCH 04/20] block: handle -EBUSY in bdrv_commit_all(), Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 20/20] test-coroutine: add performance test for nesting, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 07/20] make check: Add qemu-iotests subset, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 14/20] qcow2: Factor out count_cow_clusters, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 09/20] use QSIMPLEQ_FOREACH_SAFE when freeing list elements, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 12/20] add mode field to blockdev-snapshot-sync transaction item, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 19/20] coroutine: adding configure option for sigaltstack coroutine backend, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 13/20] qmp: convert blockdev-snapshot-sync to a wrapper around transactions, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 11/20] rename blockdev-group-snapshot-sync, Kevin Wolf, 2012/03/12
- [Qemu-devel] [PATCH 15/20] qcow2: Add qcow2_alloc_clusters_at(), Kevin Wolf, 2012/03/12