From cdd2b228b973d2a29edf7696ef6e8b08ec329019 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 7 Jul 2020 18:06:08 +0200 Subject: [PATCH] qapi: Smooth visitor error checking in generated code Use visitor functions' return values to check for failure. Eliminate error_propagate() that are now unnecessary. Delete @err that are now unused. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <20200707160613.848843-41-armbru@redhat.com> --- docs/devel/qapi-code-gen.txt | 60 ++++++++++++++---------------------- scripts/qapi/commands.py | 22 ++++++------- scripts/qapi/visit.py | 57 ++++++++++++++-------------------- 3 files changed, 55 insertions(+), 84 deletions(-) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 9bfc57063c63..69eede6c2831 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -1420,8 +1420,6 @@ Example: bool visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp) { - Error *err = NULL; - if (!visit_type_int(v, "integer", &obj->integer, errp)) { return false; } @@ -1430,13 +1428,12 @@ Example: return false; } } - error_propagate(errp, err); - return !err; + return true; } bool visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp) { - Error *err = NULL; + bool ok = false; if (!visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), errp)) { return false; @@ -1446,24 +1443,22 @@ Example: assert(visit_is_dealloc(v)); goto out_obj; } - visit_type_UserDefOne_members(v, *obj, &err); - if (err) { + if (!visit_type_UserDefOne_members(v, *obj, errp)) { goto out_obj; } - visit_check_struct(v, &err); + ok = visit_check_struct(v, errp); out_obj: visit_end_struct(v, (void **)obj); - if (err && visit_is_input(v)) { + if (!ok && visit_is_input(v)) { qapi_free_UserDefOne(*obj); *obj = NULL; } - error_propagate(errp, err); - return !err; + return ok; } bool visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp) { - Error *err = NULL; + bool ok = false; UserDefOneList *tail; size_t size = sizeof(**obj); @@ -1473,33 +1468,27 @@ Example: for (tail = *obj; tail; tail = (UserDefOneList *)visit_next_list(v, (GenericList *)tail, size)) { - visit_type_UserDefOne(v, NULL, &tail->value, &err); - if (err) { - break; + if (!visit_type_UserDefOne(v, NULL, &tail->value, errp)) { + goto out_obj; } } - if (!err) { - visit_check_list(v, &err); - } + ok = visit_check_list(v, errp); + out_obj: visit_end_list(v, (void **)obj); - if (err && visit_is_input(v)) { + if (!ok && visit_is_input(v)) { qapi_free_UserDefOneList(*obj); *obj = NULL; } - error_propagate(errp, err); - return !err; + return ok; } bool visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp) { - Error *err = NULL; - if (!visit_type_UserDefOneList(v, "arg1", &obj->arg1, errp)) { return false; } - error_propagate(errp, err); - return !err; + return true; } [Uninteresting stuff omitted...] @@ -1554,15 +1543,12 @@ Example: static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in, QObject **ret_out, Error **errp) { - Error *err = NULL; Visitor *v; v = qobject_output_visitor_new(ret_out); - visit_type_UserDefOne(v, "unused", &ret_in, &err); - if (!err) { + if (visit_type_UserDefOne(v, "unused", &ret_in, errp)) { visit_complete(v, ret_out); } - error_propagate(errp, err); visit_free(v); v = qapi_dealloc_visitor_new(); visit_type_UserDefOne(v, "unused", &ret_in, NULL); @@ -1572,33 +1558,32 @@ Example: void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp) { Error *err = NULL; + bool ok = false; Visitor *v; UserDefOne *retval; q_obj_my_command_arg arg = {0}; v = qobject_input_visitor_new(QOBJECT(args)); - visit_start_struct(v, NULL, NULL, 0, &err); - if (err) { + if (!visit_start_struct(v, NULL, NULL, 0, errp)) { goto out; } - visit_type_q_obj_my_command_arg_members(v, &arg, &err); - if (!err) { - visit_check_struct(v, &err); + if (visit_type_q_obj_my_command_arg_members(v, &arg, errp)) { + ok = visit_check_struct(v, errp); } visit_end_struct(v, NULL); - if (err) { + if (!ok) { goto out; } retval = qmp_my_command(arg.arg1, &err); + error_propagate(errp, err); if (err) { goto out; } - qmp_marshal_output_UserDefOne(retval, ret, &err); + qmp_marshal_output_UserDefOne(retval, ret, errp); out: - error_propagate(errp, err); visit_free(v); v = qapi_dealloc_visitor_new(); visit_start_struct(v, NULL, NULL, 0, NULL); @@ -1606,6 +1591,7 @@ Example: visit_end_struct(v, NULL); visit_free(v); } + [Uninteresting stuff omitted...] $ cat qapi-generated/example-qapi-init-commands.h [Uninteresting stuff omitted...] diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index 6809b0fb6e10..3cf9e1110b22 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -47,6 +47,7 @@ def gen_call(name, arg_type, boxed, ret_type): ret = mcgen(''' %(lhs)sqmp_%(c_name)s(%(args)s&err); + error_propagate(errp, err); ''', c_name=c_name(name), args=argstr, lhs=lhs) if ret_type: @@ -55,7 +56,7 @@ def gen_call(name, arg_type, boxed, ret_type): goto out; } - qmp_marshal_output_%(c_name)s(retval, ret, &err); + qmp_marshal_output_%(c_name)s(retval, ret, errp); ''', c_name=ret_type.c_name()) return ret @@ -66,15 +67,12 @@ def gen_marshal_output(ret_type): static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in, QObject **ret_out, Error **errp) { - Error *err = NULL; Visitor *v; v = qobject_output_visitor_new(ret_out); - visit_type_%(c_name)s(v, "unused", &ret_in, &err); - if (!err) { + if (visit_type_%(c_name)s(v, "unused", &ret_in, errp)) { visit_complete(v, ret_out); } - error_propagate(errp, err); visit_free(v); v = qapi_dealloc_visitor_new(); visit_type_%(c_name)s(v, "unused", &ret_in, NULL); @@ -104,6 +102,7 @@ def gen_marshal(name, arg_type, boxed, ret_type): %(proto)s { Error *err = NULL; + bool ok = false; Visitor *v; ''', proto=build_marshal_proto(name)) @@ -123,28 +122,26 @@ def gen_marshal(name, arg_type, boxed, ret_type): ret += mcgen(''' v = qobject_input_visitor_new(QOBJECT(args)); - visit_start_struct(v, NULL, NULL, 0, &err); - if (err) { + if (!visit_start_struct(v, NULL, NULL, 0, errp)) { goto out; } ''') if have_args: ret += mcgen(''' - visit_type_%(c_arg_type)s_members(v, &arg, &err); - if (!err) { - visit_check_struct(v, &err); + if (visit_type_%(c_arg_type)s_members(v, &arg, errp)) { + ok = visit_check_struct(v, errp); } ''', c_arg_type=arg_type.c_name()) else: ret += mcgen(''' - visit_check_struct(v, &err); + ok = visit_check_struct(v, errp); ''') ret += mcgen(''' visit_end_struct(v, NULL); - if (err) { + if (!ok) { goto out; } ''') @@ -154,7 +151,6 @@ def gen_marshal(name, arg_type, boxed, ret_type): ret += mcgen(''' out: - error_propagate(errp, err); visit_free(v); ''') diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index ba0cf0b074ca..3fb2f30510b2 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -41,8 +41,6 @@ def gen_visit_object_members(name, base, members, variants): bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) { - Error *err = NULL; - ''', c_name=c_name(name)) @@ -97,8 +95,7 @@ def gen_visit_object_members(name, base, members, variants): else: ret += mcgen(''' case %(case)s: - visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, &err); - break; + return visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, errp); ''', case=case_str, c_type=var.type.c_name(), c_name=c_name(var.name)) @@ -111,8 +108,7 @@ def gen_visit_object_members(name, base, members, variants): ''') ret += mcgen(''' - error_propagate(errp, err); - return !err; + return true; } ''') return ret @@ -123,7 +119,7 @@ def gen_visit_list(name, element_type): bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) { - Error *err = NULL; + bool ok = false; %(c_name)s *tail; size_t size = sizeof(**obj); @@ -133,22 +129,19 @@ def gen_visit_list(name, element_type): for (tail = *obj; tail; tail = (%(c_name)s *)visit_next_list(v, (GenericList *)tail, size)) { - visit_type_%(c_elt_type)s(v, NULL, &tail->value, &err); - if (err) { - break; + if (!visit_type_%(c_elt_type)s(v, NULL, &tail->value, errp)) { + goto out_obj; } } - if (!err) { - visit_check_list(v, &err); - } + ok = visit_check_list(v, errp); +out_obj: visit_end_list(v, (void **)obj); - if (err && visit_is_input(v)) { + if (!ok && visit_is_input(v)) { qapi_free_%(c_name)s(*obj); *obj = NULL; } - error_propagate(errp, err); - return !err; + return ok; } ''', c_name=c_name(name), c_elt_type=element_type.c_name()) @@ -173,7 +166,7 @@ def gen_visit_alternate(name, variants): bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) { - Error *err = NULL; + bool ok = false; if (!visit_start_alternate(v, name, (GenericAlternate **)obj, sizeof(**obj), errp)) { @@ -182,6 +175,7 @@ def gen_visit_alternate(name, variants): if (!*obj) { /* incomplete */ assert(visit_is_dealloc(v)); + ok = true; goto out_obj; } switch ((*obj)->type) { @@ -196,13 +190,11 @@ def gen_visit_alternate(name, variants): case=var.type.alternate_qtype()) if isinstance(var.type, QAPISchemaObjectType): ret += mcgen(''' - visit_start_struct(v, name, NULL, 0, &err); - if (err) { + if (!visit_start_struct(v, name, NULL, 0, errp)) { break; } - visit_type_%(c_type)s_members(v, &(*obj)->u.%(c_name)s, &err); - if (!err) { - visit_check_struct(v, &err); + if (visit_type_%(c_type)s_members(v, &(*obj)->u.%(c_name)s, errp)) { + ok = visit_check_struct(v, errp); } visit_end_struct(v, NULL); ''', @@ -210,7 +202,7 @@ def gen_visit_alternate(name, variants): c_name=c_name(var.name)) else: ret += mcgen(''' - visit_type_%(c_type)s(v, name, &(*obj)->u.%(c_name)s, &err); + ok = visit_type_%(c_type)s(v, name, &(*obj)->u.%(c_name)s, errp); ''', c_type=var.type.c_name(), c_name=c_name(var.name)) @@ -224,7 +216,7 @@ def gen_visit_alternate(name, variants): abort(); default: assert(visit_is_input(v)); - error_setg(&err, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "%(name)s"); /* Avoid passing invalid *obj to qapi_free_%(c_name)s() */ g_free(*obj); @@ -232,12 +224,11 @@ def gen_visit_alternate(name, variants): } out_obj: visit_end_alternate(v, (void **)obj); - if (err && visit_is_input(v)) { + if (!ok && visit_is_input(v)) { qapi_free_%(c_name)s(*obj); *obj = NULL; } - error_propagate(errp, err); - return !err; + return ok; } ''', name=name, c_name=c_name(name)) @@ -250,7 +241,7 @@ def gen_visit_object(name, base, members, variants): bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp) { - Error *err = NULL; + bool ok = false; if (!visit_start_struct(v, name, (void **)obj, sizeof(%(c_name)s), errp)) { return false; @@ -260,19 +251,17 @@ def gen_visit_object(name, base, members, variants): assert(visit_is_dealloc(v)); goto out_obj; } - visit_type_%(c_name)s_members(v, *obj, &err); - if (err) { + if (!visit_type_%(c_name)s_members(v, *obj, errp)) { goto out_obj; } - visit_check_struct(v, &err); + ok = visit_check_struct(v, errp); out_obj: visit_end_struct(v, (void **)obj); - if (err && visit_is_input(v)) { + if (!ok && visit_is_input(v)) { qapi_free_%(c_name)s(*obj); *obj = NULL; } - error_propagate(errp, err); - return !err; + return ok; } ''', c_name=c_name(name))