Skip to contentSkip to conversation

queue.3 overhaul

DISCUSSION Alejandro Colomar 3 participants 7 messages Oct 19, 2020 – Oct 23, 2020 Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#0 lore raw

Hi Michael,

I'm working on moving and fixing code from queue.3 to different pages.

I'd like to send you patches against a separate branch,
if you would create one, to ask you some questions from time to time, and maybe get suggestions.

Or maybe you could look at my branch on github
(https://github.com/alejandro-colomar/man-pages/commits/queue
(I may force push changes there sometimes)) (BTW, if you have a look there,
you can see how I'm moving&fixing the code from queue.3 to the other pages and maybe suggest a different way).

Or maybe I can just show you small pieces of code (no patches), like in this email.

Whatever works best for you.

What do you think about this SYNOPSIS for list.3?:

[[
.SH SYNOPSIS
.nf
.B #include <sys/queue.h>
.PP
.BI "int LIST_EMPTY(LIST_HEAD *" head ");"
.B " LIST_ENTRY(TYPE);"
.BI "LIST_ENTRY LIST_FIRST(LIST_HEAD *" head ");"
.BI " LIST_FOREACH(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ");"

.\".BI "           LIST_FOREACH_FROM(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ");"
.\".BI "           LIST_FOREACH_SAFE(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ", TYPE *" temp_var ");"
.\".BI "           LIST_FOREACH_FROM_SAFE(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ", TYPE *" temp_var ");"
.B  "           LIST_HEAD(HEADNAME, TYPE);"
.BI "LIST_HEAD  LIST_HEAD_INITIALIZER(LIST_HEAD " head ");"
.BI "void       LIST_INIT(LIST_HEAD *" head ");"
.BI "void       LIST_INSERT_AFTER(TYPE *" listelm ", TYPE *" elm ", LIST_ENTRY " NAME ");"
.BI "void       LIST_INSERT_BEFORE(TYPE *" listelm ", TYPE *" elm ", LIST_ENTRY " NAME ");"
.BI "void       LIST_INSERT_HEAD(LIST_HEAD *" head ", TYPE *" elm ", LIST_ENTRY " NAME ");"

.BI "LIST_ENTRY LIST_NEXT(TYPE *" elm ", LIST_ENTRY " NAME ");"
.\".BI "LIST_ENTRY LIST_PREV(TYPE *" elm ", LIST_HEAD *" head ", TYPE, LIST_ENTRY " NAME ");"
.BI "void LIST_REMOVE(TYPE *" elm ", LIST_ENTRY " NAME ");"
.\".BI "void IST_SWAP(LIST_HEAD *" head1 ", LIST_HEAD *" head2 ", TYPE, LIST_ENTRY " NAME ");"
.fi
]]

Things to note:
- The (many) spaces are there because otherwise it's unreadable (at least for me).

Also, I kept the copyright from the University of California and added myself: I consider this to be a modified redistribution but not a derived product; maybe I'm wrong in that (I'm not a lawyer :)).

Please tell me your thoughts about all of this :)

Kind regards,

Alex

#1 lore raw

Hi Alex,

Quoted 6 lines · Alejandro Colomar

Hi Michael,

I'm working on moving and fixing code from queue.3 to different pages.

Quoted 7 lines

I'd like to send you patches against a separate branch,
if you would create one, to ask you some questions from time to time, and maybe get suggestions.

Or maybe you could look at my branch on github
(https://github.com/alejandro-colomar/man-pages/commits/queue
(I may force push changes there sometimes))

I created a remote to remote to track your work. But you'll need to ping me from time to tell me to take a look. Also, I think mail to this list to discuss directions (as you are now doing) is great.

Quoted 3 lines

(BTW, if you have a look there,
you can see how I'm moving&fixing the code from queue.3 to the other pages and maybe suggest a different way).

This looks okay in principle.

Quoted 4 lines

Or maybe I can just show you small pieces of code (no patches), like in this email.

Whatever works best for you.

Both ;-)

Quoted 36 lines

What do you think about this SYNOPSIS for list.3?:

