Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/ldap/include/ldap_queue.h
4394 views
1
/* ldap_queue.h -- queue macros */
2
/* $OpenLDAP$ */
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
*
5
* Copyright 2001-2024 The OpenLDAP Foundation.
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted only as authorized by the OpenLDAP
10
* Public License.
11
*
12
* A copy of this license is available in file LICENSE in the
13
* top-level directory of the distribution or, alternatively, at
14
* <http://www.OpenLDAP.org/license.html>.
15
*/
16
/* Copyright (c) 1991, 1993
17
* The Regents of the University of California. All rights reserved.
18
*
19
* Redistribution and use in source and binary forms, with or without
20
* modification, are permitted provided that the following conditions
21
* are met:
22
* 1. Redistributions of source code must retain the above copyright
23
* notice, this list of conditions and the following disclaimer.
24
* 2. Redistributions in binary form must reproduce the above copyright
25
* notice, this list of conditions and the following disclaimer in the
26
* documentation and/or other materials provided with the distribution.
27
* 3. All advertising materials mentioning features or use of this software
28
* must display the following acknowledgement:
29
* This product includes software developed by the University of
30
* California, Berkeley and its contributors.
31
* 4. Neither the name of the University nor the names of its contributors
32
* may be used to endorse or promote products derived from this software
33
* without specific prior written permission.
34
*
35
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45
* SUCH DAMAGE.
46
*
47
* @(#)queue.h 8.5 (Berkeley) 8/20/94
48
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.5 2001/09/30 21:12:54 luigi Exp $
49
*
50
* See also: ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
51
*/
52
/* ACKNOWLEDGEMENTS:
53
* This work is derived from FreeBSD queue.h work. Adapted for use in
54
* OpenLDAP Software by Kurt D. Zeilenga.
55
*/
56
57
#ifndef _LDAP_QUEUE_H_
58
#define _LDAP_QUEUE_H_
59
60
/*
61
* This file defines five types of data structures: singly-linked lists,
62
* singly-linked tail queues, lists, tail queues, and circular queues.
63
*
64
* A singly-linked list is headed by a single forward pointer. The elements
65
* are singly linked for minimum space and pointer manipulation overhead at
66
* the expense of O(n) removal for arbitrary elements. New elements can be
67
* added to the list after an existing element or at the head of the list.
68
* Elements being removed from the head of the list should use the explicit
69
* macro for this purpose for optimum efficiency. A singly-linked list may
70
* only be traversed in the forward direction. Singly-linked lists are ideal
71
* for applications with large datasets and few or no removals or for
72
* implementing a LIFO queue.
73
*
74
* A singly-linked tail queue is headed by a pair of pointers, one to the
75
* head of the list and the other to the tail of the list. The elements are
76
* singly linked for minimum space and pointer manipulation overhead at the
77
* expense of O(n) removal for arbitrary elements. New elements can be added
78
* to the list after an existing element, at the head of the list, or at the
79
* end of the list. Elements being removed from the head of the tail queue
80
* should use the explicit macro for this purpose for optimum efficiency.
81
* A singly-linked tail queue may only be traversed in the forward direction.
82
* Singly-linked tail queues are ideal for applications with large datasets
83
* and few or no removals or for implementing a FIFO queue.
84
*
85
* A list is headed by a single forward pointer (or an array of forward
86
* pointers for a hash table header). The elements are doubly linked
87
* so that an arbitrary element can be removed without a need to
88
* traverse the list. New elements can be added to the list before
89
* or after an existing element or at the head of the list. A list
90
* may only be traversed in the forward direction.
91
*
92
* A tail queue is headed by a pair of pointers, one to the head of the
93
* list and the other to the tail of the list. The elements are doubly
94
* linked so that an arbitrary element can be removed without a need to
95
* traverse the list. New elements can be added to the list before or
96
* after an existing element, at the head of the list, or at the end of
97
* the list. A tail queue may be traversed in either direction.
98
*
99
* A circle queue is headed by a pair of pointers, one to the head of the
100
* list and the other to the tail of the list. The elements are doubly
101
* linked so that an arbitrary element can be removed without a need to
102
* traverse the list. New elements can be added to the list before or after
103
* an existing element, at the head of the list, or at the end of the list.
104
* A circle queue may be traversed in either direction, but has a more
105
* complex end of list detection. Also, it is possible to rotate the queue,
106
* rejoining the ends and splitting it so that a given element becomes the
107
* new head or tail.
108
*
109
* For details on the use of these macros, see the queue(3) manual page.
110
* All macros are prefixed with LDAP_.
111
*
112
* SLIST_ LIST_ STAILQ_ TAILQ_ CIRCLEQ_
113
* _HEAD + + + + +
114
* _ENTRY + + + + +
115
* _INIT + + + + +
116
* _ENTRY_INIT + + + + +
117
* _EMPTY + + + + +
118
* _FIRST + + + + +
119
* _NEXT + + + + +
120
* _PREV - - - + +
121
* _LAST - - + + +
122
* _FOREACH + + + + +
123
* _FOREACH_REVERSE - - - + +
124
* _INSERT_HEAD + + + + +
125
* _INSERT_BEFORE - + - + +
126
* _INSERT_AFTER + + + + +
127
* _INSERT_TAIL - - + + +
128
* _REMOVE_HEAD + - + - -
129
* _REMOVE + + + + +
130
*
131
*/
132
133
/*
134
* Singly-linked List definitions.
135
*/
136
#define LDAP_SLIST_HEAD(name, type) \
137
struct name { \
138
struct type *slh_first; /* first element */ \
139
}
140
141
#define LDAP_SLIST_HEAD_INITIALIZER(head) \
142
{ NULL }
143
144
#define LDAP_SLIST_ENTRY(type) \
145
struct { \
146
struct type *sle_next; /* next element */ \
147
}
148
149
#define LDAP_SLIST_ENTRY_INITIALIZER(entry) \
150
{ NULL }
151
152
/*
153
* Singly-linked List functions.
154
*/
155
#define LDAP_SLIST_EMPTY(head) ((head)->slh_first == NULL)
156
157
#define LDAP_SLIST_FIRST(head) ((head)->slh_first)
158
159
#define LDAP_SLIST_FOREACH(var, head, field) \
160
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
161
162
#define LDAP_SLIST_INIT(head) { \
163
(head)->slh_first = NULL; \
164
}
165
166
#define LDAP_SLIST_ENTRY_INIT(var, field) { \
167
(var)->field.sle_next = NULL; \
168
}
169
170
#define LDAP_SLIST_INSERT_AFTER(slistelm, elm, field) do { \
171
(elm)->field.sle_next = (slistelm)->field.sle_next; \
172
(slistelm)->field.sle_next = (elm); \
173
} while (0)
174
175
#define LDAP_SLIST_INSERT_HEAD(head, elm, field) do { \
176
(elm)->field.sle_next = (head)->slh_first; \
177
(head)->slh_first = (elm); \
178
} while (0)
179
180
#define LDAP_SLIST_NEXT(elm, field) ((elm)->field.sle_next)
181
182
#define LDAP_SLIST_REMOVE_HEAD(head, field) do { \
183
(head)->slh_first = (head)->slh_first->field.sle_next; \
184
} while (0)
185
186
#define LDAP_SLIST_REMOVE(head, elm, type, field) do { \
187
if ((head)->slh_first == (elm)) { \
188
LDAP_SLIST_REMOVE_HEAD((head), field); \
189
} \
190
else { \
191
struct type *curelm = (head)->slh_first; \
192
while( curelm->field.sle_next != (elm) ) \
193
curelm = curelm->field.sle_next; \
194
curelm->field.sle_next = \
195
curelm->field.sle_next->field.sle_next; \
196
} \
197
} while (0)
198
199
/*
200
* Singly-linked Tail queue definitions.
201
*/
202
#define LDAP_STAILQ_HEAD(name, type) \
203
struct name { \
204
struct type *stqh_first;/* first element */ \
205
struct type **stqh_last;/* addr of last next element */ \
206
}
207
208
#define LDAP_STAILQ_HEAD_INITIALIZER(head) \
209
{ NULL, &(head).stqh_first }
210
211
#define LDAP_STAILQ_ENTRY(type) \
212
struct { \
213
struct type *stqe_next; /* next element */ \
214
}
215
216
#define LDAP_STAILQ_ENTRY_INITIALIZER(entry) \
217
{ NULL }
218
219
/*
220
* Singly-linked Tail queue functions.
221
*/
222
#define LDAP_STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
223
224
#define LDAP_STAILQ_INIT(head) do { \
225
(head)->stqh_first = NULL; \
226
(head)->stqh_last = &(head)->stqh_first; \
227
} while (0)
228
229
#define LDAP_STAILQ_ENTRY_INIT(var, field) { \
230
(var)->field.stqe_next = NULL; \
231
}
232
233
#define LDAP_STAILQ_FIRST(head) ((head)->stqh_first)
234
235
#define LDAP_STAILQ_LAST(head, type, field) \
236
(LDAP_STAILQ_EMPTY(head) ? \
237
NULL : \
238
((struct type *) \
239
((char *)((head)->stqh_last) - offsetof(struct type, field))))
240
241
#define LDAP_STAILQ_FOREACH(var, head, field) \
242
for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
243
244
#define LDAP_STAILQ_INSERT_HEAD(head, elm, field) do { \
245
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
246
(head)->stqh_last = &(elm)->field.stqe_next; \
247
(head)->stqh_first = (elm); \
248
} while (0)
249
250
#define LDAP_STAILQ_INSERT_TAIL(head, elm, field) do { \
251
(elm)->field.stqe_next = NULL; \
252
*(head)->stqh_last = (elm); \
253
(head)->stqh_last = &(elm)->field.stqe_next; \
254
} while (0)
255
256
#define LDAP_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
257
if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
258
(head)->stqh_last = &(elm)->field.stqe_next; \
259
(tqelm)->field.stqe_next = (elm); \
260
} while (0)
261
262
#define LDAP_STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
263
264
#define LDAP_STAILQ_REMOVE_HEAD(head, field) do { \
265
if (((head)->stqh_first = \
266
(head)->stqh_first->field.stqe_next) == NULL) \
267
(head)->stqh_last = &(head)->stqh_first; \
268
} while (0)
269
270
#define LDAP_STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
271
if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
272
(head)->stqh_last = &(head)->stqh_first; \
273
} while (0)
274
275
#define LDAP_STAILQ_REMOVE(head, elm, type, field) do { \
276
if ((head)->stqh_first == (elm)) { \
277
LDAP_STAILQ_REMOVE_HEAD(head, field); \
278
} \
279
else { \
280
struct type *curelm = (head)->stqh_first; \
281
while( curelm->field.stqe_next != (elm) ) \
282
curelm = curelm->field.stqe_next; \
283
if((curelm->field.stqe_next = \
284
curelm->field.stqe_next->field.stqe_next) == NULL) \
285
(head)->stqh_last = &(curelm)->field.stqe_next; \
286
} \
287
} while (0)
288
289
/*
290
* List definitions.
291
*/
292
#define LDAP_LIST_HEAD(name, type) \
293
struct name { \
294
struct type *lh_first; /* first element */ \
295
}
296
297
#define LDAP_LIST_HEAD_INITIALIZER(head) \
298
{ NULL }
299
300
#define LDAP_LIST_ENTRY(type) \
301
struct { \
302
struct type *le_next; /* next element */ \
303
struct type **le_prev; /* address of previous next element */ \
304
}
305
306
#define LDAP_LIST_ENTRY_INITIALIZER(entry) \
307
{ NULL, NULL }
308
309
/*
310
* List functions.
311
*/
312
313
#define LDAP_LIST_EMPTY(head) ((head)->lh_first == NULL)
314
315
#define LDAP_LIST_FIRST(head) ((head)->lh_first)
316
317
#define LDAP_LIST_FOREACH(var, head, field) \
318
for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
319
320
#define LDAP_LIST_INIT(head) do { \
321
(head)->lh_first = NULL; \
322
} while (0)
323
324
#define LDAP_LIST_ENTRY_INIT(var, field) do { \
325
(var)->field.le_next = NULL; \
326
(var)->field.le_prev = NULL; \
327
} while (0)
328
329
#define LDAP_LIST_INSERT_AFTER(listelm, elm, field) do { \
330
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
331
(listelm)->field.le_next->field.le_prev = \
332
&(elm)->field.le_next; \
333
(listelm)->field.le_next = (elm); \
334
(elm)->field.le_prev = &(listelm)->field.le_next; \
335
} while (0)
336
337
#define LDAP_LIST_INSERT_BEFORE(listelm, elm, field) do { \
338
(elm)->field.le_prev = (listelm)->field.le_prev; \
339
(elm)->field.le_next = (listelm); \
340
*(listelm)->field.le_prev = (elm); \
341
(listelm)->field.le_prev = &(elm)->field.le_next; \
342
} while (0)
343
344
#define LDAP_LIST_INSERT_HEAD(head, elm, field) do { \
345
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
346
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
347
(head)->lh_first = (elm); \
348
(elm)->field.le_prev = &(head)->lh_first; \
349
} while (0)
350
351
#define LDAP_LIST_NEXT(elm, field) ((elm)->field.le_next)
352
353
#define LDAP_LIST_REMOVE(elm, field) do { \
354
if ((elm)->field.le_next != NULL) \
355
(elm)->field.le_next->field.le_prev = \
356
(elm)->field.le_prev; \
357
*(elm)->field.le_prev = (elm)->field.le_next; \
358
} while (0)
359
360
/*
361
* Tail queue definitions.
362
*/
363
#define LDAP_TAILQ_HEAD(name, type) \
364
struct name { \
365
struct type *tqh_first; /* first element */ \
366
struct type **tqh_last; /* addr of last next element */ \
367
}
368
369
#define LDAP_TAILQ_HEAD_INITIALIZER(head) \
370
{ NULL, &(head).tqh_first }
371
372
#define LDAP_TAILQ_ENTRY(type) \
373
struct { \
374
struct type *tqe_next; /* next element */ \
375
struct type **tqe_prev; /* address of previous next element */ \
376
}
377
378
#define LDAP_TAILQ_ENTRY_INITIALIZER(entry) \
379
{ NULL, NULL }
380
381
/*
382
* Tail queue functions.
383
*/
384
#define LDAP_TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
385
386
#define LDAP_TAILQ_FOREACH(var, head, field) \
387
for (var = LDAP_TAILQ_FIRST(head); var; var = LDAP_TAILQ_NEXT(var, field))
388
389
#define LDAP_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
390
for ((var) = LDAP_TAILQ_LAST((head), headname); \
391
(var); \
392
(var) = LDAP_TAILQ_PREV((var), headname, field))
393
394
#define LDAP_TAILQ_FIRST(head) ((head)->tqh_first)
395
396
#define LDAP_TAILQ_LAST(head, headname) \
397
(*(((struct headname *)((head)->tqh_last))->tqh_last))
398
399
#define LDAP_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
400
401
#define LDAP_TAILQ_PREV(elm, headname, field) \
402
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
403
404
#define LDAP_TAILQ_INIT(head) do { \
405
(head)->tqh_first = NULL; \
406
(head)->tqh_last = &(head)->tqh_first; \
407
} while (0)
408
409
#define LDAP_TAILQ_ENTRY_INIT(var, field) do { \
410
(var)->field.tqe_next = NULL; \
411
(var)->field.tqe_prev = NULL; \
412
} while (0)
413
414
#define LDAP_TAILQ_INSERT_HEAD(head, elm, field) do { \
415
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
416
(head)->tqh_first->field.tqe_prev = \
417
&(elm)->field.tqe_next; \
418
else \
419
(head)->tqh_last = &(elm)->field.tqe_next; \
420
(head)->tqh_first = (elm); \
421
(elm)->field.tqe_prev = &(head)->tqh_first; \
422
} while (0)
423
424
#define LDAP_TAILQ_INSERT_TAIL(head, elm, field) do { \
425
(elm)->field.tqe_next = NULL; \
426
(elm)->field.tqe_prev = (head)->tqh_last; \
427
*(head)->tqh_last = (elm); \
428
(head)->tqh_last = &(elm)->field.tqe_next; \
429
} while (0)
430
431
#define LDAP_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
432
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
433
(elm)->field.tqe_next->field.tqe_prev = \
434
&(elm)->field.tqe_next; \
435
else \
436
(head)->tqh_last = &(elm)->field.tqe_next; \
437
(listelm)->field.tqe_next = (elm); \
438
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
439
} while (0)
440
441
#define LDAP_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
442
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
443
(elm)->field.tqe_next = (listelm); \
444
*(listelm)->field.tqe_prev = (elm); \
445
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
446
} while (0)
447
448
#define LDAP_TAILQ_REMOVE(head, elm, field) do { \
449
if (((elm)->field.tqe_next) != NULL) \
450
(elm)->field.tqe_next->field.tqe_prev = \
451
(elm)->field.tqe_prev; \
452
else \
453
(head)->tqh_last = (elm)->field.tqe_prev; \
454
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
455
} while (0)
456
457
/*
458
* Circular queue definitions.
459
*/
460
#define LDAP_CIRCLEQ_HEAD(name, type) \
461
struct name { \
462
struct type *cqh_first; /* first element */ \
463
struct type *cqh_last; /* last element */ \
464
}
465
466
#define LDAP_CIRCLEQ_HEAD_INITIALIZER(head) \
467
{ (void *)&(head), (void *)&(head) }
468
469
#define LDAP_CIRCLEQ_ENTRY(type) \
470
struct { \
471
struct type *cqe_next; /* next element */ \
472
struct type *cqe_prev; /* previous element */ \
473
}
474
475
/*
476
* Circular queue functions.
477
*/
478
#define LDAP_CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
479
480
#define LDAP_CIRCLEQ_FIRST(head) ((head)->cqh_first)
481
482
#define LDAP_CIRCLEQ_FOREACH(var, head, field) \
483
for((var) = (head)->cqh_first; \
484
(var) != (void *)(head); \
485
(var) = (var)->field.cqe_next)
486
487
#define LDAP_CIRCLEQ_FOREACH_REVERSE(var, head, field) \
488
for((var) = (head)->cqh_last; \
489
(var) != (void *)(head); \
490
(var) = (var)->field.cqe_prev)
491
492
#define LDAP_CIRCLEQ_INIT(head) do { \
493
(head)->cqh_first = (void *)(head); \
494
(head)->cqh_last = (void *)(head); \
495
} while (0)
496
497
#define LDAP_CIRCLEQ_ENTRY_INIT(var, field) do { \
498
(var)->field.cqe_next = NULL; \
499
(var)->field.cqe_prev = NULL; \
500
} while (0)
501
502
#define LDAP_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
503
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
504
(elm)->field.cqe_prev = (listelm); \
505
if ((listelm)->field.cqe_next == (void *)(head)) \
506
(head)->cqh_last = (elm); \
507
else \
508
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
509
(listelm)->field.cqe_next = (elm); \
510
} while (0)
511
512
#define LDAP_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
513
(elm)->field.cqe_next = (listelm); \
514
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
515
if ((listelm)->field.cqe_prev == (void *)(head)) \
516
(head)->cqh_first = (elm); \
517
else \
518
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
519
(listelm)->field.cqe_prev = (elm); \
520
} while (0)
521
522
#define LDAP_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
523
(elm)->field.cqe_next = (head)->cqh_first; \
524
(elm)->field.cqe_prev = (void *)(head); \
525
if ((head)->cqh_last == (void *)(head)) \
526
(head)->cqh_last = (elm); \
527
else \
528
(head)->cqh_first->field.cqe_prev = (elm); \
529
(head)->cqh_first = (elm); \
530
} while (0)
531
532
#define LDAP_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
533
(elm)->field.cqe_next = (void *)(head); \
534
(elm)->field.cqe_prev = (head)->cqh_last; \
535
if ((head)->cqh_first == (void *)(head)) \
536
(head)->cqh_first = (elm); \
537
else \
538
(head)->cqh_last->field.cqe_next = (elm); \
539
(head)->cqh_last = (elm); \
540
} while (0)
541
542
#define LDAP_CIRCLEQ_LAST(head) ((head)->cqh_last)
543
544
#define LDAP_CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
545
546
#define LDAP_CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
547
548
#define LDAP_CIRCLEQ_REMOVE(head, elm, field) do { \
549
if ((elm)->field.cqe_next == (void *)(head)) \
550
(head)->cqh_last = (elm)->field.cqe_prev; \
551
else \
552
(elm)->field.cqe_next->field.cqe_prev = \
553
(elm)->field.cqe_prev; \
554
if ((elm)->field.cqe_prev == (void *)(head)) \
555
(head)->cqh_first = (elm)->field.cqe_next; \
556
else \
557
(elm)->field.cqe_prev->field.cqe_next = \
558
(elm)->field.cqe_next; \
559
} while (0)
560
561
#define LDAP_CIRCLEQ_LOOP_NEXT(head, elm, field) \
562
(((elm)->field.cqe_next == (void *)(head)) \
563
? ((head)->cqh_first) \
564
: ((elm)->field.cqe_next))
565
566
#define LDAP_CIRCLEQ_LOOP_PREV(head, elm, field) \
567
(((elm)->field.cqe_prev == (void *)(head)) \
568
? ((head)->cqh_last) \
569
: ((elm)->field.cqe_prev))
570
571
#define LDAP_CIRCLEQ_MAKE_HEAD(head, elm, field) do { \
572
if ((elm)->field.cqe_prev != (void *)(head)) { \
573
(head)->cqh_first->field.cqe_prev = (head)->cqh_last; \
574
(head)->cqh_last->field.cqe_next = (head)->cqh_first; \
575
(head)->cqh_first = elm; \
576
(head)->cqh_last = (elm)->field.cqe_prev; \
577
(elm)->field.cqe_prev->field.cqe_next = (void *)(head); \
578
(elm)->field.cqe_prev = (void *)(head); \
579
} \
580
} while (0)
581
582
#define LDAP_CIRCLEQ_MAKE_TAIL(head, elm, field) do { \
583
if ((elm)->field.cqe_next != (void *)(head)) { \
584
(head)->cqh_first->field.cqe_prev = (head)->cqh_last; \
585
(head)->cqh_last->field.cqe_next = (head)->cqh_first; \
586
(head)->cqh_first = (elm)->field.cqe_next; \
587
(head)->cqh_last = elm; \
588
(elm)->field.cqe_next->field.cqe_prev = (void *)(head); \
589
(elm)->field.cqe_next = (void *)(head); \
590
} \
591
} while (0)
592
593
#endif /* !_LDAP_QUEUE_H_ */
594
595