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));                        \
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to