[[
.SH SYNOPSIS
.nf
.B #include <sys/queue.h>
.PP
.BI "int LIST_EMPTY(LIST_HEAD *" head ");"
.B " LIST_ENTRY(TYPE);"
.BI "LIST_ENTRY LIST_FIRST(LIST_HEAD *" head ");"
.BI " LIST_FOREACH(TYPE *" var ", LIST_HEAD *" head ",
LIST_ENTRY " NAME ");"
.\".BI " LIST_FOREACH_FROM(TYPE *" var ", LIST_HEAD *" head ",
LIST_ENTRY " NAME ");"
.\".BI " LIST_FOREACH_SAFE(TYPE *" var ", LIST_HEAD *" head ",
LIST_ENTRY " NAME ", TYPE *" temp_var ");"
.\".BI " LIST_FOREACH_FROM_SAFE(TYPE *" var ", LIST_HEAD *"
head ", LIST_ENTRY " NAME ", TYPE *" temp_var ");"

.B  "           LIST_HEAD(HEADNAME, TYPE);"
.BI "LIST_HEAD  LIST_HEAD_INITIALIZER(LIST_HEAD " head ");"
.BI "void       LIST_INIT(LIST_HEAD *" head ");"
.BI "void       LIST_INSERT_AFTER(TYPE *" listelm ", TYPE *" elm ",

LIST_ENTRY " NAME ");"
.BI "void LIST_INSERT_BEFORE(TYPE *" listelm ", TYPE *" elm ",
LIST_ENTRY " NAME ");"
.BI "void LIST_INSERT_HEAD(LIST_HEAD *" head ", TYPE *" elm ",
LIST_ENTRY " NAME ");"
.BI "LIST_ENTRY LIST_NEXT(TYPE *" elm ", LIST_ENTRY " NAME ");" .\".BI "LIST_ENTRY LIST_PREV(TYPE *" elm ", LIST_HEAD *" head ", TYPE, LIST_ENTRY " NAME ");"
.BI "void LIST_REMOVE(TYPE *" elm ", LIST_ENTRY " NAME ");"
.\".BI "void IST_SWAP(LIST_HEAD *" head1 ", LIST_HEAD *" head2 ",
TYPE, LIST_ENTRY " NAME ");"
.fi
]]

Quoted 3 lines

Things to note:
- The (many) spaces are there because otherwise it's unreadable (at least for me).

But, I find the indentation confusing actually. When I see pieces such as

       int        LIST_EMPTY(LIST_HEAD *head);
                  LIST_ENTRY(TYPE);

It visually looks to me as though the LIST_ENTRY piece is some extension of the LIST_EMPTY pest.

I think it's best not to do horizontal indentation, but instead just use of vertical separation (.PP). We can perhaps revisit this later, to see if we can come up with something better.

Quoted 3 lines

Also, I kept the copyright from the University of California and added
myself: I consider this to be a modified redistribution but not a derived product; maybe I'm wrong in that (I'm not a lawyer :)).

This seems okay to me.

Thanks.

Michael

Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
#2 lore raw

Hi Michael,

Quoted 25 lines · Michael Kerrisk (man-pages)

Hi Alex,

Quoted 6 lines · Alejandro Colomar

Hi Michael,

I'm working on moving and fixing code from queue.3 to different pages.

Quoted 7 lines

I'd like to send you patches against a separate branch,
if you would create one, to ask you some questions from time to time, and maybe get suggestions.

Or maybe you could look at my branch on github
(https://github.com/alejandro-colomar/man-pages/commits/queue
(I may force push changes there sometimes))

I created a remote to remote to track your work. But you'll need to ping me from time to tell me to take a look. Also, I think mail to this list to discuss directions (as you are now doing) is great.

Quoted 3 lines

(BTW, if you have a look there,
you can see how I'm moving&fixing the code from queue.3 to the other pages and maybe suggest a different way).

Quoted 8 lines

This looks okay in principle.

Quoted 4 lines

Or maybe I can just show you small pieces of code (no patches), like in this email.

Whatever works best for you.

Both ;-)

Fine :-)

Quoted 8 lines

But, I find the indentation confusing actually. When I see pieces such as

        int        LIST_EMPTY(LIST_HEAD *head);
                   LIST_ENTRY(TYPE);

It visually looks to me as though the LIST_ENTRY piece is some extension of the LIST_EMPTY pest.

Agreed.

Quoted 4 lines

I think it's best not to do horizontal indentation, but instead just use of vertical separation (.PP). We can perhaps revisit this later, to see if we can come up with something better.

