qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: mdroth@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH RFC v4 26/32] qapi: Introduce a first class 'any' type
Date: Thu,  3 Sep 2015 16:30:17 +0200	[thread overview]
Message-ID: <1441290623-13631-27-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1441290623-13631-1-git-send-email-armbru@redhat.com>

It's first class, because unlike '**', it actually works, i.e. doesn't
require 'gen': false.

'**' will go away next.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 docs/qapi-code-gen.txt                             |  1 +
 include/qapi/visitor-impl.h                        |  2 +
 include/qapi/visitor.h                             |  1 +
 qapi/qapi-dealloc-visitor.c                        |  9 ++++
 qapi/qapi-visit-core.c                             |  6 +++
 qapi/qmp-input-visitor.c                           | 11 +++++
 qapi/qmp-output-visitor.c                          |  9 ++++
 scripts/qapi-types.py                              |  1 +
 scripts/qapi.py                                    |  9 ++--
 tests/Makefile                                     |  3 +-
 tests/qapi-schema/args-any.err                     |  1 +
 .../{flat-union-base-star.exit => args-any.exit}   |  0
 tests/qapi-schema/args-any.json                    |  2 +
 .../{flat-union-base-star.out => args-any.out}     |  0
 tests/qapi-schema/flat-union-base-any.err          |  1 +
 tests/qapi-schema/flat-union-base-any.exit         |  1 +
 ...ion-base-star.json => flat-union-base-any.json} |  2 +-
 tests/qapi-schema/flat-union-base-any.out          |  0
 tests/qapi-schema/flat-union-base-star.err         |  1 -
 tests/qapi-schema/qapi-schema-test.json            |  5 +-
 tests/qapi-schema/qapi-schema-test.out             |  9 +++-
 tests/qapi-schema/type-bypass.out                  |  4 +-
 tests/test-qmp-commands.c                          |  5 ++
 tests/test-qmp-input-visitor.c                     | 45 ++++++++++++++++++
 tests/test-qmp-output-visitor.c                    | 53 ++++++++++++++++++++++
 25 files changed, 171 insertions(+), 10 deletions(-)
 create mode 100644 tests/qapi-schema/args-any.err
 rename tests/qapi-schema/{flat-union-base-star.exit => args-any.exit} (100%)
 create mode 100644 tests/qapi-schema/args-any.json
 rename tests/qapi-schema/{flat-union-base-star.out => args-any.out} (100%)
 create mode 100644 tests/qapi-schema/flat-union-base-any.err
 create mode 100644 tests/qapi-schema/flat-union-base-any.exit
 rename tests/qapi-schema/{flat-union-base-star.json => flat-union-base-any.json} (95%)
 create mode 100644 tests/qapi-schema/flat-union-base-any.out
 delete mode 100644 tests/qapi-schema/flat-union-base-star.err

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 35a4a0f..c713e3a 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -158,6 +158,7 @@ The following types are predefined, and map to C as follows:
   size      uint64_t   like uint64_t, except StringInputVisitor
                        accepts size suffixes
   bool      bool       JSON true or false
+  any       QObject *  any JSON value
 
 
 === Includes ===
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index f4a2f74..8c0ba57 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -40,6 +40,8 @@ struct Visitor
     void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
     void (*type_number)(Visitor *v, double *obj, const char *name,
                         Error **errp);
