1a15fcc3cSEric Blake /* 2a15fcc3cSEric Blake * Clone Visitor 3a15fcc3cSEric Blake * 4a15fcc3cSEric Blake * Copyright (C) 2016 Red Hat, Inc. 5a15fcc3cSEric Blake * 6a15fcc3cSEric Blake * This work is licensed under the terms of the GNU GPL, version 2 or later. 7a15fcc3cSEric Blake * See the COPYING file in the top-level directory. 8a15fcc3cSEric Blake * 9a15fcc3cSEric Blake */ 10a15fcc3cSEric Blake 11a15fcc3cSEric Blake #ifndef QAPI_CLONE_VISITOR_H 12a15fcc3cSEric Blake #define QAPI_CLONE_VISITOR_H 13a15fcc3cSEric Blake 14*b0409139SAkihiko Odaki #include "qapi/error.h" 15a15fcc3cSEric Blake #include "qapi/visitor.h" 16a15fcc3cSEric Blake 17a15fcc3cSEric Blake /* 18a15fcc3cSEric Blake * The clone visitor is for direct use only by the QAPI_CLONE() macro; 19a15fcc3cSEric Blake * it requires that the root visit occur on an object, list, or 20a15fcc3cSEric Blake * alternate, and is not usable directly on built-in QAPI types. 21a15fcc3cSEric Blake */ 22a15fcc3cSEric Blake typedef struct QapiCloneVisitor QapiCloneVisitor; 23a15fcc3cSEric Blake 24*b0409139SAkihiko Odaki Visitor *qapi_clone_visitor_new(void); 25*b0409139SAkihiko Odaki Visitor *qapi_clone_members_visitor_new(void); 26a15fcc3cSEric Blake 27a15fcc3cSEric Blake /* 28a15fcc3cSEric Blake * Deep-clone QAPI object @src of the given @type, and return the result. 29a15fcc3cSEric Blake * 30a15fcc3cSEric Blake * Not usable on QAPI scalars (integers, strings, enums), nor on a 31a15fcc3cSEric Blake * QAPI object that references the 'any' type. Safe when @src is NULL. 32a15fcc3cSEric Blake */ 33a15fcc3cSEric Blake #define QAPI_CLONE(type, src) \ 34*b0409139SAkihiko Odaki ({ \ 35*b0409139SAkihiko Odaki Visitor *v_; \ 36*b0409139SAkihiko Odaki type *dst_ = (type *) (src); /* Cast away const */ \ 37*b0409139SAkihiko Odaki \ 38*b0409139SAkihiko Odaki if (dst_) { \ 39*b0409139SAkihiko Odaki v_ = qapi_clone_visitor_new(); \ 40*b0409139SAkihiko Odaki visit_type_ ## type(v_, NULL, &dst_, &error_abort); \ 41*b0409139SAkihiko Odaki visit_free(v_); \ 42*b0409139SAkihiko Odaki } \ 43*b0409139SAkihiko Odaki dst_; \ 44*b0409139SAkihiko Odaki }) 45a15fcc3cSEric Blake 464626a19cSMarkus Armbruster /* 474626a19cSMarkus Armbruster * Copy deep clones of @type members from @src to @dst. 484626a19cSMarkus Armbruster * 494626a19cSMarkus Armbruster * Not usable on QAPI scalars (integers, strings, enums), nor on a 504626a19cSMarkus Armbruster * QAPI object that references the 'any' type. 514626a19cSMarkus Armbruster */ 524626a19cSMarkus Armbruster #define QAPI_CLONE_MEMBERS(type, dst, src) \ 53*b0409139SAkihiko Odaki ({ \ 54*b0409139SAkihiko Odaki Visitor *v_; \ 55*b0409139SAkihiko Odaki \ 56*b0409139SAkihiko Odaki v_ = qapi_clone_members_visitor_new(); \ 57*b0409139SAkihiko Odaki *(type *)(dst) = *(src); \ 58*b0409139SAkihiko Odaki visit_type_ ## type ## _members(v_, (type *)(dst), &error_abort); \ 59*b0409139SAkihiko Odaki visit_free(v_); \ 60*b0409139SAkihiko Odaki }) 614626a19cSMarkus Armbruster 62a15fcc3cSEric Blake #endif 63