• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*	$NetBSD: queue.h,v 1.65 2013/12/25 17:19:34 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
32  */
33 
34 #ifndef COMPAT_QUEUE_H
35 #define COMPAT_QUEUE_H
36 
37 /*
38  * Tail queue definitions.
39  */
40 #ifndef TAILQ_END
41 #define	TAILQ_END(head)			(NULL)
42 #endif
43 
44 #ifndef TAILQ_HEAD
45 #define	_TAILQ_HEAD(name, type, qual)					\
46 struct name {								\
47 	qual type *tqh_first;		/* first element */		\
48 	qual type *qual *tqh_last;	/* addr of last next element */	\
49 }
50 #define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,)
51 
52 #define	TAILQ_HEAD_INITIALIZER(head)					\
53 	{ TAILQ_END(head), &(head).tqh_first }
54 
55 #define	_TAILQ_ENTRY(type, qual)					\
56 struct {								\
57 	qual type *tqe_next;		/* next element */		\
58 	qual type *qual *tqe_prev;	/* address of previous next element */\
59 }
60 #define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,)
61 #endif /* !TAILQ_HEAD */
62 
63 /*
64  * Tail queue access methods.
65  */
66 #ifndef TAILQ_FIRST
67 #define	TAILQ_FIRST(head)		((head)->tqh_first)
68 #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
69 #define	TAILQ_LAST(head, headname) \
70 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
71 #define	TAILQ_PREV(elm, headname, field) \
72 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
73 #define	TAILQ_EMPTY(head)		(TAILQ_FIRST(head) == TAILQ_END(head))
74 #endif /* !TAILQ_FIRST */
75 
76 #ifndef TAILQ_FOREACH
77 #define	TAILQ_FOREACH(var, head, field)					\
78 	for ((var) = ((head)->tqh_first);				\
79 	    (var) != TAILQ_END(head);					\
80 	    (var) = ((var)->field.tqe_next))
81 
82 #define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
83 	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\
84 	    (var) != TAILQ_END(head);					\
85 	    (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
86 #endif /* !TAILQ_FOREACH */
87 
88 #ifndef TAILQ_INIT
89 #define	TAILQ_INIT(head) do {						\
90 	(head)->tqh_first = TAILQ_END(head);				\
91 	(head)->tqh_last = &(head)->tqh_first;				\
92 } while (/*CONSTCOND*/0)
93 
94 #define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
95 	if (((elm)->field.tqe_next = (head)->tqh_first) != TAILQ_END(head))\
96 		(head)->tqh_first->field.tqe_prev =			\
97 		    &(elm)->field.tqe_next;				\
98 	else								\
99 		(head)->tqh_last = &(elm)->field.tqe_next;		\
100 	(head)->tqh_first = (elm);					\
101 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
102 } while (/*CONSTCOND*/0)
103 
104 #define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
105 	(elm)->field.tqe_next = TAILQ_END(head);			\
106 	(elm)->field.tqe_prev = (head)->tqh_last;			\
107 	*(head)->tqh_last = (elm);					\
108 	(head)->tqh_last = &(elm)->field.tqe_next;			\
109 } while (/*CONSTCOND*/0)
110 
111 #define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
112 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) !=	\
113 	    TAILQ_END(head))						\
114 		(elm)->field.tqe_next->field.tqe_prev =			\
115 		    &(elm)->field.tqe_next;				\
116 	else								\
117 		(head)->tqh_last = &(elm)->field.tqe_next;		\
118 	(listelm)->field.tqe_next = (elm);				\
119 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
120 } while (/*CONSTCOND*/0)
121 
122 #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
123 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
124 	(elm)->field.tqe_next = (listelm);				\
125 	*(listelm)->field.tqe_prev = (elm);				\
126 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
127 } while (/*CONSTCOND*/0)
128 
129 #define	TAILQ_REMOVE(head, elm, field) do {				\
130 	if (((elm)->field.tqe_next) != TAILQ_END(head))			\
131 		(elm)->field.tqe_next->field.tqe_prev =			\
132 		    (elm)->field.tqe_prev;				\
133 	else								\
134 		(head)->tqh_last = (elm)->field.tqe_prev;		\
135 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
136 } while (/*CONSTCOND*/0)
137 #endif /* !TAILQ_INIT */
138 
139 #ifndef TAILQ_REPLACE
140 #define TAILQ_REPLACE(head, elm, elm2, field) do {                      \
141         if (((elm2)->field.tqe_next = (elm)->field.tqe_next) !=		\
142 	    TAILQ_END(head))						\
143                 (elm2)->field.tqe_next->field.tqe_prev =                \
144                     &(elm2)->field.tqe_next;                            \
145         else                                                            \
146                 (head)->tqh_last = &(elm2)->field.tqe_next;             \
147         (elm2)->field.tqe_prev = (elm)->field.tqe_prev;                 \
148         *(elm2)->field.tqe_prev = (elm2);                               \
149 } while (/*CONSTCOND*/0)
150 #endif /* !TAILQ_REPLACE */
151 
152 #ifndef TAILQ_FOREACH_SAFE
153 #define	TAILQ_FOREACH_SAFE(var, head, field, next)			\
154 	for ((var) = TAILQ_FIRST(head);					\
155 	    (var) != TAILQ_END(head) &&					\
156 	    ((next) = TAILQ_NEXT(var, field), 1); (var) = (next))
157 
158 #define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev)	\
159 	for ((var) = TAILQ_LAST((head), headname);			\
160 	    (var) != TAILQ_END(head) &&					\
161 	    ((prev) = TAILQ_PREV((var), headname, field), 1); (var) = (prev))
162 #endif /* !TAILQ_FOREACH_SAFE */
163 
164 #ifndef TAILQ_CONCAT
165 #define	TAILQ_CONCAT(head1, head2, field) do {				\
166 	if (!TAILQ_EMPTY(head2)) {					\
167 		*(head1)->tqh_last = (head2)->tqh_first;		\
168 		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
169 		(head1)->tqh_last = (head2)->tqh_last;			\
170 		TAILQ_INIT((head2));					\
171 	}								\
172 } while (/*CONSTCOND*/0)
173 #endif /* !TAILQ_CONCAT */
174 
175 #endif	/* !COMAPT_QUEUE_H */
176