Browse Source

list: list_pop

list_top + list_del, as suggested by Ben Herrenschmidt.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 13 years ago
parent
commit
8216fa0be7
2 changed files with 36 additions and 2 deletions
  1. 28 0
      ccan/list/list.h
  2. 8 2
      ccan/list/test/run.c

+ 28 - 0
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;
 	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
  * list_tail - get the last entry in a list
  * @h: the list_head
  * @h: the list_head

+ 8 - 2
ccan/list/test/run.c

@@ -25,7 +25,7 @@ int main(int argc, char *argv[])
 	opaque_t *q, *nq;
 	opaque_t *q, *nq;
 	struct list_head opaque_list = LIST_HEAD_INIT(opaque_list);
 	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 */
 	/* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */
 	ok1(list_empty(&static_list));
 	ok1(list_empty(&static_list));
 	ok1(list_check(&static_list, NULL));
 	ok1(list_check(&static_list, NULL));
@@ -85,6 +85,11 @@ int main(int argc, char *argv[])
 	/* Test list_top */
 	/* Test list_top */
 	ok1(list_top(&parent.children, struct child, list) == &c1);
 	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 */
 	/* Test list_tail */
 	ok1(list_tail(&parent.children, struct child, list) == &c3);
 	ok1(list_tail(&parent.children, struct child, list) == &c3);
 
 
@@ -193,8 +198,9 @@ int main(int argc, char *argv[])
 	ok1(i == 3);
 	ok1(i == 3);
 	ok1(list_empty(&opaque_list));
 	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_top(&parent.children, struct child, list) == NULL);
 	ok1(list_tail(&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();
 	return exit_status();
 }
 }