Commit 0c492447 authored by Rusty Russell's avatar Rusty Russell

New list_tail() function and test for list_top() on empty list reveals a

bug!
parent 44c480c4
...@@ -198,15 +198,22 @@ static inline bool list_empty(struct list_head *h) ...@@ -198,15 +198,22 @@ static inline bool list_empty(struct list_head *h)
* first = list_top(&parent->children, struct child, list); * first = list_top(&parent->children, struct child, list);
*/ */
#define list_top(h, type, member) \ #define list_top(h, type, member) \
list_entry(_list_top(h), type, member) (list_empty(h) ? NULL : list_entry((h)->n.next, type, member))
static inline struct list_node *_list_top(struct list_head *h) /**
{ * list_tail - get the last entry in a list
(void)debug_list(h); * @h: the list_head
if (list_empty(h)) * @type: the type of the entry
return NULL; * @member: the list_node member of the type
return h->n.next; *
} * If the list is empty, returns NULL.
*
* Example:
* struct child *last;
* last = list_tail(&parent->children, struct child, list);
*/
#define list_tail(h, type, member) \
(list_empty(h) ? NULL : list_entry((h)->n.prev, type, member))
/** /**
* list_for_each - iterate through a list. * list_for_each - iterate through a list.
......
...@@ -21,7 +21,7 @@ int main(int argc, char *argv[]) ...@@ -21,7 +21,7 @@ int main(int argc, char *argv[])
struct child c1, c2, c3, *c, *n; struct child c1, c2, c3, *c, *n;
unsigned int i; unsigned int i;
plan_tests(41); plan_tests(44);
/* Test LIST_HEAD, list_empty and check_list */ /* Test LIST_HEAD, 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));
...@@ -74,6 +74,9 @@ int main(int argc, char *argv[]) ...@@ -74,6 +74,9 @@ int main(int argc, char *argv[])
/* Test list_top */ /* Test list_top */
ok1(list_top(&parent.children, struct child, list) == &c1); ok1(list_top(&parent.children, struct child, list) == &c1);
/* Test list_tail */
ok1(list_tail(&parent.children, struct child, list) == &c3);
/* Test list_for_each. */ /* Test list_for_each. */
i = 0; i = 0;
list_for_each(&parent.children, c, list) { list_for_each(&parent.children, c, list) {
...@@ -114,5 +117,9 @@ int main(int argc, char *argv[]) ...@@ -114,5 +117,9 @@ int main(int argc, char *argv[])
} }
ok1(i == 3); ok1(i == 3);
ok1(list_empty(&parent.children)); ok1(list_empty(&parent.children));
/* Test list_top/list_tail on empty list. */
ok1(list_top(&parent.children, struct child, list) == NULL);
ok1(list_tail(&parent.children, struct child, list) == NULL);
return exit_status(); return exit_status();
} }
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