From 555de0f9145c52e9fb38457cf12ee2e23da29276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Briano?= Date: Wed, 9 Sep 2009 14:05:31 +0000 Subject: [PATCH] Support EINA_INLIST to be anywhere in the struct with _FOREACH macros. Fix pointer arithmetic with EINA_CONTAINER_GET. Change Inlist test to have the int first and not assume a direct cast works. SVN revision: 42366 --- legacy/eina/src/include/eina_inlist.h | 11 ++++++++--- legacy/eina/src/tests/eina_test_inlist.c | 17 +++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/legacy/eina/src/include/eina_inlist.h b/legacy/eina/src/include/eina_inlist.h index 4830b8578e..7da125e01e 100644 --- a/legacy/eina/src/include/eina_inlist.h +++ b/legacy/eina/src/include/eina_inlist.h @@ -52,7 +52,7 @@ struct _Eina_Inlist #define EINA_INLIST Eina_Inlist __in_list #define EINA_INLIST_GET(Inlist) (&((Inlist)->__in_list)) -#define EINA_INLIST_CONTAINER_GET(ptr, type) ((type *) ((Eina_Inlist *) ptr - offsetof(type, __in_list))) +#define EINA_INLIST_CONTAINER_GET(ptr, type) ((type *) ((char *) ptr - offsetof(type, __in_list))) EAPI Eina_Inlist * eina_inlist_append(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; EAPI Eina_Inlist * eina_inlist_prepend(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; @@ -67,8 +67,13 @@ EAPI unsigned int eina_inlist_count(const Eina_Inlist *list) EINA_WARN_UNUSED_RE EAPI Eina_Iterator *eina_inlist_iterator_new(const Eina_Inlist *in_list) EINA_MALLOC EINA_WARN_UNUSED_RESULT; EAPI Eina_Accessor *eina_inlist_accessor_new(const Eina_Inlist *in_list) EINA_MALLOC EINA_WARN_UNUSED_RESULT; -#define EINA_INLIST_FOREACH(list, l) for (l = (void*)list; l; l = (void*)(l->__in_list.next)) -#define EINA_INLIST_REVERSE_FOREACH(list, l) for (l = (list ? (void*)(list->last) : NULL); l; l = (void*)(l->__in_list.prev)) +/* This two macros are helpers for the _FOREACH ones, don't use them */ +#define INLIST_OFFSET(ref) ((char*)&(ref)->__in_list - (char*)(ref)) +#define INLIST_CONTAINER(ref, ptr) (void*)((char*)(ptr) - INLIST_OFFSET(ref)) + +#define EINA_INLIST_FOREACH(list, l) for (l = (list ? INLIST_CONTAINER(l, list) : NULL); l; l = (EINA_INLIST_GET(l)->next ? INLIST_CONTAINER(l, EINA_INLIST_GET(l)->next) : NULL)) +#define EINA_INLIST_REVERSE_FOREACH(list, l) for (l = (list ? INLIST_CONTAINER(l, list->last) : NULL); l; l = (EINA_INLIST_GET(l)->prev ? INLIST_CONTAINER(l, EINA_INLIST_GET(l)->prev) : NULL)) + /** * @} diff --git a/legacy/eina/src/tests/eina_test_inlist.c b/legacy/eina/src/tests/eina_test_inlist.c index 382547ad45..dd3eea55d5 100644 --- a/legacy/eina/src/tests/eina_test_inlist.c +++ b/legacy/eina/src/tests/eina_test_inlist.c @@ -30,8 +30,8 @@ typedef struct _Eina_Test_Inlist Eina_Test_Inlist; struct _Eina_Test_Inlist { - EINA_INLIST; int i; + EINA_INLIST; }; static Eina_Test_Inlist* @@ -63,13 +63,13 @@ START_TEST(eina_inlist_simple) tmp = _eina_test_inlist_build(1664); lst = eina_inlist_append_relative(lst, EINA_INLIST_GET(tmp), lst); fail_if(!lst); - fail_if(((Eina_Test_Inlist*)lst)->i != 42); + fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42); prev = tmp; tmp = _eina_test_inlist_build(3227); lst = eina_inlist_prepend_relative(lst, EINA_INLIST_GET(tmp), EINA_INLIST_GET(prev)); fail_if(!lst); - fail_if(((Eina_Test_Inlist*)lst)->i != 42); + fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist)->i != 42); lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp)); @@ -111,16 +111,17 @@ START_TEST(eina_inlist_simple) fail_if(eina_error_get() != EINA_ERROR_SAFETY_FAILED); #endif - tmp = (Eina_Test_Inlist*) lst; + tmp = EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist); lst = eina_inlist_demote(lst, lst); - fail_if(lst == (Eina_Inlist*) tmp); + fail_if(EINA_INLIST_CONTAINER_GET(lst, Eina_Test_Inlist) == tmp); lst = eina_inlist_promote(lst, EINA_INLIST_GET(tmp)); - fail_if(lst != (Eina_Inlist*) tmp); + fail_if(lst != EINA_INLIST_GET(tmp)); - tmp = (Eina_Test_Inlist*) eina_inlist_find(lst, EINA_INLIST_GET(prev)); + tmp = EINA_INLIST_CONTAINER_GET(eina_inlist_find(lst, EINA_INLIST_GET(prev)), Eina_Test_Inlist); lst = eina_inlist_remove(lst, EINA_INLIST_GET(tmp)); - tmp = (Eina_Test_Inlist*) eina_inlist_find(lst, EINA_INLIST_GET(tmp)); + prev = eina_inlist_find(lst, EINA_INLIST_GET(tmp)); + tmp = prev ? EINA_INLIST_CONTAINER_GET(prev, Eina_Test_Inlist) : NULL; fail_if(tmp != NULL); while (lst)