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) 41270838Sume#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1) && \ 42270838Sume (void *)((elt)->link.next) != (void *)(-1)) 43158782Sume 44158782Sume#define HEAD(list) ((list).head) 45158782Sume#define TAIL(list) ((list).tail) 46158782Sume#define EMPTY(list) ((list).head == NULL) 47158782Sume 48158782Sume#define PREPEND(list, elt, link) \ 49158782Sume do { \ 50158782Sume INSIST(!LINKED(elt, link));\ 51158782Sume if ((list).head != NULL) \ 52158782Sume (list).head->link.prev = (elt); \ 53158782Sume else \ 54158782Sume (list).tail = (elt); \ 55158782Sume (elt)->link.prev = NULL; \ 56158782Sume (elt)->link.next = (list).head; \ 57158782Sume (list).head = (elt); \ 58158782Sume } while (0) 59158782Sume 60158782Sume#define APPEND(list, elt, link) \ 61158782Sume do { \ 62158782Sume INSIST(!LINKED(elt, link));\ 63158782Sume if ((list).tail != NULL) \ 64158782Sume (list).tail->link.next = (elt); \ 65158782Sume else \ 66158782Sume (list).head = (elt); \ 67158782Sume (elt)->link.prev = (list).tail; \ 68158782Sume (elt)->link.next = NULL; \ 69158782Sume (list).tail = (elt); \ 70158782Sume } while (0) 71158782Sume 72158782Sume#define UNLINK_TYPE(list, elt, link, type) \ 73158782Sume do { \ 74158782Sume INSIST(LINKED(elt, link));\ 75158782Sume if ((elt)->link.next != NULL) \ 76158782Sume (elt)->link.next->link.prev = (elt)->link.prev; \ 77170247Sume else { \ 78170247Sume INSIST((list).tail == (elt)); \ 79158782Sume (list).tail = (elt)->link.prev; \ 80170247Sume } \ 81158782Sume if ((elt)->link.prev != NULL) \ 82158782Sume (elt)->link.prev->link.next = (elt)->link.next; \ 83170247Sume else { \ 84170247Sume INSIST((list).head == (elt)); \ 85158782Sume (list).head = (elt)->link.next; \ 86170247Sume } \ 87158782Sume INIT_LINK_TYPE(elt, link, type); \ 88158782Sume } while (0) 89158782Sume#define UNLINK(list, elt, link) \ 90158782Sume UNLINK_TYPE(list, elt, link, void) 91158782Sume 92158782Sume#define PREV(elt, link) ((elt)->link.prev) 93158782Sume#define NEXT(elt, link) ((elt)->link.next) 94158782Sume 95158782Sume#define INSERT_BEFORE(list, before, elt, link) \ 96158782Sume do { \ 97158782Sume INSIST(!LINKED(elt, link));\ 98158782Sume if ((before)->link.prev == NULL) \ 99158782Sume PREPEND(list, elt, link); \ 100158782Sume else { \ 101158782Sume (elt)->link.prev = (before)->link.prev; \ 102158782Sume (before)->link.prev = (elt); \ 103158782Sume (elt)->link.prev->link.next = (elt); \ 104158782Sume (elt)->link.next = (before); \ 105158782Sume } \ 106158782Sume } while (0) 107158782Sume 108158782Sume#define INSERT_AFTER(list, after, elt, link) \ 109158782Sume do { \ 110158782Sume INSIST(!LINKED(elt, link));\ 111158782Sume if ((after)->link.next == NULL) \ 112158782Sume APPEND(list, elt, link); \ 113158782Sume else { \ 114158782Sume (elt)->link.next = (after)->link.next; \ 115158782Sume (after)->link.next = (elt); \ 116158782Sume (elt)->link.next->link.prev = (elt); \ 117158782Sume (elt)->link.prev = (after); \ 118158782Sume } \ 119158782Sume } while (0) 120158782Sume 121158782Sume#define ENQUEUE(list, elt, link) APPEND(list, elt, link) 122158782Sume#define DEQUEUE(list, elt, link) UNLINK(list, elt, link) 123158782Sume 124158782Sume#endif /* LIST_H */ 125170247Sume/*! \file */ 126