Okay, I changed it to use vertical separation (as the original one did).
Now the output is the following (I think the SYNOPSIS already looks good, and I'll move to the DESCRIPTION):

[[
LIST(3) Linux Programmer's Manual LIST(3)

NAME
LIST_EMPTY, LIST_ENTRY, LIST_FIRST, LIST_FOREACH,
LIST_HEAD,
LIST_HEAD_INITIALIZER, LIST_INIT, LIST_INSERT_AFTER,
LIST_INSERT_BE-
FORE, LIST_INSERT_HEAD, LIST_NEXT, LIST_PREV, LIST_REMOVE -
implementa-
tion of a doubly-linked list

SYNOPSIS

       #include <sys/queue.h>

       int LIST_EMPTY(LIST_HEAD *head);

       LIST_ENTRY(TYPE);

       LIST_ENTRY *LIST_FIRST(LIST_HEAD *head);

       LIST_FOREACH(TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME);

       LIST_HEAD(HEADNAME, TYPE);

       LIST_HEAD LIST_HEAD_INITIALIZER(LIST_HEAD head);

       void LIST_INIT(LIST_HEAD *head);

       void LIST_INSERT_AFTER(TYPE *listelm, TYPE *elm, LIST_ENTRY NAME);

       void LIST_INSERT_BEFORE(TYPE *listelm, TYPE *elm, LIST_ENTRY NAME);

       void LIST_INSERT_HEAD(LIST_HEAD *head, TYPE *elm, LIST_ENTRY NAME);

       LIST_ENTRY *LIST_NEXT(TYPE *elm, LIST_ENTRY NAME);

       void LIST_REMOVE(TYPE *elm, LIST_ENTRY NAME);

]]

The code for NAME and SYNOPSIS,
which are the sections that are ready in list.3,
is the following:

[[
.TH LIST 3 2020-10-19 "GNU" "Linux Programmer's Manual"
.SH NAME
LIST_EMPTY,
LIST_ENTRY,
LIST_FIRST,
LIST_FOREACH,
.\"LIST_FOREACH_FROM,
.\"LIST_FOREACH_SAFE,
.\"LIST_FOREACH_FROM_SAFE,
LIST_HEAD,
LIST_HEAD_INITIALIZER,
LIST_INIT,
LIST_INSERT_AFTER,
LIST_INSERT_BEFORE,
LIST_INSERT_HEAD,
LIST_NEXT,
LIST_PREV,
LIST_REMOVE
.\"LIST_SWAP
\- implementation of a doubly-linked list
.SH SYNOPSIS
.nf
.B #include <sys/queue.h>
.PP
.BI "int LIST_EMPTY(LIST_HEAD *" head ");"
.PP
.B "LIST_ENTRY(TYPE);"
.PP
.BI "LIST_ENTRY *LIST_FIRST(LIST_HEAD *" head ");"
.PP
.BI "LIST_FOREACH(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ");"
.\".PP
.\".BI "LIST_FOREACH_FROM(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ");"
.\".PP
.\".BI "LIST_FOREACH_SAFE(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ", TYPE *" temp_var ");" .\".PP
.\".BI "LIST_FOREACH_FROM_SAFE(TYPE *" var ", LIST_HEAD *" head ", LIST_ENTRY " NAME ", TYPE *" temp_var ");" .PP
.B "LIST_HEAD(HEADNAME, TYPE);"
.PP
.BI "LIST_HEAD LIST_HEAD_INITIALIZER(LIST_HEAD " head ");"
.PP
.BI "void LIST_INIT(LIST_HEAD *" head ");"
.PP
.BI "void LIST_INSERT_AFTER(TYPE *" listelm ", TYPE *" elm ", LIST_ENTRY " NAME ");"
.PP
.BI "void LIST_INSERT_BEFORE(TYPE *" listelm ", TYPE *" elm ", LIST_ENTRY " NAME ");"
.PP
.BI "void LIST_INSERT_HEAD(LIST_HEAD *" head ", TYPE *" elm ", LIST_ENTRY " NAME ");"
.PP
.BI "LIST_ENTRY *LIST_NEXT(TYPE *" elm ", LIST_ENTRY " NAME ");"
.\".PP
.\".BI "LIST_ENTRY LIST_PREV(TYPE *" elm ", LIST_HEAD *" head ", TYPE, LIST_ENTRY " NAME ");" .PP
.BI "void LIST_REMOVE(TYPE *" elm ", LIST_ENTRY " NAME ");"
.\".PP
.\".BI "void LIST_SWAP(LIST_HEAD *" head1 ", LIST_HEAD *" head2 ", TYPE, LIST_ENTRY " NAME ");" .fi
]]

I'll continue working on other sections;
please tell me if you find anything that could be improved.

I'll work on list.3 only, so that we then have a pattern for the rest. Also, this way they can be merged to master separately, resulting in shorter patchsets and times.

Cheers,

Alex

#4 lore raw
Quoted 9 lines · Hans Petter Selasky

Hi,

You may want to import new queue macros from FreeBSD, especially for C++ use.

https://svnweb.freebsd.org/base/head/sys/sys/queue.h

https://svnweb.freebsd.org/base?view=revision&revision=284915

--HPS

Hi Hans,

Thanks for the suggestion.

I'll add the documentation to the manual pages commented out (as with other queue.h macros that aren't present on glibc), and if glibc adds them in the future,
it can then be uncommented.

Thanks,

Alex

#5 lore raw
Quoted 15 lines · Alejandro Colomar
Quoted 10 lines · Hans Petter Selasky

Hi,

You may want to import new queue macros from FreeBSD, especially for C++ use.

https://svnweb.freebsd.org/base/head/sys/sys/queue.h

https://svnweb.freebsd.org/base?view=revision&revision=284915

--HPS

Quoted 8 lines

Hi Hans,

Thanks for the suggestion.

I'll add the documentation to the manual pages commented out (as with other queue.h macros that aren't present on glibc), and if glibc adds them in the future,
it can then be uncommented.

