diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
commit | 399644e47874bff147afb19c89228901ac39340e (patch) | |
tree | 1c4c0b733f4c16b5783b41bebb19194a9ef62ad1 /man3/stailq.3 | |
parent | Initial commit. (diff) | |
download | manpages-399644e47874bff147afb19c89228901ac39340e.tar.xz manpages-399644e47874bff147afb19c89228901ac39340e.zip |
Adding upstream version 6.05.01.upstream/6.05.01
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | man3/stailq.3 | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/man3/stailq.3 b/man3/stailq.3 new file mode 100644 index 0000000..2fca240 --- /dev/null +++ b/man3/stailq.3 @@ -0,0 +1,377 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" and Copyright (c) 2020 by Alejandro Colomar <alx@kernel.org> +.\" +.\" SPDX-License-Identifier: BSD-3-Clause +.\" +.\" +.TH STAILQ 3 2023-05-03 "Linux man-pages 6.05.01" +.SH NAME +.\"SIMPLEQ_CONCAT, +SIMPLEQ_EMPTY, +SIMPLEQ_ENTRY, +SIMPLEQ_FIRST, +SIMPLEQ_FOREACH, +.\"SIMPLEQ_FOREACH_FROM, +.\"SIMPLEQ_FOREACH_FROM_SAFE, +.\"SIMPLEQ_FOREACH_SAFE, +SIMPLEQ_HEAD, +SIMPLEQ_HEAD_INITIALIZER, +SIMPLEQ_INIT, +SIMPLEQ_INSERT_AFTER, +SIMPLEQ_INSERT_HEAD, +SIMPLEQ_INSERT_TAIL, +.\"SIMPLEQ_LAST, +SIMPLEQ_NEXT, +SIMPLEQ_REMOVE, +.\"SIMPLEQ_REMOVE_AFTER, +SIMPLEQ_REMOVE_HEAD, +.\"SIMPLEQ_SWAP, +STAILQ_CONCAT, +STAILQ_EMPTY, +STAILQ_ENTRY, +STAILQ_FIRST, +STAILQ_FOREACH, +.\"STAILQ_FOREACH_FROM, +.\"STAILQ_FOREACH_FROM_SAFE, +.\"STAILQ_FOREACH_SAFE, +STAILQ_HEAD, +STAILQ_HEAD_INITIALIZER, +STAILQ_INIT, +STAILQ_INSERT_AFTER, +STAILQ_INSERT_HEAD, +STAILQ_INSERT_TAIL, +.\"STAILQ_LAST, +STAILQ_NEXT, +STAILQ_REMOVE, +.\"STAILQ_REMOVE_AFTER, +STAILQ_REMOVE_HEAD, +.\"STAILQ_SWAP +\- implementation of a singly linked tail queue +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include <sys/queue.h> +.PP +.B STAILQ_ENTRY(TYPE); +.PP +.B STAILQ_HEAD(HEADNAME, TYPE); +.BI "STAILQ_HEAD STAILQ_HEAD_INITIALIZER(STAILQ_HEAD " head ); +.BI "void STAILQ_INIT(STAILQ_HEAD *" head ); +.PP +.BI "int STAILQ_EMPTY(STAILQ_HEAD *" head ); +.PP +.BI "void STAILQ_INSERT_HEAD(STAILQ_HEAD *" head , +.BI " struct TYPE *" elm ", STAILQ_ENTRY " NAME ); +.BI "void STAILQ_INSERT_TAIL(STAILQ_HEAD *" head , +.BI " struct TYPE *" elm ", STAILQ_ENTRY " NAME ); +.BI "void STAILQ_INSERT_AFTER(STAILQ_HEAD *" head ", struct TYPE *" listelm , +.BI " struct TYPE *" elm ", STAILQ_ENTRY " NAME ); +.PP +.BI "struct TYPE *STAILQ_FIRST(STAILQ_HEAD *" head ); +.\" .BI "struct TYPE *STAILQ_LAST(STAILQ_HEAD *" head ", struct TYPE *" elm , +.\" .BI " STAILQ_ENTRY " NAME ); +.BI "struct TYPE *STAILQ_NEXT(struct TYPE *" elm ", STAILQ_ENTRY " NAME ); +.PP +.BI "STAILQ_FOREACH(struct TYPE *" var ", STAILQ_HEAD *" head ", STAILQ_ENTRY " NAME ); +.\" .BI "STAILQ_FOREACH_FROM(struct TYPE *" var ", STAILQ_HEAD *" head , +.\" .BI " STAILQ_ENTRY " NAME ); +.\" .PP +.\" .BI "STAILQ_FOREACH_SAFE(struct TYPE *" var ", STAILQ_HEAD *" head , +.\" .BI " STAILQ_ENTRY " NAME ", struct TYPE *" temp_var ); +.\" .BI "STAILQ_FOREACH_FROM_SAFE(struct TYPE *" var ", STAILQ_HEAD *" head , +.\" .BI " STAILQ_ENTRY " NAME ", struct TYPE *" temp_var ); +.PP +.BI "void STAILQ_REMOVE(STAILQ_HEAD *" head ", struct TYPE *" elm ", TYPE," +.BI " STAILQ_ENTRY " NAME ); +.BI "void STAILQ_REMOVE_HEAD(STAILQ_HEAD *" head , +.BI " STAILQ_ENTRY " NAME ); +.\" .BI "void STAILQ_REMOVE_AFTER(STAILQ_HEAD *" head ", struct TYPE *" elm , +.\" .BI " STAILQ_ENTRY " NAME ); +.PP +.BI "void STAILQ_CONCAT(STAILQ_HEAD *" head1 ", STAILQ_HEAD *" head2 ); +.\" .BI "void STAILQ_SWAP(STAILQ_HEAD *" head1 ", STAILQ_HEAD *" head2 , +.\" .BI " STAILQ_ENTRY " NAME ); +.fi +.IR Note : +Identical macros prefixed with SIMPLEQ instead of STAILQ exist; see NOTES. +.SH DESCRIPTION +These macros define and operate on singly linked tail queues. +.PP +In the macro definitions, +.I TYPE +is the name of a user-defined structure, +that must contain a field of type +.IR STAILQ_ENTRY , +named +.IR NAME . +The argument +.I HEADNAME +is the name of a user-defined structure that must be declared +using the macro +.BR STAILQ_HEAD (). +.SS Creation +A singly linked tail queue is headed by a structure defined by the +.BR STAILQ_HEAD () +macro. +This structure contains a pair of pointers, +one to the first element in the tail queue and the other to +the last element in the tail queue. +The elements are singly linked for minimum space and pointer +manipulation overhead at the expense of O(n) removal for arbitrary elements. +New elements can be added to the tail queue after an existing element, +at the head of the tail queue, or at the end of the tail queue. +A +.I STAILQ_HEAD +structure is declared as follows: +.PP +.in +4 +.EX +STAILQ_HEAD(HEADNAME, TYPE) head; +.EE +.in +.PP +where +.I struct HEADNAME +is the structure to be defined, and +.I struct TYPE +is the type of the elements to be linked into the tail queue. +A pointer to the head of the tail queue can later be declared as: +.PP +.in +4 +.EX +struct HEADNAME *headp; +.EE +.in +.PP +(The names +.I head +and +.I headp +are user selectable.) +.PP +.BR STAILQ_ENTRY () +declares a structure that connects the elements in the tail queue. +.PP +.BR STAILQ_HEAD_INITIALIZER () +evaluates to an initializer for the tail queue +.IR head . +.PP +.BR STAILQ_INIT () +initializes the tail queue referenced by +.IR head . +.PP +.BR STAILQ_EMPTY () +evaluates to true if there are no items on the tail queue. +.SS Insertion +.BR STAILQ_INSERT_HEAD () +inserts the new element +.I elm +at the head of the tail queue. +.PP +.BR STAILQ_INSERT_TAIL () +inserts the new element +.I elm +at the end of the tail queue. +.PP +.BR STAILQ_INSERT_AFTER () +inserts the new element +.I elm +after the element +.IR listelm . +.SS Traversal +.BR STAILQ_FIRST () +returns the first item on the tail queue or NULL if the tail queue is empty. +.\" .PP +.\" .BR STAILQ_LAST () +.\" returns the last item on the tail queue. +.\" If the tail queue is empty the return value is NULL . +.PP +.BR STAILQ_NEXT () +returns the next item on the tail queue, or NULL this item is the last. +.PP +.BR STAILQ_FOREACH () +traverses the tail queue referenced by +.I head +in the forward direction, +assigning each element in turn to +.IR var . +.\" .PP +.\" .BR STAILQ_FOREACH_FROM () +.\" behaves identically to +.\" .BR STAILQ_FOREACH () +.\" when +.\" .I var +.\" is NULL, else it treats +.\" .I var +.\" as a previously found STAILQ element and begins the loop at +.\" .I var +.\" instead of the first element in the STAILQ referenced by +.\" .IR head . +.\" .PP +.\" .BR STAILQ_FOREACH_SAFE () +.\" traverses the tail queue referenced by +.\" .I head +.\" in the forward direction, assigning each element +.\" in turn to +.\" .IR var . +.\" However, unlike +.\" .BR STAILQ_FOREACH () +.\" here it is permitted to both remove +.\" .I var +.\" as well as free it from within the loop safely without interfering with the +.\" traversal. +.\" .PP +.\" .BR STAILQ_FOREACH_FROM_SAFE () +.\" behaves identically to +.\" .BR STAILQ_FOREACH_SAFE () +.\" when +.\" .I var +.\" is NULL, else it treats +.\" .I var +.\" as a previously found STAILQ element and begins the loop at +.\" .I var +.\" instead of the first element in the STAILQ referenced by +.\" .IR head . +.SS Removal +.BR STAILQ_REMOVE () +removes the element +.I elm +from the tail queue. +.PP +.BR STAILQ_REMOVE_HEAD () +removes the element at the head of the tail queue. +For optimum efficiency, +elements being removed from the head of the tail queue should +use this macro explicitly rather than the generic +.BR STAILQ_REMOVE () +macro. +.\" .PP +.\" .BR STAILQ_REMOVE_AFTER () +.\" removes the element after +.\" .I elm +.\" from the tail queue. +.\" Unlike +.\" .BR STAILQ_REMOVE (), +.\" this macro does not traverse the entire tail queue. +.SS Other features +.BR STAILQ_CONCAT () +concatenates the tail queue headed by +.I head2 +onto the end of the one headed by +.I head1 +removing all entries from the former. +.\" .PP +.\" .BR STAILQ_SWAP () +.\" swaps the contents of +.\" .I head1 +.\" and +.\" .IR head2 . +.SH RETURN VALUE +.BR STAILQ_EMPTY () +returns nonzero if the queue is empty, +and zero if the queue contains at least one entry. +.PP +.BR STAILQ_FIRST (), +and +.BR STAILQ_NEXT () +return a pointer to the first or next +.I TYPE +structure, respectively. +.PP +.BR STAILQ_HEAD_INITIALIZER () +returns an initializer that can be assigned to the queue +.IR head . +.SH VERSIONS +Some BSDs provide SIMPLEQ instead of STAILQ. +They are identical, but for historical reasons +they were named differently on different BSDs. +STAILQ originated on FreeBSD, and SIMPLEQ originated on NetBSD. +For compatibility reasons, some systems provide both sets of macros. +glibc provides both STAILQ and SIMPLEQ, +which are identical except for a missing SIMPLEQ equivalent to +.BR STAILQ_CONCAT (). +.SH BUGS +.BR STAILQ_FOREACH () +doesn't allow +.I var +to be removed or freed within the loop, +as it would interfere with the traversal. +.BR STAILQ_FOREACH_SAFE (), +which is present on the BSDs but is not present in glibc, +fixes this limitation by allowing +.I var +to safely be removed from the list and freed from within the loop +without interfering with the traversal. +.SH STANDARDS +BSD. +.SH HISTORY +4.4BSD. +.SH EXAMPLES +.\" SRC BEGIN (stailq.c) +.EX +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/queue.h> +\& +struct entry { + int data; + STAILQ_ENTRY(entry) entries; /* Singly linked tail queue */ +}; +\& +STAILQ_HEAD(stailhead, entry); +\& +int +main(void) +{ + struct entry *n1, *n2, *n3, *np; + struct stailhead head; /* Singly linked tail queue + head */ +\& + STAILQ_INIT(&head); /* Initialize the queue */ +\& + n1 = malloc(sizeof(struct entry)); /* Insert at the head */ + STAILQ_INSERT_HEAD(&head, n1, entries); +\& + n1 = malloc(sizeof(struct entry)); /* Insert at the tail */ + STAILQ_INSERT_TAIL(&head, n1, entries); +\& + n2 = malloc(sizeof(struct entry)); /* Insert after */ + STAILQ_INSERT_AFTER(&head, n1, n2, entries); +\& + STAILQ_REMOVE(&head, n2, entry, entries); /* Deletion */ + free(n2); +\& + n3 = STAILQ_FIRST(&head); + STAILQ_REMOVE_HEAD(&head, entries); /* Deletion from the head */ + free(n3); +\& + n1 = STAILQ_FIRST(&head); + n1\->data = 0; + for (unsigned int i = 1; i < 5; i++) { + n1 = malloc(sizeof(struct entry)); + STAILQ_INSERT_HEAD(&head, n1, entries); + n1\->data = i; + } + /* Forward traversal */ + STAILQ_FOREACH(np, &head, entries) + printf("%i\en", np\->data); + /* TailQ deletion */ + n1 = STAILQ_FIRST(&head); + while (n1 != NULL) { + n2 = STAILQ_NEXT(n1, entries); + free(n1); + n1 = n2; + } + STAILQ_INIT(&head); +\& + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.BR insque (3), +.BR queue (7) |