Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jun 2013 02:57:57 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r251887 - in head: share/man/man3 sys/sys
Message-ID:  <201306180257.r5I2vvoL054610@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: lstewart
Date: Tue Jun 18 02:57:56 2013
New Revision: 251887
URL: http://svnweb.freebsd.org/changeset/base/251887

Log:
  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

Modified:
  head/share/man/man3/queue.3
  head/sys/sys/queue.h

Modified: head/share/man/man3/queue.3
==============================================================================
--- head/share/man/man3/queue.3	Tue Jun 18 02:53:45 2013	(r251886)
+++ head/share/man/man3/queue.3	Tue Jun 18 02:57:56 2013	(r251887)
@@ -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 
 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 
 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
 .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 
 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 
 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 .

Modified: head/sys/sys/queue.h
==============================================================================
--- head/sys/sys/queue.h	Tue Jun 18 02:53:45 2013	(r251886)
+++ head/sys/sys/queue.h	Tue Jun 18 02:57:56 2013	(r251887)
@@ -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));			\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306180257.r5I2vvoL054610>