4 * ntp_lists.h - singly-linked lists common code
6 * These macros implement a simple singly-linked list template. Both
7 * the listhead and per-entry next fields are declared as pointers to
8 * the list entry struct type. Initialization to NULL is typically
9 * implicit (for globals and statics) or handled by zeroing of the
10 * containing structure.
12 * The name of the next link field is passed as an argument to allow
13 * membership in several lists at once using multiple next link fields.
15 * When possible, placing the link field first in the entry structure
16 * allows slightly smaller code to be generated on some platforms.
18 * LINK_SLIST(listhead, pentry, nextlink)
21 * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype)
24 * UNLINK_HEAD_SLIST(punlinked, listhead, nextlink)
25 * unlink first entry and point punlinked to it, or set punlinked
26 * to NULL if the list is empty.
28 * UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, entrytype)
29 * unlink entry pointed to by ptounlink. punlinked is set to NULL
30 * if the entry is not found on the list, otherwise it is set to
33 * UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, entrytype)
34 * unlink entry where expression expr is nonzero. expr can refer
35 * to the entry being tested using UNLINK_EXPR_SLIST_CURRENT().
36 * See the implementation of UNLINK_SLIST() below for an example.
37 * punlinked is pointed to the removed entry or NULL if none
50 #define LINK_SLIST(listhead, pentry, nextlink) \
52 (pentry)->nextlink = (listhead); \
53 (listhead) = (pentry); \
56 #define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \
60 pptail = &(listhead); \
61 while (*pptail != NULL) \
62 pptail = &((*pptail)->nextlink); \
64 (pentry)->nextlink = NULL; \
68 #define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \
70 (punlinked) = (listhead); \
71 if (NULL != (punlinked)) { \
72 (listhead) = (punlinked)->nextlink; \
73 (punlinked)->nextlink = NULL; \
77 #define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \
80 entrytype **ppentry; \
82 ppentry = &(listhead); \
85 if ((*ppentry)->nextlink != NULL) \
86 ppentry = &((*ppentry)->nextlink); \
92 if (ppentry != NULL) { \
93 (punlinked) = *ppentry; \
94 *ppentry = (punlinked)->nextlink; \
95 (punlinked)->nextlink = NULL; \
99 #define UNLINK_EXPR_SLIST_CURRENT() (*ppentry)
101 #define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \
103 UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \
104 UNLINK_EXPR_SLIST_CURRENT(), nextlink, entrytype)
106 #endif /* NTP_LISTS_H */