Commit c414947a authored by Rusty Russell's avatar Rusty Russell

list: implement list_for_each_rev()

parent 1819a36a
...@@ -315,6 +315,24 @@ static inline void list_del_from(struct list_head *h, struct list_node *n) ...@@ -315,6 +315,24 @@ static inline void list_del_from(struct list_head *h, struct list_node *n)
&i->member != &(h)->n; \ &i->member != &(h)->n; \
i = container_of_var(i->member.next, i, member)) 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 * list_for_each_safe - iterate through a list, maybe during deletion
* @h: the list_head * @h: the list_head
......
...@@ -22,7 +22,7 @@ int main(int argc, char *argv[]) ...@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
unsigned int i; unsigned int i;
struct list_head list = LIST_HEAD_INIT(list); 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 */ /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */
ok1(list_empty(&static_list)); ok1(list_empty(&static_list));
ok1(list_check(&static_list, NULL)); ok1(list_check(&static_list, NULL));
...@@ -104,6 +104,25 @@ int main(int argc, char *argv[]) ...@@ -104,6 +104,25 @@ int main(int argc, char *argv[])
} }
ok1(i == 3); 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. */ /* Test list_for_each_safe, list_del and list_del_from. */
i = 0; i = 0;
list_for_each_safe(&parent.children, c, n, list) { list_for_each_safe(&parent.children, c, n, list) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment