diff --git a/include/list.h b/include/list.h index 4706e178b..f8659f04e 100644 --- a/include/list.h +++ b/include/list.h @@ -159,6 +159,28 @@ list_add(struct list *entry, struct list *head) __list_add(entry, head, head->next); } +/** + * Append a new element to the end of the list given with this list head. + * + * The list changes from: + * head → some element → ... → lastelement + * to + * head → some element → ... → lastelement → new element + * + * Example: + * struct foo *newfoo = malloc(...); + * list_append(&newfoo->mylist, &foo->mylist); + * + * @param entry The new element to prepend to the list. + * @param head The existing list. + */ +static inline void +list_append(struct list *entry, struct list *head) +{ + __list_add(entry, head->prev, head); +} + + static inline void __list_del(struct list *prev, struct list *next) { diff --git a/test/list.c b/test/list.c index f7d7bffce..b96182e03 100644 --- a/test/list.c +++ b/test/list.c @@ -88,6 +88,36 @@ test_list_add(void) assert(memcmp(c, &child[2], sizeof(struct child)) == 0); }; +static void +test_list_append(void) +{ + struct parent parent = {0}; + struct child child[3]; + struct child *c; + int i; + + list_init(&parent.children); + + list_append(&child[0].node, &parent.children); + assert(!list_is_empty(&parent.children)); + + c = list_first_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); + + 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); + + i = 0; + list_for_each_entry(c, &parent.children, node) { + assert(memcmp(c, &child[i++], sizeof(struct child)) == 0); + } +}; + static void test_list_del(void) { @@ -325,6 +355,7 @@ int main(int argc, char** argv) { test_list_init(); test_list_add(); + test_list_append(); test_list_del(); test_list_for_each();