+    void (*type_any)(Visitor *v, QObject **obj, const char *name,
+                     Error **errp);
 
     /* May be NULL */
     void (*optional)(Visitor *v, bool *present, const char *name,
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 00ba104..cfc19a6 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -58,6 +58,7 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
 void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
 void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
 void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
+void visit_type_any(Visitor *v, QObject **obj, const char *name, Error **errp);
 bool visit_start_union(Visitor *v, bool data_present, Error **errp);
 void visit_end_union(Visitor *v, bool data_present, Error **errp);
 
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index d7f92c5..737deab 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -151,6 +151,14 @@ static void qapi_dealloc_type_number(Visitor *v, double *obj, const char *name,
 {
 }
 
+static void qapi_dealloc_type_anything(Visitor *v, QObject **obj,
+                                       const char *name, Error **errp)
+{
+    if (obj) {
+        qobject_decref(*obj);
+    }
+}
+
 static void qapi_dealloc_type_size(Visitor *v, uint64_t *obj, const char *name,
                                    Error **errp)
 {
@@ -216,6 +224,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
     v->visitor.type_bool = qapi_dealloc_type_bool;
     v->visitor.type_str = qapi_dealloc_type_str;
     v->visitor.type_number = qapi_dealloc_type_number;
+    v->visitor.type_any = qapi_dealloc_type_anything;
     v->visitor.type_size = qapi_dealloc_type_size;
     v->visitor.start_union = qapi_dealloc_start_union;
 
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 5a7c900..59ed506 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -260,6 +260,12 @@ void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
     v->type_number(v, obj, name, errp);
 }
 
+void visit_type_any(Visitor *v, QObject **obj, const char *name,
+                    Error **errp)
+{
+    v->type_any(v, obj, name, errp);
+}
+
 void output_type_enum(Visitor *v, int *obj, const char * const strings[],
                       const char *kind, const char *name,
                       Error **errp)
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index e97b8a4..5dd9ed5 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -286,6 +286,16 @@ static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
     }
 }
 
