summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/list.h15
-rw-r--r--test/list.c6
2 files changed, 21 insertions, 0 deletions
diff --git a/include/list.h b/include/list.h
index f8659f04e..73ff0bee9 100644
--- a/include/list.h
+++ b/include/list.h
@@ -262,6 +262,21 @@ list_is_empty(struct list *head)
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
+/**
+ * Retrieve the last list entry for the given listpointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = list_last_entry(&foo->mylist, struct foo, mylist);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct list field in the list element.
+ * @return A pointer to the last list element.
+ */
+#define list_last_entry(ptr, type, member) \
+ list_entry((ptr)->prev, type, member)
+
#define __container_of(ptr, sample, member) \
(void *)((char *)(ptr) \
- ((char *)&(sample)->member - (char *)(sample)))
diff --git a/test/list.c b/test/list.c
index b96182e03..ffb85efd0 100644
--- a/test/list.c
+++ b/test/list.c
@@ -103,14 +103,20 @@ test_list_append(void)
c = list_first_entry(&parent.children, struct child, node);
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
+ c = list_last_entry(&parent.children, struct child, node);
+ assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
list_append(&child[1].node, &parent.children);
c = list_first_entry(&parent.children, struct child, node);
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
+ c = list_last_entry(&parent.children, struct child, node);
+ assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
list_append(&child[2].node, &parent.children);
c = list_first_entry(&parent.children, struct child, node);
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
+ c = list_last_entry(&parent.children, struct child, node);
+ assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
i = 0;
list_for_each_entry(c, &parent.children, node) {