head	1.4;
access;
symbols
	milter-greylist-4-5-13:1.4
	milter-greylist-4-5-12:1.4
	milter-greylist-4-5-11:1.4
	milter-greylist-4-5-10:1.4
	milter-greylist-4-9-10:1.4
	milter-greylist-4-5-8:1.4
	milter-greylist-4-5-9:1.4
	milter-greylist-4-5-7:1.4
	milter-greylist-4-5-6:1.4
	milter-greylist-4-5:1.4
	milter-greylist-4-5-5:1.4
	milter-greylist-4-5-4:1.4
	milter-greylist-4-5-3:1.4
	milter-greylist-4-5-2:1.4
	milter-greylist-4-5-1:1.4
	milter-greylist-4-4-3:1.4
	milter-greylist-4-4-2:1.3
	milter-greylist-4-4-1:1.3
	milter-greylist-4-4:1.3
	milter-greylist-4-4-rc1:1.3
	milter-greylist-4-4-alpha4:1.3
	milter-greylist-4-4-alpha3:1.3
	milter-greylist-4-4-alpha2:1.3
	milter-greylist-4-4-alpha1:1.3
	milter-greylist-4-2-7:1.3
	milter-greylist-4-3-9:1.3
	milter-greylist-4-2-6:1.3
	milter-gresylit-4-2-6:1.3
	milter-greylist-4-3-8:1.3
	milter-greylist-4-3-7:1.3
	milter-greylist-4-2-5:1.3
	milter-greylist-4-3-6:1.3
	milter-greylist-4-2-4:1.3
	milter-greylist-4-3-5:1.3
	milter-greylist-4-3-4:1.3
	milter-greylist-4-2-3:1.3
	milter-greylist-4-3-3:1.3
	rmilter-greylist-4-2-3:1.3
	milter-greylist-4-3-2:1.3
	milter-greylist-4-3-1:1.3
	milter-greylist-2-2-2:1.3
	milter-greylist-4-2-2:1.3
	milter-greylist-4-2-1:1.3
	milter-greylist-4-2:1.3
	milter-greylist-4-2-rc1:1.3
	milter-greylist-4-2-beta1:1.3
	milter-greylist-4-2-branch:1.3.0.2
	milter-greylist-4-2-base:1.3
	milter-greylist-4-2-0-base:1.3
	milter-greylist-4-1-12:1.3
	milter-greylist-4-1-11:1.1
	milter-greylist-4-1-10:1.1
	milter-greylist-4-1-9:1.1
	milter-greylist-4-1-8:1.1
	milter-greylist-4-1-7:1.1
	milter-greylist-4-1-6:1.1
	milter-greylist-4-0-1:1.1
	milter-greylist-4-0-1-rc1:1.1
	milter-greylist-4-1-5:1.1
	milter-greylist-4-1-4:1.1
	milter-greylist-4-1-3:1.1
	milter-greylist-4-1-2:1.1
	milter-greylist-4-1-1:1.1
	milter-greylist-4-0-branch:1.1.0.16
	milter-greylist-4-0-base:1.1
	milter-greylist-4-0:1.1
	milter-greylist-4-0-rc2:1.1
	milter-greylist-4-0-rc1:1.1
	milter-greylist-4-0-beta4:1.1
	milter-greylist-4-0-beta3:1.1
	milter-greylist-4-0-beta2:1.1
	milter-greylist-4-0-beta1:1.1
	milter-greylist-4-0-alpha6:1.1
	milter-greylist-4-0-alpha5:1.1
	milter-greylist-4-0-alpha4:1.1
	milter-greylist-4-0-alpha3:1.1
	milter-greylist-4-0-alpha2:1.1
	milter-greylist-4-0-alpha1:1.1
	milter-greylist-3-1-8:1.1
	milter-greylist-3-1-7:1.1
	milter-greylist-3-1-6:1.1
	milter-greylist-3-1-5:1.1
	milter-greylist-3-1-5-alpha1:1.1
	milter-greylist-3-0-1-beta1:1.1
	milter-greylist-3-1-4:1.1
	milter-greylist-3-1-3:1.1
	milter-greylist-3-1-2:1.1
	milter-greylist-3-1-1:1.1
	milter-greylist-3-0:1.1
	milter-greylist-3-0-rc7:1.1
	milter-greylist-3-0-rc6:1.1
	milter-greylist-3-0-rc5:1.1
	milter-greylist-3-0-rc4:1.1
	milter-greylist-3-0-rc3:1.1
	milter-greylist-3-0-rc2:1.1
	milter-greylist-3-0-rc1:1.1
	milter-greylist-3-0-alpha6:1.1
	milter-greylist-3-0-branch:1.1.0.14
	milter-greylist-3-0-base:1.1
	milter-greylist-3-0-alpha5:1.1
	milter-greylist-3-0-alpha4:1.1
	milter-greylist-3-0-alpha3:1.1
	milter-greylist-3-0-alpha2:1.1
	milter-greylist-3-0-alpha1:1.1
	milter-greylist-2-1-12:1.1
	milter-greylist-2-1-11:1.1
	milter-greylist-2-1-10:1.1
	milter-greylist-2-1-9:1.1
	milter-greylist-2-1-9a1:1.1
	milter-greylist-2-1-8:1.1
	milter-greylist-2-1-7:1.1
	milter-greylist-2-1-6:1.1
	milter-greylist-2-1-5:1.1
	milter-greylist-2-1-4:1.1
	milter-greylist-2-1-3:1.1
	milter-greylist-2-1-2:1.1
	milter-greylist-2-1-1:1.1
	milter-greylist-2-0-2:1.1
	milter-greylist-2-0-1:1.1
	milter-greylist-2-0-1-b1:1.1
	milter-greylist-2-0-release:1.1
	milter-greylist-2-0-rc5:1.1
	milter-greylist-2-0-rc4:1.1
	milter-greylist-2-0-rc3:1.1
	milter-grey-list-2-0-rc3:1.1
	milter-grey-list-2-0-rc2:1.1
	milter-grey-list-2-0-rc1:1.1
	milter-greylist-2-0-beta7:1.1
	milter-greylist-2-0-beta6:1.1
	milter-gre-ylist-2-0-beta5:1.1
	milter-greylist-2-0-beta5:1.1
	milter-greylist-2-0-beta4:1.1
	milter-greylist-2-0-beta3:1.1
	milter-greylist-2-0-beta2:1.1
	milter-greylist-2-0:1.1.0.12
	milter-greylist-2-0-base:1.1
	milter-greylist-2-0-beta1:1.1
	milter-greylist-1-7-5:1.1
	before_delayed_tempfail:1.1
	milter-greylist-1-7-4:1.1
	milter-greylist-1-7-3:1.1
	milter-greylist-1-7-2:1.1
	milter-greylist-1-6-0:1.1
	milter-greylist-1-7-1:1.1
	milter-greylist-1-6rc1:1.1
	milter-greylist-1-6:1.1.0.10
	milter-greylist-1-6-base:1.1
	milter-greylist-1-5-12:1.1
	milter-greylist-1-5-11:1.1
	milter-greylist-1-5-10:1.1
	milter-greylist-1-5-9:1.1
	milter-greylist-1-5-8:1.1
	milter-greylist-1-5-7:1.1
	milter-greylist-1-5-6:1.1
	milter-greylist-1-5-5:1.1
	milter-greylist-1-5-4:1.1
	milter-greylist-1-5-3:1.1
	milter-greylist-1-5-2:1.1
	milter-greylist-1-5-1:1.1
	milter-greylist-1-4:1.1.0.8
	milter-greylist-1-4-base:1.1
	milter-greylist-1-3-9:1.1
	milter-greylist-1-3-8:1.1
	milter-greylist-1-3-7:1.1
	milter-greylist-1-3-6:1.1
	milter-greylist-1-3-5:1.1
	milter-greylist-1-3-4:1.1
	milter-greylist-1-3-3:1.1
	BDB:1.1.0.6
	BDB-base:1.1
	before_BDB:1.1
	milter-greylist-1-2-2:1.1
	milter-greylist-1-3-2:1.1
	milter-greylist-1-2-1:1.1
	milter-greylist-1-2-0:1.1
	milter-greylist-1-2:1.1.0.4
	milter-greylist-1-2-base:1.1
	milter-greylist-1-1-16:1.1
	milter-greylist-1-1-15:1.1
	milter-greylis-1-1-15:1.1
	milter-greylis-1-1-16:1.1
	milter-greylist-1-1-14:1.1
	milter-greylist-1-1-13:1.1
	milter-greylist-1-1-12:1.1
	milter-greylist-1-1-11:1.1
	milter-greylist-1-1-10:1.1
	milter-greylist-1-10rc1:1.1
	milter-greylist-1-1-9:1.1
	milter-greylist-1-1-8:1.1
	milter-greylist-1-1-7:1.1
	milter-greylist-1-1-6:1.1
	milter-greylist-1-1-5:1.1
	milter-greylist-1-1-4:1.1
	milter-greylist-1-1-3:1.1
	milter-greylist-1-1-2:1.1
	milter-greylist-1-0-2:1.1
	rmilter-greylist-1-0-1:1.1
	milter-greylist-1-0-1:1.1
	milter-greylist-1-1-1:1.1
	milter-greylist-1-0-base:1.1
	milter-greylist-1-0:1.1.0.2
	milter-greylist-1-0-0:1.1
	milter-greylist-0-27:1.1
	milter-greylist-0-26:1.1
	milter-greylist-0-25:1.1
	milter-greylist-0-24:1.1
	milter-greylist-0-23:1.1
	milter-greylist-0-22:1.1
	milter-greylist-0-21:1.1
	milter-greylist-0-20:1.1
	milter-greylist-0-19:1.1;
locks; strict;
comment	@ * @;


1.4
date	2013.01.19.16.01.15;	author manu;	state Exp;
branches;
next	1.3;

1.3
date	2009.02.09.04.12.07;	author manu;	state Exp;
branches;
next	1.2;

1.2
date	2009.02.09.02.26.14;	author manu;	state Exp;
branches;
next	1.1;

1.1
date	2004.03.18.09.55.15;	author manu;	state Exp;
branches;
next	;


desc
@@


1.4
log
@More Solaris build fixes (Jim Klimov)
@
text
@/* $Id: queue.h,v 1.3 2009/02/09 04:12:07 manu Exp $ */
/*	$NetBSD: queue.h,v 1.53 2011/11/19 22:51:31 tls Exp $	*/

/*
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@@(#)queue.h	8.5 (Berkeley) 8/20/94
 */

#ifndef	_SYS_QUEUE_H_
#define	_SYS_QUEUE_H_

/*
 * This file defines five types of data structures: singly-linked lists,
 * lists, simple queues, tail queues, and circular queues.
 *
 * A singly-linked list is headed by a single forward pointer. The
 * elements are singly linked for minimum space and pointer manipulation
 * overhead at the expense of O(n) removal for arbitrary elements. New
 * elements can be added to the list after an existing element or at the
 * head of the list.  Elements being removed from the head of the list
 * should use the explicit macro for this purpose for optimum
 * efficiency. A singly-linked list may only be traversed in the forward
 * direction.  Singly-linked lists are ideal for applications with large
 * datasets and few or no removals or for implementing a LIFO queue.
 *
 * A list is headed by a single forward pointer (or an array of forward
 * pointers for a hash table header). The elements are doubly linked
 * so that an arbitrary element can be removed without a need to
 * traverse the list. New elements can be added to the list before
 * or after an existing element or at the head of the list. A list
 * may only be traversed in the forward direction.
 *
 * A simple queue is headed by a pair of pointers, one the head of the
 * list and the other to the tail of the list. The elements are singly
 * linked to save space, so elements can only be removed from the
 * head of the list. New elements can be added to the list after
 * an existing element, at the head of the list, or at the end of the
 * list. A simple queue may only be traversed in the forward direction.
 *
 * A tail queue is headed by a pair of pointers, one to the head of the
 * list and the other to the tail of the list. The elements are doubly
 * linked so that an arbitrary element can be removed without a need to
 * traverse the list. New elements can be added to the list before or
 * after an existing element, at the head of the list, or at the end of
 * the list. A tail queue may be traversed in either direction.
 *
 * A circle queue is headed by a pair of pointers, one to the head of the
 * list and the other to the tail of the list. The elements are doubly
 * linked so that an arbitrary element can be removed without a need to
 * traverse the list. New elements can be added to the list before or after
 * an existing element, at the head of the list, or at the end of the list.
 * A circle queue may be traversed in either direction, but has a more
 * complex end of list detection.
 *
 * For details on the use of these macros, see the queue(3) manual page.
 */

/*
 * List definitions.
 */
#define	LIST_HEAD(name, type)						\
struct name {								\
	struct type *lh_first;	/* first element */			\
}

#define	LIST_HEAD_INITIALIZER(head)					\
	{ NULL }

#define	LIST_ENTRY(type)						\
struct {								\
	struct type *le_next;	/* next element */			\
	struct type **le_prev;	/* address of previous next element */	\
}

