1158782Sume/* 2158782Sume * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3158782Sume * Copyright (c) 1997,1999 by Internet Software Consortium. 4158782Sume * 5158782Sume * Permission to use, copy, modify, and distribute this software for any 6158782Sume * purpose with or without fee is hereby granted, provided that the above 7158782Sume * copyright notice and this permission notice appear in all copies. 8158782Sume * 9158782Sume * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10158782Sume * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11158782Sume * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12158782Sume * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13158782Sume * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14158782Sume * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15158782Sume * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16158782Sume */ 17158782Sume 18158787Sume/* $FreeBSD$ */ 19158787Sume 20158782Sume#ifndef LIST_H 21158782Sume#define LIST_H 1 22158787Sume#ifdef _LIBC 23158787Sume#include <assert.h> 24158787Sume#define INSIST(cond) assert(cond) 25158787Sume#else 26158782Sume#include <isc/assertions.h> 27158787Sume#endif 28158782Sume 29158782Sume#define LIST(type) struct { type *head, *tail; } 30158782Sume#define INIT_LIST(list) \ 31158782Sume do { (list).head = NULL; (list).tail = NULL; } while (0) 32158782Sume 33158782Sume#define LINK(type) struct { type *prev, *next; } 34158782Sume#define INIT_LINK_TYPE(elt, link, type) \ 35158782Sume do { \ 36158782Sume (elt)->link.prev = (type *)(-1); \ 37158782Sume (elt)->link.next = (type *)(-1); \ 38158782Sume } while (0) 39158782Sume#define INIT_LINK(elt, link) \ 40158782Sume INIT_LINK_TYPE(elt, link, void) 41158782Sume#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1)) 42158782Sume 43158782Sume#define HEAD(list) ((list).head) 44158782Sume#define TAIL(list) ((list).tail) 45158782Sume#define EMPTY(list) ((list).head == NULL) 46158782Sume 47158782Sume#define PREPEND(list, elt, link) \ 48158782Sume do { \ 49158782Sume INSIST(!LINKED(elt, link));\ 50158782Sume if ((list).head != NULL) \ 51158782Sume (list).head->link.prev = (elt); \ 52158782Sume else \ 53158782Sume (list).tail = (elt); \ 54158782Sume (elt)->link.prev = NULL; \ 55158782Sume (elt)->link.next = (list).head; \ 56158782Sume (list).head = (elt); \ 57158782Sume } while (0) 58158782Sume 59158782Sume#define APPEND(list, elt, link) \ 60158782Sume do { \ 61158782Sume INSIST(!LINKED(elt, link));\ 62158782Sume if ((list).tail != NULL) \ 63158782Sume (list).tail->link.next = (elt); \ 64158782Sume else \ 65158782Sume (list).head = (elt); \ 66158782Sume (elt)->link.prev = (list).tail; \ 67158782Sume (elt)->link.next = NULL; \ 68158782Sume (list).tail = (elt); \ 69158782Sume } while (0) 70158782Sume 71158782Sume#define UNLINK_TYPE(list, elt, link, type) \ 72158782Sume do { \ 73158782Sume INSIST(LINKED(elt, link));\ 74158782Sume if ((elt)->link.next != NULL) \ 75158782Sume (elt)->link.next->link.prev = (elt)->link.prev; \ 76170247Sume else { \ 77170247Sume INSIST((list).tail == (elt)); \ 78158782Sume (list).tail = (elt)->link.prev; \ 79170247Sume } \ 80158782Sume if ((elt)->link.prev != NULL) \ 81158782Sume (elt)->link.prev->link.next = (elt)->link.next; \ 82170247Sume else { \ 83170247Sume INSIST((list).head == (elt)); \ 84158782Sume (list).head = (elt)->link.next; \ 85170247Sume } \ 86158782Sume INIT_LINK_TYPE(elt, link, type); \ 87158782Sume } while (0) 88158782Sume#define UNLINK(list, elt, link) \ 89158782Sume UNLINK_TYPE(list, elt, link, void) 90158782Sume 91158782Sume#define PREV(elt, link) ((elt)->link.prev) 92158782Sume#define NEXT(elt, link) ((elt)->link.next) 93158782Sume 94158782Sume#define INSERT_BEFORE(list, before, elt, link) \ 95158782Sume do { \ 96158782Sume INSIST(!LINKED(elt, link));\ 97158782Sume if ((before)->link.prev == NULL) \ 98158782Sume PREPEND(list, elt, link); \ 99158782Sume else { \ 100158782Sume (elt)->link.prev = (before)->link.prev; \ 101158782Sume (before)->link.prev = (elt); \ 102158782Sume (elt)->link.prev->link.next = (elt); \ 103158782Sume (elt)->link.next = (before); \ 104158782Sume } \ 105158782Sume } while (0) 106158782Sume 107158782Sume#define INSERT_AFTER(list, after, elt, link) \ 108158782Sume do { \ 109158782Sume INSIST(!LINKED(elt, link));\ 110158782Sume if ((after)->link.next == NULL) \ 111158782Sume APPEND(list, elt, link); \ 112158782Sume else { \ 113158782Sume (elt)->link.next = (after)->link.next; \ 114158782Sume (after)->link.next = (elt); \ 115158782Sume (elt)->link.next->link.prev = (elt); \ 116158782Sume (elt)->link.prev = (after); \ 117158782Sume } \ 118158782Sume } while (0) 119158782Sume 120158782Sume#define ENQUEUE(list, elt, link) APPEND(list, elt, link) 121158782Sume#define DEQUEUE(list, elt, link) UNLINK(list, elt, link) 122158782Sume 123158782Sume#endif /* LIST_H */ 124170247Sume/*! \file */ 125