death to trailing whitespace
[openafs.git] / src / bucoord / dlq.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/stds.h>
12 #ifdef HAVE_STDLIB_H
13 #include <stdlib.h>
14 #endif
15
16 #include "bc.h"
17 #include <afs/bubasics.h>
18 #include "bucoord_prototypes.h"
19
20 /* protos */
21 int dlqCount(dlqlinkP );
22 void dlqMoveb( dlqlinkP, dlqlinkP);
23 dlqlinkP dlqUnlinkb(dlqlinkP );
24 dlqlinkP dlqUnlinkf(dlqlinkP );
25 dlqlinkP dlqFront(dlqlinkP headptr);
26
27 #define DLQ_ASSERT_HEAD(headptr)                                \
28         if ( (headptr)->dlq_type != DLQ_HEAD )                  \
29         {                                                       \
30             printf("file %s line %d, invalid queue head\n",     \
31                    __FILE__, __LINE__);                         \
32             exit(1);                                            \
33         }
34
35
36 /* dlqEmpty
37  * exit:
38  *      1 - queue is empty
39  *      0 - items on queue
40  */
41
42 int dlqEmpty(dlqlinkP headptr )
43 {
44     DLQ_ASSERT_HEAD(headptr);
45     if (headptr->dlq_next == headptr)
46         return (1);
47     return (0);
48 }
49
50 int dlqInit(dlqlinkP headptr)
51 {
52     headptr->dlq_next = headptr;
53     headptr->dlq_prev = headptr;
54     headptr->dlq_type = DLQ_HEAD;
55     headptr->dlq_structPtr = NULL;
56     return (0);
57 }
58
59 /* dlqLinkf
60  *      link item to front of chain
61  */
62 int dlqLinkf(dlqlinkP headptr, dlqlinkP entryptr)
63 {
64     DLQ_ASSERT_HEAD(headptr);
65     /* link in as first item in chain */
66     entryptr->dlq_next = headptr->dlq_next;
67     headptr->dlq_next->dlq_prev = entryptr;
68     entryptr->dlq_prev = headptr;
69     headptr->dlq_next = entryptr;
70     return (0);
71 }
72
73 /* dlqLinkb
74  *      link item to end of chain
75  */
76
77 int dlqLinkb(dlqlinkP headptr, dlqlinkP entryptr)
78 {
79     DLQ_ASSERT_HEAD(headptr);
80     entryptr->dlq_next = headptr;
81     entryptr->dlq_prev = headptr->dlq_prev;
82
83     headptr->dlq_prev = entryptr;
84     entryptr->dlq_prev->dlq_next = entryptr;
85     return (0);
86 }
87
88 /* dlqMoveb
89  *      move all the items on the fromptr and append to the toptr's list
90  */
91
92 void dlqMoveb( dlqlinkP fromptr, dlqlinkP toptr)
93 {
94     dlqlinkP tailptr;
95
96     DLQ_ASSERT_HEAD(fromptr);
97     DLQ_ASSERT_HEAD(toptr);
98
99     if (dlqEmpty(fromptr))
100         return;
101
102     tailptr = toptr->dlq_prev;
103
104     tailptr->dlq_next = fromptr->dlq_next;
105     tailptr->dlq_next->dlq_prev = tailptr;
106
107     /* now fix up the last item in the new chain */
108     tailptr = fromptr->dlq_prev;
109
110     tailptr->dlq_next = toptr;
111     toptr->dlq_prev = tailptr;
112
113     fromptr->dlq_next = fromptr;
114     fromptr->dlq_prev = fromptr;
115     return;
116 }
117
118 /* dlqUnlinkb
119  *      unlink the last item on the queue
120  */
121
122 dlqlinkP dlqUnlinkb(dlqlinkP headptr)
123 {
124     dlqlinkP ptr;
125     DLQ_ASSERT_HEAD(headptr);
126
127     if (dlqEmpty(headptr))
128         return (0);
129
130     ptr = headptr->dlq_prev;
131     ptr->dlq_prev->dlq_next = headptr;
132     headptr->dlq_prev = ptr->dlq_prev;
133
134     ptr->dlq_next = ptr;
135     ptr->dlq_prev = ptr;
136     return (ptr);
137 }
138
139 /* dlqUnlinkf
140  *      unlink the item on the front of the queue
141  */
142
143 dlqlinkP dlqUnlinkf(dlqlinkP headptr)
144 {
145     dlqlinkP ptr;
146     DLQ_ASSERT_HEAD(headptr);
147
148     if (dlqEmpty(headptr))
149         return (0);
150
151     ptr = headptr->dlq_next;
152
153     headptr->dlq_next = ptr->dlq_next;
154     ptr->dlq_next->dlq_prev = headptr;
155
156     ptr->dlq_next = ptr;
157     ptr->dlq_prev = ptr;
158     return (ptr);
159 }
160
161 /* dlqUnlink
162  *      unlink the specified item from the queue.
163  */
164
165 void dlqUnlink( dlqlinkP ptr)
166 {
167     /* must not be the queue head */
168     if (ptr->dlq_type == DLQ_HEAD) {
169         printf("dlqUnlink: invalid unlink\n");
170         exit(1);
171     }
172
173     ptr->dlq_prev->dlq_next = ptr->dlq_next;
174     ptr->dlq_next->dlq_prev = ptr->dlq_prev;
175
176     ptr->dlq_next = 0;
177     ptr->dlq_prev = 0;
178 }
179
180 /* dlqFront
181  *      return point to item at front of queuen
182  */
183
184 dlqlinkP dlqFront(dlqlinkP headptr)
185 {
186     DLQ_ASSERT_HEAD(headptr);
187
188     if (dlqEmpty(headptr))
189         return (0);
190
191     return (headptr->dlq_next);
192 }
193
194 int dlqCount(dlqlinkP headptr)
195 {
196     dlqlinkP ptr;
197     int count = 0;
198
199     DLQ_ASSERT_HEAD(headptr);
200
201     ptr = headptr->dlq_next;
202     while (ptr != headptr) {
203         ptr = ptr->dlq_next;
204         count++;
205     }
206     return (count);
207 }
208
209 int dlqTraverseQueue(dlqlinkP headptr, int (*fn1)(void *), int (*fn2)(void *))
210 {
211     dlqlinkP ptr, oldPtr;
212
213     DLQ_ASSERT_HEAD(headptr);
214
215     ptr = headptr->dlq_next;
216     while (ptr != headptr) {
217         if (fn2 && ptr->dlq_structPtr)
218             (*fn2) (ptr->dlq_structPtr);
219         oldPtr = ptr;
220         ptr = ptr->dlq_next;
221         if (fn1)
222             (*fn1) (oldPtr);
223     }
224     return (0);
225 }