@@ -69,8 +69,7 @@ struct Visitor
Error **errp);
/* May be NULL; most useful for input visitors. */
- void (*optional)(Visitor *v, bool *present, const char *name,
- Error **errp);
+ void (*optional)(Visitor *v, bool *present, const char *name);
/* Only required to visit uint64 differently than (*type_int)(). */
void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name,
@@ -118,10 +118,9 @@ void visit_end_list(Visitor *v, Error **errp);
* Check if an optional member @name of a QDict needs visiting.
* For input visitors, set *@present according to whether the
* corresponding visit_type_*() needs calling; for other visitors,
- * leave *@present unchanged.
+ * leave *@present unchanged. Return *@present for convenience.
*/
-void visit_optional(Visitor *v, bool *present, const char *name,
- Error **errp);
+bool visit_optional(Visitor *v, bool *present, const char *name);
/**
* Determine the qtype of the item @name in the current QDict visit.
@@ -488,7 +488,7 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
static void
-opts_optional(Visitor *v, bool *present, const char *name, Error **errp)
+opts_optional(Visitor *v, bool *present, const char *name)
{
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
@@ -62,12 +62,12 @@ void visit_end_list(Visitor *v, Error **errp)
v->end_list(v, errp);
}
-void visit_optional(Visitor *v, bool *present, const char *name,
- Error **errp)
+bool visit_optional(Visitor *v, bool *present, const char *name)
{
if (v->optional) {
- v->optional(v, present, name, errp);
+ v->optional(v, present, name);
}
+ return *present;
}
void visit_get_next_type(Visitor *v, qtype_code *type, bool promote_int,
@@ -300,8 +300,7 @@ static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name,
*obj = qobj;
}
-static void qmp_input_optional(Visitor *v, bool *present, const char *name,
- Error **errp)
+static void qmp_input_optional(Visitor *v, bool *present, const char *name)
{
QmpInputVisitor *qiv = to_qiv(v);
QObject *qobj = qmp_input_get_object(qiv, name, true);
@@ -299,8 +299,7 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
*obj = val;
}
-static void parse_optional(Visitor *v, bool *present, const char *name,
- Error **errp)
+static void parse_optional(Visitor *v, bool *present, const char *name)
{
StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
@@ -1475,15 +1475,10 @@ def gen_visit_fields(members, prefix, errarg):
for memb in members:
if memb.optional:
ret += mcgen('''
-visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s);
+if (visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s")) {
''',
prefix=prefix, c_name=c_name(memb.name),
- name=memb.name, errp=errparg)
- ret += gen_err_check(errarg)
- ret += mcgen('''
-if (%(prefix)shas_%(c_name)s) {
-''',
- prefix=prefix, c_name=c_name(memb.name))
+ name=memb.name)
push_indent()
ret += mcgen('''
None of the visitor callbacks would set an error when testing if an optional field was present; make this part of the interface contract by eliminating the errp argument. Then, for less code, reflect the determined boolean value back to the caller instead of making the caller read the boolean after the fact. The resulting generated code has a nice diff: |- visit_optional(v, &has_fdset_id, "fdset-id", &err); |- if (err) { |- goto out; |- } |- if (has_fdset_id) { |+ if (visit_optional(v, &has_fdset_id, "fdset-id")) { | visit_type_int(v, &fdset_id, "fdset-id", &err); | if (err) { | goto out; | } | } Signed-off-by: Eric Blake <eblake@redhat.com> --- include/qapi/visitor-impl.h | 3 +-- include/qapi/visitor.h | 5 ++--- qapi/opts-visitor.c | 2 +- qapi/qapi-visit-core.c | 6 +++--- qapi/qmp-input-visitor.c | 3 +-- qapi/string-input-visitor.c | 3 +-- scripts/qapi.py | 9 ++------- 7 files changed, 11 insertions(+), 20 deletions(-)