windows-kfw-sdk-20060921
[openafs.git] / src / WINNT / kfw / inc / netidmgr / khlist.h
1 /*
2  * Copyright (c) 2005 Massachusetts Institute of Technology
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 /* $Id$ */
26
27 /* Not exported */
28 #ifndef _KHIMAIRA_KHLIST_H
29 #define _KHIMAIRA_KHLIST_H
30
31 /* Note that most of these are "unsafe" macros.  Not for general use */
32
33 /* LIFO lists */
34 #define LDCL(type)                              \
35     type * next;                                \
36     type * prev
37
38 #define LINIT(pe)                               \
39     do {                                        \
40     (pe)->next = NULL;                          \
41     (pe)->prev = NULL; } while(0)
42
43 #define LPUSH(pph,pe)                           \
44     do {                                        \
45     (pe)->next = *pph;                          \
46     (pe)->prev = NULL;                          \
47     if(*(pph)) (*(pph))->prev = (pe);           \
48     (*(pph)) = (pe); } while(0)
49
50 #define LPOP(pph,ppe)                           \
51     do {                                        \
52     *(ppe) = *(pph);                            \
53     if(*(pph)) *(pph) = (*(pph))->next;         \
54     if(*(pph)) (*(pph))->prev = NULL;           \
55     if(*(ppe)) (*(ppe))->next = NULL;           \
56     } while(0)
57
58 #define LDELETE(pph,pe)                                 \
59     do {                                                \
60     if((pe)->prev) (pe)->prev->next = (pe)->next;       \
61     if((pe)->next) (pe)->next->prev = (pe)->prev;       \
62     if(*(pph) == (pe)) *(pph) = (pe)->next;             \
63     (pe)->next = (pe)->prev = NULL;                     \
64     } while(0)
65
66 #define LEMPTY(pph) (*(pph) == NULL)
67
68 #define LNEXT(pe) ((pe)?(pe)->next:NULL)
69
70 #define LPREV(pe) ((pe)?(pe)->prev:NULL)
71
72 /* Trees with LIFO child lists */
73 #define TDCL(type)                              \
74     LDCL(type);                                 \
75     type * children;                            \
76     type * parent
77
78 #define TINIT(pe)                               \
79     do {                                        \
80     (pe)->children = NULL;                      \
81     (pe)->parent = NULL; } while(0)
82
83 #define TADDCHILD(pt,pe)                        \
84     do {                                        \
85     LPUSH(&((pt)->children),(pe));              \
86     (pe)->parent = (pt); } while(0)
87
88 #define TFIRSTCHILD(pt) ((pt)?(pt)->children:NULL)
89
90 #define TPOPCHILD(pt, ppe)                      \
91     do {                                        \
92     LPOP(&((pt)->children), ppe);               \
93     if(*(ppe)) (*(ppe))->parent = NULL;         \
94     } while(0)
95
96 #define TDELCHILD(pt, pe)                       \
97     do {                                        \
98     LDELETE(&((pt)->children), (pe));           \
99     (pe)->parent = NULL; } while(0)
100
101 #define TPARENT(pe) ((pe)?(pe)->parent:NULL)
102
103 /* FIFO lists */
104 #define QDCL(type)                              \
105     type * head;                                \
106     type * tail
107
108 #define QINIT(pq)                               \
109     do {                                        \
110     (pq)->head = (pq)->tail = NULL;             \
111     } while(0)
112
113 #define QPUT(pq, pe)                            \
114     do {                                        \
115     LPUSH(&(pq)->tail, (pe));                   \
116     if(!(pq)->head) (pq)->head = (pe);          \
117     } while(0)
118
119 #define QGET(pq, ppe)                                           \
120     do {                                                        \
121     *(ppe) = (pq)->head;                                        \
122     if(*(ppe)) {                                                \
123         (pq)->head = (*(ppe))->prev;                            \
124         if( (*(ppe))->prev ) (*(ppe))->prev->next = NULL;       \
125         (*(ppe))->prev = NULL;                                  \
126         if( (pq)->tail == *(ppe)) (pq)->tail = NULL;            \
127     }                                                           \
128     } while(0)
129
130 #define QDEL(pq, pe)                                    \
131     do {                                                \
132         if((pq)->head == (pe)) (pq)->head = LPREV(pe);  \
133         LDELETE(&((pq)->tail), (pe));                   \
134     } while(0)
135
136
137 #define QGETT(pq,ppe)                                           \
138     do {                                                        \
139     *(ppe) = (pq)->tail;                                        \
140     if(*(ppe)) {                                                \
141         (pq)->tail = (*(ppe))->next;                            \
142         if( (*(ppe))->next ) (*(ppe))->next->prev = NULL;       \
143         (*(ppe))->next = NULL;                                  \
144         if( (pq)->head == *(ppe)) (pq)->head = NULL;            \
145     }                                                           \
146     } while(0)
147
148 #define QTOP(pq) ((pq)->head)
149 #define QBOTTOM(pq) ((pq)->tail)
150 #define QNEXT(pe) ((pe)->prev)
151 #define QPREV(pe) ((pe)->next)
152
153 /* Trees with FIFO child lists */
154 #define TQDCL(type)                             \
155     LDCL(type);                                 \
156     QDCL(type);                                 \
157     type * parent
158
159 #define TQINIT(pe)                              \
160     do {                                        \
161     QINIT(pe);                                  \
162     (pe)->parent = NULL; } while(0)
163
164 #define TQADDCHILD(pt,pe)                       \
165     do {                                        \
166     QPUT((pt), (pe));                           \
167     (pe)->parent = (pt); } while(0)
168
169 #define TQFIRSTCHILD(pt) ((pt)?QTOP(pt):NULL)
170
171 #define TQPARENT(pe) ((pe)?(pe)->parent:NULL)
172
173 #endif