From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42308) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEC-0003k8-Vu for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlAEB-0005Su-5j for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:04 -0400 Received: from e7.ny.us.ibm.com ([32.97.182.137]:60612) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEA-0005Sh-GY for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:02 -0400 Received: from d01relay01.pok.ibm.com (d01relay01.pok.ibm.com [9.56.227.233]) by e7.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p6P1JRiY022676 for ; Sun, 24 Jul 2011 21:19:27 -0400 Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6P1j2CL123710 for ; Sun, 24 Jul 2011 21:45:02 -0400 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6P1j2Xc007265 for ; Sun, 24 Jul 2011 21:45:02 -0400 From: Anthony Liguori Date: Sun, 24 Jul 2011 20:44:39 -0500 Message-Id: <1311558293-5855-8-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> References: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 07/21] plug: add generated property types List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori Right now this uses the preprocessor and is vomit inducing. I think a python generator is in the near future. Signed-off-by: Anthony Liguori --- include/qemu/plug-proptypes.h | 29 +++++++++- include/qemu/plug.h | 4 +- qom/plug-proptypes.c | 119 ++++++++++++++++++++++++++++++++++++++++- qom/plug.c | 10 ++-- 4 files changed, 151 insertions(+), 11 deletions(-) diff --git a/include/qemu/plug-proptypes.h b/include/qemu/plug-proptypes.h index 2c7be0e..cf3e06e 100644 --- a/include/qemu/plug-proptypes.h +++ b/include/qemu/plug-proptypes.h @@ -3,8 +3,33 @@ #include "plug.h" -typedef bool (PlugPropertyGetterBool)(Plug *plug); -typedef void (PlugPropertySetterBool)(Plug *plug, bool value); +#define CONCAT_I(a, b) a ## b +#define CONCAT(a, b) CONCAT_I(a, b) + +#define GEN_PROP(ctype, typename, ctypename) \ +typedef ctype (CONCAT(PlugPropertyGetter, typename))(Plug *plug, Error **errp); \ +typedef void (CONCAT(PlugPropertySetter, typename))(Plug *plug, ctype value, Error **errp); \ + \ +void CONCAT(plug_add_property_, ctypename)(Plug *plug, const char *name, \ + CONCAT(PlugPropertyGetter, typename) *getter, \ + CONCAT(PlugPropertySetter, typename) *setter, \ + int flags) + +GEN_PROP(int8_t, Int8, int8); +GEN_PROP(int16_t, Int16, int16); +GEN_PROP(int32_t, Int32, int32); +GEN_PROP(int64_t, Int64, int64); +GEN_PROP(uint8_t, UInt8, uint8); +GEN_PROP(uint16_t, UInt16, uint16); +GEN_PROP(uint32_t, UInt32, uint32); +GEN_PROP(uint64_t, UInt64, uint64); +GEN_PROP(int64_t, Int, int); +GEN_PROP(const char *, Str, str); + +#undef GEN_PROP + +typedef bool (PlugPropertyGetterBool)(Plug *plug, Error **errp); +typedef void (PlugPropertySetterBool)(Plug *plug, bool value, Error **errp); void plug_add_property_bool(Plug *plug, const char *name, PlugPropertyGetterBool *getter, diff --git a/include/qemu/plug.h b/include/qemu/plug.h index a7ca985..03b63a2 100644 --- a/include/qemu/plug.h +++ b/include/qemu/plug.h @@ -62,8 +62,8 @@ void plug_unlock_property(Plug *plug, const char *name); void plug_lock_all_properties(Plug *plug); void plug_unlock_all_properties(Plug *plug); -void plug_set_realized(Plug *plug, bool realized); -bool plug_get_realized(Plug *plug); +void plug_set_realized(Plug *plug, bool realized, Error **errp); +bool plug_get_realized(Plug *plug, Error **errp); void plug_realize_all(Plug *plug); void plug_unrealize_all(Plug *plug); diff --git a/qom/plug-proptypes.c b/qom/plug-proptypes.c index e9152a7..b25093f 100644 --- a/qom/plug-proptypes.c +++ b/qom/plug-proptypes.c @@ -8,13 +8,78 @@ typedef struct FunctionPointer void (*setter)(void); } FunctionPointer; +#define STRIFY_I(a) # a +#define STRIFY(a) STRIFY_I(a) + +static void plug_del_property__fp(Plug *plug, const char *name, void *opaque) +{ + FunctionPointer *fp = opaque; + qemu_free(fp); +} + +#define GEN_PROP(ctype, typename, ctypename) \ +static void CONCAT(plug_get_property__, ctypename)(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) \ +{ \ + FunctionPointer *fp = opaque; \ + CONCAT(PlugPropertyGetter, typename) *getter = (CONCAT(PlugPropertyGetter, typename) *)fp->getter; \ + int64_t value; \ + \ + value = getter(plug, errp); \ + visit_type_int(v, &value, name, errp); \ +} \ + \ +static void CONCAT(plug_set_property__, ctypename)(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) \ +{ \ + FunctionPointer *fp = opaque; \ + CONCAT(PlugPropertySetter, typename) *setter = (CONCAT(PlugPropertySetter, typename) *)fp->setter; \ + int64_t value = 0; \ + Error *local_err = NULL; \ + \ + visit_type_int(v, &value, name, &local_err); \ + if (local_err) { \ + error_propagate(errp, local_err); \ + return; \ + } \ + \ + setter(plug, value, errp); \ +} \ + \ +void CONCAT(plug_add_property_, ctypename)(Plug *plug, const char *name, \ + CONCAT(PlugPropertyGetter, typename) *getter, \ + CONCAT(PlugPropertySetter, typename) *setter, \ + int flags) \ +{ \ + FunctionPointer *fp = qemu_mallocz(sizeof(*fp)); \ + \ + fp->getter = (void (*)(void))getter; \ + fp->setter = (void (*)(void))setter; \ + \ + plug_add_property_full(plug, name, \ + CONCAT(plug_get_property__, ctypename), \ + CONCAT(plug_set_property__, ctypename), \ + plug_del_property__fp, \ + fp, STRIFY(ctypename), flags); \ +} + +GEN_PROP(int8_t, Int8, int8); +GEN_PROP(int16_t, Int16, int16); +GEN_PROP(int32_t, Int32, int32); +GEN_PROP(int64_t, Int64, int64); +GEN_PROP(uint8_t, UInt8, uint8); +GEN_PROP(uint16_t, UInt16, uint16); +GEN_PROP(uint32_t, UInt32, uint32); +GEN_PROP(uint64_t, UInt64, uint64); +GEN_PROP(int64_t, Int, int); + +#undef GEN_PROP + static void plug_get_property__bool(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) { FunctionPointer *fp = opaque; PlugPropertyGetterBool *getter = (PlugPropertyGetterBool *)fp->getter; bool value; - value = getter(plug); + value = getter(plug, errp); visit_type_bool(v, &value, name, errp); } @@ -31,7 +96,7 @@ static void plug_set_property__bool(Plug *plug, const char *name, Visitor *v, vo return; } - setter(plug, value); + setter(plug, value, errp); } void plug_add_property_bool(Plug *plug, const char *name, @@ -50,3 +115,53 @@ void plug_add_property_bool(Plug *plug, const char *name, plug_del_property__fp, fp, "bool", flags); } + +/** str **/ + +static void plug_get_property__str(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) +{ + FunctionPointer *fp = opaque; + PlugPropertyGetterStr *getter = (PlugPropertyGetterStr *)fp->getter; + char *value; + + value = (char *)getter(plug, errp); + if (value == NULL) { + value = (char *)""; + } + visit_type_str(v, &value, name, errp); +} + +static void plug_set_property__str(Plug *plug, const char *name, Visitor *v, void *opaque, Error **errp) +{ + FunctionPointer *fp = opaque; + PlugPropertySetterStr *setter = (PlugPropertySetterStr *)fp->setter; + char *value = false; + Error *local_err = NULL; + + visit_type_str(v, &value, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + setter(plug, value, errp); + + qemu_free(value); +} + +void plug_add_property_str(Plug *plug, const char *name, + PlugPropertyGetterStr *getter, + PlugPropertySetterStr *setter, + int flags) +{ + FunctionPointer *fp = qemu_mallocz(sizeof(*fp)); + + fp->getter = (void (*)(void))getter; + fp->setter = (void (*)(void))setter; + + plug_add_property_full(plug, name, + plug_get_property__str, + plug_set_property__str, + plug_del_property__fp, + fp, "str", flags); +} diff --git a/qom/plug.c b/qom/plug.c index a9d8154..7f21c6b 100644 --- a/qom/plug.c +++ b/qom/plug.c @@ -136,7 +136,7 @@ void plug_foreach_property(Plug *plug, PropertyEnumerator *enumfn, void *opaque) } } -void plug_set_realized(Plug *plug, bool realized) +void plug_set_realized(Plug *plug, bool realized, Error **errp) { PlugClass *class = PLUG_GET_CLASS(plug); bool old_value = plug->realized; @@ -154,7 +154,7 @@ void plug_set_realized(Plug *plug, bool realized) } } -bool plug_get_realized(Plug *plug) +bool plug_get_realized(Plug *plug, Error **errp) { return plug->realized; } @@ -180,7 +180,7 @@ static void plug_propagate_realized(Plug *plug, const char *name, child_name = plug_get_property_str(plug, name, NULL); child_plug = PLUG(type_find_by_id(child_name)); - plug_set_realized(child_plug, plug_get_realized(plug)); + plug_set_realized(child_plug, plug_get_realized(plug, NULL), NULL); qemu_free(child_name); } @@ -329,7 +329,7 @@ void plug_realize_all(Plug *plug) { /* This doesn't loop infinitely because the callbacks are only called when * the state changes. */ - plug_set_realized(plug, true); + plug_set_realized(plug, true, NULL); plug_lock_all_properties(plug); plug_foreach_property(plug, plug_propagate_realized, NULL); } @@ -338,7 +338,7 @@ void plug_unrealize_all(Plug *plug) { /* This doesn't loop infinitely because the callbacks are only called when * the state changes. */ - plug_set_realized(plug, false); + plug_set_realized(plug, false, NULL); plug_unlock_all_properties(plug); plug_foreach_property(plug, plug_propagate_realized, NULL); } -- 1.7.4.1