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