/*
 * List functions.
 */
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
	if ((head)->lh_first &&						\
	    (head)->lh_first->field.le_prev != &(head)->lh_first)	\
		panic("LIST_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
#define	QUEUEDEBUG_LIST_OP(elm, field)					\
	if ((elm)->field.le_next &&					\
	    (elm)->field.le_next->field.le_prev !=			\
	    &(elm)->field.le_next)					\
		panic("LIST_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
	if (*(elm)->field.le_prev != (elm))				\
		panic("LIST_* back %p %s:%d", (elm), __FILE__, __LINE__);
#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
	(elm)->field.le_next = (void *)1L;				\
	(elm)->field.le_prev = (void *)1L;
#else
#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
#define	QUEUEDEBUG_LIST_OP(elm, field)
#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
#endif

#define	LIST_INIT(head) do {						\
	(head)->lh_first = NULL;					\
} while (/*CONSTCOND*/0)

#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
	QUEUEDEBUG_LIST_OP((listelm), field)				\
	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
		(listelm)->field.le_next->field.le_prev =		\
		    &(elm)->field.le_next;				\
	(listelm)->field.le_next = (elm);				\
	(elm)->field.le_prev = &(listelm)->field.le_next;		\
} while (/*CONSTCOND*/0)

#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
	QUEUEDEBUG_LIST_OP((listelm), field)				\
	(elm)->field.le_prev = (listelm)->field.le_prev;		\
	(elm)->field.le_next = (listelm);				\
	*(listelm)->field.le_prev = (elm);				\
	(listelm)->field.le_prev = &(elm)->field.le_next;		\
} while (/*CONSTCOND*/0)

#define	LIST_INSERT_HEAD(head, elm, field) do {				\
	QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)		\
	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
	(head)->lh_first = (elm);					\
	(elm)->field.le_prev = &(head)->lh_first;			\
} while (/*CONSTCOND*/0)

#define	LIST_REMOVE(elm, field) do {					\
	QUEUEDEBUG_LIST_OP((elm), field)				\
	if ((elm)->field.le_next != NULL)				\
		(elm)->field.le_next->field.le_prev = 			\
		    (elm)->field.le_prev;				\
	*(elm)->field.le_prev = (elm)->field.le_next;			\
	QUEUEDEBUG_LIST_POSTREMOVE((elm), field)			\
} while (/*CONSTCOND*/0)

#define	LIST_FOREACH(var, head, field)					\
	for ((var) = ((head)->lh_first);				\
		(var);							\
		(var) = ((var)->field.le_next))

#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = LIST_FIRST((head));				\
		(var) && ((tvar) = LIST_NEXT((var), field), 1);		\
		(var) = (tvar))
/*
 * List access methods.
 */
#define	LIST_EMPTY(head)		((head)->lh_first == NULL)
#define	LIST_FIRST(head)		((head)->lh_first)
#define	LIST_NEXT(elm, field)		((elm)->field.le_next)


/*
 * Singly-linked List definitions.
 */
#define	SLIST_HEAD(name, type)						\
struct name {								\
	struct type *slh_first;	/* first element */			\
}

#define	SLIST_HEAD_INITIALIZER(head)					\
	{ NULL }

#define	SLIST_ENTRY(type)						\
struct {								\
	struct type *sle_next;	/* next element */			\
}

/*
 * Singly-linked List functions.
 */
#define	SLIST_INIT(head) do {						\
	(head)->slh_first = NULL;					\
} while (/*CONSTCOND*/0)

#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
	(slistelm)->field.sle_next = (elm);				\
} while (/*CONSTCOND*/0)

#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
	(elm)->field.sle_next = (head)->slh_first;			\
	(head)->slh_first = (elm);					\
} while (/*CONSTCOND*/0)

#define	SLIST_REMOVE_HEAD(head, field) do {				\
	(head)->slh_first = (head)->slh_first->field.sle_next;		\
} while (/*CONSTCOND*/0)

#define	SLIST_REMOVE(head, elm, type, field) do {			\
	if ((head)->slh_first == (elm)) {				\
		SLIST_REMOVE_HEAD((head), field);			\
	}								\
	else {								\
		struct type *curelm = (head)->slh_first;		\
		while(curelm->field.sle_next != (elm))			\
			curelm = curelm->field.sle_next;		\
		curelm->field.sle_next =				\
		    curelm->field.sle_next->field.sle_next;		\
	}								\
} while (/*CONSTCOND*/0)

#define	SLIST_REMOVE_AFTER(slistelm, field) do {			\
	(slistelm)->field.sle_next =					\
	    SLIST_NEXT(SLIST_NEXT((slistelm), field), field);		\
} while (/*CONSTCOND*/0)

#define	SLIST_FOREACH(var, head, field)					\
	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)

#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = SLIST_FIRST((head));				\
	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
	    (var) = (tvar))

/*
 * Singly-linked List access methods.
 */
#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
#define	SLIST_FIRST(head)	((head)->slh_first)
#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)


/*
 * Singly-linked Tail queue declarations.
 */
#define	STAILQ_HEAD(name, type)					\
struct name {								\
	struct type *stqh_first;	/* first element */			\
	struct type **stqh_last;	/* addr of last next element */		\
}

#define	STAILQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).stqh_first }

#define	STAILQ_ENTRY(type)						\
struct {								\
	struct type *stqe_next;	/* next element */			\
}

/*
 * Singly-linked Tail queue functions.
 */
#define	STAILQ_INIT(head) do {						\
	(head)->stqh_first = NULL;					\
	(head)->stqh_last = &(head)->stqh_first;				\
} while (/*CONSTCOND*/0)

#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
		(head)->stqh_last = &(elm)->field.stqe_next;		\
	(head)->stqh_first = (elm);					\
} while (/*CONSTCOND*/0)

#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
	(elm)->field.stqe_next = NULL;					\
	*(head)->stqh_last = (elm);					\
	(head)->stqh_last = &(elm)->field.stqe_next;			\
} while (/*CONSTCOND*/0)

#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
		(head)->stqh_last = &(elm)->field.stqe_next;		\
	(listelm)->field.stqe_next = (elm);				\
} while (/*CONSTCOND*/0)

#define	STAILQ_REMOVE_HEAD(head, field) do {				\
	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
		(head)->stqh_last = &(head)->stqh_first;			\
} while (/*CONSTCOND*/0)

#define	STAILQ_REMOVE(head, elm, type, field) do {			\
	if ((head)->stqh_first == (elm)) {				\
		STAILQ_REMOVE_HEAD((head), field);			\
	} else {							\
		struct type *curelm = (head)->stqh_first;		\
		while (curelm->field.stqe_next != (elm))			\
			curelm = curelm->field.stqe_next;		\
		if ((curelm->field.stqe_next =				\
			curelm->field.stqe_next->field.stqe_next) == NULL) \
			    (head)->stqh_last = &(curelm)->field.stqe_next; \
	}								\
} while (/*CONSTCOND*/0)

