* 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.
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));
/* 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) {
}
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();
}