The migration subsystem currently has code to merge two objects of the
same type. It does so by checking which fields are present in a source
object and overwriting the corresponding fields on the destination
object. This leads to a lot of open-coded lines such as:
if (src->has_foobar) {
dst->foobar = src->foobar;
}
This pattern could be replaced by a copy using visitors. Implement a
macro that extracts elements from a source object using an output
visitor and merges it with a destination object using an input
visitor.
Signed-off-by: Fabiano Rosas <[email protected]>
---
include/qapi/type-helpers.h | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/include/qapi/type-helpers.h b/include/qapi/type-helpers.h
index fc8352cdec..011716c6ad 100644
--- a/include/qapi/type-helpers.h
+++ b/include/qapi/type-helpers.h
@@ -10,6 +10,8 @@
*/
#include "qapi/qapi-types-common.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qobject-output-visitor.h"
HumanReadableText *human_readable_text_from_str(GString *str);
@@ -20,3 +22,30 @@ HumanReadableText *human_readable_text_from_str(GString
*str);
* cleanup.
*/
char **strv_from_str_list(const strList *list);
+
+/*
+ * Merge @src over @dst by copying deep clones of the present members
+ * from @src to @dst. Non-present on @src are left untouched on @dst.
+ */
+#define QAPI_MERGE(type, dst_, src_) \
+ ({ \
+ QObject *out_ = NULL; \
+ Visitor *v_; \
+ /* read in from src */ \
+ v_ = qobject_output_visitor_new(&out_); \
+ visit_type_ ## type(v_, NULL, &src_, &error_abort); \
+ visit_complete(v_, &out_); \
+ visit_free(v_); \
+ /* \
+ * Write to dst but leave existing fields intact (except for \
+ * has_* which will be updated according to their presence in \
+ * src). \
+ */ \
+ v_ = qobject_input_visitor_new(out_); \
+ visit_start_struct(v_, NULL, NULL, 0, &error_abort); \
+ visit_type_ ## type ## _members(v_, dst_, &error_abort); \
+ visit_check_struct(v_, &error_abort); \
+ visit_end_struct(v_, NULL); \
+ visit_free(v_); \
+ qobject_unref(out_); \
+ })
--
2.51.0