2
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3
* Copyright (c) 1997-2003 by Internet Software Consortium
5
* Permission to use, copy, modify, and 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.
9
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
12
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
* Internet Systems Consortium, Inc.
19
* Redwood City, CA 94063
27
#define ISC_LIST(type) struct { type *head, *tail; }
28
#define ISC_LIST_INIT(list) \
29
do { (list).head = NULL; (list).tail = NULL; } while (0)
31
#define ISC_LINK(type) struct { type *prev, *next; }
32
#define ISC_LINK_INIT(elt, link) \
34
(elt)->link.prev = (void *)(-1); \
35
(elt)->link.next = (void *)(-1); \
37
#define ISC_LINK_LINKED(elt, link) ((elt)->link.prev != (void *)(-1))
39
#define ISC_LIST_HEAD(list) ((list).head)
40
#define ISC_LIST_TAIL(list) ((list).tail)
41
#define ISC_LIST_EMPTY(list) ((list).head == NULL)
43
#define ISC_LIST_PREPEND(list, elt, link) \
45
if ((list).head != NULL) \
46
(list).head->link.prev = (elt); \
48
(list).tail = (elt); \
49
(elt)->link.prev = NULL; \
50
(elt)->link.next = (list).head; \
51
(list).head = (elt); \
54
#define ISC_LIST_APPEND(list, elt, link) \
56
if ((list).tail != NULL) \
57
(list).tail->link.next = (elt); \
59
(list).head = (elt); \
60
(elt)->link.prev = (list).tail; \
61
(elt)->link.next = NULL; \
62
(list).tail = (elt); \
65
#define ISC_LIST_UNLINK(list, elt, link) \
67
if ((elt)->link.next != NULL) \
68
(elt)->link.next->link.prev = (elt)->link.prev; \
70
(list).tail = (elt)->link.prev; \
71
if ((elt)->link.prev != NULL) \
72
(elt)->link.prev->link.next = (elt)->link.next; \
74
(list).head = (elt)->link.next; \
75
(elt)->link.prev = (void *)(-1); \
76
(elt)->link.next = (void *)(-1); \
79
#define ISC_LIST_PREV(elt, link) ((elt)->link.prev)
80
#define ISC_LIST_NEXT(elt, link) ((elt)->link.next)
82
#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \
84
if ((before)->link.prev == NULL) \
85
ISC_LIST_PREPEND(list, elt, link); \
87
(elt)->link.prev = (before)->link.prev; \
88
(before)->link.prev = (elt); \
89
(elt)->link.prev->link.next = (elt); \
90
(elt)->link.next = (before); \
94
#define ISC_LIST_INSERTAFTER(list, after, elt, link) \
96
if ((after)->link.next == NULL) \
97
ISC_LIST_APPEND(list, elt, link); \
99
(elt)->link.next = (after)->link.next; \
100
(after)->link.next = (elt); \
101
(elt)->link.next->link.prev = (elt); \
102
(elt)->link.prev = (after); \
106
#define ISC_LIST_APPENDLIST(list1, list2, link) \
108
if (ISC_LIST_EMPTY(list1)) \
110
else if (!ISC_LIST_EMPTY(list2)) { \
111
(list1).tail->link.next = (list2).head; \
112
(list2).head->link.prev = (list1).tail; \
113
(list1).tail = (list2).tail; \
114
(list2).head = NULL; \
115
(list2).tail = NULL; \
119
#define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
120
#define ISC_LIST_DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link)
122
#endif /* ISC_LIST_H */