Hi Ingo, On Wed, Jun 04, 2025 at 07:14:47PM +0200, Ingo Schwarze wrote: > Hello Alejandro, > > Alejandro Colomar wrote on Wed, Jun 04, 2025 at 05:58:54PM +0200: > > > +.P > > +.SY int\~dl_iterate_phdr( > > +.BI typeof(int\~(struct\~dl_phdr_info\~* info ,\~size_t\~ size , > > +.BI \~\~\~\~\~\~\~\~\~\~\~\~void\~* data )) > > +.br > > +.BI \~\~\~\~* callback , > > +.br > > +.BI void\~* data ); > > +.YS > > > which I'm relatively pleased with. > > I find it hard to understand how anyone could possibly be pleased > with the above code. It certainly feels disgusting to me.
Hmmm, I'm not pleased, actually. I should have said something like "I'm not horrified by it, and I see no better alternatives". What led me to this is working on nftw(3); that one is even worse than this. I have now this: .SY int\~nftw( .BI const\~char\~* dirpath , .br .BI typeof(int\~(const\~char\~* fpath ,\~const\~struct\~stat\~* sb, .br .BI \~\~\~\~\~\~\~\~\~\~\~\~int\~ typeflag ,\~struct\~FTW\~* ftwbuf )) .br .BI \~\~\~\~* fn, .br .BI int\~ nopenfd , .BI int\~ flags ); .YS . int nftw( const char *dirpath, typeof(int (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)) *fn, int nopenfd, int flags); which previously was .BI "int nftw(const char *" dirpath , .BI " typeof(int (const char *" fpath ", const struct stat *" sb, .BI " int " typeflag ", struct FTW *" ftwbuf )) .BI " *" fn, .BI " int " nopenfd ", int " flags ); int nftw(const char *dirpath, typeof(int (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)) *fn, int nopenfd, int flags); and in OpenBSD is .Ft int .Fo nftw .Fa "const char *path" .Fa "int (*fn)(const\ char\ *, const\ struct\ stat\ *, int, struct\ FTW\ *)" .Fa "int maxfds" .Fa "int flags" int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int maxfds, int flags); An issue I see with the OpenBSD version is not having names for the parameters. That makes the manual page more difficult to follow, IMO. A reader can deduce to which parameter you're referring to because of the type of the parameter, but I'd very much prefer explicitly calling it by name. This in turn results in the callback necessarily needing more than one line. Which in turn results in me needing to hand-tune the formatting so that it is pretty. Considering that I want names in the callback parameters, even if I had 4-space indentation like mdoc(7), I'd need several lines for a single parameter, so I need manual intervention. Now, I've done that in two pages so far, and I've transformed maybe an 80% of the project. I haven't finished, so it might happen again in one or two pages, but I don't expect this to be a common thing to do. > The code uses a high-level macro which is supposed to be semantic. > In spite of that, the code is littered with a large numbers of purely > presentational low-level roff(7) constructions, which demonstrates > that .SY is utterly unfit for its supposed job. > > * .P is not used in its semantical function here (there is no > paragraph of text), but abused as a presentational hack > to insert vertical spacing, similar to the .sp request, > which means that .SY fails at adequately controlling > vertical spacing. In some (most) cases, I want function prototypes to not insert blanks before them. See man-pages(7), as written by Michael: SYNOPSIS Wrap the function prototype(s) in a .nf/.fi pair to prevent fill‐ ing. In general, where more than one function prototype is shown in the SYNOPSIS, the prototypes should not be separated by blank lines. However, blank lines (achieved using .P) may be added in the fol‐ lowing cases: • to separate long lists of function prototypes into related groups (see for example list(3)); • in other cases that may improve readability. In the SYNOPSIS, a long function prototype may need to be contin‐ ued over to the next line. The continuation line is indented ac‐ cording to the following rules: (1) If there is a single such prototype that needs to be contin‐ ued, then align the continuation line so that when the page is rendered on a fixed‐width font device (e.g., on an xterm) the continuation line starts just below the start of the ar‐ gument list in the line above. (Exception: the indentation may be adjusted if necessary to prevent a very long continua‐ tion line or a further continuation line where the function prototype is very long.) As an example: int tcsetattr(int fd, int optional_actions, const struct termios *termios_p); (2) But, where multiple functions in the SYNOPSIS require contin‐ uation lines, and the function names have different lengths, then align all continuation lines to start in the same col‐ umn. This provides a nicer rendering in PDF output (because the SYNOPSIS uses a variable width font where spaces render narrower than most characters). As an example: int getopt(int argc, char * const argv[], const char *optstring); int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); Michael and I agreed on those formatting conventions without much discussion. > * Manual indentation with explicit space escape sequences > is not only extremely ugly, but whether it works as intended > is also output-device-dependent. Yep. The rule we have is that while PDF or other non-terminal devices might have weird indentation, it will be consistent through a single page. (See the mention of PDF in man-pages(7).) > * And then we have the low-level .br requests. Again, certainly > not the worst requests to sneak into a manual page, but in > the middle of a semantic macro? Yikes. As I said, I do want to control line breaks in parameters. printf(3) is an excellent example, and parameters that take up multiple lines --like in ftw(3)-- are another good example. > > Yours, > Ingo Have a lovely day! Alex -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature