Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / include / ntp_lists.h
blob020de17ed479ea860375b5cd36c4c4a8f1843a54
1 /* $NetBSD$ */
3 /*
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)
19 * add entry at head
21 * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype)
22 * add entry at tail
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
31 * ptounlink.
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
38 * satisfy expr.
40 #ifndef NTP_LISTS_H
41 #define NTP_LISTS_H
43 #ifdef HAVE_CONFIG_H
44 # include <config.h>
45 #endif
47 #include <isc/list.h>
50 #define LINK_SLIST(listhead, pentry, nextlink) \
51 do { \
52 (pentry)->nextlink = (listhead); \
53 (listhead) = (pentry); \
54 } while (0)
56 #define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \
57 do { \
58 entrytype **pptail; \
60 pptail = &(listhead); \
61 while (*pptail != NULL) \
62 pptail = &((*pptail)->nextlink); \
64 (pentry)->nextlink = NULL; \
65 *pptail = (pentry); \
66 } while (0)
68 #define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \
69 do { \
70 (punlinked) = (listhead); \
71 if (NULL != (punlinked)) { \
72 (listhead) = (punlinked)->nextlink; \
73 (punlinked)->nextlink = NULL; \
74 } \
75 } while (0)
77 #define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \
78 entrytype) \
79 do { \
80 entrytype **ppentry; \
82 ppentry = &(listhead); \
84 while (!(expr)) \
85 if ((*ppentry)->nextlink != NULL) \
86 ppentry = &((*ppentry)->nextlink); \
87 else { \
88 ppentry = NULL; \
89 break; \
90 } \
92 if (ppentry != NULL) { \
93 (punlinked) = *ppentry; \
94 *ppentry = (punlinked)->nextlink; \
95 (punlinked)->nextlink = NULL; \
96 } else \
97 (punlinked) = NULL; \
98 } while (0)
99 #define UNLINK_EXPR_SLIST_CURRENT() (*ppentry)
101 #define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \
102 entrytype) \
103 UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \
104 UNLINK_EXPR_SLIST_CURRENT(), nextlink, entrytype)
106 #endif /* NTP_LISTS_H */