summaryrefslogtreecommitdiff
path: root/qapi
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-04-28 15:45:20 -0600
committerMarkus Armbruster <armbru@redhat.com>2016-05-12 09:47:54 +0200
commitadfb264c9ed04bfc694921b72173be8e29e90024 (patch)
treef30741b641b2d2a4cf38cf5fa7c80e5f4dae2343 /qapi
parentfcf3cb21783b2dae3358fdbe7001cb2f74e0cedf (diff)
downloadqemu-adfb264c9ed04bfc694921b72173be8e29e90024.zip
qapi: Document visitor interfaces, add assertions
The visitor interface for mapping between QObject/QemuOpts/string and QAPI is scandalously under-documented, making changes to visitor core, individual visitors, and users of visitors difficult to coordinate. Among other questions: when is it safe to pass NULL, vs. when a string must be provided; which visitors implement which callbacks; the difference between concrete and virtual visits. Correct this by retrofitting proper contracts, and document where some of the interface warts remain (for example, we may want to modify visit_end_* to require the same 'obj' as the visit_start counterpart, so the dealloc visitor can be simplified). Later patches in this series will tackle some, but not all, of these warts. Add assertions to (partially) enforce the contract. Some of these were only made possible by recent cleanup commits. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <1461879932-9020-13-git-send-email-eblake@redhat.com> [Doc fix from Eric squashed in] Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'qapi')
-rw-r--r--qapi/qapi-visit-core.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 528092e55f..0f59a1d8e5 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -25,6 +25,10 @@ void visit_start_struct(Visitor *v, const char *name, void **obj,
{
Error *err = NULL;
+ if (obj) {
+ assert(size);
+ assert(v->type != VISITOR_OUTPUT || *obj);
+ }
v->start_struct(v, name, obj, size, &err);
if (obj && v->type == VISITOR_INPUT) {
assert(!err != !*obj);
@@ -60,6 +64,7 @@ void visit_start_alternate(Visitor *v, const char *name,
Error *err = NULL;
assert(obj && size >= sizeof(GenericAlternate));
+ assert(v->type != VISITOR_OUTPUT || *obj);
if (v->start_alternate) {
v->start_alternate(v, name, obj, size, promote_int, &err);
}
@@ -86,6 +91,7 @@ bool visit_optional(Visitor *v, const char *name, bool *present)
void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
{
+ assert(obj);
v->type_int64(v, name, obj, errp);
}
@@ -133,6 +139,7 @@ void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
Error **errp)
{
+ assert(obj);
v->type_uint64(v, name, obj, errp);
}
@@ -180,12 +187,14 @@ void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
Error **errp)
{
+ assert(obj);
v->type_int64(v, name, obj, errp);
}
void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
Error **errp)
{
+ assert(obj);
if (v->type_size) {
v->type_size(v, name, obj, errp);
} else {
@@ -195,6 +204,7 @@ void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
{
+ assert(obj);
v->type_bool(v, name, obj, errp);
}
@@ -203,6 +213,10 @@ void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
Error *err = NULL;
assert(obj);
+ /* TODO: Fix callers to not pass NULL when they mean "", so that we
+ * can enable:
+ assert(v->type != VISITOR_OUTPUT || *obj);
+ */
v->type_str(v, name, obj, &err);
if (v->type == VISITOR_INPUT) {
assert(!err != !*obj);
@@ -213,6 +227,7 @@ void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
void visit_type_number(Visitor *v, const char *name, double *obj,
Error **errp)
{
+ assert(obj);
v->type_number(v, name, obj, errp);
}
@@ -221,6 +236,7 @@ void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
Error *err = NULL;
assert(obj);
+ assert(v->type != VISITOR_OUTPUT || *obj);
v->type_any(v, name, obj, &err);
if (v->type == VISITOR_INPUT) {
assert(!err != !*obj);
@@ -278,7 +294,7 @@ static void input_type_enum(Visitor *v, const char *name, int *obj,
void visit_type_enum(Visitor *v, const char *name, int *obj,
const char *const strings[], Error **errp)
{
- assert(strings);
+ assert(obj && strings);
if (v->type == VISITOR_INPUT) {
input_type_enum(v, name, obj, strings, errp);
} else if (v->type == VISITOR_OUTPUT) {