Add new FOREACH_FROM variants of the queue(3) FOREACH macros which can
optionally start the traversal from a previously found element by passing the element in as "var". Passing a NULL "var" retains the same semantics as the regular FOREACH macros. Kudos to phk for suggesting the "FROM" suffix instead of my original proposal. Reviewed by: jhb (previous version), rpaulo MFC after: 1 week
This commit is contained in:
parent
937a200089
commit
7ecb40192e
@ -32,7 +32,7 @@
|
||||
.\" @(#)queue.3 8.2 (Berkeley) 1/24/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Sep 12, 2012
|
||||
.Dd June 17, 2013
|
||||
.Dt QUEUE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,7 +40,9 @@
|
||||
.Nm SLIST_ENTRY ,
|
||||
.Nm SLIST_FIRST ,
|
||||
.Nm SLIST_FOREACH ,
|
||||
.Nm SLIST_FOREACH_FROM ,
|
||||
.Nm SLIST_FOREACH_SAFE ,
|
||||
.Nm SLIST_FOREACH_FROM_SAFE ,
|
||||
.Nm SLIST_HEAD ,
|
||||
.Nm SLIST_HEAD_INITIALIZER ,
|
||||
.Nm SLIST_INIT ,
|
||||
@ -56,7 +58,9 @@
|
||||
.Nm STAILQ_ENTRY ,
|
||||
.Nm STAILQ_FIRST ,
|
||||
.Nm STAILQ_FOREACH ,
|
||||
.Nm STAILQ_FOREACH_FROM ,
|
||||
.Nm STAILQ_FOREACH_SAFE ,
|
||||
.Nm STAILQ_FOREACH_FROM_SAFE ,
|
||||
.Nm STAILQ_HEAD ,
|
||||
.Nm STAILQ_HEAD_INITIALIZER ,
|
||||
.Nm STAILQ_INIT ,
|
||||
@ -73,7 +77,9 @@
|
||||
.Nm LIST_ENTRY ,
|
||||
.Nm LIST_FIRST ,
|
||||
.Nm LIST_FOREACH ,
|
||||
.Nm LIST_FOREACH_FROM ,
|
||||
.Nm LIST_FOREACH_SAFE ,
|
||||
.Nm LIST_FOREACH_FROM_SAFE ,
|
||||
.Nm LIST_HEAD ,
|
||||
.Nm LIST_HEAD_INITIALIZER ,
|
||||
.Nm LIST_INIT ,
|
||||
@ -89,9 +95,13 @@
|
||||
.Nm TAILQ_ENTRY ,
|
||||
.Nm TAILQ_FIRST ,
|
||||
.Nm TAILQ_FOREACH ,
|
||||
.Nm TAILQ_FOREACH_FROM ,
|
||||
.Nm TAILQ_FOREACH_SAFE ,
|
||||
.Nm TAILQ_FOREACH_FROM_SAFE ,
|
||||
.Nm TAILQ_FOREACH_REVERSE ,
|
||||
.Nm TAILQ_FOREACH_REVERSE_FROM ,
|
||||
.Nm TAILQ_FOREACH_REVERSE_SAFE ,
|
||||
.Nm TAILQ_FOREACH_REVERSE_FROM_SAFE ,
|
||||
.Nm TAILQ_HEAD ,
|
||||
.Nm TAILQ_HEAD_INITIALIZER ,
|
||||
.Nm TAILQ_INIT ,
|
||||
@ -113,7 +123,9 @@ lists and tail queues
|
||||
.Fn SLIST_ENTRY "TYPE"
|
||||
.Fn SLIST_FIRST "SLIST_HEAD *head"
|
||||
.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_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
|
||||
.Fn SLIST_HEAD "HEADNAME" "TYPE"
|
||||
.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
|
||||
.Fn SLIST_INIT "SLIST_HEAD *head"
|
||||
@ -130,7 +142,9 @@ lists and tail queues
|
||||
.Fn STAILQ_ENTRY "TYPE"
|
||||
.Fn STAILQ_FIRST "STAILQ_HEAD *head"
|
||||
.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_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||
.Fn STAILQ_HEAD "HEADNAME" "TYPE"
|
||||
.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
|
||||
.Fn STAILQ_INIT "STAILQ_HEAD *head"
|
||||
@ -148,7 +162,9 @@ lists and tail queues
|
||||
.Fn LIST_ENTRY "TYPE"
|
||||
.Fn LIST_FIRST "LIST_HEAD *head"
|
||||
.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_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
|
||||
.Fn LIST_HEAD "HEADNAME" "TYPE"
|
||||
.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
|
||||
.Fn LIST_INIT "LIST_HEAD *head"
|
||||
@ -165,9 +181,13 @@ lists and tail queues
|
||||
.Fn TAILQ_ENTRY "TYPE"
|
||||
.Fn TAILQ_FIRST "TAILQ_HEAD *head"
|
||||
.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_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_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_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
|
||||
.Fn TAILQ_HEAD "HEADNAME" "TYPE"
|
||||
.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
|
||||
.Fn TAILQ_INIT "TAILQ_HEAD *head"
|
||||
@ -365,6 +385,19 @@ turn to
|
||||
.Fa var .
|
||||
.Pp
|
||||
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
|
||||
traverses the list referenced by
|
||||
.Fa head
|
||||
@ -379,6 +412,19 @@ as well as free it from within the loop safely without interfering with the
|
||||
traversal.
|
||||
.Pp
|
||||
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
|
||||
initializes the list referenced by
|
||||
.Fa head .
|
||||
@ -545,6 +591,19 @@ in turn to
|
||||
.Fa var .
|
||||
.Pp
|
||||
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
|
||||
traverses the tail queue referenced by
|
||||
.Fa head
|
||||
@ -559,6 +618,19 @@ as well as free it from within the loop safely without interfering with the
|
||||
traversal.
|
||||
.Pp
|
||||
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
|
||||
initializes the tail queue referenced by
|
||||
.Fa head .
|
||||
@ -735,6 +807,19 @@ in the forward direction, assigning each element in turn to
|
||||
.Fa var .
|
||||
.Pp
|
||||
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
|
||||
traverses the list referenced by
|
||||
.Fa head
|
||||
@ -748,6 +833,19 @@ as well as free it from within the loop safely without interfering with the
|
||||
traversal.
|
||||
.Pp
|
||||
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
|
||||
initializes the list referenced by
|
||||
.Fa head .
|
||||
@ -920,12 +1018,38 @@ is set to
|
||||
if the loop completes normally, or if there were no elements.
|
||||
.Pp
|
||||
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
|
||||
traverses the tail queue referenced by
|
||||
.Fa head
|
||||
in the reverse direction, assigning each element in turn to
|
||||
.Fa var .
|
||||
.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
|
||||
.Nm TAILQ_FOREACH_SAFE
|
||||
and
|
||||
@ -945,6 +1069,32 @@ as well as free it from within the loop safely without interfering with the
|
||||
traversal.
|
||||
.Pp
|
||||
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
|
||||
initializes the tail queue referenced by
|
||||
.Fa head .
|
||||
|
@ -88,9 +88,13 @@
|
||||
* _PREV - + - +
|
||||
* _LAST - - + +
|
||||
* _FOREACH + + + +
|
||||
* _FOREACH_FROM + + + +
|
||||
* _FOREACH_SAFE + + + +
|
||||
* _FOREACH_FROM_SAFE + + + +
|
||||
* _FOREACH_REVERSE - - - +
|
||||
* _FOREACH_REVERSE_FROM - - - +
|
||||
* _FOREACH_REVERSE_SAFE - - - +
|
||||
* _FOREACH_REVERSE_FROM_SAFE - - - +
|
||||
* _INSERT_HEAD + + + +
|
||||
* _INSERT_BEFORE - + - +
|
||||
* _INSERT_AFTER + + + +
|
||||
@ -167,11 +171,21 @@ struct { \
|
||||
(var); \
|
||||
(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) \
|
||||
for ((var) = SLIST_FIRST((head)); \
|
||||
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
|
||||
(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) \
|
||||
for ((varp) = &SLIST_FIRST((head)); \
|
||||
((var) = *(varp)) != NULL; \
|
||||
@ -259,12 +273,21 @@ struct { \
|
||||
(var); \
|
||||
(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) \
|
||||
for ((var) = STAILQ_FIRST((head)); \
|
||||
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
|
||||
(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 { \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
@ -389,11 +412,21 @@ struct { \
|
||||
(var); \
|
||||
(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) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
||||
(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 { \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
@ -526,21 +559,41 @@ struct { \
|
||||
(var); \
|
||||
(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) \
|
||||
for ((var) = TAILQ_FIRST((head)); \
|
||||
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
|
||||
(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) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var); \
|
||||
(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) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
|
||||
(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 { \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
|
Loading…
Reference in New Issue
Block a user