Controversial: find all remaining patterns that generate a goto statement due to 'err', and convert them to use gen_err_check(). The bulk of these replacements actually lead to code duplication (extra mcgen() calls with common parameterization), so I will probably drop this patch.
Signed-off-by: Eric Blake <ebl...@redhat.com> --- v7: split off of 15/16, for discussion purposes v6: new, split off of 10/46, add label parameter, and catch more instances that could use it --- scripts/qapi-commands.py | 12 ++++++----- scripts/qapi-event.py | 6 +++--- scripts/qapi-visit.py | 55 +++++++++++++++++++++++++++--------------------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 43a893b..6994329 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -121,7 +121,7 @@ def gen_marshal_input_visit(arg_type, dealloc=False): def gen_marshal_output(ret_type): - return mcgen(''' + ret = mcgen(''' static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in, QObject **ret_out, Error **errp) { @@ -132,9 +132,10 @@ static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in, QObject **ret_out, v = qmp_output_get_visitor(qov); visit_type_%(c_name)s(v, &ret_in, "unused", &err); - if (err) { - goto out; - } +''', + c_type=ret_type.c_type(), c_name=ret_type.c_name()) + ret += gen_err_check() + ret += mcgen(''' *ret_out = qmp_output_get_qobject(qov); out: @@ -146,7 +147,8 @@ out: qapi_dealloc_visitor_cleanup(qdv); } ''', - c_type=ret_type.c_type(), c_name=ret_type.c_name()) + c_name=ret_type.c_name()) + return ret def gen_marshal_proto(name): diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py index b5e4d59..8eb353e 100644 --- a/scripts/qapi-event.py +++ b/scripts/qapi-event.py @@ -75,9 +75,9 @@ def gen_event_send(name, arg_type): ret += mcgen(''' visit_end_struct(v, &err); - if (err) { - goto out; - } +''') + ret += gen_err_check() + ret += mcgen(''' obj = qmp_output_get_qobject(qov); g_assert(obj != NULL); diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 4f97781..46c4d56 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -128,7 +128,7 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error def gen_visit_list(name, element_type): - return mcgen(''' + ret = mcgen(''' void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error **errp) { @@ -136,9 +136,10 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error GenericList *i, **prev; visit_start_list(v, name, &err); - if (err) { - goto out; - } +''', + c_name=c_name(name), c_elt_type=element_type.c_name()) + ret += gen_err_check() + ret += mcgen(''' for (prev = (GenericList **)obj; !err && (i = visit_next_list(v, prev, &err)) != NULL; @@ -155,6 +156,7 @@ out: } ''', c_name=c_name(name), c_elt_type=element_type.c_name()) + return ret def gen_visit_enum(name): @@ -176,16 +178,17 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error Error *err = NULL; visit_start_implicit_struct(v, (void**) obj, sizeof(%(c_name)s), &err); - if (err) { - goto out; - } +''', + c_name=c_name(name)) + ret += gen_err_check() + ret += mcgen(''' visit_get_next_type(v, (int*) &(*obj)->kind, %(c_name)s_qtypes, name, &err); - if (err) { - goto out_obj; - } +''', + c_name=c_name(name)) + ret += gen_err_check(label='out_obj') + ret += mcgen(''' switch ((*obj)->kind) { -''', - c_name=c_name(name)) +''') for var in variants.variants: ret += mcgen(''' @@ -233,14 +236,14 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error Error *err = NULL; visit_start_struct(v, (void **)obj, "%(name)s", name, sizeof(%(c_name)s), &err); - if (err) { - goto out; - } +''', + c_name=c_name(name), name=name) + ret += gen_err_check() + ret += mcgen(''' if (!*obj) { goto out_obj; } -''', - c_name=c_name(name), name=name) +''') if base: ret += mcgen(''' @@ -255,13 +258,6 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error tag_key = 'type' ret += mcgen(''' visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err); - if (err) { - goto out_obj; - } - if (!visit_start_union(v, !!(*obj)->data, &err) || err) { - goto out_obj; - } - switch ((*obj)->%(c_name)s) { ''', c_type=variants.tag_member.type.c_name(), # TODO ugly special case for simple union @@ -269,6 +265,17 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error # it, then: c_name=c_name(variants.tag_member.name) c_name=c_name(variants.tag_name or 'kind'), name=tag_key) + ret += gen_err_check(label='out_obj') + ret += mcgen(''' + if (!visit_start_union(v, !!(*obj)->data, &err) || err) { + goto out_obj; + } + switch ((*obj)->%(c_name)s) { +''', + # TODO ugly special case for simple union + # Use same tag name in C as on the wire to get rid of + # it, then: c_name=c_name(variants.tag_member.name) + c_name=c_name(variants.tag_name or 'kind')) for var in variants.variants: # TODO ugly special case for simple union -- 2.4.3