1 #pragma once
2 
3 /* Implementation from BSD headers*/
4 #define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
5 #define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
6 #define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
7 
8 #define	STAILQ_FIRST(head)	((head)->stqh_first)
9 
10 #define	STAILQ_HEAD(name, type)						\
11 struct name {								\
12 	struct type *stqh_first;/* first element */			\
13 	struct type **stqh_last;/* addr of last next element */		\
14 }
15 
16 #define	STAILQ_ENTRY(type)						\
17 struct {								\
18 	struct type *stqe_next;	/* next element */			\
19 }
20 
21 #define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
22 	STAILQ_NEXT((elm), field) = NULL;				\
23 	*(head)->stqh_last = (elm);					\
24 	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
25 } while (0)
26 
27 #define	STAILQ_INIT(head) do {						\
28 	STAILQ_FIRST((head)) = NULL;					\
29 	(head)->stqh_last = &STAILQ_FIRST((head));			\
30 } while (0)
31 
32 #define	STAILQ_FOREACH(var, head, field)				\
33 	for((var) = STAILQ_FIRST((head));				\
34 	   (var);							\
35 	   (var) = STAILQ_NEXT((var), field))
36 
37 #define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
38 	for ((var) = STAILQ_FIRST((head));				\
39 	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
40 	    (var) = (tvar))
41 
42 #define STAILQ_REMOVE_AFTER(head, elm, field) do {			\
43 	if ((STAILQ_NEXT(elm, field) =					\
44 	     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)	\
45 		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
46 } while (0)
47 
48 #define	STAILQ_REMOVE_HEAD(head, field) do {				\
49 	if ((STAILQ_FIRST((head)) =					\
50 	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
51 		(head)->stqh_last = &STAILQ_FIRST((head));		\
52 } while (0)
53 
54 #define	STAILQ_REMOVE(head, elm, type, field) do {			\
55 	QMD_SAVELINK(oldnext, (elm)->field.stqe_next);			\
56 	if (STAILQ_FIRST((head)) == (elm)) {				\
57 		STAILQ_REMOVE_HEAD((head), field);			\
58 	}								\
59 	else {								\
60 		struct type *curelm = STAILQ_FIRST((head));		\
61 		while (STAILQ_NEXT(curelm, field) != (elm))		\
62 			curelm = STAILQ_NEXT(curelm, field);		\
63 		STAILQ_REMOVE_AFTER(head, curelm, field);		\
64 	}								\
65 	TRASHIT(*oldnext);						\
66 } while (0)
67