+static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name,
+                               Error **errp)
+{
+    QmpInputVisitor *qiv = to_qiv(v);
+    QObject *qobj = qmp_input_get_object(qiv, name, true);
+
+    qobject_incref(qobj);
+    *obj = qobj;
+}
+
 static void qmp_input_optional(Visitor *v, bool *present, const char *name,
                                Error **errp)
 {
@@ -329,6 +339,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
     v->visitor.type_bool = qmp_input_type_bool;
     v->visitor.type_str = qmp_input_type_str;
     v->visitor.type_number = qmp_input_type_number;
+    v->visitor.type_any = qmp_input_type_any;
     v->visitor.optional = qmp_input_optional;
     v->visitor.get_next_type = qmp_input_get_next_type;
 
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index efc19d5..1e36a7a 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -186,6 +186,14 @@ static void qmp_output_type_number(Visitor *v, double *obj, const char *name,
     qmp_output_add(qov, name, qfloat_from_double(*obj));
 }
 
+static void qmp_output_type_any(Visitor *v, QObject **obj, const char *name,
+                                Error **errp)
+{
+    QmpOutputVisitor *qov = to_qov(v);
+    qobject_incref(*obj);
+    qmp_output_add_obj(qov, name, *obj);
+}
+
 QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
 {
     QObject *obj = qmp_output_first(qov);
@@ -233,6 +241,7 @@ QmpOutputVisitor *qmp_output_visitor_new(void)
     v->visitor.type_bool = qmp_output_type_bool;
     v->visitor.type_str = qmp_output_type_str;
     v->visitor.type_number = qmp_output_type_number;
+    v->visitor.type_any = qmp_output_type_any;
 
     QTAILQ_INIT(&v->stack);
 
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index b5ebeee..70a57c0 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -305,6 +305,7 @@ fdef.write(mcgen('''
 fdecl.write(mcgen('''
 #include <stdbool.h>
 #include <stdint.h>
+#include "qapi/qmp/qobject.h"
 '''))
 
 schema = QAPISchema(input_file)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 0a325d5..a3e4b66 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -33,6 +33,7 @@ builtin_types = {
     'uint32':   'QTYPE_QINT',
     'uint64':   'QTYPE_QINT',
     'size':     'QTYPE_QINT',
+    'any':      None,           # any qtype_code possible, actually
 }
 
 # Whitelist of commands allowed to return a non-dictionary
@@ -1036,8 +1037,7 @@ class QAPISchema(object):
 
     def _def_builtin_type(self, name, json_type, c_type, c_null):
         self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type, c_null))
-        if name != '**':
-            self._make_array_type(name) # TODO really needed?
+        self._make_array_type(name) # TODO really needed?
 
     def _def_predefineds(self):
         for t in [('str',    'string',  'char' + pointer_suffix, 'NULL'),
@@ -1053,8 +1053,9 @@ class QAPISchema(object):
                   ('uint64', 'int',     'uint64_t', '0'),
                   ('size',   'int',     'uint64_t', '0'),
                   ('bool',   'boolean', 'bool',     'false'),
-                  ('**',     'value',   None,       None)]:
+                  ('any',    'value',   'QObject' + pointer_suffix , 'NULL')]:
             self._def_builtin_type(*t)
+        self.entity_dict['**'] = self.lookup_type('any') # TODO drop this alias
 
     def _make_implicit_enum_type(self, name, values):
         name = name + 'Kind'
@@ -1201,6 +1202,8 @@ class QAPISchema(object):
     def visit(self, visitor):
         visitor.visit_begin(self)
         for name in sorted(self.entity_dict.keys()):
+            if self.entity_dict[name].name != name:
+                continue        # ignore alias TODO drop alias and remove
             self.entity_dict[name].visit(visitor)
         visitor.visit_end()
 
diff --git a/tests/Makefile b/tests/Makefile
index b128e28..fc6169a 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -233,6 +233,7 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
 	args-array-empty.json args-array-unknown.json args-int.json \
 	args-unknown.json args-member-unknown.json args-member-array.json \
 	args-member-array-bad.json args-alternate.json args-union.json \
+	args-any.json \
 	returns-array-bad.json returns-int.json returns-dict.json \
 	returns-unknown.json returns-alternate.json returns-whitelist.json \
 	missing-colon.json missing-comma-list.json missing-comma-object.json \
@@ -249,7 +250,7 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
 	flat-union-invalid-branch-key.json flat-union-reverse-define.json \
 	flat-union-string-discriminator.json union-base-no-discriminator.json \
 	flat-union-bad-discriminator.json flat-union-bad-base.json \
-	flat-union-base-star.json \
+	flat-union-base-any.json \
 	flat-union-array-branch.json flat-union-int-branch.json \
 	flat-union-base-union.json flat-union-branch-clash.json \
 	alternate-nested.json alternate-unknown.json alternate-clash.json \
diff --git a/tests/qapi-schema/args-any.err b/tests/qapi-schema/args-any.err
new file mode 100644
index 0000000..bf9b5e0
--- /dev/null
+++ b/tests/qapi-schema/args-any.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-any.json:2: 'data' for command 'oops' cannot use built-in type 'any'
diff --git a/tests/qapi-schema/flat-union-base-star.exit b/tests/qapi-schema/args-any.exit
similarity index 100%
rename from tests/qapi-schema/flat-union-base-star.exit
rename to tests/qapi-schema/args-any.exit
diff --git a/tests/qapi-schema/args-any.json b/tests/qapi-schema/args-any.json
new file mode 100644
index 0000000..58fe5e4
--- /dev/null
+++ b/tests/qapi-schema/args-any.json
@@ -0,0 +1,2 @@
+# we do not allow an 'any' argument
+{ 'command': 'oops', 'data': 'any' }
diff --git a/tests/qapi-schema/flat-union-base-star.out b/tests/qapi-schema/args-any.out
similarity index 100%
rename from tests/qapi-schema/flat-union-base-star.out
rename to tests/qapi-schema/args-any.out
diff --git a/tests/qapi-schema/flat-union-base-any.err b/tests/qapi-schema/flat-union-base-any.err
new file mode 100644
index 0000000..ad4d629
--- /dev/null
+++ b/tests/qapi-schema/flat-union-base-any.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-base-any.json:8: Base 'any' is not a valid struct
diff --git a/tests/qapi-schema/flat-union-base-any.exit b/tests/qapi-schema/flat-union-base-any.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/flat-union-base-any.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/flat-union-base-star.json b/tests/qapi-schema/flat-union-base-any.json
similarity index 95%
rename from tests/qapi-schema/flat-union-base-star.json
rename to tests/qapi-schema/flat-union-base-any.json
index 5099439..fe66b71 100644
--- a/tests/qapi-schema/flat-union-base-star.json
+++ b/tests/qapi-schema/flat-union-base-any.json
@@ -6,7 +6,7 @@
 { 'struct': 'TestTypeB',
   'data': { 'integer': 'int' } }
 { 'union': 'TestUnion',
-  'base': '**',
+  'base': 'any',
   'discriminator': 'enum1',
   'data': { 'value1': 'TestTypeA',
             'value2': 'TestTypeB' } }
diff --git a/tests/qapi-schema/flat-union-base-any.out b/tests/qapi-schema/flat-union-base-any.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/flat-union-base-star.err b/tests/qapi-schema/flat-union-base-star.err
deleted file mode 100644
index b7748f0..0000000
--- a/tests/qapi-schema/flat-union-base-star.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/flat-union-base-star.json:8: Base '**' is not a valid struct
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 90b4740..e855018 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -73,7 +73,8 @@
             'number': ['number'],
             'boolean': ['bool'],
             'string': ['str'],
-            'sizes': ['size'] } }
+            'sizes': ['size'],
+            'any': ['any'] } }
 
 # testing commands
 { 'command': 'user_def_cmd', 'data': {} }
@@ -83,6 +84,8 @@
   'returns': 'UserDefTwo' }
 { 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' },
   'returns': 'int' }
+# note: command name 'guest-sync' chosen to avoid "cannot use built-in" error
+{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
 
 # For testing integer range flattening in opts-visitor. The following schema
 # corresponds to the option format:
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index b30bccc..fbb590f 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -12,8 +12,12 @@ object :obj-__org.qemu_x-command-arg
     member b: __org.qemu_x-StructList optional=False
     member c: __org.qemu_x-Union2 optional=False
     member d: __org.qemu_x-Alt optional=False
+object :obj-anyList-wrapper
+    member data: anyList optional=False
 object :obj-boolList-wrapper
     member data: boolList optional=False
+object :obj-guest-sync-arg
+    member arg: any optional=False
 object :obj-int16List-wrapper
     member data: int16List optional=False
 object :obj-int32List-wrapper
@@ -100,7 +104,8 @@ object UserDefNativeListUnion
     case boolean: :obj-boolList-wrapper
     case string: :obj-strList-wrapper
     case sizes: :obj-sizeList-wrapper
-enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes']
+    case any: :obj-anyList-wrapper
+enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
 object UserDefOne
     base UserDefZero
     member string: str optional=False
@@ -149,6 +154,8 @@ object __org.qemu_x-Union2
     case __org.qemu_x-value: __org.qemu_x-Struct2
 command __org.qemu_x-command :obj-__org.qemu_x-command-arg -> __org.qemu_x-Union1
    gen=True success_response=True
+command guest-sync :obj-guest-sync-arg -> any
+   gen=True success_response=True
 command user_def_cmd None -> None
    gen=True success_response=True
 command user_def_cmd1 :obj-user_def_cmd1-arg -> None
diff --git a/tests/qapi-schema/type-bypass.out b/tests/qapi-schema/type-bypass.out
index 0070d4b..db2a4e6 100644
--- a/tests/qapi-schema/type-bypass.out
+++ b/tests/qapi-schema/type-bypass.out
@@ -1,4 +1,4 @@
 object :obj-unsafe-arg
-    member arg: ** optional=False
-command unsafe :obj-unsafe-arg -> **
+    member arg: any optional=False
+command unsafe :obj-unsafe-arg -> any
    gen=False success_response=True
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 9918f23..8d5249e 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -51,6 +51,11 @@ int64_t qmp_user_def_cmd3(int64_t a, bool has_b, int64_t b, Error **errp)
     return a + (has_b ? b : 0);
 }
 
+QObject *qmp_guest_sync(QObject *arg, Error **errp)
+{
+    return arg;
+}
+
 __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
                                               __org_qemu_x_StructList *b,
                                               __org_qemu_x_Union2 *c,
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 508c11a..61715b3 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -298,6 +298,49 @@ static void test_visitor_in_list(TestInputVisitorData *data,
     qapi_free_UserDefOneList(head);
 }
 
+static void test_visitor_in_any(TestInputVisitorData *data,
+                                const void *unused)
+{
+    QObject *res = NULL;
+    Error *err = NULL;
+    Visitor *v;
+    QInt *qint;
+    QBool *qbool;
+    QString *qstring;
+    QDict *qdict;
+    QObject *qobj;
+
+    v = visitor_input_test_init(data, "-42");
+    visit_type_any(v, &res, NULL, &err);
+    g_assert(!err);
+    qint = qobject_to_qint(res);
+    g_assert(qint);
+    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qobject_decref(res);
+
+    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
+    visit_type_any(v, &res, NULL, &err);
+    g_assert(!err);
+    qdict = qobject_to_qdict(res);
+    g_assert(qdict && qdict_size(qdict) == 3);
+    qobj = qdict_get(qdict, "integer");
+    g_assert(qobj);
+    qint = qobject_to_qint(qobj);
+    g_assert(qint);
+    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qobj = qdict_get(qdict, "boolean");
+    g_assert(qobj);
+    qbool = qobject_to_qbool(qobj);
+    g_assert(qbool);
+    g_assert(qbool_get_bool(qbool) == true);
+    qobj = qdict_get(qdict, "string");
+    g_assert(qobj);
+    qstring = qobject_to_qstring(qobj);
+    g_assert(qstring);
+    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
+    qobject_decref(res);
+}
+
 static void test_visitor_in_union_flat(TestInputVisitorData *data,
                                        const void *unused)
 {
@@ -669,6 +712,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/any",
+                           &in_visitor_data, test_visitor_in_any);
     input_visitor_test_add("/visitor/input/union-flat",
                            &in_visitor_data, test_visitor_in_union_flat);
     input_visitor_test_add("/visitor/input/alternate",
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 338ada0..1a28dc2 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -428,6 +428,57 @@ static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
     qapi_free_UserDefTwoList(head);
 }
 
+static void test_visitor_out_any(TestOutputVisitorData *data,
+                                 const void *unused)
+{
+    QObject *qobj;
+    Error *err = NULL;
+    QInt *qint;
+    QBool *qbool;
+    QString *qstring;
+    QDict *qdict;
+    QObject *obj;
+
+    qobj = QOBJECT(qint_from_int(-42));
+    visit_type_any(data->ov, &qobj, NULL, &err);
+    g_assert(!err);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
+    g_assert(qobject_type(obj) == QTYPE_QINT);
+    g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, -42);
+    qobject_decref(obj);
+    qobject_decref(qobj);
+
+    qdict = qdict_new();
+    qdict_put(qdict, "integer", qint_from_int(-42));
+    qdict_put(qdict, "boolean", qbool_from_bool(true));
+    qdict_put(qdict, "string", qstring_from_str("foo"));
+    qobj = QOBJECT(qdict);
+    visit_type_any(data->ov, &qobj, NULL, &err);
+    g_assert(!err);
+    obj = qmp_output_get_qobject(data->qov);
+    g_assert(obj != NULL);
+    qdict = qobject_to_qdict(obj);
+    g_assert(qdict);
+    qobj = qdict_get(qdict, "integer");
+    g_assert(qobj);
+    qint = qobject_to_qint(qobj);
+    g_assert(qint);
+    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qobj = qdict_get(qdict, "boolean");
+    g_assert(qobj);
+    qbool = qobject_to_qbool(qobj);
+    g_assert(qbool);
+    g_assert(qbool_get_bool(qbool) == true);
+    qobj = qdict_get(qdict, "string");
+    g_assert(qobj);
+    qstring = qobject_to_qstring(qobj);
+    g_assert(qstring);
+    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
+    qobject_decref(obj);
+    qobject_decref(qobj);
+}
+
 static void test_visitor_out_union_flat(TestOutputVisitorData *data,
                                         const void *unused)
 {
@@ -832,6 +883,8 @@ int main(int argc, char **argv)
                             &out_visitor_data, test_visitor_out_struct_errors);
     output_visitor_test_add("/visitor/output/list",
                             &out_visitor_data, test_visitor_out_list);
+    output_visitor_test_add("/visitor/output/any",
+                            &out_visitor_data, test_visitor_out_any);
     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-flat",
-- 
2.4.3

  parent reply	other threads:[~2015-09-03 14:30 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-03 14:29 [Qemu-devel] [PATCH RFC v4 00/32] qapi: QMP introspection Markus Armbruster
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 01/32] qapi: Rename class QAPISchema to QAPISchemaParser Markus Armbruster
2015-09-03 15:55   ` Daniel P. Berrange
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 02/32] qapi: New QAPISchema intermediate reperesentation Markus Armbruster
2015-09-03 16:11   ` Daniel P. Berrange
2015-09-04  7:12     ` Markus Armbruster
2015-09-04  8:51       ` Daniel P. Berrange
2015-09-04 11:13         ` Markus Armbruster
2015-09-04  3:05   ` Eric Blake
2015-09-04 12:34   ` Eric Blake
2015-09-04 14:40     ` Markus Armbruster
2015-09-04 23:51       ` [Qemu-devel] [PATCH RFC v4 02.5/32] qapi: Hide internal data members of schema objects Eric Blake
2015-09-05 13:19         ` Eric Blake
2015-09-05 13:25           ` Eric Blake
2015-09-05 13:45             ` Eric Blake
2015-09-07  6:57               ` Markus Armbruster
2015-09-07  6:58         ` Markus Armbruster
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 03/32] qapi: QAPISchema code generation helper methods Markus Armbruster
2015-09-03 16:13   ` Daniel P. Berrange
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 04/32] qapi: New QAPISchemaVisitor Markus Armbruster
2015-09-03 16:16   ` Daniel P. Berrange
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 05/32] tests/qapi-schema: Convert test harness to QAPISchemaVisitor Markus Armbruster
2015-09-03 16:18   ` Daniel P. Berrange
2015-09-03 16:24   ` Eric Blake
2015-09-05 13:23   ` Eric Blake
2015-09-07  7:10     ` Markus Armbruster
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 06/32] qapi: Split up some typedefs to ease review Markus Armbruster
2015-09-03 16:19   ` Daniel P. Berrange
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 07/32] qapi: Generate comments to simplify splitting for review Markus Armbruster
2015-09-03 16:21   ` Daniel P. Berrange
2015-09-03 14:29 ` [Qemu-devel] [PATCH RFC v4 08/32] Revert "qapi: Generate comments to simplify splitting for review" Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 09/32] Revert "qapi: Split up some typedefs to ease review" Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 10/32] qapi-types: Convert to QAPISchemaVisitor, fixing flat unions Markus Armbruster
2015-09-04  3:11   ` Eric Blake
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 11/32] qapi-visit: Convert to QAPISchemaVisitor, fixing bugs Markus Armbruster
2015-09-04  3:14   ` Eric Blake
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 12/32] qapi-commands: Convert to QAPISchemaVisitor Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 13/32] qapi: De-duplicate enum code generation Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 14/32] qapi-event: Eliminate global variable event_enum_value Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 15/32] qapi-event: Convert to QAPISchemaVisitor, fixing data with base Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 16/32] qapi: Generate comments to simplify splitting for review Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 17/32] Revert "qapi: Generate comments to simplify splitting for review" Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 18/32] qapi: Replace dirty is_c_ptr() by method c_null() Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 19/32] qapi: Clean up after recent conversions to QAPISchemaVisitor Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 20/32] qapi-visit: Rearrange code a bit Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 21/32] qapi-commands: Rearrange code Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 22/32] qapi: Rename qmp_marshal_input_FOO() to qmp_marshal_FOO() Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 23/32] qapi: De-duplicate parameter list generation Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 24/32] qapi-commands: De-duplicate output marshaling functions Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 25/32] qapi: Improve built-in type documentation Markus Armbruster
2015-09-03 14:30 ` Markus Armbruster [this message]
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 27/32] qom: Don't use 'gen': false for qom-get, qom-set, object-add Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 28/32] qapi-schema: Fix up misleading specification of netdev_add Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 29/32] qapi: Pseudo-type '**' is now unused, drop it Markus Armbruster
2015-09-03 20:42   ` Eric Blake
2015-09-04  7:14     ` Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 30/32] qapi: New QMP command query-schema for QMP schema introspection Markus Armbruster
2015-09-03 20:50   ` Eric Blake
2015-09-04  0:04     ` Michael Roth
2015-09-04  7:19       ` Markus Armbruster
2015-09-03 23:59   ` Michael Roth
2015-09-04  8:54     ` Markus Armbruster
2015-09-04  2:03   ` Eric Blake
2015-09-04  3:12     ` Eric Blake
2015-09-04  9:55     ` Markus Armbruster
2015-09-04 13:58       ` Eric Blake
2015-09-04 15:08         ` Markus Armbruster
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 31/32] qapi-introspect: Map all integer types to 'int' Markus Armbruster
2015-09-04 14:00   ` Eric Blake
2015-09-03 14:30 ` [Qemu-devel] [PATCH RFC v4 32/32] qapi-introspect: Hide type names Markus Armbruster
2015-09-04 14:07   ` Eric Blake
2015-09-04 15:52     ` Markus Armbruster
2015-09-04 12:57 ` [Qemu-devel] [PATCH RFC v4 00/32] qapi: QMP introspection Marc-André Lureau
2015-09-04 14:14   ` Eric Blake
2015-09-04 15:55   ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1441290623-13631-27-git-send-email-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).