mirror of
https://gitlab.freedesktop.org/libbsd/libbsd.git
synced 2025-01-24 10:59:29 +01:00
Sync queue(3) from FreeBSD
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=85147
This commit is contained in:
parent
3267114483
commit
c7e01e9884
@ -65,7 +65,7 @@
|
|||||||
* so that an arbitrary element can be removed without a need to
|
* so that an arbitrary element can be removed without a need to
|
||||||
* traverse the list. New elements can be added to the list before
|
* 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
|
* or after an existing element or at the head of the list. A list
|
||||||
* may only be traversed in the forward direction.
|
* may be traversed in either direction.
|
||||||
*
|
*
|
||||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
* 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
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
@ -85,12 +85,16 @@
|
|||||||
* _EMPTY + + + +
|
* _EMPTY + + + +
|
||||||
* _FIRST + + + +
|
* _FIRST + + + +
|
||||||
* _NEXT + + + +
|
* _NEXT + + + +
|
||||||
* _PREV - - - +
|
* _PREV - + - +
|
||||||
* _LAST - - + +
|
* _LAST - - + +
|
||||||
* _FOREACH + + + +
|
* _FOREACH + + + +
|
||||||
|
* _FOREACH_FROM + + + +
|
||||||
* _FOREACH_SAFE + + + +
|
* _FOREACH_SAFE + + + +
|
||||||
|
* _FOREACH_FROM_SAFE + + + +
|
||||||
* _FOREACH_REVERSE - - - +
|
* _FOREACH_REVERSE - - - +
|
||||||
|
* _FOREACH_REVERSE_FROM - - - +
|
||||||
* _FOREACH_REVERSE_SAFE - - - +
|
* _FOREACH_REVERSE_SAFE - - - +
|
||||||
|
* _FOREACH_REVERSE_FROM_SAFE - - - +
|
||||||
* _INSERT_HEAD + + + +
|
* _INSERT_HEAD + + + +
|
||||||
* _INSERT_BEFORE - + - +
|
* _INSERT_BEFORE - + - +
|
||||||
* _INSERT_AFTER + + + +
|
* _INSERT_AFTER + + + +
|
||||||
@ -99,19 +103,22 @@
|
|||||||
* _REMOVE_AFTER + - + -
|
* _REMOVE_AFTER + - + -
|
||||||
* _REMOVE_HEAD + - + -
|
* _REMOVE_HEAD + - + -
|
||||||
* _REMOVE + + + +
|
* _REMOVE + + + +
|
||||||
|
* _SWAP + + + +
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef QUEUE_MACRO_DEBUG
|
#ifdef QUEUE_MACRO_DEBUG
|
||||||
/* Store the last 2 places the queue element or head was altered */
|
/* Store the last 2 places the queue element or head was altered */
|
||||||
struct qm_trace {
|
struct qm_trace {
|
||||||
char * lastfile;
|
unsigned long lastline;
|
||||||
int lastline;
|
unsigned long prevline;
|
||||||
char * prevfile;
|
const char *lastfile;
|
||||||
int prevline;
|
const char *prevfile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TRACEBUF struct qm_trace trace;
|
#define TRACEBUF struct qm_trace trace;
|
||||||
|
#define TRACEBUF_INITIALIZER { __FILE__, __LINE__, NULL, 0 } ,
|
||||||
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
|
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
|
||||||
|
#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
|
||||||
|
|
||||||
#define QMD_TRACE_HEAD(head) do { \
|
#define QMD_TRACE_HEAD(head) do { \
|
||||||
(head)->trace.prevline = (head)->trace.lastline; \
|
(head)->trace.prevline = (head)->trace.lastline; \
|
||||||
@ -130,7 +137,9 @@ struct qm_trace {
|
|||||||
#else
|
#else
|
||||||
#define QMD_TRACE_ELEM(elem)
|
#define QMD_TRACE_ELEM(elem)
|
||||||
#define QMD_TRACE_HEAD(head)
|
#define QMD_TRACE_HEAD(head)
|
||||||
|
#define QMD_SAVELINK(name, link)
|
||||||
#define TRACEBUF
|
#define TRACEBUF
|
||||||
|
#define TRACEBUF_INITIALIZER
|
||||||
#define TRASHIT(x)
|
#define TRASHIT(x)
|
||||||
#endif /* QUEUE_MACRO_DEBUG */
|
#endif /* QUEUE_MACRO_DEBUG */
|
||||||
|
|
||||||
@ -162,11 +171,21 @@ struct { \
|
|||||||
(var); \
|
(var); \
|
||||||
(var) = SLIST_NEXT((var), field))
|
(var) = SLIST_NEXT((var), field))
|
||||||
|
|
||||||
|
#define SLIST_FOREACH_FROM(var, head, field) \
|
||||||
|
for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
|
||||||
|
(var); \
|
||||||
|
(var) = SLIST_NEXT((var), field))
|
||||||
|
|
||||||
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
|
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
for ((var) = SLIST_FIRST((head)); \
|
for ((var) = SLIST_FIRST((head)); \
|
||||||
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
|
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
|
||||||
(var) = (tvar))
|
(var) = (tvar))
|
||||||
|
|
||||||
|
#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
|
||||||
|
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
|
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
|
||||||
for ((varp) = &SLIST_FIRST((head)); \
|
for ((varp) = &SLIST_FIRST((head)); \
|
||||||
((var) = *(varp)) != NULL; \
|
((var) = *(varp)) != NULL; \
|
||||||
@ -189,6 +208,7 @@ struct { \
|
|||||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||||
|
|
||||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||||
|
QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
|
||||||
if (SLIST_FIRST((head)) == (elm)) { \
|
if (SLIST_FIRST((head)) == (elm)) { \
|
||||||
SLIST_REMOVE_HEAD((head), field); \
|
SLIST_REMOVE_HEAD((head), field); \
|
||||||
} \
|
} \
|
||||||
@ -198,7 +218,7 @@ struct { \
|
|||||||
curelm = SLIST_NEXT(curelm, field); \
|
curelm = SLIST_NEXT(curelm, field); \
|
||||||
SLIST_REMOVE_AFTER(curelm, field); \
|
SLIST_REMOVE_AFTER(curelm, field); \
|
||||||
} \
|
} \
|
||||||
TRASHIT((elm)->field.sle_next); \
|
TRASHIT(*oldnext); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SLIST_REMOVE_AFTER(elm, field) do { \
|
#define SLIST_REMOVE_AFTER(elm, field) do { \
|
||||||
@ -210,6 +230,12 @@ struct { \
|
|||||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_SWAP(head1, head2, type) do { \
|
||||||
|
struct type *swap_first = SLIST_FIRST(head1); \
|
||||||
|
SLIST_FIRST(head1) = SLIST_FIRST(head2); \
|
||||||
|
SLIST_FIRST(head2) = swap_first; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Singly-linked Tail queue declarations.
|
* Singly-linked Tail queue declarations.
|
||||||
*/
|
*/
|
||||||
@ -247,12 +273,21 @@ struct { \
|
|||||||
(var); \
|
(var); \
|
||||||
(var) = STAILQ_NEXT((var), field))
|
(var) = STAILQ_NEXT((var), field))
|
||||||
|
|
||||||
|
#define STAILQ_FOREACH_FROM(var, head, field) \
|
||||||
|
for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
|
||||||
|
(var); \
|
||||||
|
(var) = STAILQ_NEXT((var), field))
|
||||||
|
|
||||||
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
for ((var) = STAILQ_FIRST((head)); \
|
for ((var) = STAILQ_FIRST((head)); \
|
||||||
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
|
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
|
||||||
(var) = (tvar))
|
(var) = (tvar))
|
||||||
|
|
||||||
|
#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
|
||||||
|
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
#define STAILQ_INIT(head) do { \
|
#define STAILQ_INIT(head) do { \
|
||||||
STAILQ_FIRST((head)) = NULL; \
|
STAILQ_FIRST((head)) = NULL; \
|
||||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
@ -277,14 +312,13 @@ struct { \
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_LAST(head, type, field) \
|
#define STAILQ_LAST(head, type, field) \
|
||||||
(STAILQ_EMPTY((head)) ? \
|
(STAILQ_EMPTY((head)) ? NULL : \
|
||||||
NULL : \
|
__containerof((head)->stqh_last, struct type, field.stqe_next))
|
||||||
((struct type *)(void *) \
|
|
||||||
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
|
||||||
|
|
||||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||||
|
|
||||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||||
|
QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
|
||||||
if (STAILQ_FIRST((head)) == (elm)) { \
|
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||||
STAILQ_REMOVE_HEAD((head), field); \
|
STAILQ_REMOVE_HEAD((head), field); \
|
||||||
} \
|
} \
|
||||||
@ -294,13 +328,7 @@ struct { \
|
|||||||
curelm = STAILQ_NEXT(curelm, field); \
|
curelm = STAILQ_NEXT(curelm, field); \
|
||||||
STAILQ_REMOVE_AFTER(head, curelm, field); \
|
STAILQ_REMOVE_AFTER(head, curelm, field); \
|
||||||
} \
|
} \
|
||||||
TRASHIT((elm)->field.stqe_next); \
|
TRASHIT(*oldnext); \
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
|
||||||
if ((STAILQ_FIRST((head)) = \
|
|
||||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
|
||||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
|
#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
|
||||||
@ -309,6 +337,12 @@ struct { \
|
|||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||||
|
if ((STAILQ_FIRST((head)) = \
|
||||||
|
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||||
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_SWAP(head1, head2, type) do { \
|
#define STAILQ_SWAP(head1, head2, type) do { \
|
||||||
struct type *swap_first = STAILQ_FIRST(head1); \
|
struct type *swap_first = STAILQ_FIRST(head1); \
|
||||||
struct type **swap_last = (head1)->stqh_last; \
|
struct type **swap_last = (head1)->stqh_last; \
|
||||||
@ -378,11 +412,21 @@ struct { \
|
|||||||
(var); \
|
(var); \
|
||||||
(var) = LIST_NEXT((var), field))
|
(var) = LIST_NEXT((var), field))
|
||||||
|
|
||||||
|
#define LIST_FOREACH_FROM(var, head, field) \
|
||||||
|
for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
|
||||||
|
(var); \
|
||||||
|
(var) = LIST_NEXT((var), field))
|
||||||
|
|
||||||
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
for ((var) = LIST_FIRST((head)); \
|
for ((var) = LIST_FIRST((head)); \
|
||||||
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
||||||
(var) = (tvar))
|
(var) = (tvar))
|
||||||
|
|
||||||
|
#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
|
||||||
|
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
#define LIST_INIT(head) do { \
|
#define LIST_INIT(head) do { \
|
||||||
LIST_FIRST((head)) = NULL; \
|
LIST_FIRST((head)) = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -414,15 +458,21 @@ struct { \
|
|||||||
|
|
||||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||||
|
|
||||||
|
#define LIST_PREV(elm, head, type, field) \
|
||||||
|
((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
|
||||||
|
__containerof((elm)->field.le_prev, struct type, field.le_next))
|
||||||
|
|
||||||
#define LIST_REMOVE(elm, field) do { \
|
#define LIST_REMOVE(elm, field) do { \
|
||||||
|
QMD_SAVELINK(oldnext, (elm)->field.le_next); \
|
||||||
|
QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
|
||||||
QMD_LIST_CHECK_NEXT(elm, field); \
|
QMD_LIST_CHECK_NEXT(elm, field); \
|
||||||
QMD_LIST_CHECK_PREV(elm, field); \
|
QMD_LIST_CHECK_PREV(elm, field); \
|
||||||
if (LIST_NEXT((elm), field) != NULL) \
|
if (LIST_NEXT((elm), field) != NULL) \
|
||||||
LIST_NEXT((elm), field)->field.le_prev = \
|
LIST_NEXT((elm), field)->field.le_prev = \
|
||||||
(elm)->field.le_prev; \
|
(elm)->field.le_prev; \
|
||||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||||
TRASHIT((elm)->field.le_next); \
|
TRASHIT(*oldnext); \
|
||||||
TRASHIT((elm)->field.le_prev); \
|
TRASHIT(*oldprev); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LIST_SWAP(head1, head2, type, field) do { \
|
#define LIST_SWAP(head1, head2, type, field) do { \
|
||||||
@ -446,7 +496,7 @@ struct name { \
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||||
{ NULL, &(head).tqh_first }
|
{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
|
||||||
|
|
||||||
#define TAILQ_ENTRY(type) \
|
#define TAILQ_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
@ -509,21 +559,41 @@ struct { \
|
|||||||
(var); \
|
(var); \
|
||||||
(var) = TAILQ_NEXT((var), field))
|
(var) = TAILQ_NEXT((var), field))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_FROM(var, head, field) \
|
||||||
|
for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
|
||||||
|
(var); \
|
||||||
|
(var) = TAILQ_NEXT((var), field))
|
||||||
|
|
||||||
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
for ((var) = TAILQ_FIRST((head)); \
|
for ((var) = TAILQ_FIRST((head)); \
|
||||||
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
|
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
|
||||||
(var) = (tvar))
|
(var) = (tvar))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
|
||||||
|
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||||
for ((var) = TAILQ_LAST((head), headname); \
|
for ((var) = TAILQ_LAST((head), headname); \
|
||||||
(var); \
|
(var); \
|
||||||
(var) = TAILQ_PREV((var), headname, field))
|
(var) = TAILQ_PREV((var), headname, field))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
|
||||||
|
for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
|
||||||
|
(var); \
|
||||||
|
(var) = TAILQ_PREV((var), headname, field))
|
||||||
|
|
||||||
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
|
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
|
||||||
for ((var) = TAILQ_LAST((head), headname); \
|
for ((var) = TAILQ_LAST((head), headname); \
|
||||||
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
|
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
|
||||||
(var) = (tvar))
|
(var) = (tvar))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
|
||||||
|
for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
|
||||||
|
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
#define TAILQ_INIT(head) do { \
|
#define TAILQ_INIT(head) do { \
|
||||||
TAILQ_FIRST((head)) = NULL; \
|
TAILQ_FIRST((head)) = NULL; \
|
||||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||||
@ -587,6 +657,8 @@ struct { \
|
|||||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||||
|
|
||||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||||
|
QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
|
||||||
|
QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
|
||||||
QMD_TAILQ_CHECK_NEXT(elm, field); \
|
QMD_TAILQ_CHECK_NEXT(elm, field); \
|
||||||
QMD_TAILQ_CHECK_PREV(elm, field); \
|
QMD_TAILQ_CHECK_PREV(elm, field); \
|
||||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||||
@ -597,8 +669,8 @@ struct { \
|
|||||||
QMD_TRACE_HEAD(head); \
|
QMD_TRACE_HEAD(head); \
|
||||||
} \
|
} \
|
||||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||||
TRASHIT((elm)->field.tqe_next); \
|
TRASHIT(*oldnext); \
|
||||||
TRASHIT((elm)->field.tqe_prev); \
|
TRASHIT(*oldprev); \
|
||||||
QMD_TRACE_ELEM(&(elm)->field); \
|
QMD_TRACE_ELEM(&(elm)->field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
186
man/queue.3bsd
186
man/queue.3bsd
@ -9,7 +9,7 @@
|
|||||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
.\" notice, this list of conditions and the following disclaimer in the
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
.\" documentation and/or other materials provided with the distribution.
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
.\" 4. Neither the name of the University nor the names of its contributors
|
.\" 3. Neither the name of the University nor the names of its contributors
|
||||||
.\" may be used to endorse or promote products derived from this software
|
.\" may be used to endorse or promote products derived from this software
|
||||||
.\" without specific prior written permission.
|
.\" without specific prior written permission.
|
||||||
.\"
|
.\"
|
||||||
@ -28,15 +28,17 @@
|
|||||||
.\" @(#)queue.3 8.2 (Berkeley) 1/24/94
|
.\" @(#)queue.3 8.2 (Berkeley) 1/24/94
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd May 13, 2011
|
.Dd June 17, 2013
|
||||||
.Dt QUEUE 3bsd
|
.Dt QUEUE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm SLIST_EMPTY ,
|
.Nm SLIST_EMPTY ,
|
||||||
.Nm SLIST_ENTRY ,
|
.Nm SLIST_ENTRY ,
|
||||||
.Nm SLIST_FIRST ,
|
.Nm SLIST_FIRST ,
|
||||||
.Nm SLIST_FOREACH ,
|
.Nm SLIST_FOREACH ,
|
||||||
|
.Nm SLIST_FOREACH_FROM ,
|
||||||
.Nm SLIST_FOREACH_SAFE ,
|
.Nm SLIST_FOREACH_SAFE ,
|
||||||
|
.Nm SLIST_FOREACH_FROM_SAFE ,
|
||||||
.Nm SLIST_HEAD ,
|
.Nm SLIST_HEAD ,
|
||||||
.Nm SLIST_HEAD_INITIALIZER ,
|
.Nm SLIST_HEAD_INITIALIZER ,
|
||||||
.Nm SLIST_INIT ,
|
.Nm SLIST_INIT ,
|
||||||
@ -52,7 +54,9 @@
|
|||||||
.Nm STAILQ_ENTRY ,
|
.Nm STAILQ_ENTRY ,
|
||||||
.Nm STAILQ_FIRST ,
|
.Nm STAILQ_FIRST ,
|
||||||
.Nm STAILQ_FOREACH ,
|
.Nm STAILQ_FOREACH ,
|
||||||
|
.Nm STAILQ_FOREACH_FROM ,
|
||||||
.Nm STAILQ_FOREACH_SAFE ,
|
.Nm STAILQ_FOREACH_SAFE ,
|
||||||
|
.Nm STAILQ_FOREACH_FROM_SAFE ,
|
||||||
.Nm STAILQ_HEAD ,
|
.Nm STAILQ_HEAD ,
|
||||||
.Nm STAILQ_HEAD_INITIALIZER ,
|
.Nm STAILQ_HEAD_INITIALIZER ,
|
||||||
.Nm STAILQ_INIT ,
|
.Nm STAILQ_INIT ,
|
||||||
@ -69,7 +73,9 @@
|
|||||||
.Nm LIST_ENTRY ,
|
.Nm LIST_ENTRY ,
|
||||||
.Nm LIST_FIRST ,
|
.Nm LIST_FIRST ,
|
||||||
.Nm LIST_FOREACH ,
|
.Nm LIST_FOREACH ,
|
||||||
|
.Nm LIST_FOREACH_FROM ,
|
||||||
.Nm LIST_FOREACH_SAFE ,
|
.Nm LIST_FOREACH_SAFE ,
|
||||||
|
.Nm LIST_FOREACH_FROM_SAFE ,
|
||||||
.Nm LIST_HEAD ,
|
.Nm LIST_HEAD ,
|
||||||
.Nm LIST_HEAD_INITIALIZER ,
|
.Nm LIST_HEAD_INITIALIZER ,
|
||||||
.Nm LIST_INIT ,
|
.Nm LIST_INIT ,
|
||||||
@ -77,6 +83,7 @@
|
|||||||
.Nm LIST_INSERT_BEFORE ,
|
.Nm LIST_INSERT_BEFORE ,
|
||||||
.Nm LIST_INSERT_HEAD ,
|
.Nm LIST_INSERT_HEAD ,
|
||||||
.Nm LIST_NEXT ,
|
.Nm LIST_NEXT ,
|
||||||
|
.Nm LIST_PREV ,
|
||||||
.Nm LIST_REMOVE ,
|
.Nm LIST_REMOVE ,
|
||||||
.Nm LIST_SWAP ,
|
.Nm LIST_SWAP ,
|
||||||
.Nm TAILQ_CONCAT ,
|
.Nm TAILQ_CONCAT ,
|
||||||
@ -84,9 +91,13 @@
|
|||||||
.Nm TAILQ_ENTRY ,
|
.Nm TAILQ_ENTRY ,
|
||||||
.Nm TAILQ_FIRST ,
|
.Nm TAILQ_FIRST ,
|
||||||
.Nm TAILQ_FOREACH ,
|
.Nm TAILQ_FOREACH ,
|
||||||
|
.Nm TAILQ_FOREACH_FROM ,
|
||||||
.Nm TAILQ_FOREACH_SAFE ,
|
.Nm TAILQ_FOREACH_SAFE ,
|
||||||
|
.Nm TAILQ_FOREACH_FROM_SAFE ,
|
||||||
.Nm TAILQ_FOREACH_REVERSE ,
|
.Nm TAILQ_FOREACH_REVERSE ,
|
||||||
|
.Nm TAILQ_FOREACH_REVERSE_FROM ,
|
||||||
.Nm TAILQ_FOREACH_REVERSE_SAFE ,
|
.Nm TAILQ_FOREACH_REVERSE_SAFE ,
|
||||||
|
.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE ,
|
||||||
.Nm TAILQ_HEAD ,
|
.Nm TAILQ_HEAD ,
|
||||||
.Nm TAILQ_HEAD_INITIALIZER ,
|
.Nm TAILQ_HEAD_INITIALIZER ,
|
||||||
.Nm TAILQ_INIT ,
|
.Nm TAILQ_INIT ,
|
||||||
@ -108,7 +119,9 @@ lists and tail queues
|
|||||||
.Fn SLIST_ENTRY "TYPE"
|
.Fn SLIST_ENTRY "TYPE"
|
||||||
.Fn SLIST_FIRST "SLIST_HEAD *head"
|
.Fn SLIST_FIRST "SLIST_HEAD *head"
|
||||||
.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
|
.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
|
||||||
|
.Fn SLIST_FOREACH_FROM "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
|
||||||
.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
|
.Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
|
||||||
|
.Fn SLIST_FOREACH_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
|
||||||
.Fn SLIST_HEAD "HEADNAME" "TYPE"
|
.Fn SLIST_HEAD "HEADNAME" "TYPE"
|
||||||
.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
|
.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
|
||||||
.Fn SLIST_INIT "SLIST_HEAD *head"
|
.Fn SLIST_INIT "SLIST_HEAD *head"
|
||||||
@ -125,7 +138,9 @@ lists and tail queues
|
|||||||
.Fn STAILQ_ENTRY "TYPE"
|
.Fn STAILQ_ENTRY "TYPE"
|
||||||
.Fn STAILQ_FIRST "STAILQ_HEAD *head"
|
.Fn STAILQ_FIRST "STAILQ_HEAD *head"
|
||||||
.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
|
.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
|
||||||
|
.Fn STAILQ_FOREACH_FROM "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
|
||||||
.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
|
.Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||||
|
.Fn STAILQ_FOREACH_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||||
.Fn STAILQ_HEAD "HEADNAME" "TYPE"
|
.Fn STAILQ_HEAD "HEADNAME" "TYPE"
|
||||||
.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
|
.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
|
||||||
.Fn STAILQ_INIT "STAILQ_HEAD *head"
|
.Fn STAILQ_INIT "STAILQ_HEAD *head"
|
||||||
@ -143,7 +158,9 @@ lists and tail queues
|
|||||||
.Fn LIST_ENTRY "TYPE"
|
.Fn LIST_ENTRY "TYPE"
|
||||||
.Fn LIST_FIRST "LIST_HEAD *head"
|
.Fn LIST_FIRST "LIST_HEAD *head"
|
||||||
.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
|
.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
|
||||||
|
.Fn LIST_FOREACH_FROM "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
|
.Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
|
||||||
|
.Fn LIST_FOREACH_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
|
||||||
.Fn LIST_HEAD "HEADNAME" "TYPE"
|
.Fn LIST_HEAD "HEADNAME" "TYPE"
|
||||||
.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
|
.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
|
||||||
.Fn LIST_INIT "LIST_HEAD *head"
|
.Fn LIST_INIT "LIST_HEAD *head"
|
||||||
@ -151,6 +168,7 @@ lists and tail queues
|
|||||||
.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
|
.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
|
.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
|
.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
|
||||||
|
.Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
|
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
|
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
|
||||||
.\"
|
.\"
|
||||||
@ -159,9 +177,13 @@ lists and tail queues
|
|||||||
.Fn TAILQ_ENTRY "TYPE"
|
.Fn TAILQ_ENTRY "TYPE"
|
||||||
.Fn TAILQ_FIRST "TAILQ_HEAD *head"
|
.Fn TAILQ_FIRST "TAILQ_HEAD *head"
|
||||||
.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
|
.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
|
||||||
|
.Fn TAILQ_FOREACH_FROM "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
|
||||||
.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
.Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||||
|
.Fn TAILQ_FOREACH_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||||
.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
|
.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
|
||||||
|
.Fn TAILQ_FOREACH_REVERSE_FROM "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
|
||||||
.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
.Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||||
|
.Fn TAILQ_FOREACH_REVERSE_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||||
.Fn TAILQ_HEAD "HEADNAME" "TYPE"
|
.Fn TAILQ_HEAD "HEADNAME" "TYPE"
|
||||||
.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
|
.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
|
||||||
.Fn TAILQ_INIT "TAILQ_HEAD *head"
|
.Fn TAILQ_INIT "TAILQ_HEAD *head"
|
||||||
@ -244,8 +266,18 @@ Code size and execution time of operations (except for removal) is about
|
|||||||
twice that of the singly-linked data-structures.
|
twice that of the singly-linked data-structures.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Linked lists are the simplest of the doubly linked data structures and support
|
Linked lists are the simplest of the doubly linked data structures.
|
||||||
only the above functionality over singly-linked lists.
|
They add the following functionality over the above:
|
||||||
|
.Bl -enum -compact -offset indent
|
||||||
|
.It
|
||||||
|
They may be traversed backwards.
|
||||||
|
.El
|
||||||
|
However:
|
||||||
|
.Bl -enum -compact -offset indent
|
||||||
|
.It
|
||||||
|
To traverse backwards, an entry to begin the traversal and the list in
|
||||||
|
which it is contained must be specified.
|
||||||
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Tail queues add the following functionality:
|
Tail queues add the following functionality:
|
||||||
.Bl -enum -compact -offset indent
|
.Bl -enum -compact -offset indent
|
||||||
@ -349,6 +381,19 @@ turn to
|
|||||||
.Fa var .
|
.Fa var .
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm SLIST_FOREACH_FROM
|
||||||
|
behaves identically to
|
||||||
|
.Nm SLIST_FOREACH
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found SLIST element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the SLIST referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm SLIST_FOREACH_SAFE
|
.Nm SLIST_FOREACH_SAFE
|
||||||
traverses the list referenced by
|
traverses the list referenced by
|
||||||
.Fa head
|
.Fa head
|
||||||
@ -363,6 +408,19 @@ as well as free it from within the loop safely without interfering with the
|
|||||||
traversal.
|
traversal.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm SLIST_FOREACH_FROM_SAFE
|
||||||
|
behaves identically to
|
||||||
|
.Nm SLIST_FOREACH_SAFE
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found SLIST element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the SLIST referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm SLIST_INIT
|
.Nm SLIST_INIT
|
||||||
initializes the list referenced by
|
initializes the list referenced by
|
||||||
.Fa head .
|
.Fa head .
|
||||||
@ -388,7 +446,8 @@ The macro
|
|||||||
.Nm SLIST_REMOVE_AFTER
|
.Nm SLIST_REMOVE_AFTER
|
||||||
removes the element after
|
removes the element after
|
||||||
.Fa elm
|
.Fa elm
|
||||||
from the list. Unlike
|
from the list.
|
||||||
|
Unlike
|
||||||
.Fa SLIST_REMOVE ,
|
.Fa SLIST_REMOVE ,
|
||||||
this macro does not traverse the entire list.
|
this macro does not traverse the entire list.
|
||||||
.Pp
|
.Pp
|
||||||
@ -528,6 +587,19 @@ in turn to
|
|||||||
.Fa var .
|
.Fa var .
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm STAILQ_FOREACH_FROM
|
||||||
|
behaves identically to
|
||||||
|
.Nm STAILQ_FOREACH
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found STAILQ element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the STAILQ referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm STAILQ_FOREACH_SAFE
|
.Nm STAILQ_FOREACH_SAFE
|
||||||
traverses the tail queue referenced by
|
traverses the tail queue referenced by
|
||||||
.Fa head
|
.Fa head
|
||||||
@ -542,6 +614,19 @@ as well as free it from within the loop safely without interfering with the
|
|||||||
traversal.
|
traversal.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm STAILQ_FOREACH_FROM_SAFE
|
||||||
|
behaves identically to
|
||||||
|
.Nm STAILQ_FOREACH_SAFE
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found STAILQ element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the STAILQ referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm STAILQ_INIT
|
.Nm STAILQ_INIT
|
||||||
initializes the tail queue referenced by
|
initializes the tail queue referenced by
|
||||||
.Fa head .
|
.Fa head .
|
||||||
@ -579,7 +664,8 @@ The macro
|
|||||||
.Nm STAILQ_REMOVE_AFTER
|
.Nm STAILQ_REMOVE_AFTER
|
||||||
removes the element after
|
removes the element after
|
||||||
.Fa elm
|
.Fa elm
|
||||||
from the tail queue. Unlike
|
from the tail queue.
|
||||||
|
Unlike
|
||||||
.Fa STAILQ_REMOVE ,
|
.Fa STAILQ_REMOVE ,
|
||||||
this macro does not traverse the entire tail queue.
|
this macro does not traverse the entire tail queue.
|
||||||
.Pp
|
.Pp
|
||||||
@ -717,6 +803,19 @@ in the forward direction, assigning each element in turn to
|
|||||||
.Fa var .
|
.Fa var .
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm LIST_FOREACH_FROM
|
||||||
|
behaves identically to
|
||||||
|
.Nm LIST_FOREACH
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found LIST element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the LIST referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm LIST_FOREACH_SAFE
|
.Nm LIST_FOREACH_SAFE
|
||||||
traverses the list referenced by
|
traverses the list referenced by
|
||||||
.Fa head
|
.Fa head
|
||||||
@ -730,6 +829,19 @@ as well as free it from within the loop safely without interfering with the
|
|||||||
traversal.
|
traversal.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm LIST_FOREACH_FROM_SAFE
|
||||||
|
behaves identically to
|
||||||
|
.Nm LIST_FOREACH_SAFE
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found LIST element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the LIST referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm LIST_INIT
|
.Nm LIST_INIT
|
||||||
initializes the list referenced by
|
initializes the list referenced by
|
||||||
.Fa head .
|
.Fa head .
|
||||||
@ -759,6 +871,14 @@ The macro
|
|||||||
returns the next element in the list, or NULL if this is the last.
|
returns the next element in the list, or NULL if this is the last.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm LIST_PREV
|
||||||
|
returns the previous element in the list, or NULL if this is the first.
|
||||||
|
List
|
||||||
|
.Fa head
|
||||||
|
must contain element
|
||||||
|
.Fa elm .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm LIST_REMOVE
|
.Nm LIST_REMOVE
|
||||||
removes the element
|
removes the element
|
||||||
.Fa elm
|
.Fa elm
|
||||||
@ -894,12 +1014,38 @@ is set to
|
|||||||
if the loop completes normally, or if there were no elements.
|
if the loop completes normally, or if there were no elements.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm TAILQ_FOREACH_FROM
|
||||||
|
behaves identically to
|
||||||
|
.Nm TAILQ_FOREACH
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found TAILQ element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the TAILQ referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm TAILQ_FOREACH_REVERSE
|
.Nm TAILQ_FOREACH_REVERSE
|
||||||
traverses the tail queue referenced by
|
traverses the tail queue referenced by
|
||||||
.Fa head
|
.Fa head
|
||||||
in the reverse direction, assigning each element in turn to
|
in the reverse direction, assigning each element in turn to
|
||||||
.Fa var .
|
.Fa var .
|
||||||
.Pp
|
.Pp
|
||||||
|
The macro
|
||||||
|
.Nm TAILQ_FOREACH_REVERSE_FROM
|
||||||
|
behaves identically to
|
||||||
|
.Nm TAILQ_FOREACH_REVERSE
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found TAILQ element and begins the reverse loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the last element in the TAILQ referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
The macros
|
The macros
|
||||||
.Nm TAILQ_FOREACH_SAFE
|
.Nm TAILQ_FOREACH_SAFE
|
||||||
and
|
and
|
||||||
@ -919,6 +1065,32 @@ as well as free it from within the loop safely without interfering with the
|
|||||||
traversal.
|
traversal.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Nm TAILQ_FOREACH_FROM_SAFE
|
||||||
|
behaves identically to
|
||||||
|
.Nm TAILQ_FOREACH_SAFE
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found TAILQ element and begins the loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the first element in the TAILQ referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
|
.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE
|
||||||
|
behaves identically to
|
||||||
|
.Nm TAILQ_FOREACH_REVERSE_SAFE
|
||||||
|
when
|
||||||
|
.Fa var
|
||||||
|
is NULL, else it treats
|
||||||
|
.Fa var
|
||||||
|
as a previously found TAILQ element and begins the reverse loop at
|
||||||
|
.Fa var
|
||||||
|
instead of the last element in the TAILQ referenced by
|
||||||
|
.Fa head .
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm TAILQ_INIT
|
.Nm TAILQ_INIT
|
||||||
initializes the tail queue referenced by
|
initializes the tail queue referenced by
|
||||||
.Fa head .
|
.Fa head .
|
||||||
|
Loading…
x
Reference in New Issue
Block a user