Skip to contentSkip to conversation

diffman(1)

DISCUSSION Alejandro Colomar 2 participants 8 messages Nov 25, 2024 – Jan 10, 2025 Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore

Alejandro Colomar

author maintainer
#0 lore raw

Hi!

I've developed a new program (actually, a bash script) that diffs manual pages. I find it quite useful for quickly seeing differences between a page as installed in the system, and the file I'm working on. The output is diff -u of formatted manual pages (suitable for less -R).

You can find it here:
<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/commit/?h=contrib&id=fa4743c43762cc3be4af9672ce12a7ed58f9a500>
and soon in the <kernel.org> repo.

The script is just a fancy version of

	diff -u \
	       <(man -w "$1" | xargs groff -man -Tutf8) \
	       <(man -w "$2" | xargs groff -man -Tutf8);

I had to make it fancier for error handling, since process substitution doesn't propagate errors (not even with set -Eeo pipefail).

You may find it useful for development of manual pages. If so, please let me know any feedback you have for it. I was wondering if I should pipe to less -R, just like man(1) does. For now, having doubts, I kept it simple, which would allow wrapping this in fancier scripts that for exaple diff an entire repository of manual pages (although that maybe calls for running groff(1) and diff(1) directly).

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es/>
author maintainer
#1 lore raw
Quoted 20 lines · Alejandro Colomar

Hi!

I've developed a new program (actually, a bash script) that diffs manual pages. I find it quite useful for quickly seeing differences between a page as installed in the system, and the file I'm working on. The output is diff -u of formatted manual pages (suitable for less -R).

You can find it here:
<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/commit/?h=contrib&id=fa4743c43762cc3be4af9672ce12a7ed58f9a500>
and soon in the <kernel.org> repo.

The script is just a fancy version of

	diff -u \
	       <(man -w "$1" | xargs groff -man -Tutf8) \
	       <(man -w "$2" | xargs groff -man -Tutf8);

I had to make it fancier for error handling, since process substitution doesn't propagate errors (not even with set -Eeo pipefail).

Quoted 6 lines

You may find it useful for development of manual pages. If so, please let me know any feedback you have for it. I was wondering if I should pipe to less -R, just like man(1) does. For now, having doubts, I kept it simple, which would allow wrapping this in fancier scripts that for exaple diff an entire repository of manual pages (although that maybe calls for running groff(1) and diff(1) directly).

I've decided to keep it without piping to less(1). For piping, I'll let users write their own wrapper, since it's trivial. I've called mine duffman, which is like diffman(1), but with more fun. :-)

	$ which duffman | xargs cat
	#!/bin/bash
	set -Eeuo pipefail;

	diffman $@ | less -R;

duffman is not in the repo for now.

Quoted 6 lines

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es/>
Signature · 1 line
<https://www.alejandro-colomar.es/>
#2 lore raw
In reply to Alejandro Colomar

Hi Alejandro,

Quoted 6 lines · Alejandro Colomar

You may find it useful for development of manual pages. If so, please let me know any feedback you have for it. I was wondering if I should pipe to less -R, just like man(1) does. For now, having doubts, I kept it simple, which would allow wrapping this in fancier scripts that for exaple diff an entire repository of manual pages (although that maybe calls for running groff(1) and diff(1) directly).

less simply pipes the data through if it's not at the end of a pipeline, so piping the diff's output to less -R shouldn't complicate use in scripts in any way (except perhaps for escape sequences if you use color).

  $ less -R /usr/include/stdio.h | grep -E '^#' | wc -l
  241
  $ sed -E "s/^/$(printf '\033[1m')/; s/\$/$(printf '\033[m')/" \
      /usr/include/stdio.h | less -R | wc -l
  985

~ onf

author maintainer
#3 lore raw

Hi onf,

Quoted 10 lines · onf

Hi Alejandro,

Quoted 6 lines · Alejandro Colomar

You may find it useful for development of manual pages. If so, please let me know any feedback you have for it. I was wondering if I should pipe to less -R, just like man(1) does. For now, having doubts, I kept it simple, which would allow wrapping this in fancier scripts that for exaple diff an entire repository of manual pages (although that maybe calls for running groff(1) and diff(1) directly).

Quoted 4 lines

less simply pipes the data through if it's not at the end of a pipeline, so piping the diff's output to less -R shouldn't complicate use in scripts in any way (except perhaps for escape sequences if you use color).

I've seen less(1) cause issues when called in a while loop. And indeed, there's good reasons for calling this in a loop. Here's a useful wrapper I came up with after writing this email:

	$ tail -n19 scripts/bash_aliases 
	# diff all modified pages against the system ones.
	duffman()
	{
		cd $(git rev-parse --show-toplevel);

		git diff --name-only \
		| grep -E \
		   '(\.[[:digit:]]([[:alpha:]][[:alnum:]]*)?\>|\.man)+(\.man|\.in)*$' \
		| sortman \
		| while read f; do \
			local sys="$(basename "$f")";

			diffman "$sys" "$f";
		done \
		| less -R;

		cd -;
	}
Quoted 8 lines
  $ less -R /usr/include/stdio.h | grep -E '^#' | wc -l
  241
  $ sed -E "s/^/$(printf '\033[1m')/; s/\$/$(printf '\033[m')/" \
      /usr/include/stdio.h | less -R | wc -l
  985

~ onf

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es/>
author maintainer
#4 lore raw

duffman(1) (was: diffman(1))

Hi!

I have added a duffman(1) program (script) to the Linux man-pages repo. It is similar to diffman(1), but it diffs the git working directory (or a commit, if specified).

Here are a couple of examples.