Thanks for that, Alex. (And thanks for the heads-up, Hans.)

Cheers,

Michael

Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
#6 lore raw

sys/queue.h: Add macros present on BSDs

Quoted 25 lines · Michael Kerrisk (man-pages)
Quoted 15 lines · Alejandro Colomar
Quoted 10 lines · Hans Petter Selasky

Hi,

You may want to import new queue macros from FreeBSD, especially for C++ use.

https://svnweb.freebsd.org/base/head/sys/sys/queue.h

https://svnweb.freebsd.org/base?view=revision&revision=284915

--HPS

Quoted 8 lines

Hi Hans,

Thanks for the suggestion.

I'll add the documentation to the manual pages commented out (as with other queue.h macros that aren't present on glibc), and if glibc adds them in the future,
it can then be uncommented.

Quoted 6 lines

Thanks for that, Alex. (And thanks for the heads-up, Hans.)

Cheers,

Michael

After Hans' suggestion,
I decided to find all <sys/queue.h> macros available on BSDs and not on glibc. You may want to add them to glibc. I'll write them when I have some time.

Here's the list of what I could find:

* OpenBSD:

struct TYPE *
SLIST_END(SLIST_HEAD *head);

SLIST_FOREACH_SAFE(VARNAME, SLIST_HEAD *head, FIELDNAME, TEMP_VARNAME);

void
SLIST_REMOVE_AFTER(struct TYPE *elm, FIELDNAME);

struct TYPE *
LIST_END(LIST_HEAD *head);

LIST_FOREACH_SAFE(VARNAME, LIST_HEAD *head, FIELDNAME, TEMP_VARNAME);

void
LIST_REPLACE(struct TYPE *elm, struct TYPE *elm2, FIELDNAME);

struct TYPE * SIMPLEQ_END(SIMPLEQ_HEAD *head);

SIMPLEQ_FOREACH_SAFE(VARNAME, SIMPLEQ_HEAD *head, FIELDNAME, TEMP_VARNAME);

void
SIMPLEQ_REMOVE_AFTER(SIMPLEQ_HEAD *head, struct TYPE *elm, FIELDNAME);

struct TYPE *
TAILQ_END(TAILQ_HEAD *head);

TAILQ_FOREACH_SAFE(VARNAME, TAILQ_HEAD *head, FIELDNAME, TEMP_VARNAME);

TAILQ_FOREACH_REVERSE_SAFE(VARNAME, TAILQ_HEAD *head, HEADNAME, FIELDNAME, TEMP_VARNAME);

void
TAILQ_REPLACE(TAILQ_HEAD *head, struct TYPE *elm, struct TYPE *elm2, FIELDNAME);

struct TYPE * CIRCLEQ_END(CIRCLEQ_HEAD *head);

CIRCLEQ_FOREACH_SAFE(VARNAME, CIRCLEQ_HEAD *head, FIELDNAME, TEMP_VARNAME);

CIRCLEQ_FOREACH_REVERSE_SAFE(VARNAME, CIRCLEQ_HEAD *head, FIELDNAME, TEMP_VARNAME);

void
CIRCLEQ_REPLACE(CIRCLEQ_HEAD *head, struct TYPE *elm, struct TYPE *elm2, FIELDNAME);

* FreeBSD:

SLIST_CLASS_ENTRY(CLASSTYPE);

SLIST_CLASS_HEAD(HEADNAME, CLASSTYPE);

STAILQ_CLASS_ENTRY(CLASSTYPE);

STAILQ_CLASS_HEAD(HEADNAME, CLASSTYPE);

LIST_CLASS_ENTRY(CLASSTYPE);

LIST_CLASS_HEAD(HEADNAME, CLASSTYPE);

TAILQ_CLASS_ENTRY(CLASSTYPE);

TAILQ_CLASS_HEAD(HEADNAME, CLASSTYPE);

* Interesting, but not present on BSDs (at list on the ones I checked):

SIMPLEQ_CLASS_ENTRY(CLASSTYPE);

SIMPLEQ_CLASS_HEAD(HEADNAME, CLASSTYPE);

CIRCLEQ_CLASS_ENTRY(CLASSTYPE);

CIRCLEQ_CLASS_HEAD(HEADNAME, CLASSTYPE);