#include <sys/queue.h> LIST_ENTRY(TYPE); LIST_HEAD(HEADNAME, TYPE); LIST_HEAD LIST_HEAD_INITIALIZER(LIST_HEAD head); void LIST_INIT(LIST_HEAD *head); int LIST_EMPTY(LIST_HEAD *head); void LIST_INSERT_HEAD(LIST_HEAD *head, struct TYPE *elm, LIST_ENTRY NAME); void LIST_INSERT_BEFORE(struct TYPE *listelm, struct TYPE *elm, LIST_ENTRY NAME); void LIST_INSERT_AFTER(struct TYPE *listelm, struct TYPE *elm, LIST_ENTRY NAME); struct TYPE *LIST_FIRST(LIST_HEAD *head); struct TYPE *LIST_NEXT(struct TYPE *elm, LIST_ENTRY NAME); LIST_FOREACH(struct TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME); void LIST_REMOVE(struct TYPE *elm, LIST_ENTRY NAME);
In the macro definitions, TYPE is the name of a user-defined structure, that must contain a field of type LIST_ENTRY, named NAME. The argument HEADNAME is the name of a user-defined structure that must be declared using the macro LIST_HEAD().
LIST_HEAD(HEADNAME, TYPE) head;
where struct HEADNAME is the structure to be defined, and struct TYPE is the type of the elements to be linked into the list. A pointer to the head of the list can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
LIST_ENTRY() declares a structure that connects the elements in the list.
LIST_HEAD_INITIALIZER() evaluates to an initializer for the list head.
LIST_INIT() initializes the list referenced by head.
LIST_EMPTY() evaluates to true if there are no elements in the list.
LIST_INSERT_BEFORE() inserts the new element elm before the element listelm.
LIST_INSERT_AFTER() inserts the new element elm after the element listelm.
LIST_NEXT() returns the next element in the list, or NULL if this is the last.
LIST_FOREACH() traverses the list referenced by head in the forward direction, assigning each element in turn to var.
LIST_FIRST(), and LIST_NEXT() return a pointer to the first or next TYPE structure, respectively.
LIST_HEAD_INITIALIZER() returns an initializer that can be assigned to the list head.
struct entry {
int data;
LIST_ENTRY(entry) entries; /* List */
};
LIST_HEAD(listhead, entry);
int
main(void)
{
struct entry *n1, *n2, *n3, *np;
struct listhead head; /* List head */
int i;
LIST_INIT(&head); /* Initialize the list */
n1 = malloc(sizeof(struct entry)); /* Insert at the head */
LIST_INSERT_HEAD(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after */
LIST_INSERT_AFTER(n1, n2, entries);
n3 = malloc(sizeof(struct entry)); /* Insert before */
LIST_INSERT_BEFORE(n2, n3, entries);
i = 0; /* Forward traversal */
LIST_FOREACH(np, &head, entries)
np->data = i++;
LIST_REMOVE(n2, entries); /* Deletion */
free(n2);
/* Forward traversal */
LIST_FOREACH(np, &head, entries)
printf("%i\n", np->data);
/* List deletion */
n1 = LIST_FIRST(&head);
while (n1 != NULL) {
n2 = LIST_NEXT(n1, entries);
free(n1);
n1 = n2;
}
LIST_INIT(&head);