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
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));
/* 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);
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();
}