From be1e8086b11b1ecb3ca4b8e265e0850d447149d5 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Mon, 31 Jan 2022 21:23:20 +0100
Subject: [PATCH 1/2] <sys/queue.h>: Add some macros for mkimg(1).

---
 share/man/man3/Makefile |  12 +++-
 share/man/man3/queue.3  | 122 +++++++++++++++++++++++++++++++++++++++-
 sys/sys/queue.h         |  41 ++++++++++++++
 3 files changed, 172 insertions(+), 3 deletions(-)

diff --git a/share/man/man3/Makefile b/share/man/man3/Makefile
index f4f340feec..0ff714201e 100644
--- a/share/man/man3/Makefile
+++ b/share/man/man3/Makefile
@@ -15,6 +15,10 @@ MLINKS+=fpgetround.3 fpsetprec.3 fpgetround.3 fpgetprec.3
 
 MLINKS+=queue.3 LIST_EMPTY.3
 MLINKS+=queue.3 LIST_ENTRY.3
+MLINKS+=queue.3 LIST_FIRST.3
+MLINKS+=queue.3 LIST_FOREACH.3
+MLINKS+=queue.3 LIST_FOREACH_FROM.3
+MLINKS+=queue.3 LIST_FOREACH_FROM_MUTABLE.3
 MLINKS+=queue.3 LIST_FOREACH_MUTABLE.3
 MLINKS+=queue.3 LIST_HEAD.3
 MLINKS+=queue.3 LIST_HEAD_INITIALIZER.3
@@ -22,14 +26,14 @@ MLINKS+=queue.3 LIST_INIT.3
 MLINKS+=queue.3 LIST_INSERT_AFTER.3
 MLINKS+=queue.3 LIST_INSERT_BEFORE.3
 MLINKS+=queue.3 LIST_INSERT_HEAD.3
-MLINKS+=queue.3 LIST_FIRST.3
-MLINKS+=queue.3 LIST_FOREACH.3
 MLINKS+=queue.3 LIST_NEXT.3
 MLINKS+=queue.3 LIST_REMOVE.3
 MLINKS+=queue.3 SLIST_EMPTY.3
 MLINKS+=queue.3 SLIST_ENTRY.3
 MLINKS+=queue.3 SLIST_FIRST.3
 MLINKS+=queue.3 SLIST_FOREACH.3
+MLINKS+=queue.3 SLIST_FOREACH_FROM.3
+MLINKS+=queue.3 SLIST_FOREACH_FROM_MUTABLE.3
 MLINKS+=queue.3 SLIST_FOREACH_MUTABLE.3
 MLINKS+=queue.3 SLIST_FOREACH_PREVPTR.3
 MLINKS+=queue.3 SLIST_HEAD.3
@@ -46,6 +50,8 @@ MLINKS+=queue.3 STAILQ_EMPTY.3
 MLINKS+=queue.3 STAILQ_ENTRY.3
 MLINKS+=queue.3 STAILQ_FIRST.3
 MLINKS+=queue.3 STAILQ_FOREACH.3
+MLINKS+=queue.3 STAILQ_FOREACH_FROM.3
+MLINKS+=queue.3 STAILQ_FOREACH_FROM_MUTABLE.3
 MLINKS+=queue.3 STAILQ_FOREACH_MUTABLE.3
 MLINKS+=queue.3 STAILQ_HEAD.3
 MLINKS+=queue.3 STAILQ_HEAD_INITIALIZER.3
@@ -63,6 +69,8 @@ MLINKS+=queue.3 TAILQ_EMPTY.3
 MLINKS+=queue.3 TAILQ_ENTRY.3
 MLINKS+=queue.3 TAILQ_FIRST.3
 MLINKS+=queue.3 TAILQ_FOREACH.3
+MLINKS+=queue.3 TAILQ_FOREACH_FROM.3
+MLINKS+=queue.3 TAILQ_FOREACH_FROM_MUTABLE.3
 MLINKS+=queue.3 TAILQ_FOREACH_MUTABLE.3
 MLINKS+=queue.3 TAILQ_FOREACH_REVERSE.3
 MLINKS+=queue.3 TAILQ_FOREACH_REVERSE_MUTABLE.3
diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3
index b283ee370e..ae691aaac3 100644
--- a/share/man/man3/queue.3
+++ b/share/man/man3/queue.3
@@ -28,7 +28,7 @@
 .\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
 .\" $FreeBSD: src/share/man/man3/queue.3,v 1.46 2011/01/11 13:33:42 gavin Exp $
 .\"
-.Dd March 3, 2011
+.Dd January 30, 2022
 .Dt QUEUE 3
 .Os
 .Sh NAME
@@ -36,6 +36,8 @@
 .Nm SLIST_ENTRY ,
 .Nm SLIST_FIRST ,
 .Nm SLIST_FOREACH ,
+.Nm SLIST_FOREACH_FROM ,
+.Nm SLIST_FOREACH_FROM_MUTABLE ,
 .Nm SLIST_FOREACH_MUTABLE ,
 .Nm SLIST_FOREACH_PREVPTR ,
 .Nm SLIST_HEAD ,
@@ -52,6 +54,8 @@
 .Nm STAILQ_ENTRY ,
 .Nm STAILQ_FIRST ,
 .Nm STAILQ_FOREACH ,
+.Nm STAILQ_FOREACH_FROM ,
+.Nm STAILQ_FOREACH_FROM_MUTABLE ,
 .Nm STAILQ_FOREACH_MUTABLE ,
 .Nm STAILQ_HEAD ,
 .Nm STAILQ_HEAD_INITIALIZER ,
