From: Rusty Russell Date: Sun, 17 Mar 2013 04:42:14 +0000 (+1030) Subject: list: list_pop X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=8216fa0be7d9bf39774a192d52fef955f6bd7cd8 list: list_pop list_top + list_del, as suggested by Ben Herrenschmidt. Signed-off-by: Rusty Russell --- diff --git a/ccan/list/list.h b/ccan/list/list.h index 8e2f6df0..ab324087 100644 --- a/ccan/list/list.h +++ b/ccan/list/list.h @@ -292,6 +292,34 @@ static inline const void *list_top_(const struct list_head *h, size_t off) return (const char *)h->n.next - off; } +/** + * list_pop - remove the first 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 *one; + * one = list_pop(&parent->children, struct child, list); + * if (!one) + * printf("Empty list!\n"); + */ +#define list_pop(h, type, member) \ + ((type *)list_pop_((h), list_off_(type, member))) + +static inline const void *list_pop_(const struct list_head *h, size_t off) +{ + struct list_node *n; + + if (list_empty(h)) + return NULL; + n = h->n.next; + list_del(n); + return (const char *)n - off; +} + /** * list_tail - get the last entry in a list * @h: the list_head diff --git a/ccan/list/test/run.c b/ccan/list/test/run.c index 1d02acd5..dad30828 100644 --- a/ccan/list/test/run.c +++ b/ccan/list/test/run.c @@ -25,7 +25,7 @@ int main(int argc, char *argv[]) opaque_t *q, *nq; struct list_head opaque_list = LIST_HEAD_INIT(opaque_list); - plan_tests(65); + plan_tests(68); /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */ ok1(list_empty(&static_list)); ok1(list_check(&static_list, NULL)); @@ -85,6 +85,11 @@ int main(int argc, char *argv[]) /* Test list_top */ ok1(list_top(&parent.children, struct child, list) == &c1); + /* Test list_pop */ + ok1(list_pop(&parent.children, struct child, list) == &c1); + ok1(list_top(&parent.children, struct child, list) == &c2); + list_add(&parent.children, &c1.list); + /* Test list_tail */ ok1(list_tail(&parent.children, struct child, list) == &c3); @@ -193,8 +198,9 @@ int main(int argc, char *argv[]) ok1(i == 3); ok1(list_empty(&opaque_list)); - /* Test list_top/list_tail on empty list. */ + /* Test list_top/list_tail/list_pop on empty list. */ ok1(list_top(&parent.children, struct child, list) == NULL); ok1(list_tail(&parent.children, struct child, list) == NULL); + ok1(list_pop(&parent.children, struct child, list) == NULL); return exit_status(); }