1*86d7f5d3SJohn Marino /* 2*86d7f5d3SJohn Marino * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3*86d7f5d3SJohn Marino * Copyright (c) 1997,1999 by Internet Software Consortium. 4*86d7f5d3SJohn Marino * 5*86d7f5d3SJohn Marino * Permission to use, copy, modify, and distribute this software for any 6*86d7f5d3SJohn Marino * purpose with or without fee is hereby granted, provided that the above 7*86d7f5d3SJohn Marino * copyright notice and this permission notice appear in all copies. 8*86d7f5d3SJohn Marino * 9*86d7f5d3SJohn Marino * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10*86d7f5d3SJohn Marino * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*86d7f5d3SJohn Marino * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12*86d7f5d3SJohn Marino * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*86d7f5d3SJohn Marino * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*86d7f5d3SJohn Marino * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15*86d7f5d3SJohn Marino * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*86d7f5d3SJohn Marino */ 17*86d7f5d3SJohn Marino 18*86d7f5d3SJohn Marino #ifndef LIST_H 19*86d7f5d3SJohn Marino #define LIST_H 1 20*86d7f5d3SJohn Marino #ifdef _LIBC 21*86d7f5d3SJohn Marino #include <assert.h> 22*86d7f5d3SJohn Marino #define INSIST(cond) assert(cond) 23*86d7f5d3SJohn Marino #else 24*86d7f5d3SJohn Marino #include <isc/assertions.h> 25*86d7f5d3SJohn Marino #endif 26*86d7f5d3SJohn Marino #define LIST(type) struct { type *head, *tail; } 27*86d7f5d3SJohn Marino #define INIT_LIST(list) \ 28*86d7f5d3SJohn Marino do { (list).head = NULL; (list).tail = NULL; } while (0) 29*86d7f5d3SJohn Marino 30*86d7f5d3SJohn Marino #define LINK(type) struct { type *prev, *next; } 31*86d7f5d3SJohn Marino #define INIT_LINK_TYPE(elt, link, type) \ 32*86d7f5d3SJohn Marino do { \ 33*86d7f5d3SJohn Marino (elt)->link.prev = (type *)(-1); \ 34*86d7f5d3SJohn Marino (elt)->link.next = (type *)(-1); \ 35*86d7f5d3SJohn Marino } while (0) 36*86d7f5d3SJohn Marino #define INIT_LINK(elt, link) \ 37*86d7f5d3SJohn Marino INIT_LINK_TYPE(elt, link, void) 38*86d7f5d3SJohn Marino #define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1)) 39*86d7f5d3SJohn Marino 40*86d7f5d3SJohn Marino #define HEAD(list) ((list).head) 41*86d7f5d3SJohn Marino #define TAIL(list) ((list).tail) 42*86d7f5d3SJohn Marino #define EMPTY(list) ((list).head == NULL) 43*86d7f5d3SJohn Marino 44*86d7f5d3SJohn Marino #define PREPEND(list, elt, link) \ 45*86d7f5d3SJohn Marino do { \ 46*86d7f5d3SJohn Marino INSIST(!LINKED(elt, link));\ 47*86d7f5d3SJohn Marino if ((list).head != NULL) \ 48*86d7f5d3SJohn Marino (list).head->link.prev = (elt); \ 49*86d7f5d3SJohn Marino else \ 50*86d7f5d3SJohn Marino (list).tail = (elt); \ 51*86d7f5d3SJohn Marino (elt)->link.prev = NULL; \ 52*86d7f5d3SJohn Marino (elt)->link.next = (list).head; \ 53*86d7f5d3SJohn Marino (list).head = (elt); \ 54*86d7f5d3SJohn Marino } while (0) 55*86d7f5d3SJohn Marino 56*86d7f5d3SJohn Marino #define APPEND(list, elt, link) \ 57*86d7f5d3SJohn Marino do { \ 58*86d7f5d3SJohn Marino INSIST(!LINKED(elt, link));\ 59*86d7f5d3SJohn Marino if ((list).tail != NULL) \ 60*86d7f5d3SJohn Marino (list).tail->link.next = (elt); \ 61*86d7f5d3SJohn Marino else \ 62*86d7f5d3SJohn Marino (list).head = (elt); \ 63*86d7f5d3SJohn Marino (elt)->link.prev = (list).tail; \ 64*86d7f5d3SJohn Marino (elt)->link.next = NULL; \ 65*86d7f5d3SJohn Marino (list).tail = (elt); \ 66*86d7f5d3SJohn Marino } while (0) 67*86d7f5d3SJohn Marino 68*86d7f5d3SJohn Marino #define UNLINK_TYPE(list, elt, link, type) \ 69*86d7f5d3SJohn Marino do { \ 70*86d7f5d3SJohn Marino INSIST(LINKED(elt, link));\ 71*86d7f5d3SJohn Marino if ((elt)->link.next != NULL) \ 72*86d7f5d3SJohn Marino (elt)->link.next->link.prev = (elt)->link.prev; \ 73*86d7f5d3SJohn Marino else { \ 74*86d7f5d3SJohn Marino INSIST((list).tail == (elt)); \ 75*86d7f5d3SJohn Marino (list).tail = (elt)->link.prev; \ 76*86d7f5d3SJohn Marino } \ 77*86d7f5d3SJohn Marino if ((elt)->link.prev != NULL) \ 78*86d7f5d3SJohn Marino (elt)->link.prev->link.next = (elt)->link.next; \ 79*86d7f5d3SJohn Marino else { \ 80*86d7f5d3SJohn Marino INSIST((list).head == (elt)); \ 81*86d7f5d3SJohn Marino (list).head = (elt)->link.next; \ 82*86d7f5d3SJohn Marino } \ 83*86d7f5d3SJohn Marino INIT_LINK_TYPE(elt, link, type); \ 84*86d7f5d3SJohn Marino } while (0) 85*86d7f5d3SJohn Marino #define UNLINK(list, elt, link) \ 86*86d7f5d3SJohn Marino UNLINK_TYPE(list, elt, link, void) 87*86d7f5d3SJohn Marino 88*86d7f5d3SJohn Marino #define PREV(elt, link) ((elt)->link.prev) 89*86d7f5d3SJohn Marino #define NEXT(elt, link) ((elt)->link.next) 90*86d7f5d3SJohn Marino 91*86d7f5d3SJohn Marino #define INSERT_BEFORE(list, before, elt, link) \ 92*86d7f5d3SJohn Marino do { \ 93*86d7f5d3SJohn Marino INSIST(!LINKED(elt, link));\ 94*86d7f5d3SJohn Marino if ((before)->link.prev == NULL) \ 95*86d7f5d3SJohn Marino PREPEND(list, elt, link); \ 96*86d7f5d3SJohn Marino else { \ 97*86d7f5d3SJohn Marino (elt)->link.prev = (before)->link.prev; \ 98*86d7f5d3SJohn Marino (before)->link.prev = (elt); \ 99*86d7f5d3SJohn Marino (elt)->link.prev->link.next = (elt); \ 100*86d7f5d3SJohn Marino (elt)->link.next = (before); \ 101*86d7f5d3SJohn Marino } \ 102*86d7f5d3SJohn Marino } while (0) 103*86d7f5d3SJohn Marino 104*86d7f5d3SJohn Marino #define INSERT_AFTER(list, after, elt, link) \ 105*86d7f5d3SJohn Marino do { \ 106*86d7f5d3SJohn Marino INSIST(!LINKED(elt, link));\ 107*86d7f5d3SJohn Marino if ((after)->link.next == NULL) \ 108*86d7f5d3SJohn Marino APPEND(list, elt, link); \ 109*86d7f5d3SJohn Marino else { \ 110*86d7f5d3SJohn Marino (elt)->link.next = (after)->link.next; \ 111*86d7f5d3SJohn Marino (after)->link.next = (elt); \ 112*86d7f5d3SJohn Marino (elt)->link.next->link.prev = (elt); \ 113*86d7f5d3SJohn Marino (elt)->link.prev = (after); \ 114*86d7f5d3SJohn Marino } \ 115*86d7f5d3SJohn Marino } while (0) 116*86d7f5d3SJohn Marino 117*86d7f5d3SJohn Marino #define ENQUEUE(list, elt, link) APPEND(list, elt, link) 118*86d7f5d3SJohn Marino #define DEQUEUE(list, elt, link) UNLINK(list, elt, link) 119*86d7f5d3SJohn Marino 120*86d7f5d3SJohn Marino #endif /* LIST_H */ 121*86d7f5d3SJohn Marino /*! \file */ 122