From 08357cd15390b022671877399fc0abf9e84bcb1e Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Mon, 12 Nov 2018 18:10:20 -0200 Subject: [PATCH] eo: fix and rework efl_replace() Summary: Check if the Eo to be replaced is NULL before calling efl_unref. The documentation implies that the replaced object can be NULL, so this check avoids unnecessary function calls and warning logs. Add an EINA_SAFETY check in order to properly print an error message when the function is used with an NULL storage pointer. The documentation specifies that the first parameter can not be NULL. So printing an error message should be better than silently returning. Add a boolean return to the function that signalizes if the content of the storage was changed. It is NOT an success/error flag, it is just a simple helper to quickly test for a change in content. This feature was inspired by eina_stringshare_replace that is used in similar ways around the code. Change the documentation to match the changes and to be more specific about what is expected and how the arguments are treated. Reviewers: raster, bu5hm4n, cedric, felipealmeida Reviewed By: bu5hm4n Subscribers: #reviewers, #committers, larryolj Tags: #efl Differential Revision: https://phab.enlightenment.org/D7256 --- src/lib/eo/Eo.h | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 223b7a9f5a..05c7cc5286 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -2059,23 +2059,31 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_ /** * @def Replace the previous Eo pointer with new content. * - * @param storage The object to replace the old reference. It can not be @c NULL. + * @param storage Pointer to the space holding the object to be replaced. + * It can not be @c NULL. * @param new_obj The new object. It may be @c NULL. + * @return @c true if objects were different and thus replaced, @c false + * if nothing happened, i.e. either the objects were the same or a @c NULL + * pointer was wrongly given as @a storage. * - * The object pointed by @a storage must be previously an Eo or - * @c NULL and it will be efl_unref(). The @a new_obj will be passed - * to efl_ref() and then assigned to @c *storage. + * The object pointed by @c *storage must be previously an Eo or + * @c NULL; if it is an Eo then it will be efl_unref(). The @a new_obj + * will be passed to efl_ref() if not @c NULL, and then assigned to @c *storage. * + * @note The return is NOT a success/error flag, it just signalizes if + * the value has changed. * @see efl_ref() * @see efl_unref() */ -static inline void +static inline Eina_Bool efl_replace(Eo **storage, Eo *new_obj) { - if (!storage || *storage == new_obj) return; + EINA_SAFETY_ON_NULL_RETURN_VAL(storage, EINA_FALSE); + if (*storage == new_obj) return EINA_FALSE; if (new_obj) efl_ref(new_obj); - efl_unref(*storage); + if (*storage) efl_unref(*storage); *storage = new_obj; + return EINA_TRUE; } EOAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_OBJECT;