eo: fix and rework efl_replace()
authorVitor Sousa <vitorsousa@expertisesolutions.com.br>
Mon, 12 Nov 2018 20:10:20 +0000 (18:10 -0200)
committerSangHyeon Jade Lee <sh10233.lee@samsung.com>
Tue, 20 Nov 2018 06:58:45 +0000 (15:58 +0900)
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

index 223b7a9..05c7cc5 100644 (file)
@@ -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 @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;