#define	STAILQ_FOREACH(var, head, field)				\
	for ((var) = ((head)->stqh_first);				\
		(var);							\
		(var) = ((var)->field.stqe_next))

#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
	for ((var) = STAILQ_FIRST((head));				\
	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
	    (var) = (tvar))

#define	STAILQ_CONCAT(head1, head2) do {				\
	if (!STAILQ_EMPTY((head2))) {					\
		*(head1)->stqh_last = (head2)->stqh_first;		\
		(head1)->stqh_last = (head2)->stqh_last;		\
		STAILQ_INIT((head2));					\
	}								\
} while (/*CONSTCOND*/0)

#define	STAILQ_LAST(head, type, field)					\
	(STAILQ_EMPTY((head)) ?						\
		NULL :							\
	        ((struct type *)(void *)				\
		((char *)((head)->stqh_last) - offsetof(struct type, field))))

/*
 * Singly-linked Tail queue access methods.
 */
#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
#define	STAILQ_FIRST(head)	((head)->stqh_first)
#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)


/*
 * Simple queue definitions.
 */
#define	SIMPLEQ_HEAD(name, type)					\
struct name {								\
	struct type *sqh_first;	/* first element */			\
	struct type **sqh_last;	/* addr of last next element */		\
}

#define	SIMPLEQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).sqh_first }

#define	SIMPLEQ_ENTRY(type)						\
struct {								\
	struct type *sqe_next;	/* next element */			\
}

/*
 * Simple queue functions.
 */
#define	SIMPLEQ_INIT(head) do {						\
	(head)->sqh_first = NULL;					\
	(head)->sqh_last = &(head)->sqh_first;				\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
		(head)->sqh_last = &(elm)->field.sqe_next;		\
	(head)->sqh_first = (elm);					\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
	(elm)->field.sqe_next = NULL;					\
	*(head)->sqh_last = (elm);					\
	(head)->sqh_last = &(elm)->field.sqe_next;			\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
		(head)->sqh_last = &(elm)->field.sqe_next;		\
	(listelm)->field.sqe_next = (elm);				\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\
	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
		(head)->sqh_last = &(head)->sqh_first;			\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\
	if ((head)->sqh_first == (elm)) {				\
		SIMPLEQ_REMOVE_HEAD((head), field);			\
	} else {							\
		struct type *curelm = (head)->sqh_first;		\
		while (curelm->field.sqe_next != (elm))			\
			curelm = curelm->field.sqe_next;		\
		if ((curelm->field.sqe_next =				\
			curelm->field.sqe_next->field.sqe_next) == NULL) \
			    (head)->sqh_last = &(curelm)->field.sqe_next; \
	}								\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_FOREACH(var, head, field)				\
	for ((var) = ((head)->sqh_first);				\
		(var);							\
		(var) = ((var)->field.sqe_next))

#define	SIMPLEQ_FOREACH_SAFE(var, head, field, next)			\
	for ((var) = ((head)->sqh_first);				\
		(var) && ((next = ((var)->field.sqe_next)), 1);		\
		(var) = (next))

#define	SIMPLEQ_CONCAT(head1, head2) do {				\
	if (!SIMPLEQ_EMPTY((head2))) {					\
		*(head1)->sqh_last = (head2)->sqh_first;		\
		(head1)->sqh_last = (head2)->sqh_last;		\
		SIMPLEQ_INIT((head2));					\
	}								\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_LAST(head, type, field)					\
	(SIMPLEQ_EMPTY((head)) ?						\
		NULL :							\
	        ((struct type *)(void *)				\
		((char *)((head)->sqh_last) - offsetof(struct type, field))))

/*
 * Simple queue access methods.
 */
#define	SIMPLEQ_EMPTY(head)		((head)->sqh_first == NULL)
#define	SIMPLEQ_FIRST(head)		((head)->sqh_first)
#define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)


/*
 * Tail queue definitions.
 */
#define	_TAILQ_HEAD(name, type, qual)					\
struct name {								\
	qual type *tqh_first;		/* first element */		\
	qual type *qual *tqh_last;	/* addr of last next element */	\
}
#define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,)

#define	TAILQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).tqh_first }

#define	_TAILQ_ENTRY(type, qual)					\
struct {								\
	qual type *tqe_next;		/* next element */		\
	qual type *qual *tqe_prev;	/* address of previous next element */\
}
#define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,)

/*
 * Tail queue functions.
 */
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
	if ((head)->tqh_first &&					\
	    (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)	\
		panic("TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
	if (*(head)->tqh_last != NULL)					\
		panic("TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
#define	QUEUEDEBUG_TAILQ_OP(elm, field)					\
	if ((elm)->field.tqe_next &&					\
	    (elm)->field.tqe_next->field.tqe_prev !=			\
	    &(elm)->field.tqe_next)					\
		panic("TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
	if (*(elm)->field.tqe_prev != (elm))				\
		panic("TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)			\
	if ((elm)->field.tqe_next == NULL &&				\
	    (head)->tqh_last != &(elm)->field.tqe_next)			\
		panic("TAILQ_PREREMOVE head %p elm %p %s:%d",		\
		      (head), (elm), __FILE__, __LINE__);
#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
	(elm)->field.tqe_next = (void *)1L;				\
	(elm)->field.tqe_prev = (void *)1L;
#else
#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
#define	QUEUEDEBUG_TAILQ_OP(elm, field)
#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
#endif

#define	TAILQ_INIT(head) do {						\
	(head)->tqh_first = NULL;					\
	(head)->tqh_last = &(head)->tqh_first;				\
} while (/*CONSTCOND*/0)

#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
	QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)		\
	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
		(head)->tqh_first->field.tqe_prev =			\
		    &(elm)->field.tqe_next;				\
	else								\
		(head)->tqh_last = &(elm)->field.tqe_next;		\
	(head)->tqh_first = (elm);					\
	(elm)->field.tqe_prev = &(head)->tqh_first;			\
} while (/*CONSTCOND*/0)

#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
	QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)		\
	(elm)->field.tqe_next = NULL;					\
	(elm)->field.tqe_prev = (head)->tqh_last;			\
	*(head)->tqh_last = (elm);					\
	(head)->tqh_last = &(elm)->field.tqe_next;			\
} while (/*CONSTCOND*/0)

#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
		(elm)->field.tqe_next->field.tqe_prev = 		\
		    &(elm)->field.tqe_next;				\
	else								\
		(head)->tqh_last = &(elm)->field.tqe_next;		\
	(listelm)->field.tqe_next = (elm);				\
	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
} while (/*CONSTCOND*/0)