@@ -68,6 +72,8 @@
 .Nm LIST_ENTRY ,
 .Nm LIST_FIRST ,
 .Nm LIST_FOREACH ,
+.Nm LIST_FOREACH_FROM ,
+.Nm LIST_FOREACH_FROM_MUTABLE ,
 .Nm LIST_FOREACH_MUTABLE ,
 .Nm LIST_HEAD ,
 .Nm LIST_HEAD_INITIALIZER ,
@@ -83,6 +89,8 @@
 .Nm TAILQ_FIRST ,
 .Nm TAILQ_FOREACH ,
 .Nm TAILQ_FOREACH_MUTABLE ,
+.Nm TAILQ_FOREACH_FROM ,
+.Nm TAILQ_FOREACH_FROM_MUTABLE ,
 .Nm TAILQ_FOREACH_REVERSE ,
 .Nm TAILQ_FOREACH_REVERSE_MUTABLE ,
 .Nm TAILQ_HEAD ,
@@ -105,6 +113,8 @@ 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_FROM_MUTABLE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
 .Fn SLIST_FOREACH_MUTABLE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
 .Fn SLIST_FOREACH_PREVPTR "TYPE *var" "TYPE *varp" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
 .Fn SLIST_HEAD "HEADNAME" "TYPE"
@@ -122,6 +132,8 @@ 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_FROM_MUTABLE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
 .Fn STAILQ_FOREACH_MUTABLE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
 .Fn STAILQ_HEAD "HEADNAME" "TYPE"
 .Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
@@ -139,6 +151,8 @@ 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_FROM_MUTABLE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
 .Fn LIST_FOREACH_MUTABLE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
 .Fn LIST_HEAD "HEADNAME" "TYPE"
 .Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
@@ -154,6 +168,8 @@ 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_FROM_MUTABLE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
 .Fn TAILQ_FOREACH_MUTABLE "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_MUTABLE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
@@ -341,6 +357,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_MUTABLE
 traverses the list referenced by
 .Fa head
@@ -354,6 +383,19 @@ here it is permitted to both remove
 as well as free it from within the loop safely without interfering with the
 traversal.
 .Pp
+The macro
+.Nm SLIST_FOREACH_FROM_MUTABLE
+behaves identically to
+.Nm SLIST_FOREACH_MUTABLE
+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
 .Nm SLIST_FOREACH_PREVPTR
 macro is similar to
@@ -522,6 +564,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_MUTABLE
 traverses the tail queue referenced by
 .Fa head
@@ -536,6 +591,19 @@ as well as free it from within the loop safely without interfering with the
 traversal.
 .Pp
 The macro
+.Nm STAILQ_FOREACH_FROM_MUTABLE
+behaves identically to
+.Nm STAILQ_FOREACH_MUTABLE
+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 .
@@ -704,6 +772,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_MUTABLE
 traverses the list referenced by
 .Fa head
@@ -717,6 +798,19 @@ as well as free it from within the loop safely without interfering with the
 traversal.
 .Pp
 The macro
+.Nm LIST_FOREACH_FROM_MUTABLE
+behaves identically to
+.Nm LIST_FOREACH_MUTABLE
+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 .
@@ -874,6 +968,19 @@ 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
@@ -899,6 +1006,19 @@ as well as free it from within the loop safely without interfering with the
 traversal.
 .Pp
 The macro
+.Nm TAILQ_FOREACH_FROM_MUTABLE
+behaves identically to
+.Nm TAILQ_FOREACH_MUTABLE
+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_INIT
 initializes the tail queue referenced by
 .Fa head .
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index d13f26028f..dd8dc7429a 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -88,7 +88,9 @@
  * _PREV			-	-	-	+
  * _LAST			-	-	+	+
  * _FOREACH			+	+	+	+
+ * _FOREACH_FROM		+	+	+	+
  * _FOREACH_MUTABLE		+	+	+	+
+ * _FOREACH_FROM_MUTABLE	+	+	+	+
  * _FOREACH_REVERSE		-	-	-	+
  * _FOREACH_REVERSE_MUTABLE	-	-	-	+
  * _INSERT_HEAD			+	+	+	+
@@ -167,11 +169,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_MUTABLE(var, head, field, tvar)			\
 	for ((var) = SLIST_FIRST((head));				\
 	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
 	    (var) = (tvar))
 
+#define	SLIST_FOREACH_FROM_MUTABLE(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 +271,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_MUTABLE(var, head, field, tvar)			\
 	for ((var) = STAILQ_FIRST((head));				\
 	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
 	    (var) = (tvar))
 
+#define	STAILQ_FOREACH_FROM_MUTABLE(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));			\
@@ -386,6 +407,11 @@ struct {								\
 
 #define	LIST_FIRST(head)	((head)->lh_first)
 
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = LIST_FIRST((head));				\
+	    (var);							\
+	    (var) = LIST_NEXT((var), field))
+
 #define	LIST_FOREACH(var, head, field)					\
 	for ((var) = LIST_FIRST((head));				\
 	    (var);							\
@@ -396,6 +422,11 @@ struct {								\
 	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
 	    (var) = (tvar))
 
+#define	LIST_FOREACH_FROM_MUTABLE(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,11 +557,21 @@ 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_MUTABLE(var, head, field, tvar)			\
 	for ((var) = TAILQ_FIRST((head));				\
 	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
 	    (var) = (tvar))
 
+#define	TAILQ_FOREACH_FROM_MUTABLE(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);							\
-- 
2.32.0

