Add a new qmp_output_visitor_reset(), to make it easier for a caller to reset all state while still reusing an existing visitor, regardless of whether the previous visit was successfully completed. Then use it in the testsuite.
The tests needing patching were found by tightening asserts in the QMP output visitor; see the next patch. An audit of all other users of qmp_output_visitor_new() did not find any other attempts to reuse a visitor. Signed-off-by: Eric Blake <ebl...@redhat.com> --- v15: new patch, split off of v14 13/19 --- include/qapi/qmp-output-visitor.h | 1 + qapi/qmp-output-visitor.c | 8 +++++++- tests/test-qmp-output-visitor.c | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/qapi/qmp-output-visitor.h b/include/qapi/qmp-output-visitor.h index 2266770..5093f0d 100644 --- a/include/qapi/qmp-output-visitor.h +++ b/include/qapi/qmp-output-visitor.h @@ -21,6 +21,7 @@ typedef struct QmpOutputVisitor QmpOutputVisitor; QmpOutputVisitor *qmp_output_visitor_new(void); void qmp_output_visitor_cleanup(QmpOutputVisitor *v); +void qmp_output_visitor_reset(QmpOutputVisitor *v); QObject *qmp_output_get_qobject(QmpOutputVisitor *v); Visitor *qmp_output_get_visitor(QmpOutputVisitor *v); diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c index 5681ad3..6c44210 100644 --- a/qapi/qmp-output-visitor.c +++ b/qapi/qmp-output-visitor.c @@ -221,7 +221,7 @@ Visitor *qmp_output_get_visitor(QmpOutputVisitor *v) return &v->visitor; } -void qmp_output_visitor_cleanup(QmpOutputVisitor *v) +void qmp_output_visitor_reset(QmpOutputVisitor *v) { QStackEntry *e, *tmp; @@ -231,6 +231,12 @@ void qmp_output_visitor_cleanup(QmpOutputVisitor *v) } qobject_decref(v->root); + v->root = NULL; +} + +void qmp_output_visitor_cleanup(QmpOutputVisitor *v) +{ + qmp_output_visitor_reset(v); g_free(v); } diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index 8acc229..0e83099 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -139,6 +139,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, EnumOne_lookup[i]); qobject_decref(obj); + qmp_output_visitor_reset(data->qov); } } @@ -153,6 +154,7 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data, visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err); g_assert(err); error_free(err); + qmp_output_visitor_reset(data->qov); } } @@ -262,6 +264,7 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data, visit_type_UserDefOne(data->ov, "unused", &pu, &err); g_assert(err); error_free(err); + qmp_output_visitor_reset(data->qov); } } @@ -366,6 +369,7 @@ static void test_visitor_out_any(TestOutputVisitorData *data, qobject_decref(obj); qobject_decref(qobj); + qmp_output_visitor_reset(data->qov); qdict = qdict_new(); qdict_put(qdict, "integer", qint_from_int(-42)); qdict_put(qdict, "boolean", qbool_from_bool(true)); @@ -442,6 +446,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, qapi_free_UserDefAlternate(tmp); qobject_decref(arg); + qmp_output_visitor_reset(data->qov); tmp = g_new0(UserDefAlternate, 1); tmp->type = QTYPE_QSTRING; tmp->u.s = g_strdup("hello"); @@ -455,6 +460,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, qapi_free_UserDefAlternate(tmp); qobject_decref(arg); + qmp_output_visitor_reset(data->qov); tmp = g_new0(UserDefAlternate, 1); tmp->type = QTYPE_QDICT; tmp->u.udfu.integer = 1; -- 2.5.5