[1/2] list.h: Add macros for reverse iteration

Dan Hipschman dsh at linux.ucla.edu
Mon Jun 4 20:30:39 CDT 2007


This patch adds the ability to iterate over wine lists in the reverse
direction, which is very helpful for my next patch where I need to process
the array dimension list from right to left.  It's factored so the left
and right iteration macros use the same code, as it seemed cleaner not to
duplicate it.  To verify the forward iteration macros were still good, I
expanded the macros with gcc -E using the old and new list.h, and every-
thing came out the same.  Because I'm really paranoid, I also ran winetest
before and after the patch, and got no new failures.

---
 include/wine/list.h |   51 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/include/wine/list.h b/include/wine/list.h
index dede5b4..4f6fde0 100644
--- a/include/wine/list.h
+++ b/include/wine/list.h
@@ -172,29 +172,48 @@ static inline void list_move_head( struct list *dst, struct list *src )
     list_init(src);
 }
 
-/* iterate through the list */
-#define LIST_FOR_EACH(cursor,list) \
-    for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
+#define LIST_FOR_EACH_LINK(cursor, list, link) \
+    for ((cursor) = (list)->link; (cursor) != (list); (cursor) = (cursor)->link)
 
-/* iterate through the list, with safety against removal */
-#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
-    for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
+#define LIST_FOR_EACH_SAFE_LINK(cursor, cursor2, list, link) \
+    for ((cursor) = (list)->link, (cursor2) = (cursor)->link; \
          (cursor) != (list); \
-         (cursor) = (cursor2), (cursor2) = (cursor)->next)
+         (cursor) = (cursor2), (cursor2) = (cursor)->link)
 
-/* iterate through the list using a list entry */
-#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
-    for ((elem) = LIST_ENTRY((list)->next, type, field); \
+#define LIST_FOR_EACH_ENTRY_LINK(elem, list, type, field, link) \
+    for ((elem) = LIST_ENTRY((list)->link, type, field); \
          &(elem)->field != (list); \
-         (elem) = LIST_ENTRY((elem)->field.next, type, field))
+         (elem) = LIST_ENTRY((elem)->field.link, type, field))
 
-/* iterate through the list using a list entry, with safety against removal */
-#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
-    for ((cursor) = LIST_ENTRY((list)->next, type, field), \
-         (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
+#define LIST_FOR_EACH_ENTRY_SAFE_LINK(cursor, cursor2, list, type, field, link) \
+    for ((cursor) = LIST_ENTRY((list)->link, type, field), \
+         (cursor2) = LIST_ENTRY((cursor)->field.link, type, field); \
          &(cursor)->field != (list); \
          (cursor) = (cursor2), \
-         (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
+         (cursor2) = LIST_ENTRY((cursor)->field.link, type, field))
+
+/* iterate through the list */
+#define LIST_FOR_EACH(cursor, list) \
+    LIST_FOR_EACH_LINK(cursor, list, next)
+/* iterate through the list, with safety against removal */
+#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
+    LIST_FOR_EACH_SAFE_LINK(cursor, cursor2, list, next)
+/* iterate through the list using a list entry */
+#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
+    LIST_FOR_EACH_ENTRY_LINK(elem, list, type, field, next)
+/* iterate through the list using a list entry, with safety against removal */
+#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
+    LIST_FOR_EACH_ENTRY_SAFE_LINK(cursor, cursor2, list, type, field, next)
+
+/* same as above, but start from the tail and work towards the head */
+#define LIST_FOR_EACH_REV(cursor, list) \
+    LIST_FOR_EACH_LINK(cursor, list, prev)
+#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
+    LIST_FOR_EACH_SAFE_LINK(cursor, cursor2, list, prev)
+#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
+    LIST_FOR_EACH_ENTRY_LINK(elem, list, type, field, prev)
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
+    LIST_FOR_EACH_ENTRY_SAFE_LINK(cursor, cursor2, list, type, field, prev)
 
 /* macros for statically initialized lists */
 #define LIST_INIT(list)  { &(list), &(list) }



More information about the wine-patches mailing list