#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
	(elm)->field.tqe_next = (listelm);				\
	*(listelm)->field.tqe_prev = (elm);				\
	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
} while (/*CONSTCOND*/0)

#define	TAILQ_REMOVE(head, elm, field) do {				\
	QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field)		\
	QUEUEDEBUG_TAILQ_OP((elm), field)				\
	if (((elm)->field.tqe_next) != NULL)				\
		(elm)->field.tqe_next->field.tqe_prev = 		\
		    (elm)->field.tqe_prev;				\
	else								\
		(head)->tqh_last = (elm)->field.tqe_prev;		\
	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
	QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);			\
} while (/*CONSTCOND*/0)

#define	TAILQ_FOREACH(var, head, field)					\
	for ((var) = ((head)->tqh_first);				\
		(var);							\
		(var) = ((var)->field.tqe_next))

#define	TAILQ_FOREACH_SAFE(var, head, field, next)			\
	for ((var) = ((head)->tqh_first);				\
	        (var) != NULL && ((next) = TAILQ_NEXT(var, field), 1);	\
		(var) = (next))

#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
		(var);							\
		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))

#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev)	\
	for ((var) = TAILQ_LAST((head), headname);			\
		(var) && ((prev) = TAILQ_PREV((var), headname, field), 1);\
		(var) = (prev))

#define	TAILQ_CONCAT(head1, head2, field) do {				\
	if (!TAILQ_EMPTY(head2)) {					\
		*(head1)->tqh_last = (head2)->tqh_first;		\
		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
		(head1)->tqh_last = (head2)->tqh_last;			\
		TAILQ_INIT((head2));					\
	}								\
} while (/*CONSTCOND*/0)

/*
 * Tail queue access methods.
 */
#define	TAILQ_EMPTY(head)		((head)->tqh_first == NULL)
#define	TAILQ_FIRST(head)		((head)->tqh_first)
#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)

#define	TAILQ_LAST(head, headname) \
	(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define	TAILQ_PREV(elm, headname, field) \
	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))


/*
 * Circular queue definitions.
 */
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)				\
	if ((head)->cqh_first != (void *)(head) &&			\
	    (head)->cqh_first->field.cqe_prev != (void *)(head))	\
		panic("CIRCLEQ head forw %p %s:%d", (head),		\
		      __FILE__, __LINE__);				\
	if ((head)->cqh_last != (void *)(head) &&			\
	    (head)->cqh_last->field.cqe_next != (void *)(head))		\
		panic("CIRCLEQ head back %p %s:%d", (head),		\
		      __FILE__, __LINE__);
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)			\
	if ((elm)->field.cqe_next == (void *)(head)) {			\
		if ((head)->cqh_last != (elm))				\
			panic("CIRCLEQ elm last %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	} else {							\
		if ((elm)->field.cqe_next->field.cqe_prev != (elm))	\
			panic("CIRCLEQ elm forw %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	}								\
	if ((elm)->field.cqe_prev == (void *)(head)) {			\
		if ((head)->cqh_first != (elm))				\
			panic("CIRCLEQ elm first %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	} else {							\
		if ((elm)->field.cqe_prev->field.cqe_next != (elm))	\
			panic("CIRCLEQ elm prev %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	}
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)			\
	(elm)->field.cqe_next = (void *)1L;				\
	(elm)->field.cqe_prev = (void *)1L;
#else
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
#endif

#define	CIRCLEQ_HEAD(name, type)					\
struct name {								\
	struct type *cqh_first;		/* first element */		\
	struct type *cqh_last;		/* last element */		\
}

#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
	{ (void *)&head, (void *)&head }

#define	CIRCLEQ_ENTRY(type)						\
struct {								\
	struct type *cqe_next;		/* next element */		\
	struct type *cqe_prev;		/* previous element */		\
}

/*
 * Circular queue functions.
 */
#define	CIRCLEQ_INIT(head) do {						\
	(head)->cqh_first = (void *)(head);				\
	(head)->cqh_last = (void *)(head);				\
} while (/*CONSTCOND*/0)

#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
	(elm)->field.cqe_prev = (listelm);				\
	if ((listelm)->field.cqe_next == (void *)(head))		\
		(head)->cqh_last = (elm);				\
	else								\
		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
	(listelm)->field.cqe_next = (elm);				\
} while (/*CONSTCOND*/0)

#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
	(elm)->field.cqe_next = (listelm);				\
	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
	if ((listelm)->field.cqe_prev == (void *)(head))		\
		(head)->cqh_first = (elm);				\
	else								\
		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
	(listelm)->field.cqe_prev = (elm);				\
} while (/*CONSTCOND*/0)

#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	(elm)->field.cqe_next = (head)->cqh_first;			\
	(elm)->field.cqe_prev = (void *)(head);				\
	if ((head)->cqh_last == (void *)(head))				\
		(head)->cqh_last = (elm);				\
	else								\
		(head)->cqh_first->field.cqe_prev = (elm);		\
	(head)->cqh_first = (elm);					\
} while (/*CONSTCOND*/0)

#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	(elm)->field.cqe_next = (void *)(head);				\
	(elm)->field.cqe_prev = (head)->cqh_last;			\
	if ((head)->cqh_first == (void *)(head))			\
		(head)->cqh_first = (elm);				\
	else								\
		(head)->cqh_last->field.cqe_next = (elm);		\
	(head)->cqh_last = (elm);					\
} while (/*CONSTCOND*/0)

#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field)			\
	if ((elm)->field.cqe_next == (void *)(head))			\
		(head)->cqh_last = (elm)->field.cqe_prev;		\
	else								\
		(elm)->field.cqe_next->field.cqe_prev =			\
		    (elm)->field.cqe_prev;				\
	if ((elm)->field.cqe_prev == (void *)(head))			\
		(head)->cqh_first = (elm)->field.cqe_next;		\
	else								\
		(elm)->field.cqe_prev->field.cqe_next =			\
		    (elm)->field.cqe_next;				\
	QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field)			\
} while (/*CONSTCOND*/0)

#define	CIRCLEQ_FOREACH(var, head, field)				\
	for ((var) = ((head)->cqh_first);				\
		(var) != (const void *)(head);				\
		(var) = ((var)->field.cqe_next))

#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
	for ((var) = ((head)->cqh_last);				\
		(var) != (const void *)(head);				\
		(var) = ((var)->field.cqe_prev))

/*
 * Circular queue access methods.
 */
