New list_tail() function and test for list_top() on empty list reveals a
authorRusty Russell <rusty@rustcorp.com.au>
Sat, 15 Nov 2008 12:24:23 +0000 (22:54 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Sat, 15 Nov 2008 12:24:23 +0000 (22:54 +1030)
bug!

ccan/list/list.h
ccan/list/test/run.c

index 58c0a97c43246185e2dcb17adb103a922f19e277..e1f07a0e043ae7f460d2650e2acdf39d468ab5aa 100644 (file)
@@ -198,15 +198,22 @@ static inline bool list_empty(struct list_head *h)
  *     first = list_top(&parent->children, struct child, list);
  */
 #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)
-{
-       (void)debug_list(h);
-       if (list_empty(h))
-               return NULL;
-       return h->n.next;
-}
+/**
+ * list_tail - get the last entry in a list
+ * @h: the list_head
+ * @type: the type of the entry
+ * @member: the list_node member of the type
+ *
+ * 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.
index 66b9630db514610ac9d78c76212492e39b6465ca..ac318e1a7fe484c75b072feeb7c5ac96bfca297c 100644 (file)
@@ -21,7 +21,7 @@ int main(int argc, char *argv[])
        struct child c1, c2, c3, *c, *n;
        unsigned int i;
 
-       plan_tests(41);
+       plan_tests(44);
        /* Test LIST_HEAD, list_empty and check_list */
        ok1(list_empty(&static_list));
        ok1(list_check(&static_list, NULL));
@@ -74,6 +74,9 @@ int main(int argc, char *argv[])
        /* Test list_top */
        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. */
        i = 0;
        list_for_each(&parent.children, c, list) {
@@ -114,5 +117,9 @@ int main(int argc, char *argv[])
        }
        ok1(i == 3);
        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();
 }