From c414947a861ff1bc0eed6dc906cc33d4a227adec Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 30 Nov 2011 09:02:11 +1030 Subject: [PATCH] list: implement list_for_each_rev() --- ccan/list/list.h | 18 ++++++++++++++++++ ccan/list/test/run.c | 21 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/ccan/list/list.h b/ccan/list/list.h index 18f077ae..bda2922b 100644 --- a/ccan/list/list.h +++ b/ccan/list/list.h @@ -315,6 +315,24 @@ static inline void list_del_from(struct list_head *h, struct list_node *n) &i->member != &(h)->n; \ i = container_of_var(i->member.next, i, member)) +/** + * list_for_each_rev - iterate through a list backwards. + * @h: the list_head + * @i: the structure containing the list_node + * @member: the list_node member of the structure + * + * This is a convenient wrapper to iterate @i over the entire list. It's + * a for loop, so you can break and continue as normal. + * + * Example: + * list_for_each_rev(&parent->children, child, list) + * printf("Name: %s\n", child->name); + */ +#define list_for_each_rev(h, i, member) \ + for (i = container_of_var(list_debug(h)->n.prev, i, member); \ + &i->member != &(h)->n; \ + i = container_of_var(i->member.prev, i, member)) + /** * list_for_each_safe - iterate through a list, maybe during deletion * @h: the list_head diff --git a/ccan/list/test/run.c b/ccan/list/test/run.c index f80e364a..4ac2dcda 100644 --- a/ccan/list/test/run.c +++ b/ccan/list/test/run.c @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) unsigned int i; struct list_head list = LIST_HEAD_INIT(list); - plan_tests(49); + plan_tests(53); /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */ ok1(list_empty(&static_list)); ok1(list_check(&static_list, NULL)); @@ -104,6 +104,25 @@ int main(int argc, char *argv[]) } ok1(i == 3); + /* Test list_for_each_rev. */ + i = 0; + list_for_each_rev(&parent.children, c, list) { + switch (i++) { + case 0: + ok1(c == &c3); + break; + case 1: + ok1(c == &c2); + break; + case 2: + ok1(c == &c1); + break; + } + if (i > 2) + break; + } + ok1(i == 3); + /* Test list_for_each_safe, list_del and list_del_from. */ i = 0; list_for_each_safe(&parent.children, c, n, list) { -- 2.39.2