#define	CIRCLEQ_EMPTY(head)		((head)->cqh_first == (void *)(head))
#define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
#define	CIRCLEQ_LAST(head)		((head)->cqh_last)
#define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
#define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)

#define CIRCLEQ_LOOP_NEXT(head, elm, field)				\
	(((elm)->field.cqe_next == (void *)(head))			\
	    ? ((head)->cqh_first)					\
	    : (elm->field.cqe_next))
#define CIRCLEQ_LOOP_PREV(head, elm, field)				\
	(((elm)->field.cqe_prev == (void *)(head))			\
	    ? ((head)->cqh_last)					\
	    : (elm->field.cqe_prev))

#endif	/* !_SYS_QUEUE_H_ */
@


1.3
log
@Roll back previous build fix, as it requires <null.h>, a header that is not
available anywhere.

Change STAILQ_* to TAILQ_* instead
@
text
@d1 2
a2 2
/* $Id: queue.h,v 1.1 2004/03/18 09:55:15 manu Exp $ */
/*	$NetBSD: queue.h,v 1.30 2001/06/22 06:18:22 chs Exp $	*/
d65 1
a65 1
 * linked to save space, so only elements can only be removed from the
d91 1
a91 1
#define LIST_HEAD(name, type)						\
d96 1
a96 1
#define LIST_HEAD_INITIALIZER(head)					\
d99 1
a99 1
#define LIST_ENTRY(type)						\
d109 1
a109 1
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
d113 1
a113 1
#define QUEUEDEBUG_LIST_OP(elm, field)					\
d120 1
a120 1
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
d124 3
a126 3
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
#define QUEUEDEBUG_LIST_OP(elm, field)
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
d133 1
a133 1
#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
d150 1
a150 1
#define LIST_INSERT_HEAD(head, elm, field) do {				\
d158 1
a158 1
#define LIST_REMOVE(elm, field) do {					\
d167 1
a167 1
#define LIST_FOREACH(var, head, field)					\
d172 4
d183 1
d187 1
a187 1
#define SLIST_HEAD(name, type)						\
d192 1
a192 1
#define SLIST_HEAD_INITIALIZER(head)					\
d194 2
a195 2
 
#define SLIST_ENTRY(type)						\
d199 1
a199 1
 
d203 1
a203 8
#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
#define	SLIST_FIRST(head)	((head)->slh_first)
#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)

#define SLIST_FOREACH(var, head, field)					\
	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)

#define SLIST_INIT(head) do {						\
d207 1
a207 1
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
d212 1
a212 1
#define SLIST_INSERT_HEAD(head, elm, field) do {			\
d217 1
a217 3
#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)

#define SLIST_REMOVE_HEAD(head, field) do {				\
d221 1
a221 1
#define SLIST_REMOVE(head, elm, type, field) do {			\
d234 114
d351 1
a351 1
#define SIMPLEQ_HEAD(name, type)					\
d357 1
a357 1
#define SIMPLEQ_HEAD_INITIALIZER(head)					\
d360 1
a360 1
#define SIMPLEQ_ENTRY(type)						\
d373 1
a373 1
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
d379 1
a379 1
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
d385 1
a385 1
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d391 2
a392 2
#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {			\
	if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)	\
d396 14
a409 1
#define SIMPLEQ_FOREACH(var, head, field)				\
d414 19
d440 1
d444 1
a444 1
#define TAILQ_HEAD(name, type)						\
d446 2
a447 2
	struct type *tqh_first;	/* first element */			\
	struct type **tqh_last;	/* addr of last next element */		\
d449 1
d451 1
a451 1
#define TAILQ_HEAD_INITIALIZER(head)					\
d454 1
a454 1
#define TAILQ_ENTRY(type)						\
d456 2
a457 2
	struct type *tqe_next;	/* next element */			\
	struct type **tqe_prev;	/* address of previous next element */	\
d459 1
d465 1
a465 1
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
d469 1
a469 1
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
d472 1
a472 1
#define QUEUEDEBUG_TAILQ_OP(elm, field)					\
d479 6
a484 1
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
d488 5
a492 4
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
#define QUEUEDEBUG_TAILQ_OP(elm, field)
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
d500 1
a500 1
#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
d511 1
a511 1
#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
d519 1
a519 1
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d538 2
a539 1
#define TAILQ_REMOVE(head, elm, field) do {				\
d550 29
d586 1
a586 1
#define TAILQ_LAST(head, headname) \
d588 1
a588 1
#define TAILQ_PREV(elm, headname, field) \
a590 9
#define TAILQ_FOREACH(var, head, field)					\
	for ((var) = ((head)->tqh_first);				\
		(var);							\
		(var) = ((var)->field.tqe_next))

#define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
		(var);							\
		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
d595 39
a633 1
#define CIRCLEQ_HEAD(name, type)					\
d639 1
a639 1
#define CIRCLEQ_HEAD_INITIALIZER(head)					\
d642 1
a642 1
#define CIRCLEQ_ENTRY(type)						\
d656 3
a658 1
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d668 3
a670 1
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
d680 2
a681 1
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
d691 2
a692 1
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
d703 2
d715 1
d718 1
a718 1
#define CIRCLEQ_FOREACH(var, head, field)				\
d720 1
a720 1
		(var) != (void *)(head);				\
d723 1
a723 1
#define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
d725 1
a725 1
		(var) != (void *)(head);				\
d736 10
@


1.2
log
@Build fix for missing STAILQ_* macros
@
text
@d1 2
a2 1
/*	$NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $	*/
d16 5
a20 1
 * 3. Neither the name of the University nor the names of its contributors
a41 2
#include <sys/null.h>

d65 1
a65 1
 * linked to save space, so elements can only be removed from the
d91 1
a91 1
#define	LIST_HEAD(name, type)						\
d96 1
a96 1
#define	LIST_HEAD_INITIALIZER(head)					\
d99 1
a99 1
#define	LIST_ENTRY(type)						\
d109 1
a109 1
#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
d113 1
a113 1
#define	QUEUEDEBUG_LIST_OP(elm, field)					\
d120 1
a120 1
#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
d124 3
a126 3
#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
#define	QUEUEDEBUG_LIST_OP(elm, field)
#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
d133 1
a133 1
#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
d150 1
a150 1
#define	LIST_INSERT_HEAD(head, elm, field) do {				\
d158 1
a158 1
#define	LIST_REMOVE(elm, field) do {					\
d167 1
a167 1
#define	LIST_FOREACH(var, head, field)					\
a178 1

d182 1
a182 1
#define	SLIST_HEAD(name, type)						\
d187 1
a187 1
#define	SLIST_HEAD_INITIALIZER(head)					\
d189 2
a190 2

#define	SLIST_ENTRY(type)						\
d194 1
a194 1

