aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/qapi/opts-visitor.h3
-rw-r--r--include/qapi/string-input-visitor.h3
-rw-r--r--include/qapi/string-output-visitor.h3
-rw-r--r--include/qapi/visitor-impl.h8
-rw-r--r--include/qapi/visitor.h49
5 files changed, 37 insertions, 29 deletions
diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h
index fe37ed9a36..ae1bf7cf51 100644
--- a/include/qapi/opts-visitor.h
+++ b/include/qapi/opts-visitor.h
@@ -32,7 +32,8 @@ typedef struct OptsVisitor OptsVisitor;
*
* The Opts input visitor does not implement support for visiting QAPI
* alternates, numbers (other than integers), null, or arbitrary
- * QTypes.
+ * QTypes. It also requires a non-null list argument to
+ * visit_start_list().
*/
OptsVisitor *opts_visitor_new(const QemuOpts *opts);
void opts_visitor_cleanup(OptsVisitor *nv);
diff --git a/include/qapi/string-input-visitor.h b/include/qapi/string-input-visitor.h
index a8d8f6723b..7b76c2b9e3 100644
--- a/include/qapi/string-input-visitor.h
+++ b/include/qapi/string-input-visitor.h
@@ -19,7 +19,8 @@ typedef struct StringInputVisitor StringInputVisitor;
/*
* The string input visitor does not implement support for visiting
- * QAPI structs, alternates, null, or arbitrary QTypes.
+ * QAPI structs, alternates, null, or arbitrary QTypes. It also
+ * requires a non-null list argument to visit_start_list().
*/
StringInputVisitor *string_input_visitor_new(const char *str);
void string_input_visitor_cleanup(StringInputVisitor *v);
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
index 89b7e4bc9b..e10522a35b 100644
--- a/include/qapi/string-output-visitor.h
+++ b/include/qapi/string-output-visitor.h
@@ -19,7 +19,8 @@ typedef struct StringOutputVisitor StringOutputVisitor;
/*
* The string output visitor does not implement support for visiting
- * QAPI structs, alternates, null, or arbitrary QTypes.
+ * QAPI structs, alternates, null, or arbitrary QTypes. It also
+ * requires a non-null list argument to visit_start_list().
*/
StringOutputVisitor *string_output_visitor_new(bool human);
void string_output_visitor_cleanup(StringOutputVisitor *v);
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index b20a9226e0..145afd03e7 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -49,11 +49,13 @@ struct Visitor
/* Must be set to visit structs */
void (*end_struct)(Visitor *v);
- /* Must be set */
- void (*start_list)(Visitor *v, const char *name, Error **errp);
+ /* Must be set; implementations may require @list to be non-null,
+ * but must document it. */
+ void (*start_list)(Visitor *v, const char *name, GenericList **list,
+ size_t size, Error **errp);
/* Must be set */
- GenericList *(*next_list)(Visitor *v, GenericList **list, size_t size);
+ GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
/* Must be set */
void (*end_list)(Visitor *v);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index fe268fe78d..8de6b436fb 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -176,7 +176,7 @@
* if (err) {
* goto out;
* }
- * visit_start_list(v, "list", &err);
+ * visit_start_list(v, "list", NULL, 0, &err);
* if (err) {
* goto outobj;
* }
@@ -281,19 +281,27 @@ void visit_end_struct(Visitor *v);
* @name expresses the relationship of this list to its parent
* container; see the general description of @name above.
*
+ * @list must be non-NULL for a real walk, in which case @size
+ * determines how much memory an input visitor will allocate into
+ * *@list (at least sizeof(GenericList)). Some visitors also allow
+ * @list to be NULL for a virtual walk, in which case @size is
+ * ignored.
+ *
* @errp obeys typical error usage, and reports failures such as a
- * member @name is not present, or present but not a list.
+ * member @name is not present, or present but not a list. On error,
+ * input visitors set *@list to NULL.
*
* After visit_start_list() succeeds, the caller may visit its members
- * one after the other. A real visit uses visit_next_list() for
- * traversing the linked list, while a virtual visit uses other means.
- * For each list element, call the appropriate visit_type_FOO() with
- * name set to NULL and obj set to the address of the value member of
- * the list element. Finally, visit_end_list() needs to be called to
- * clean up, even if intermediate visits fail. See the examples
- * above.
+ * one after the other. A real visit (where @obj is non-NULL) uses
+ * visit_next_list() for traversing the linked list, while a virtual
+ * visit (where @obj is NULL) uses other means. For each list
+ * element, call the appropriate visit_type_FOO() with name set to
+ * NULL and obj set to the address of the value member of the list
+ * element. Finally, visit_end_list() needs to be called to clean up,
+ * even if intermediate visits fail. See the examples above.
*/
-void visit_start_list(Visitor *v, const char *name, Error **errp);
+void visit_start_list(Visitor *v, const char *name, GenericList **list,
+ size_t size, Error **errp);
/*
* Iterate over a GenericList during a non-virtual list visit.
@@ -301,20 +309,15 @@ void visit_start_list(Visitor *v, const char *name, Error **errp);
* @size represents the size of a linked list node (at least
* sizeof(GenericList)).
*
- * @list must not be NULL; on the first call, @list contains the
- * address of the list head, and on subsequent calls *@list must be
- * the previously returned value. Should be called in a loop until a
- * NULL return or error occurs; for each non-NULL return, the caller
- * then calls the appropriate visit_type_*() for the element type
- * of the list, with that function's name parameter set to NULL and
- * obj set to the address of (*@list)->value.
- *
- * FIXME: This interface is awkward; it requires all callbacks to
- * track whether it is the first or a subsequent call. A better
- * interface would pass the head of the list through
- * visit_start_list().
+ * @tail must not be NULL; on the first call, @tail is the value of
+ * *list after visit_start_list(), and on subsequent calls @tail must
+ * be the previously returned value. Should be called in a loop until
+ * a NULL return or error occurs; for each non-NULL return, the caller
+ * then calls the appropriate visit_type_*() for the element type of
+ * the list, with that function's name parameter set to NULL and obj
+ * set to the address of @tail->value.
*/
-GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size);
+GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);
/*
* Complete a list visit started earlier.