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) {