d198 8
a205 1
#define	SLIST_INIT(head) do {						\
d209 1
a209 1
#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
d214 1
a214 1
#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
d219 3
a221 1
#define	SLIST_REMOVE_HEAD(head, field) do {				\
d225 1
a225 1
#define	SLIST_REMOVE(head, elm, type, field) do {			\
a237 85
#define	SLIST_FOREACH(var, head, field)					\
	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)

/*
 * Singly-linked List access methods.
 */
#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
#define	SLIST_FIRST(head)	((head)->slh_first)
#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)


/*
 * Singly-linked Tail queue declarations.
 */
#define	STAILQ_HEAD(name, type)					\
struct name {								\
	struct type *stqh_first;	/* first element */			\
	struct type **stqh_last;	/* addr of last next element */		\
}

#define	STAILQ_HEAD_INITIALIZER(head)					\
	{ NULL, &(head).stqh_first }

#define	STAILQ_ENTRY(type)						\
struct {								\
	struct type *stqe_next;	/* next element */			\
}

/*
 * Singly-linked Tail queue functions.
 */
#define	STAILQ_INIT(head) do {						\
	(head)->stqh_first = NULL;					\
	(head)->stqh_last = &(head)->stqh_first;				\
} while (/*CONSTCOND*/0)

#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
		(head)->stqh_last = &(elm)->field.stqe_next;		\
	(head)->stqh_first = (elm);					\
} while (/*CONSTCOND*/0)

#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
	(elm)->field.stqe_next = NULL;					\
	*(head)->stqh_last = (elm);					\
	(head)->stqh_last = &(elm)->field.stqe_next;			\
} while (/*CONSTCOND*/0)

#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
		(head)->stqh_last = &(elm)->field.stqe_next;		\
	(listelm)->field.stqe_next = (elm);				\
} while (/*CONSTCOND*/0)

#define	STAILQ_REMOVE_HEAD(head, field) do {				\
	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
		(head)->stqh_last = &(head)->stqh_first;			\
} while (/*CONSTCOND*/0)

#define	STAILQ_REMOVE(head, elm, type, field) do {			\
	if ((head)->stqh_first == (elm)) {				\
		STAILQ_REMOVE_HEAD((head), field);			\
	} else {							\
		struct type *curelm = (head)->stqh_first;		\
		while (curelm->field.stqe_next != (elm))			\
			curelm = curelm->field.stqe_next;		\
		if ((curelm->field.stqe_next =				\
			curelm->field.stqe_next->field.stqe_next) == NULL) \
			    (head)->stqh_last = &(curelm)->field.stqe_next; \
	}								\
} while (/*CONSTCOND*/0)

#define	STAILQ_FOREACH(var, head, field)				\
	for ((var) = ((head)->stqh_first);				\
		(var);							\
		(var) = ((var)->field.stqe_next))

/*
 * Singly-linked Tail queue access methods.
 */
#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
#define	STAILQ_FIRST(head)	((head)->stqh_first)
#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)


d241 1
a241 1
#define	SIMPLEQ_HEAD(name, type)					\
d247 1
a247 1
#define	SIMPLEQ_HEAD_INITIALIZER(head)					\
d250 1
a250 1
#define	SIMPLEQ_ENTRY(type)						\
d263 1
a263 1
#define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
d269 1
a269 1
#define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
d275 1
a275 1
#define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d281 2
a282 2
#define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\
	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
d286 1
a286 14
#define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\
	if ((head)->sqh_first == (elm)) {				\
		SIMPLEQ_REMOVE_HEAD((head), field);			\
	} else {							\
		struct type *curelm = (head)->sqh_first;		\
		while (curelm->field.sqe_next != (elm))			\
			curelm = curelm->field.sqe_next;		\
		if ((curelm->field.sqe_next =				\
			curelm->field.sqe_next->field.sqe_next) == NULL) \
			    (head)->sqh_last = &(curelm)->field.sqe_next; \
	}								\
} while (/*CONSTCOND*/0)

#define	SIMPLEQ_FOREACH(var, head, field)				\
a297 1

d301 1
a301 1
#define	_TAILQ_HEAD(name, type, qual)					\
d303 2
a304 2
	qual type *tqh_first;		/* first element */		\
	qual type *qual *tqh_last;	/* addr of last next element */	\
a305 1
#define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,)
d307 1
a307 1
#define	TAILQ_HEAD_INITIALIZER(head)					\
d310 1
a310 1
#define	_TAILQ_ENTRY(type, qual)					\
d312 2
a313 2
	qual type *tqe_next;		/* next element */		\
	qual type *qual *tqe_prev;	/* address of previous next element */\
a314 1
#define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,)
d320 1
a320 1
#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
d324 1
a324 1
#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
d327 1
a327 1
#define	QUEUEDEBUG_TAILQ_OP(elm, field)					\
d334 1
a334 6
#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)			\
	if ((elm)->field.tqe_next == NULL &&				\
	    (head)->tqh_last != &(elm)->field.tqe_next)			\
		panic("TAILQ_PREREMOVE head %p elm %p %s:%d",		\
		      (head), (elm), __FILE__, __LINE__);
#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
d338 4
a341 5
#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
#define	QUEUEDEBUG_TAILQ_OP(elm, field)
#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
d349 1
a349 1
#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
d360 1
a360 1
#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
d368 1
a368 1
#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d387 1
a387 2
#define	TAILQ_REMOVE(head, elm, field) do {				\
	QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field)		\
a397 10
#define	TAILQ_FOREACH(var, head, field)					\
	for ((var) = ((head)->tqh_first);				\
		(var);							\
		(var) = ((var)->field.tqe_next))

#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
		(var);							\
		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))

