1/* 2 * ntp_lists.h - singly-linked lists common code 3 * 4 * These macros implement a simple singly-linked list template. Both 5 * the listhead and per-entry next fields are declared as pointers to 6 * the list entry struct type. Initialization to NULL is typically 7 * implicit (for globals and statics) or handled by zeroing of the 8 * containing structure. 9 * 10 * The name of the next link field is passed as an argument to allow 11 * membership in several lists at once using multiple next link fields. 12 * 13 * When possible, placing the link field first in the entry structure 14 * allows slightly smaller code to be generated on some platforms. 15 * 16 * LINK_SLIST(listhead, pentry, nextlink) 17 * add entry at head 18 * 19 * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) 20 * add entry at tail 21 * 22 * UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) 23 * unlink first entry and point punlinked to it, or set punlinked 24 * to NULL if the list is empty. 25 * 26 * UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, entrytype) 27 * unlink entry pointed to by ptounlink. punlinked is set to NULL 28 * if the entry is not found on the list, otherwise it is set to 29 * ptounlink. 30 * 31 * UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, entrytype) 32 * unlink entry where expression expr is nonzero. expr can refer 33 * to the entry being tested using UNLINK_EXPR_SLIST_CURRENT(). 34 * See the implementation of UNLINK_SLIST() below for an example. 35 * punlinked is pointed to the removed entry or NULL if none 36 * satisfy expr. 37 */ 38#ifndef NTP_LISTS_H 39#define NTP_LISTS_H 40 41#ifdef HAVE_CONFIG_H 42# include <config.h> 43#endif 44 45#include <isc/list.h> 46 47 48#define LINK_SLIST(listhead, pentry, nextlink) \ 49do { \ 50 (pentry)->nextlink = (listhead); \ 51 (listhead) = (pentry); \ 52} while (0) 53 54#define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \ 55do { \ 56 entrytype **pptail; \ 57 \ 58 pptail = &(listhead); \ 59 while (*pptail != NULL) \ 60 pptail = &((*pptail)->nextlink); \ 61 \ 62 (pentry)->nextlink = NULL; \ 63 *pptail = (pentry); \ 64} while (0) 65 66#define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \ 67do { \ 68 (punlinked) = (listhead); \ 69 if (NULL != (punlinked)) { \ 70 (listhead) = (punlinked)->nextlink; \ 71 (punlinked)->nextlink = NULL; \ 72 } \ 73} while (0) 74 75#define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \ 76 entrytype) \ 77do { \ 78 entrytype **ppentry; \ 79 \ 80 ppentry = &(listhead); \ 81 \ 82 while (!(expr)) \ 83 if ((*ppentry)->nextlink != NULL) \ 84 ppentry = &((*ppentry)->nextlink); \ 85 else { \ 86 ppentry = NULL; \ 87 break; \ 88 } \ 89 \ 90 if (ppentry != NULL) { \ 91 (punlinked) = *ppentry; \ 92 *ppentry = (punlinked)->nextlink; \ 93 (punlinked)->nextlink = NULL; \ 94 } else \ 95 (punlinked) = NULL; \ 96} while (0) 97#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry) 98 99#define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \ 100 entrytype) \ 101 UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \ 102 UNLINK_EXPR_SLIST_CURRENT(), nextlink, entrytype) 103 104#endif /* NTP_LISTS_H */ 105