From 03fca99e56e3a861f1f557810d8e0cf7e9da0c0b Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Sat, 6 Dec 2008 02:13:01 +0000 Subject: [PATCH] Add safe Eina list walk function. SVN revision: 37949 --- legacy/edje/src/lib/edje_util.c | 5 ++-- legacy/eina/src/include/eina_list.h | 44 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index 81cdc9dfc9..9eb14472b2 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/src/lib/edje_util.c @@ -2420,6 +2420,7 @@ Evas_Bool _edje_real_part_box_remove_all(Edje_Real_Part *rp, Evas_Bool clear) { Evas_Object_Box_Data *priv; + Evas_Object_Box_Option *opt; Eina_List *l, *l_next; int i; @@ -2427,11 +2428,9 @@ _edje_real_part_box_remove_all(Edje_Real_Part *rp, Evas_Bool clear) return evas_object_box_remove_all(rp->object, clear); priv = evas_object_smart_data_get(rp->object); i = 0; - for (l = priv->children; l != NULL; l = l_next) + EINA_LIST_FOREACH_SAFE(priv->children, l, l_next, opt) { - Evas_Object_Box_Option *opt = l->data; Evas_Object *child_obj; - l_next = l->next; child_obj = opt->obj; if (evas_object_data_get(child_obj, "\377 edje.box_item")) { diff --git a/legacy/eina/src/include/eina_list.h b/legacy/eina/src/include/eina_list.h index 254b055b15..c966171dd4 100644 --- a/legacy/eina/src/include/eina_list.h +++ b/legacy/eina/src/include/eina_list.h @@ -137,9 +137,53 @@ EAPI Eina_Accessor *eina_list_accessor_new(const Eina_List *list); * EINA_LIST_FOREACH(list, l, data) * free(data); * @endcode + * + * @warning do not delete list nodes, specially the current node, while + * iterating. If you wish to do so, use EINA_LIST_FOREACH_SAFE(). */ #define EINA_LIST_FOREACH(list, l, data) for (l = list, data = eina_list_data_get(l); l; l = eina_list_next(l), data = eina_list_data_get(l)) +/** + * @def EINA_LIST_FOREACH_SAFE + * @brief Macro to iterate over a list easily, supporting deletion. + * + * @param list The list to iterate over. + * @param l A list that is used as loop index. + * @param l_next A second list that is used as loop next index. + * @param data The data. + * + * This macro allow the iteration over @p list in an easy way. It + * iterates from the first element to the last one. @p data is the + * data of each element of the list. @p l is an #Eina_List that is + * used as counter. + * + * This is the safe version, which stores the next pointer in @p l_next + * before proceeding, so deletion of @b current node is safe. If you wish + * to remove anything else, remember to set @p l_next accordingly. + * + * This macro can be used for freeing list nodes, like in + * the following example: + * + * @code + * Eina_List *list; + * Eina_List *l; + * Eina_List *l_next; + * char *data; + * + * // list is already filled, + * // its elements are just duplicated strings, + * // EINA_LIST_FOREACH_SAFE will be used to free elements that match "key". + * + * EINA_LIST_FOREACH_SAFE(list, l, l_next, data) + * if (strcmp(data, "key") == 0) { + * free(data); + * list = eina_list_remove_list(list, l); + * } + * @endcode + */ +#define EINA_LIST_FOREACH_SAFE(list, l, l_next, data) for (l = list, l_next = eina_list_next(l), data = eina_list_data_get(l); l; l = l_next, l_next = eina_list_next(l), data = eina_list_data_get(l)) + + #include "eina_inline_list.x" /**