d405 1
a405 1
#define	TAILQ_LAST(head, headname) \
d407 1
a407 1
#define	TAILQ_PREV(elm, headname, field) \
d410 9
d423 1
a423 39
#if defined(_KERNEL) && defined(QUEUEDEBUG)
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)				\
	if ((head)->cqh_first != (void *)(head) &&			\
	    (head)->cqh_first->field.cqe_prev != (void *)(head))	\
		panic("CIRCLEQ head forw %p %s:%d", (head),		\
		      __FILE__, __LINE__);				\
	if ((head)->cqh_last != (void *)(head) &&			\
	    (head)->cqh_last->field.cqe_next != (void *)(head))		\
		panic("CIRCLEQ head back %p %s:%d", (head),		\
		      __FILE__, __LINE__);
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)			\
	if ((elm)->field.cqe_next == (void *)(head)) {			\
		if ((head)->cqh_last != (elm))				\
			panic("CIRCLEQ elm last %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	} else {							\
		if ((elm)->field.cqe_next->field.cqe_prev != (elm))	\
			panic("CIRCLEQ elm forw %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	}								\
	if ((elm)->field.cqe_prev == (void *)(head)) {			\
		if ((head)->cqh_first != (elm))				\
			panic("CIRCLEQ elm first %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	} else {							\
		if ((elm)->field.cqe_prev->field.cqe_next != (elm))	\
			panic("CIRCLEQ elm prev %p %s:%d", (elm),	\
			      __FILE__, __LINE__);			\
	}
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)			\
	(elm)->field.cqe_next = (void *)1L;				\
	(elm)->field.cqe_prev = (void *)1L;
#else
#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
#endif

#define	CIRCLEQ_HEAD(name, type)					\
d429 1
a429 1
#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
d432 1
a432 1
#define	CIRCLEQ_ENTRY(type)						\
d446 1
a446 3
#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
d456 1
a456 3
#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
d466 1
a466 2
#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
d476 1
a476 2
#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
a486 2
	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
	QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field)			\
a496 1
	QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field)			\
d499 1
a499 1
#define	CIRCLEQ_FOREACH(var, head, field)				\
d501 1
a501 1
		(var) != (const void *)(head);				\
d504 1
a504 1
#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
d506 1
a506 1
		(var) != (const void *)(head);				\
a516 10

#define CIRCLEQ_LOOP_NEXT(head, elm, field)				\
	(((elm)->field.cqe_next == (void *)(head))			\
	    ? ((head)->cqh_first)					\
	    : (elm->field.cqe_next))
#define CIRCLEQ_LOOP_PREV(head, elm, field)				\
	(((elm)->field.cqe_prev == (void *)(head))			\
	    ? ((head)->cqh_last)					\
	    : (elm->field.cqe_prev))

@


1.1
log
@Use a modern queue.h if it is missing from the system (Linux...)
@
text
@d1 1
a1 2
/* $Id$ */
/*	$NetBSD: queue.h,v 1.30 2001/06/22 06:18:22 chs Exp $	*/
d15 1
a15 5
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
d37 2
d62 1
a62 1
 * linked to save space, so only elements can only be removed from the
d88 1
a88 1
#define LIST_HEAD(name, type)						\
d93 1
a93 1
#define LIST_HEAD_INITIALIZER(head)					\
d96 1
a96 1
#define LIST_ENTRY(type)						\
d106 1
a106 1
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
d110 1
a110 1
#define QUEUEDEBUG_LIST_OP(elm, field)					\
d117 1
a117 1
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
d121 3
a123 3
#define QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
#define QUEUEDEBUG_LIST_OP(elm, field)
#define QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
d130 1
a130 1
#define LIST_INSERT_AFTER(listelm, elm, field) do {			\
d147 1
a147 1
#define LIST_INSERT_HEAD(head, elm, field) do {				\
d155 1
a155 1
#define LIST_REMOVE(elm, field) do {					\
d164 1
a164 1
#define LIST_FOREACH(var, head, field)					\
d176 1
d180 1
a180 1
#define SLIST_HEAD(name, type)						\
d185 1
a185 1
#define SLIST_HEAD_INITIALIZER(head)					\
d187 2
a188 2
 
#define SLIST_ENTRY(type)						\
d192 1
a192 1
 
d196 1
a196 8
#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
#define	SLIST_FIRST(head)	((head)->slh_first)
#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)

#define SLIST_FOREACH(var, head, field)					\
	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)

#define SLIST_INIT(head) do {						\
d200 1
a200 1
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
d205 1
a205 1
#define SLIST_INSERT_HEAD(head, elm, field) do {			\
d210 1
a210 3
#define SLIST_NEXT(elm, field)	((elm)->field.sle_next)

#define SLIST_REMOVE_HEAD(head, field) do {				\
d214 1
a214 1
#define SLIST_REMOVE(head, elm, type, field) do {			\
d227 85
d315 1
a315 1
#define SIMPLEQ_HEAD(name, type)					\
d321 1
a321 1
#define SIMPLEQ_HEAD_INITIALIZER(head)					\
d324 1
a324 1
#define SIMPLEQ_ENTRY(type)						\
d337 1
a337 1
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
d343 1
a343 1
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
d349 1
a349 1
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d355 2
a356 2
#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {			\
	if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)	\
d360 14
a373 1
#define SIMPLEQ_FOREACH(var, head, field)				\
d385 1
d389 1
a389 1
#define TAILQ_HEAD(name, type)						\
d391 2
a392 2
	struct type *tqh_first;	/* first element */			\
	struct type **tqh_last;	/* addr of last next element */		\
d394 1
d396 1
a396 1
#define TAILQ_HEAD_INITIALIZER(head)					\
d399 1
a399 1
#define TAILQ_ENTRY(type)						\
d401 2
a402 2
	struct type *tqe_next;	/* next element */			\
	struct type **tqe_prev;	/* address of previous next element */	\
d404 1
d410 1
a410 1
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
d414 1
a414 1
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
d417 1
a417 1
#define QUEUEDEBUG_TAILQ_OP(elm, field)					\
d424 6
a429 1
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
d433 5
a437 4
#define QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
#define QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
#define QUEUEDEBUG_TAILQ_OP(elm, field)
#define QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
d445 1
a445 1
#define TAILQ_INSERT_HEAD(head, elm, field) do {			\
d456 1
a456 1
#define TAILQ_INSERT_TAIL(head, elm, field) do {			\
d464 1
a464 1
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d483 2
a484 1
#define TAILQ_REMOVE(head, elm, field) do {				\
d495 10
d512 1
a512 1
#define TAILQ_LAST(head, headname) \
d514 1
a514 1
#define TAILQ_PREV(elm, headname, field) \
a516 9
#define TAILQ_FOREACH(var, head, field)					\
	for ((var) = ((head)->tqh_first);				\
		(var);							\
		(var) = ((var)->field.tqe_next))

#define TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
		(var);							\
		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
d521 39
a559 1
#define CIRCLEQ_HEAD(name, type)					\
d565 1
a565 1
#define CIRCLEQ_HEAD_INITIALIZER(head)					\
d568 1
a568 1
#define CIRCLEQ_ENTRY(type)						\
d582 3
a584 1
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
d594 3
a596 1
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
d606 2
a607 1
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
d617 2
a618 1
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
d629 2
d641 1
d644 1
a644 1
#define CIRCLEQ_FOREACH(var, head, field)				\
d646 1
a646 1
		(var) != (void *)(head);				\
d649 1
a649 1
#define CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
d651 1
a651 1
		(var) != (void *)(head);				\
d662 10
@

