Le Tue, Dec 29, 2020 at 12:36:22PM -0700, Todd C. Miller a écrit :
> On Sat, 26 Dec 2020 15:07:36 -0700, "Theo de Raadt" wrote:
>
> > Well in that case this should still be a multistep process.
> >
> > Add STAILQ
> >
> > Convert things, including everything in ports
> >
> > No diff should change a line of code before it's time
>
> That looks something like this. I used the FreeBSD macros which
> incorporate STAILQ_NEXT and STAILQ_FIRST but I can inline things
> if someone has a strong opinion on this.
>
> If this is OK I will send an update to the man page.
>
Sometime STAILQ_FIRST is used, sometime it is (head)->stqh_first.
Apart from that, OK denis@
> - todd
>
> Index: sys/sys/queue.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/queue.h,v
> retrieving revision 1.45
> diff -u -p -u -r1.45 queue.h
> --- sys/sys/queue.h 12 Jul 2018 14:22:54 -0000 1.45
> +++ sys/sys/queue.h 29 Dec 2020 17:32:31 -0000
> @@ -533,4 +533,101 @@ struct {
> \
> } \
> } while (0)
>
> +/*
> + * Singly-linked Tail queue declarations.
> + */
> +#define STAILQ_HEAD(name, type)
> \
> +struct name {
> \
> + struct type *stqh_first; /* first element */ \
> + struct type **stqh_last; /* addr of last next element */ \
> +}
> +
> +#define STAILQ_HEAD_INITIALIZER(head)
> \
> + { NULL, &(head).stqh_first }
> +
> +#define STAILQ_ENTRY(type)
> \
> +struct { \
> + struct type *stqe_next; /* next element */ \
> +}
> +
> +/*
> + * Singly-linked Tail queue access methods.
> + */
> +#define STAILQ_FIRST(head) ((head)->stqh_first)
> +#define STAILQ_END(head) NULL
> +#define STAILQ_EMPTY(head) (STAILQ_FIRST(head) == STAILQ_END(head))
> +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
> +
> +#define STAILQ_FOREACH(var, head, field) \
> + for ((var) = STAILQ_FIRST(head); \
> + (var) != STAILQ_END(head); \
> + (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))
> +
> +/*
> + * Singly-linked Tail queue functions.
> + */
> +#define STAILQ_INIT(head) do {
> \
> + (head)->stqh_first = NULL; \
> + (head)->stqh_last = &(head)->stqh_first; \
> +} while (0)
> +
> +#define STAILQ_INSERT_HEAD(head, elm, field) do {
> \
> + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
> + (head)->stqh_last = &STAILQ_NEXT((elm), field); \
> + STAILQ_FIRST((head)) = (elm); \
> +} while (0)
> +
> +#define STAILQ_INSERT_TAIL(head, elm, field) do {
> \
> + STAILQ_NEXT((elm), field) = NULL; \
> + *(head)->stqh_last = (elm); \
> + (head)->stqh_last = &STAILQ_NEXT((elm), field); \
> +} while (0)
> +
> +#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {
> \
> + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((elm), field)) == NULL)\
> + (head)->stqh_last = &STAILQ_NEXT((elm), field); \
> + STAILQ_NEXT((elm), field) = (elm); \
> +} while (0)
> +
> +#define STAILQ_REMOVE_HEAD(head, field) do { \
> + if ((STAILQ_FIRST((head)) = \
> + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
> + (head)->stqh_last = &STAILQ_FIRST((head)); \
> +} while (0)
> +
> +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
> + if ((STAILQ_NEXT(elm, field) = \
> + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
> + (head)->stqh_last = &STAILQ_NEXT((elm), field); \
> +} while (0)
> +
> +#define STAILQ_REMOVE(head, elm, type, field) do {
> \
> + if ((head)->stqh_first == (elm)) { \
> + STAILQ_REMOVE_HEAD((head), field); \
> + } else { \
> + struct type *curelm = (head)->stqh_first; \
> + while (STAILQ_NEXT(curelm, field) != (elm)) \
> + curelm = STAILQ_NEXT(curelm, field); \
> + STAILQ_REMOVE_AFTER(head, curelm, field); \
> + } \
> +} while (0)
> +
> +#define STAILQ_CONCAT(head1, head2) do {
> \
> + if (!STAILQ_EMPTY((head2))) { \
> + *(head1)->stqh_last = (head2)->stqh_first; \
> + (head1)->stqh_last = (head2)->stqh_last; \
> + STAILQ_INIT((head2)); \
> + } \
> +} while (0)
> +
> +#define STAILQ_LAST(head, type, field)
> \
> + (STAILQ_EMPTY((head)) ? NULL : \
> + ((struct type *)(void *) \
> + ((char *)((head)->stqh_last) - offsetof(struct type, field))))
> +
> #endif /* !_SYS_QUEUE_H_ */