versadac  1
versadac - Scalable Recorder Firmware
ldap_queue.h
1 /* ldap_queue.h -- queue macros */
2 /* $OpenLDAP: pkg/ldap/include/ldap_queue.h,v 1.13.2.3 2008/02/11 23:26:40 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2001-2008 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.
106  *
107  * For details on the use of these macros, see the queue(3) manual page.
108  * All macros are prefixed with LDAP_.
109  *
110  * SLIST_ LIST_ STAILQ_ TAILQ_ CIRCLEQ_
111  * _HEAD + + + + +
112  * _ENTRY + + + + +
113  * _INIT + + + + +
114  * _ENTRY_INIT + + + + +
115  * _EMPTY + + + + +
116  * _FIRST + + + + +
117  * _NEXT + + + + +
118  * _PREV - - - + +
119  * _LAST - - + + +
120  * _FOREACH + + + + +
121  * _FOREACH_REVERSE - - - + +
122  * _INSERT_HEAD + + + + +
123  * _INSERT_BEFORE - + - + +
124  * _INSERT_AFTER + + + + +
125  * _INSERT_TAIL - - + + +
126  * _REMOVE_HEAD + - + - -
127  * _REMOVE + + + + +
128  *
129  */
130 
131 /*
132  * Singly-linked List definitions.
133  */
134 #define LDAP_SLIST_HEAD(name, type) \
135 struct name { \
136  struct type *slh_first; /* first element */ \
137 }
138 
139 #define LDAP_SLIST_HEAD_INITIALIZER(head) \
140  { NULL }
141 
142 #define LDAP_SLIST_ENTRY(type) \
143 struct { \
144  struct type *sle_next; /* next element */ \
145 }
146 
147 #define LDAP_SLIST_ENTRY_INITIALIZER(entry) \
148  { NULL }
149 
150 /*
151  * Singly-linked List functions.
152  */
153 #define LDAP_SLIST_EMPTY(head) ((head)->slh_first == NULL)
154 
155 #define LDAP_SLIST_FIRST(head) ((head)->slh_first)
156 
157 #define LDAP_SLIST_FOREACH(var, head, field) \
158  for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
159 
160 #define LDAP_SLIST_INIT(head) { \
161  (head)->slh_first = NULL; \
162 }
163 
164 #define LDAP_SLIST_ENTRY_INIT(var, field) { \
165  (var)->field.sle_next = NULL; \
166 }
167 
168 #define LDAP_SLIST_INSERT_AFTER(slistelm, elm, field) do { \
169  (elm)->field.sle_next = (slistelm)->field.sle_next; \
170  (slistelm)->field.sle_next = (elm); \
171 } while (0)
172 
173 #define LDAP_SLIST_INSERT_HEAD(head, elm, field) do { \
174  (elm)->field.sle_next = (head)->slh_first; \
175  (head)->slh_first = (elm); \
176 } while (0)
177 
178 #define LDAP_SLIST_NEXT(elm, field) ((elm)->field.sle_next)
179 
180 #define LDAP_SLIST_REMOVE_HEAD(head, field) do { \
181  (head)->slh_first = (head)->slh_first->field.sle_next; \
182 } while (0)
183 
184 #define LDAP_SLIST_REMOVE(head, elm, type, field) do { \
185  if ((head)->slh_first == (elm)) { \
186  LDAP_SLIST_REMOVE_HEAD((head), field); \
187  } \
188  else { \
189  struct type *curelm = (head)->slh_first; \
190  while( curelm->field.sle_next != (elm) ) \
191  curelm = curelm->field.sle_next; \
192  curelm->field.sle_next = \
193  curelm->field.sle_next->field.sle_next; \
194  } \
195 } while (0)
196 
197 /*
198  * Singly-linked Tail queue definitions.
199  */
200 #define LDAP_STAILQ_HEAD(name, type) \
201 struct name { \
202  struct type *stqh_first;/* first element */ \
203  struct type **stqh_last;/* addr of last next element */ \
204 }
205 
206 #define LDAP_STAILQ_HEAD_INITIALIZER(head) \
207  { NULL, &(head).stqh_first }
208 
209 #define LDAP_STAILQ_ENTRY(type) \
210 struct { \
211  struct type *stqe_next; /* next element */ \
212 }
213 
214 #define LDAP_STAILQ_ENTRY_INITIALIZER(entry) \
215  { NULL }
216 
217 /*
218  * Singly-linked Tail queue functions.
219  */
220 #define LDAP_STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
221 
222 #define LDAP_STAILQ_INIT(head) do { \
223  (head)->stqh_first = NULL; \
224  (head)->stqh_last = &(head)->stqh_first; \
225 } while (0)
226 
227 #define LDAP_STAILQ_ENTRY_INIT(var, field) { \
228  (entry)->field.stqe_next = NULL; \
229 }
230 
231 #define LDAP_STAILQ_FIRST(head) ((head)->stqh_first)
232 
233 #define LDAP_STAILQ_LAST(head, type, field) \
234  (LDAP_STAILQ_EMPTY(head) ? \
235  NULL : \
236  ((struct type *) \
237  ((char *)((head)->stqh_last) - offsetof(struct type, field))))
238 
239 #define LDAP_STAILQ_FOREACH(var, head, field) \
240  for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
241 
242 #define LDAP_STAILQ_INSERT_HEAD(head, elm, field) do { \
243  if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
244  (head)->stqh_last = &(elm)->field.stqe_next; \
245  (head)->stqh_first = (elm); \
246 } while (0)
247 
248 #define LDAP_STAILQ_INSERT_TAIL(head, elm, field) do { \
249  (elm)->field.stqe_next = NULL; \
250  *(head)->stqh_last = (elm); \
251  (head)->stqh_last = &(elm)->field.stqe_next; \
252 } while (0)
253 
254 #define LDAP_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
255  if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
256  (head)->stqh_last = &(elm)->field.stqe_next; \
257  (tqelm)->field.stqe_next = (elm); \
258 } while (0)
259 
260 #define LDAP_STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
261 
262 #define LDAP_STAILQ_REMOVE_HEAD(head, field) do { \
263  if (((head)->stqh_first = \
264  (head)->stqh_first->field.stqe_next) == NULL) \
265  (head)->stqh_last = &(head)->stqh_first; \
266 } while (0)
267 
268 #define LDAP_STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
269  if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
270  (head)->stqh_last = &(head)->stqh_first; \
271 } while (0)
272 
273 #define LDAP_STAILQ_REMOVE(head, elm, type, field) do { \
274  if ((head)->stqh_first == (elm)) { \
275  LDAP_STAILQ_REMOVE_HEAD(head, field); \
276  } \
277  else { \
278  struct type *curelm = (head)->stqh_first; \
279  while( curelm->field.stqe_next != (elm) ) \
280  curelm = curelm->field.stqe_next; \
281  if((curelm->field.stqe_next = \
282  curelm->field.stqe_next->field.stqe_next) == NULL) \
283  (head)->stqh_last = &(curelm)->field.stqe_next; \
284  } \
285 } while (0)
286 
287 /*
288  * List definitions.
289  */
290 #define LDAP_LIST_HEAD(name, type) \
291 struct name { \
292  struct type *lh_first; /* first element */ \
293 }
294 
295 #define LDAP_LIST_HEAD_INITIALIZER(head) \
296  { NULL }
297 
298 #define LDAP_LIST_ENTRY(type) \
299 struct { \
300  struct type *le_next; /* next element */ \
301  struct type **le_prev; /* address of previous next element */ \
302 }
303 
304 #define LDAP_LIST_ENTRY_INITIALIZER(entry) \
305  { NULL, NULL }
306 
307 /*
308  * List functions.
309  */
310 
311 #define LDAP_LIST_EMPTY(head) ((head)->lh_first == NULL)
312 
313 #define LDAP_LIST_FIRST(head) ((head)->lh_first)
314 
315 #define LDAP_LIST_FOREACH(var, head, field) \
316  for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
317 
318 #define LDAP_LIST_INIT(head) do { \
319  (head)->lh_first = NULL; \
320 } while (0)
321 
322 #define LDAP_LIST_ENTRY_INIT(var, field) do { \
323  (var)->field.le_next = NULL; \
324  (var)->field.le_prev = NULL; \
325 } while (0)
326 
327 #define LDAP_LIST_INSERT_AFTER(listelm, elm, field) do { \
328  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
329  (listelm)->field.le_next->field.le_prev = \
330  &(elm)->field.le_next; \
331  (listelm)->field.le_next = (elm); \
332  (elm)->field.le_prev = &(listelm)->field.le_next; \
333 } while (0)
334 
335 #define LDAP_LIST_INSERT_BEFORE(listelm, elm, field) do { \
336  (elm)->field.le_prev = (listelm)->field.le_prev; \
337  (elm)->field.le_next = (listelm); \
338  *(listelm)->field.le_prev = (elm); \
339  (listelm)->field.le_prev = &(elm)->field.le_next; \
340 } while (0)
341 
342 #define LDAP_LIST_INSERT_HEAD(head, elm, field) do { \
343  if (((elm)->field.le_next = (head)->lh_first) != NULL) \
344  (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
345  (head)->lh_first = (elm); \
346  (elm)->field.le_prev = &(head)->lh_first; \
347 } while (0)
348 
349 #define LDAP_LIST_NEXT(elm, field) ((elm)->field.le_next)
350 
351 #define LDAP_LIST_REMOVE(elm, field) do { \
352  if ((elm)->field.le_next != NULL) \
353  (elm)->field.le_next->field.le_prev = \
354  (elm)->field.le_prev; \
355  *(elm)->field.le_prev = (elm)->field.le_next; \
356 } while (0)
357 
358 /*
359  * Tail queue definitions.
360  */
361 #define LDAP_TAILQ_HEAD(name, type) \
362 struct name { \
363  struct type *tqh_first; /* first element */ \
364  struct type **tqh_last; /* addr of last next element */ \
365 }
366 
367 #define LDAP_TAILQ_HEAD_INITIALIZER(head) \
368  { NULL, &(head).tqh_first }
369 
370 #define LDAP_TAILQ_ENTRY(type) \
371 struct { \
372  struct type *tqe_next; /* next element */ \
373  struct type **tqe_prev; /* address of previous next element */ \
374 }
375 
376 #define LDAP_TAILQ_ENTRY_INITIALIZER(entry) \
377  { NULL, NULL }
378 
379 /*
380  * Tail queue functions.
381  */
382 #define LDAP_TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
383 
384 #define LDAP_TAILQ_FOREACH(var, head, field) \
385  for (var = LDAP_TAILQ_FIRST(head); var; var = LDAP_TAILQ_NEXT(var, field))
386 
387 #define LDAP_TAILQ_FOREACH_REVERSE(var, head, type, field) \
388  for ((var) = LDAP_TAILQ_LAST((head), type, field); \
389  (var); \
390  (var) = LDAP_TAILQ_PREV((var), head, type, field))
391 
392 #define LDAP_TAILQ_FIRST(head) ((head)->tqh_first)
393 
394 #define LDAP_TAILQ_LAST(head, type, field) \
395  (LDAP_TAILQ_EMPTY(head) ? \
396  NULL : \
397  ((struct type *) \
398  ((char *)((head)->tqh_last) - offsetof(struct type, field))))
399 
400 #define LDAP_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
401 
402 #define LDAP_TAILQ_PREV(elm, head, type, field) \
403  ((struct type *)((elm)->field.tqe_prev) == LDAP_TAILQ_FIRST(head) ? \
404  NULL : \
405  ((struct type *) \
406  ((char *)((elm)->field.tqe_prev) - offsetof(struct type, field))))
407 
408 #define LDAP_TAILQ_INIT(head) do { \
409  (head)->tqh_first = NULL; \
410  (head)->tqh_last = &(head)->tqh_first; \
411 } while (0)
412 
413 #define LDAP_TAILQ_ENTRY_INIT(var, field) do { \
414  (var)->field.tqe_next = NULL; \
415  (var)->field.tqe_prev = NULL; \
416 } while (0)
417 
418 #define LDAP_TAILQ_INSERT_HEAD(head, elm, field) do { \
419  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
420  (head)->tqh_first->field.tqe_prev = \
421  &(elm)->field.tqe_next; \
422  else \
423  (head)->tqh_last = &(elm)->field.tqe_next; \
424  (head)->tqh_first = (elm); \
425  (elm)->field.tqe_prev = &(head)->tqh_first; \
426 } while (0)
427 
428 #define LDAP_TAILQ_INSERT_TAIL(head, elm, field) do { \
429  (elm)->field.tqe_next = NULL; \
430  (elm)->field.tqe_prev = (head)->tqh_last; \
431  *(head)->tqh_last = (elm); \
432  (head)->tqh_last = &(elm)->field.tqe_next; \
433 } while (0)
434 
435 #define LDAP_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
436  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
437  (elm)->field.tqe_next->field.tqe_prev = \
438  &(elm)->field.tqe_next; \
439  else \
440  (head)->tqh_last = &(elm)->field.tqe_next; \
441  (listelm)->field.tqe_next = (elm); \
442  (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
443 } while (0)
444 
445 #define LDAP_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
446  (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
447  (elm)->field.tqe_next = (listelm); \
448  *(listelm)->field.tqe_prev = (elm); \
449  (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
450 } while (0)
451 
452 #define LDAP_TAILQ_REMOVE(head, elm, field) do { \
453  if (((elm)->field.tqe_next) != NULL) \
454  (elm)->field.tqe_next->field.tqe_prev = \
455  (elm)->field.tqe_prev; \
456  else \
457  (head)->tqh_last = (elm)->field.tqe_prev; \
458  *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
459 } while (0)
460 
461 /*
462  * Circular queue definitions.
463  */
464 #define LDAP_CIRCLEQ_HEAD(name, type) \
465 struct name { \
466  struct type *cqh_first; /* first element */ \
467  struct type *cqh_last; /* last element */ \
468 }
469 
470 #define LDAP_CIRCLEQ_ENTRY(type) \
471 struct { \
472  struct type *cqe_next; /* next element */ \
473  struct type *cqe_prev; /* previous element */ \
474 }
475 
476 /*
477  * Circular queue functions.
478  */
479 #define LDAP_CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
480 
481 #define LDAP_CIRCLEQ_FIRST(head) ((head)->cqh_first)
482 
483 #define LDAP_CIRCLEQ_FOREACH(var, head, field) \
484  for((var) = (head)->cqh_first; \
485  (var) != (void *)(head); \
486  (var) = (var)->field.cqe_next)
487 
488 #define LDAP_CIRCLEQ_FOREACH_REVERSE(var, head, field) \
489  for((var) = (head)->cqh_last; \
490  (var) != (void *)(head); \
491  (var) = (var)->field.cqe_prev)
492 
493 #define LDAP_CIRCLEQ_INIT(head) do { \
494  (head)->cqh_first = (void *)(head); \
495  (head)->cqh_last = (void *)(head); \
496 } while (0)
497 
498 #define LDAP_CIRCLEQ_ENTRY_INIT(var, field) do { \
499  (var)->field.cqe_next = NULL; \
500  (var)->field.cqe_prev = NULL; \
501 } while (0)
502 
503 #define LDAP_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
504  (elm)->field.cqe_next = (listelm)->field.cqe_next; \
505  (elm)->field.cqe_prev = (listelm); \
506  if ((listelm)->field.cqe_next == (void *)(head)) \
507  (head)->cqh_last = (elm); \
508  else \
509  (listelm)->field.cqe_next->field.cqe_prev = (elm); \
510  (listelm)->field.cqe_next = (elm); \
511 } while (0)
512 
513 #define LDAP_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
514  (elm)->field.cqe_next = (listelm); \
515  (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
516  if ((listelm)->field.cqe_prev == (void *)(head)) \
517  (head)->cqh_first = (elm); \
518  else \
519  (listelm)->field.cqe_prev->field.cqe_next = (elm); \
520  (listelm)->field.cqe_prev = (elm); \
521 } while (0)
522 
523 #define LDAP_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
524  (elm)->field.cqe_next = (head)->cqh_first; \
525  (elm)->field.cqe_prev = (void *)(head); \
526  if ((head)->cqh_last == (void *)(head)) \
527  (head)->cqh_last = (elm); \
528  else \
529  (head)->cqh_first->field.cqe_prev = (elm); \
530  (head)->cqh_first = (elm); \
531 } while (0)
532 
533 #define LDAP_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
534  (elm)->field.cqe_next = (void *)(head); \
535  (elm)->field.cqe_prev = (head)->cqh_last; \
536  if ((head)->cqh_first == (void *)(head)) \
537  (head)->cqh_first = (elm); \
538  else \
539  (head)->cqh_last->field.cqe_next = (elm); \
540  (head)->cqh_last = (elm); \
541 } while (0)
542 
543 #define LDAP_CIRCLEQ_LAST(head) ((head)->cqh_last)
544 
545 #define LDAP_CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
546 
547 #define LDAP_CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
548 
549 #define LDAP_CIRCLEQ_REMOVE(head, elm, field) do { \
550  if ((elm)->field.cqe_next == (void *)(head)) \
551  (head)->cqh_last = (elm)->field.cqe_prev; \
552  else \
553  (elm)->field.cqe_next->field.cqe_prev = \
554  (elm)->field.cqe_prev; \
555  if ((elm)->field.cqe_prev == (void *)(head)) \
556  (head)->cqh_first = (elm)->field.cqe_next; \
557  else \
558  (elm)->field.cqe_prev->field.cqe_next = \
559  (elm)->field.cqe_next; \
560 } while (0)
561 
562 #endif /* !_LDAP_QUEUE_H_ */