summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-12-16 21:08:21 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-12-16 21:08:21 +0000
commit3a97292e159afb28cb76d16899c36d4c360a7752 (patch)
tree0cb560b2862be94458ca69f9c6b75f4d6f137e36
parent1797fd7b7a5f9823a70b63fa8b4ea907e8bacf08 (diff)
Add SLIST_FOREACH_PREVPTR and SLIST_REMOVE_NEXT. SLIST_FOREACH_PREVPTR
is like SLIST_FOREACH but it saves a pointer to the previous element. SLIST_REMOVE_NEXT will remove the element *after* the one passed in. SLIST_FOREACH_PREVPTR is from FreeBSD; SLIST_REMOVE_NEXT was suggested by canacar@; man page additions by yours truly. OK deraadt@ (grudgingly) and man page changes OK jmc@.
-rw-r--r--share/man/man3/queue.321
-rw-r--r--sys/sys/queue.h11
2 files changed, 30 insertions, 2 deletions
diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3
index b739e762944..b9d5832bb6b 100644
--- a/share/man/man3/queue.3
+++ b/share/man/man3/queue.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: queue.3,v 1.32 2003/12/05 21:55:29 millert Exp $
+.\" $OpenBSD: queue.3,v 1.33 2003/12/16 21:08:20 millert Exp $
.\" $NetBSD: queue.3,v 1.4 1995/07/03 00:25:36 mycroft Exp $
.\"
.\" Copyright (c) 1993 The Regents of the University of California.
@@ -42,10 +42,12 @@
.Nm SLIST_END ,
.Nm SLIST_EMPTY ,
.Nm SLIST_FOREACH ,
+.Nm SLIST_FOREACH_PREVPTR ,
.Nm SLIST_INIT ,
.Nm SLIST_INSERT_AFTER ,
.Nm SLIST_INSERT_HEAD ,
.Nm SLIST_REMOVE_HEAD ,
+.Nm SLIST_REMOVE_NEXT ,
.Nm SLIST_REMOVE ,
.Nm LIST_ENTRY ,
.Nm LIST_HEAD ,
@@ -124,6 +126,7 @@
.Ft "bool"
.Fn SLIST_EMPTY "SLIST_HEAD *head"
.Fn SLIST_FOREACH "VARNAME" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
+.Fn SLIST_FOREACH_PREVPTR "VARNAME" "VARNAMEP" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
.Ft void
.Fn SLIST_INIT "SLIST_HEAD *head"
.Ft void
@@ -133,6 +136,8 @@
.Ft void
.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
.Ft void
+.Fn SLIST_REMOVE_NEXT "SLIST_HEAD *head" "struct TYPE *elm" "SLIST_ENTRY NAME"
+.Ft void
.Fn SLIST_REMOVE "SLIST_HEAD *head" "struct TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
.Pp
.Fn LIST_ENTRY "TYPE"
@@ -443,6 +448,11 @@ macro removes the first element of the list pointed by
.Fa head .
.Pp
The
+.Fn SLIST_REMOVE_NEXT
+macro removes the list element immediately following
+.Fa elm .
+.Pp
+The
.Fn SLIST_REMOVE
macro removes the element
.Fa elm
@@ -466,6 +476,15 @@ SLIST_FOREACH(np, head, NAME)
.Ed
.Pp
The
+.Fn SLIST_FOREACH_PREVPTR
+macro is similar to
+.Fn SLIST_FOREACH
+except that it stores a pointer to the previous element in
+.Fa VARNAMEP .
+This provides access to the previous element while traversing the list,
+as one would have with a doubly-linked list.
+.Pp
+The
.Fn SLIST_EMPTY
macro should be used to check whether a simple list is empty.
.Sh LISTS
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 9b2b8dd5788..7d5fb83c455 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.h,v 1.23 2003/06/02 23:28:21 millert Exp $ */
+/* $OpenBSD: queue.h,v 1.24 2003/12/16 21:08:20 millert Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
@@ -111,6 +111,11 @@ struct { \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
+#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
+ for ((varp) = &SLIST_FIRST((head)); \
+ ((var) = *(varp)) != SLIST_END(head); \
+ (varp) = &SLIST_NEXT((var), field))
+
/*
* Singly-linked List functions.
*/
@@ -128,6 +133,10 @@ struct { \
(head)->slh_first = (elm); \
} while (0)
+#define SLIST_REMOVE_NEXT(head, elm, field) do { \
+ (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
+} while (0)
+
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)