A change in the working directory:

	alx@devuan:~/src/linux/man-pages/man-pages/contrib$ git diff
	diff --git i/man/man3/printf.3 w/man/man3/printf.3
	index 2129e26dc..a379ae609 100644
	--- i/man/man3/printf.3
	+++ w/man/man3/printf.3
	@@ -24,7 +24,7 @@ .SH SYNOPSIS
	 .nf
	 .B #include <stdio.h>
	 .P
	-.BI "int printf(const char *restrict " format ", ...);"
	+.BI "int foo(const char *restrict " format ", ...);"
	 .BI "int fprintf(FILE *restrict " stream ,
	 .BI "            const char *restrict " format ", ...);"
	 .BI "int dprintf(int " fd ,
	alx@devuan:~/src/linux/man-pages/man-pages/contrib$ duffman 
	--- HEAD:man/man3/printf.3
	+++ man/man3/printf.3
	@@ -10,7 +10,7 @@
	 SYNOPSIS
	      #include <stdio.h>

- int printf(const char *restrict format, ...);
+ int foo(const char *restrict format, ...);
int fprintf(FILE *restrict stream,
const char *restrict format, ...);
int dprintf(int fd,

(The actual output includes bold and italics.)

And with an old commit:

	alx@devuan:~/src/linux/man-pages/man-pages/contrib$ git show 437e4afec6ca
	commit 437e4afec6cae16ba75587f835acee1e251f2e75
	Author: Alejandro Colomar <[email protected]>
	Date:   Sun Jan 5 13:44:32 2025 +0100
	    man/man3/sem_open.3: SYNOPSIS: This is a variadic function
	    
	    Specify the prototype consistently with open(2).
	    
	    Signed-off-by: Alejandro Colomar <[email protected]>

	diff --git a/man/man3/sem_open.3 b/man/man3/sem_open.3
	index 6a2aceb50..35275a024 100644
	--- a/man/man3/sem_open.3
	+++ b/man/man3/sem_open.3
	@@ -15,9 +15,8 @@ .SH SYNOPSIS
	 .BR "#include <sys/stat.h>" "        /* For mode constants */"
	 .B #include <semaphore.h>
	 .P
	-.BI "sem_t *sem_open(const char *" name ", int " oflag );
	-.BI "sem_t *sem_open(const char *" name ", int " oflag ,
	-.BI "                mode_t " mode ", unsigned int " value );
	+.BI "sem_t *sem_open(const char *" name ", int " oflag ", ..."
	+.BI "                \fR/*\fP mode_t " mode ", unsigned int " value " \fR*/\fP );"
	 .fi
	 .SH DESCRIPTION
	 .BR sem_open ()
	alx@devuan:~/src/linux/man-pages/man-pages/contrib$ duffman 437e4afec6ca
	--- 437e4afec6ca^:man/man3/sem_open.3
	+++ 437e4afec6ca:man/man3/sem_open.3
	@@ -11,9 +11,8 @@
	      #include <sys/stat.h>        /* For mode constants */
	      #include <semaphore.h>
	 
	-     sem_t *sem_open(const char *name, int oflag);
	-     sem_t *sem_open(const char *name, int oflag,
	-                     mode_t mode, unsigned int value);
	+     sem_t *sem_open(const char *name, int oflag, ...
	+                     /* mode_t mode, unsigned int value */ );
	 
	 DESCRIPTION
	      sem_open()  creates  a new POSIX semaphore or opens an existing semaphore.

I found this very useful for reviewing changes. Maybe you do too. :)

Have a lovely day!
Alex

Signature · 1 line
<https://www.alejandro-colomar.es/>
#5 lore raw

Re: duffman(1) (was: diffman(1))

Hi Alex,

Quoted 7 lines · Alejandro Colomar

I have added a duffman(1) program (script) to the Linux man-pages repo. It is similar to diffman(1), but it diffs the git working directory (or a commit, if specified).

[...]

I found this very useful for reviewing changes. Maybe you do too. :)

Where? I don't see it here:
https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/tree/scripts
nor here:
https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/tree/src/bin
nor here:
https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/scripts
or here:
https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/src/bin

~ onf

author maintainer
#6 lore raw

Re: duffman(1) (was: diffman(1))

Hi onf,

Quoted 11 lines · onf

Hi Alex,

Quoted 7 lines · Alejandro Colomar

I have added a duffman(1) program (script) to the Linux man-pages repo. It is similar to diffman(1), but it diffs the git working directory (or a commit, if specified).

[...]

I found this very useful for reviewing changes. Maybe you do too. :)

Quoted 8 lines

Where? I don't see it here:
https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/tree/scripts
nor here:
https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/tree/src/bin
nor here:
https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/scripts
or here:
https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/src/bin

It's on the contrib branch still. I haven't pushed to main yet.

I renamed it to diffman-git yesterday, BTW.

<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/tree/src/bin/diffman-git?h=contrib>
Plain text:
<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/plain/src/bin/diffman-git?h=contrib>

Have a lovely day!
Alex

Quoted 2 lines

~ onf

Signature · 1 line
<https://www.alejandro-colomar.es/>
#7 lore raw

Re: duffman(1) (was: diffman(1))

Hi Alex,

Quoted 9 lines · Alejandro Colomar
Quoted 6 lines · onf
Quoted 3 lines · Alejandro Colomar

I have added a duffman(1) program (script) to the Linux man-pages repo. It is similar to diffman(1), but it diffs the git working directory (or a commit, if specified).

Where? I don't see it here:

It's on the contrib branch still. I haven't pushed to main yet.

Ah, I see. Thanks!

~ onf