1 /* $NetBSD: ntp_lists.h,v 1.1.1.1 2009/12/13 16:54:51 kardel Exp $ */ 2 3 /* 4 * ntp_lists.h - singly-linked lists common code 5 * 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. 11 * 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. 14 * 15 * When possible, placing the link field first in the entry structure 16 * allows slightly smaller code to be generated on some platforms. 17 * 18 * LINK_SLIST(listhead, pentry, nextlink) 19 * add entry at head 20 * 21 * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) 22 * add entry at tail 23 * 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. 27 * 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. 32 * 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. 39 */ 40 #ifndef NTP_LISTS_H 41 #define NTP_LISTS_H 42 43 #ifdef HAVE_CONFIG_H 44 # include <config.h> 45 #endif 46 47 #include <isc/list.h> 48 49 50 #define LINK_SLIST(listhead, pentry, nextlink) \ 51 do { \ 52 (pentry)->nextlink = (listhead); \ 53 (listhead) = (pentry); \ 54 } while (0) 55 56 #define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \ 57 do { \ 58 entrytype **pptail; \ 59 \ 60 pptail = &(listhead); \ 61 while (*pptail != NULL) \ 62 pptail = &((*pptail)->nextlink); \ 63 \ 64 (pentry)->nextlink = NULL; \ 65 *pptail = (pentry); \ 66 } while (0) 67 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) 76 77 #define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \ 78 entrytype) \ 79 do { \ 80 entrytype **ppentry; \ 81 \ 82 ppentry = &(listhead); \ 83 \ 84 while (!(expr)) \ 85 if ((*ppentry)->nextlink != NULL) \ 86 ppentry = &((*ppentry)->nextlink); \ 87 else { \ 88 ppentry = NULL; \ 89 break; \ 90 } \ 91 \ 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) 100 101 #define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \ 102 entrytype) \ 103 UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \ 104 UNLINK_EXPR_SLIST_CURRENT(), nextlink, entrytype) 105 106 #endif /* NTP_LISTS_H */ 107