1/* 2 * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1997-2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: list.h,v 1.14 2007/06/19 23:47:23 tbox Exp $ */ 19 20#ifndef LWRES_LIST_H 21#define LWRES_LIST_H 1 22 23/*! \file lwres/list.h */ 24 25#define LWRES_LIST(type) struct { type *head, *tail; } 26#define LWRES_LIST_INIT(list) \ 27 do { (list).head = NULL; (list).tail = NULL; } while (0) 28 29#define LWRES_LINK(type) struct { type *prev, *next; } 30#define LWRES_LINK_INIT(elt, link) \ 31 do { \ 32 (elt)->link.prev = (void *)(-1); \ 33 (elt)->link.next = (void *)(-1); \ 34 } while (0) 35#define LWRES_LINK_LINKED(elt, link) \ 36 ((void *)((elt)->link.prev) != (void *)(-1)) 37 38#define LWRES_LIST_HEAD(list) ((list).head) 39#define LWRES_LIST_TAIL(list) ((list).tail) 40#define LWRES_LIST_EMPTY(list) LWRES_TF((list).head == NULL) 41 42#define LWRES_LIST_PREPEND(list, elt, link) \ 43 do { \ 44 if ((list).head != NULL) \ 45 (list).head->link.prev = (elt); \ 46 else \ 47 (list).tail = (elt); \ 48 (elt)->link.prev = NULL; \ 49 (elt)->link.next = (list).head; \ 50 (list).head = (elt); \ 51 } while (0) 52 53#define LWRES_LIST_APPEND(list, elt, link) \ 54 do { \ 55 if ((list).tail != NULL) \ 56 (list).tail->link.next = (elt); \ 57 else \ 58 (list).head = (elt); \ 59 (elt)->link.prev = (list).tail; \ 60 (elt)->link.next = NULL; \ 61 (list).tail = (elt); \ 62 } while (0) 63 64#define LWRES_LIST_UNLINK(list, elt, link) \ 65 do { \ 66 if ((elt)->link.next != NULL) \ 67 (elt)->link.next->link.prev = (elt)->link.prev; \ 68 else \ 69 (list).tail = (elt)->link.prev; \ 70 if ((elt)->link.prev != NULL) \ 71 (elt)->link.prev->link.next = (elt)->link.next; \ 72 else \ 73 (list).head = (elt)->link.next; \ 74 (elt)->link.prev = (void *)(-1); \ 75 (elt)->link.next = (void *)(-1); \ 76 } while (0) 77 78#define LWRES_LIST_PREV(elt, link) ((elt)->link.prev) 79#define LWRES_LIST_NEXT(elt, link) ((elt)->link.next) 80 81#define LWRES_LIST_INSERTBEFORE(list, before, elt, link) \ 82 do { \ 83 if ((before)->link.prev == NULL) \ 84 LWRES_LIST_PREPEND(list, elt, link); \ 85 else { \ 86 (elt)->link.prev = (before)->link.prev; \ 87 (before)->link.prev = (elt); \ 88 (elt)->link.prev->link.next = (elt); \ 89 (elt)->link.next = (before); \ 90 } \ 91 } while (0) 92 93#define LWRES_LIST_INSERTAFTER(list, after, elt, link) \ 94 do { \ 95 if ((after)->link.next == NULL) \ 96 LWRES_LIST_APPEND(list, elt, link); \ 97 else { \ 98 (elt)->link.next = (after)->link.next; \ 99 (after)->link.next = (elt); \ 100 (elt)->link.next->link.prev = (elt); \ 101 (elt)->link.prev = (after); \ 102 } \ 103 } while (0) 104 105#define LWRES_LIST_APPENDLIST(list1, list2, link) \ 106 do { \ 107 if (LWRES_LIST_EMPTY(list1)) \ 108 (list1) = (list2); \ 109 else if (!LWRES_LIST_EMPTY(list2)) { \ 110 (list1).tail->link.next = (list2).head; \ 111 (list2).head->link.prev = (list1).tail; \ 112 (list1).tail = (list2).tail; \ 113 } \ 114 (list2).head = NULL; \ 115 (list2).tail = NULL; \ 116 } while (0) 117 118#define LWRES_LIST_ENQUEUE(list, elt, link) LWRES_LIST_APPEND(list, elt, link) 119#define LWRES_LIST_DEQUEUE(list, elt, link) LWRES_LIST_UNLINK(list, elt, link) 120 121#endif /* LWRES_LIST_H */ 122