On Fri, Dec 11, 2020 at 09:54:22PM -0500, Andras Farkas wrote: > Hi! > > After seeing the diff for cat -n earlier today, and just browsing Unix > stuff on my own, I noticed OpenBSD's pr(1) command has no -p option > despite pr.1 stating: > > The pr utility is compliant with the IEEE Std 1003.1-2008 ("POSIX.1") > > specification. > https://man.openbsd.org/pr.1 > This part of the man page was added in this diff: > https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/pr/pr.1.diff?r1=1.16&r2=1.17 > https://github.com/openbsd/src/commit/7c5a075bb35c9874ed6ed8040f78870dae704a20 > and was never correct. -p has been a mandatory (it's neither XSI nor > optional) part of POSIX since 2001. > It's also not merely a SysVism or POSIXism, as -p exists in Unix 8th > and 10th editions: > http://man.cat-v.org/unix_8th/1/pr > http://man.cat-v.org/unix_10th/1/pr > > In case the -p option is not desired, I have a small diff attached > (no-p.txt) that fixes the man page, and fixes a typo in pr.c > But I also have a bigger diff (pr-p.txt) adding -p to pr. > It's inspired by the FreeBSD and NetBSD diffs, but mostly the NetBSD one: > https://github.com/freebsd/freebsd/commit/cace3f9d081619c267182e7e1c926cafabc283e2 > https://svnweb.freebsd.org/base?view=revision&revision=93481 > https://github.com/NetBSD/src/commit/a19c45064f8d362783a3e36c2820544bc05d644a > http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/pr/pr.c > > I did not touch -f or -F, though those can easily be changed later if desired. > I also did not touch -n and its numbering limit. > Implementation note: while POSIX says a "<carriage-return>", i.e. > '\r', should be waited for, FreeBSD, NetBSD, OpenSolaris, and Unix > 10th edition wait for '\n' and I followed them rather than POSIX. It > would be easy to make pr wait for either '\n' or '\r' though. > > I don't know whether to add a new date or name to the > copyright/license text at the top. A whole new flag was added, but > it's adapted from another implementation. > I mostly imitated pr's pre-existing non-style(9) style, except for > using proper style(9) inside the new prpause() function. > > Thanks for reading!
hi. it's an oversight on my part - the posix page for pr renders poorly on lynx, and -p is difficult to spot. i have added a note to say that -p is unsupported. if anyone chooses to add support, we can easily fix it. i also took the typo fix for pr.c. thanks! jmc > Index: pr.1 > =================================================================== > RCS file: /cvs/src/usr.bin/pr/pr.1,v > retrieving revision 1.27 > diff -u -p -r1.27 pr.1 > --- pr.1 4 Jun 2014 07:57:27 -0000 1.27 > +++ pr.1 11 Dec 2020 23:33:33 -0000 > @@ -310,12 +310,6 @@ operand is > .Xr more 1 , > .Xr ascii 7 > .Sh STANDARDS > -The > -.Nm > -utility is compliant with the > -.St -p1003.1-2008 > -specification. > -.Pp > The flag > .Op Fl f > is marked by > Index: pr.c > =================================================================== > RCS file: /cvs/src/usr.bin/pr/pr.c,v > retrieving revision 1.43 > diff -u -p -r1.43 pr.c > --- pr.c 22 Jan 2020 07:52:37 -0000 1.43 > +++ pr.c 11 Dec 2020 23:33:33 -0000 > @@ -64,7 +64,7 @@ > * pr: more boundary conditions than a four-legged porcupine > * > * the original version didn't support form-feeds, while many of the ad-hoc > - * pr implementations out there do. Addding this and making it work > reasonably > + * pr implementations out there do. Adding this and making it work > reasonably > * in all four output modes required quite a bit of hacking and a few minor > * bugs were noted and fixed in the process. Some implementations have this > * as the as -f, some as -F so we accept either. > Index: extern.h > =================================================================== > RCS file: /cvs/src/usr.bin/pr/extern.h,v > retrieving revision 1.6 > diff -u -p -r1.6 extern.h > --- extern.h 19 Jan 2015 15:30:52 -0000 1.6 > +++ extern.h 12 Dec 2020 02:42:34 -0000 > @@ -50,6 +50,7 @@ int onecol(int, char **); > int otln(char *, int, int *, int *, int); > void pfail(void); > int prhead(char *, char *, int); > +void prpause(int); > int prtail(int, int); > int setup(int, char **); > void terminate(int); > Index: pr.1 > =================================================================== > RCS file: /cvs/src/usr.bin/pr/pr.1,v > retrieving revision 1.27 > diff -u -p -r1.27 pr.1 > --- pr.1 4 Jun 2014 07:57:27 -0000 1.27 > +++ pr.1 12 Dec 2020 02:42:34 -0000 > @@ -33,7 +33,7 @@ > .\" > .\" from: @(#)pr.1 8.1 (Berkeley) 6/6/93 > .\" > -.Dd $Mdocdate: June 4 2014 $ > +.Dd $Mdocdate: December 11 2020 $ > .Dt PR 1 > .Os > .Sh NAME > @@ -43,7 +43,7 @@ > .Nm pr > .Op Cm + Ns Ar page > .Op Fl Ar column > -.Op Fl adFfmrt > +.Op Fl adFfmprt > .Op Fl e Ns Oo Ar char Oc Ns Op Ar gap > .Op Fl h Ar header > .Op Fl i Ns Oo Ar char Oc Ns Op Ar gap > @@ -256,6 +256,9 @@ If the > .Fl o > option is not specified, the default is zero. > The space taken is in addition to the output line width. > +.It Fl p > +Pause before beginning each page if the standard output is a terminal, ring > the bell, and wait for a newline on > +.Pa /dev/tty > .It Fl r > Write no diagnostic reports on failure to open a file. > .It Fl s Ns Op Ar char > Index: pr.c > =================================================================== > RCS file: /cvs/src/usr.bin/pr/pr.c,v > retrieving revision 1.43 > diff -u -p -r1.43 pr.c > --- pr.c 22 Jan 2020 07:52:37 -0000 1.43 > +++ pr.c 12 Dec 2020 02:42:34 -0000 > @@ -64,7 +64,7 @@ > * pr: more boundary conditions than a four-legged porcupine > * > * the original version didn't support form-feeds, while many of the ad-hoc > - * pr implementations out there do. Addding this and making it work > reasonably > + * pr implementations out there do. Adding this and making it work > reasonably > * in all four output modes required quite a bit of hacking and a few minor > * bugs were noted and fixed in the process. Some implementations have this > * as the as -f, some as -F so we accept either. > @@ -123,16 +123,19 @@ int nodiag; /* do not report file open > char schar; /* text column separation character */ > int sflag; /* -s option for multiple columns */ > int nohead; /* do not write head and trailer */ > +int pgpause; /* pause before each page */ > int pgwd; /* page width with multiple col output */ > > /* > * misc globals > */ > volatile sig_atomic_t ferr; /* error message delayed */ > +int ttyout; /* output is a tty */ > int addone = 0; /* page length is odd with double space */ > int errcnt = 0; /* error count on file processing */ > int beheaded = 0; /* header / trailer link */ > char digs[] = "0123456789"; /* page number translation map */ > +FILE *ttyinf; /* input terminal for page pauses */ > > int > main(int argc, char *argv[]) > @@ -258,8 +261,13 @@ onecol(int argc, char *argv[]) > rc = inln(inf,lbuf,LBUF,&cnt,&cps,0,&mor); > if (cnt >= 0) { > if (!lrgln) > - if (!linecnt && prhead(hbuf, fname, ++pagecnt)) > - goto out; > + if (!linecnt) { > + if (pgpause) > + prpause(pagecnt+1); > + > + if (prhead(hbuf, fname, ++pagecnt)) > + goto out; > + } > > /* > * start new line or continue a long one > @@ -541,6 +549,8 @@ vertcol(int argc, char *argv[]) > * print header iff we got anything on the first read > */ > if (vc[0].cnt >= 0) { > + if (pgpause) > + prpause(pagecnt+1); > if (prhead(hbuf, fname, ++pagecnt)) > goto out; > > @@ -751,8 +761,13 @@ horzcol(int argc, char *argv[]) > */ > rc = inln(inf,ptbf,colwd,&cnt,&cps,1, &mor); > if (cnt >= 0) { > - if (!i && !j && prhead(hbuf, fname, ++pagecnt)) > - goto out; > + if (!i && !j) { > + if (pgpause) > + prpause(pagecnt+1); > + > + if (prhead(hbuf, fname, ++pagecnt)) > + goto out; > + } > > ptbf += cnt; > lstdat = ptbf; > @@ -1075,8 +1090,13 @@ mulfile(int argc, char *argv[]) > * if there was anything to do, print it > */ > if (fproc != 0) { > - if (!i && prhead(hbuf, fname, ++pagecnt)) > - goto out; > + if (!i) { > + if (pgpause) > + prpause(pagecnt+1); > + > + if (prhead(hbuf, fname, ++pagecnt)) > + goto out; > + } > > /* > * output line > @@ -1619,6 +1639,32 @@ prhead(char *buf, char *fname, int pagcn > } > > /* > + * prpause(): pause before printing each page > + * > + * pagcnt page number > + */ > +void > +prpause(int pagcnt) > +{ > + if (ttyout) { > + int c; > + > + putc('\a', stderr); > + fflush(stderr); > + > + while ((c = getc(ttyinf)) != '\n' && c != EOF) > + ; > + > + /* > + * Pause ONLY before first page of first file. > + * This would be used in order to pause ONLY before first page > of first file to support an XSI-style -f option, but is currently a no-op. > + */ > + if (pgpause == FIRSTPAGE && pagcnt == 1) > + pgpause = NO_PAUSE; > + } > +} > + > +/* > * prtail(): pad page with empty lines (if required) and print page > trailer > * if requested > * > @@ -1741,7 +1787,7 @@ void > usage(void) > { > ferrout( > - "usage: pr [+page] [-column] [-adFfmrt] [-e[char][gap]] [-h header]\n"); > + "usage: pr [+page] [-column] [-adFfmprt] [-e[char][gap]] [-h > header]\n"); > ferrout( > "\t[-i[char][gap]] [-l lines] [-n[char][width]] [-o offset] > [-s[char]]\n"); > ferrout( > @@ -1762,10 +1808,14 @@ setup(int argc, char *argv[]) > int cflag = 0; > const char *errstr; > > - if (isatty(fileno(stdout))) > + ttyinf = stdin; > + > + if (isatty(fileno(stdout))) { > ferr = 1; > + ttyout = 1; > + } > > - while ((c = egetopt(argc, argv, "#adfFmrte?h:i?l:n?o:s?w:")) != -1) { > + while ((c = egetopt(argc, argv, "#adfFmprte?h:i?l:n?o:s?w:")) != -1) { > switch (c) { > case '+': > pgnm = strtonum(eoptarg, 1, INT_MAX, &errstr); > @@ -1871,6 +1921,9 @@ setup(int argc, char *argv[]) > return(1); > } > break; > + case 'p': > + pgpause |= EACHPAGE; > + break; > case 'r': > nodiag = 1; > break; > @@ -1982,6 +2035,17 @@ setup(int argc, char *argv[]) > if (lines & 1) > ++addone; > lines /= 2; > + } > + } > + > + /* > + * Open /dev/tty if we are to pause before each page, > + * but only if stdout is a terminal and stdin is not a terminal. > + */ > + if (ttyout && pgpause && !isatty(fileno(stdin))) { > + if ((ttyinf = fopen("/dev/tty", "r")) == NULL) { > + ferrout("pr: cannot open terminal\n"); > + return (1); > } > } > > Index: pr.h > =================================================================== > RCS file: /cvs/src/usr.bin/pr/pr.h,v > retrieving revision 1.5 > diff -u -p -r1.5 pr.h > --- pr.h 19 Jan 2015 15:30:52 -0000 1.5 > +++ pr.h 12 Dec 2020 02:42:34 -0000 > @@ -70,6 +70,14 @@ > #define NORMAL 0 > > /* > + * Which pages to pause before (for -p option, and for a potential XSI-style > -f option) > + */ > +#define NO_PAUSE 0 > +#define FIRSTPAGE 1 > +#define ENSUINGPAGES 2 > +#define EACHPAGE (FIRSTPAGE | ENSUINGPAGES) > + > +/* > * structure for vertical columns. Used to balance cols on last page > */ > struct vcol {