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 {

Reply via email to