Home | History | Annotate | Line # | Download | only in asn1
      1 /*	$NetBSD: asn1_queue.h,v 1.2 2017/01/28 21:31:45 christos Exp $	*/
      2 
      3 /*	NetBSD: queue.h,v 1.38 2004/04/18 14:12:05 lukem Exp	*/
      4 /*	Id */
      5 
      6 /*
      7  * Copyright (c) 1991, 1993
      8  *	The Regents of the University of California.  All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  *
     34  *	@(#)queue.h	8.5 (Berkeley) 8/20/94
     35  */
     36 
     37 #ifndef	_ASN1_QUEUE_H_
     38 #define	_ASN1_QUEUE_H_
     39 
     40 /*
     41  * Tail queue definitions.
     42  */
     43 #define	ASN1_TAILQ_HEAD(name, type)					\
     44 struct name {								\
     45 	struct type *tqh_first;	/* first element */			\
     46 	struct type **tqh_last;	/* addr of last next element */		\
     47 }
     48 
     49 #define	ASN1_TAILQ_HEAD_INITIALIZER(head)				\
     50 	{ NULL, &(head).tqh_first }
     51 #define	ASN1_TAILQ_ENTRY(type)						\
     52 struct {								\
     53 	struct type *tqe_next;	/* next element */			\
     54 	struct type **tqe_prev;	/* address of previous next element */	\
     55 }
     56 
     57 /*
     58  * Tail queue functions.
     59  */
     60 #if defined(_KERNEL) && defined(QUEUEDEBUG)
     61 #define	QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field)		\
     62 	if ((head)->tqh_first &&					\
     63 	    (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)	\
     64 		panic("ASN1_TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
     65 #define	QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field)		\
     66 	if (*(head)->tqh_last != NULL)					\
     67 		panic("ASN1_TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
     68 #define	QUEUEDEBUG_ASN1_TAILQ_OP(elm, field)				\
     69 	if ((elm)->field.tqe_next &&					\
     70 	    (elm)->field.tqe_next->field.tqe_prev !=			\
     71 	    &(elm)->field.tqe_next)					\
     72 		panic("ASN1_TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
     73 	if (*(elm)->field.tqe_prev != (elm))				\
     74 		panic("ASN1_TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
     75 #define	QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field)		\
     76 	if ((elm)->field.tqe_next == NULL &&				\
     77 	    (head)->tqh_last != &(elm)->field.tqe_next)			\
     78 		panic("ASN1_TAILQ_PREREMOVE head %p elm %p %s:%d",	\
     79 		      (head), (elm), __FILE__, __LINE__);
     80 #define	QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field)			\
     81 	(elm)->field.tqe_next = (void *)1L;				\
     82 	(elm)->field.tqe_prev = (void *)1L;
     83 #else
     84 #define	QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field)
     85 #define	QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field)
     86 #define	QUEUEDEBUG_ASN1_TAILQ_OP(elm, field)
     87 #define	QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field)
     88 #define	QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field)
     89 #endif
     90 
     91 #define	ASN1_TAILQ_INIT(head) do {					\
     92 	(head)->tqh_first = NULL;					\
     93 	(head)->tqh_last = &(head)->tqh_first;				\
     94 } while (/*CONSTCOND*/0)
     95 
     96 #define	ASN1_TAILQ_INSERT_HEAD(head, elm, field) do {			\
     97 	QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD((head), (elm), field)		\
     98 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
     99 		(head)->tqh_first->field.tqe_prev =			\
    100 		    &(elm)->field.tqe_next;				\
    101 	else								\
    102 		(head)->tqh_last = &(elm)->field.tqe_next;		\
    103 	(head)->tqh_first = (elm);					\
    104 	(elm)->field.tqe_prev = &(head)->tqh_first;			\
    105 } while (/*CONSTCOND*/0)
    106 
    107 #define	ASN1_TAILQ_INSERT_TAIL(head, elm, field) do {			\
    108 	QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL((head), (elm), field)		\
    109 	(elm)->field.tqe_next = NULL;					\
    110 	(elm)->field.tqe_prev = (head)->tqh_last;			\
    111 	*(head)->tqh_last = (elm);					\
    112 	(head)->tqh_last = &(elm)->field.tqe_next;			\
    113 } while (/*CONSTCOND*/0)
    114 
    115 #define	ASN1_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
    116 	QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field)			\
    117 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
    118 		(elm)->field.tqe_next->field.tqe_prev = 		\
    119 		    &(elm)->field.tqe_next;				\
    120 	else								\
    121 		(head)->tqh_last = &(elm)->field.tqe_next;		\
    122 	(listelm)->field.tqe_next = (elm);				\
    123 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
    124 } while (/*CONSTCOND*/0)
    125 
    126 #define	ASN1_TAILQ_INSERT_BEFORE(listelm, elm, field) do {		\
    127 	QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field)			\
    128 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
    129 	(elm)->field.tqe_next = (listelm);				\
    130 	*(listelm)->field.tqe_prev = (elm);				\
    131 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
    132 } while (/*CONSTCOND*/0)
    133 
    134 #define	ASN1_TAILQ_REMOVE(head, elm, field) do {			\
    135 	QUEUEDEBUG_ASN1_TAILQ_PREREMOVE((head), (elm), field)		\
    136 	QUEUEDEBUG_ASN1_TAILQ_OP((elm), field)				\
    137 	if (((elm)->field.tqe_next) != NULL)				\
    138 		(elm)->field.tqe_next->field.tqe_prev = 		\
    139 		    (elm)->field.tqe_prev;				\
    140 	else								\
    141 		(head)->tqh_last = (elm)->field.tqe_prev;		\
    142 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
    143 	QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE((elm), field);			\
    144 } while (/*CONSTCOND*/0)
    145 
    146 #define	ASN1_TAILQ_FOREACH(var, head, field)				\
    147 	for ((var) = ((head)->tqh_first);				\
    148 		(var);							\
    149 		(var) = ((var)->field.tqe_next))
    150 
    151 #define	ASN1_TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
    152 	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
    153 		(var);							\
    154 		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
    155 
    156 /*
    157  * Tail queue access methods.
    158  */
    159 #define	ASN1_TAILQ_EMPTY(head)		((head)->tqh_first == NULL)
    160 #define	ASN1_TAILQ_FIRST(head)		((head)->tqh_first)
    161 #define	ASN1_TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
    162 
    163 #define	ASN1_TAILQ_LAST(head, headname) \
    164 	(*(((struct headname *)((head)->tqh_last))->tqh_last))
    165 #define	ASN1_TAILQ_PREV(elm, headname, field) \
    166 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
    167 
    168 
    169 #endif	/* !_ASN1_QUEUE_H_ */
    170