Subject: standards/19468: pr(1) does not support -f or -p options
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ryany@pobox.com>
List: netbsd-bugs
Date: 12/19/2002 21:27:20
>Number: 19468
>Category: standards
>Synopsis: pr(1) does not support -f or -p options
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: standards-manager
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Dec 19 18:48:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Ryan Younce
>Release: NetBSD 1.6K
>Organization:
>Environment:
System: NetBSD rdu25-023-020.nc.rr.com 1.6K NetBSD 1.6K (build) #0: Mon Dec 9 14:01:02 EST 2002 root@rdu168-187-047.nc.rr.com:/root/build i386
Architecture: i386
Machine: i386
>Description:
The 2001 version of the POSIX specification indicates two options, -f
and -p, for the pr(1) utility, one of which is new and one which was
pre-existing.
These are directly quoted from the specification:
-f Use a form feed for new pages, instead of the default behavior that
uses a sequence of <newline>s. Pause before beginning the first page
if the standard output is associated with a terminal.
-p Pause before beginning each page if the standard output is
directed to a terminal (pr shall write an <alert> to standard
error and wait for a <carriage-return> to be read on /dev/tty).
I've updated the files pr.c, extern.h, and pr.1 to reflect this behavior.
(Note: POSIX states -f is to pause at the beginning of the first page.
This is rather vague as it could be debated that the first page indicates
the first page of output or the first page of each file. The patch
assumes it means the first page of each file).
(Furthermore, -f does not state a required alert be generated to standard
error. The patch does generate an alert to standard error whenever it
pauses, but the delay() function in pr.c is written to easily accomodate
either case by taking an integer parameter).
>How-To-Repeat:
Not applicable.
>Fix:
Index: extern.h
===================================================================
RCS file: /cvsroot/src/usr.bin/pr/extern.h,v
retrieving revision 1.2
diff -u -r1.2 extern.h
--- extern.h 1997/01/09 15:01:35 1.2
+++ extern.h 2002/12/20 02:37:40
@@ -44,6 +44,7 @@
extern char *eoptarg;
void addnum __P((char *, int, int));
+void delay __P((int));
int egetopt __P((int, char * const *, const char *));
void flsh_errs __P((void));
int horzcol __P((int, char **));
Index: pr.1
===================================================================
RCS file: /cvsroot/src/usr.bin/pr/pr.1,v
retrieving revision 1.13
diff -u -r1.13 pr.1
--- pr.1 2002/02/08 01:36:31 1.13
+++ pr.1 2002/12/20 02:37:40
@@ -95,6 +95,7 @@
.Bk -words
.Op Fl w Ar width
.Ek
+.Op Fl fp
.Op -
.Op Ar file ...
.Sh DESCRIPTION
@@ -189,6 +190,14 @@
sequence of
.Em \*[Lt]newline\*[Gt]
characters.
+.It Fl f
+Same as
+.Fl F ,
+except
+.Nm
+also pauses before beginning
+the first page if the standard output
+is associated with a terminal.
.It Fl h Ar header
Use the string
.Ar header
@@ -267,6 +276,13 @@
.Fl o
option is not specified, the default is zero.
The space taken is in addition to the output line width.
+.It Fl p
+If standard output refers to a terminal device, for the
+beginning of each page generate
+an alert on standard error and then pause until a
+.Em \*[Lt]carriage-return\*[Gt]
+is read from
+.Pa /dev/tty .
.It Fl r
Write no diagnostic reports on failure to open a file.
.It Fl s Ar char
@@ -351,6 +367,6 @@
.Sh STANDARDS
The
.Nm
-utility is
-.St -p1003.2
-compatible.
+utility is compliant with the
+.St -p1003.1-2001
+specification.
Index: pr.c
===================================================================
RCS file: /cvsroot/src/usr.bin/pr/pr.c,v
retrieving revision 1.10
diff -u -r1.10 pr.c
--- pr.c 2001/07/22 13:34:13 1.10
+++ pr.c 2002/12/20 02:37:41
@@ -101,6 +101,9 @@
int sflag; /* -s option for multiple columns */
int nohead; /* do not write head and trailer */
int pgwd; /* page width with multiple col output */
+int delayfile; /* delay before each file (if terminal) */
+int delaypage; /* interpage delay (if terminal) */
+FILE *tty; /* terminal device for page delays */
char *timefrmt = TIMEFMT; /* time conversion string */
/*
@@ -217,6 +220,9 @@
pagecnt = 1;
lncnt = 0;
+ if (delayfile && !delaypage)
+ delay(1);
+
/*
* loop by page
*/
@@ -227,6 +233,9 @@
ips = 0;
cps = 0;
+ if (delaypage)
+ delay(1);
+
/*
* loop by line
*/
@@ -411,10 +420,16 @@
pagecnt = 1;
lncnt = 0;
+ if (delayfile && !delaypage)
+ delay(1);
+
/*
* loop by page
*/
for(;;) {
+ if (delaypage)
+ delay(1);
+
/*
* loop by column
*/
@@ -438,7 +453,7 @@
if (!i) {
ptbf = buf + indy[j];
lstdat[j] = ptbf;
- } else
+ } else
ptbf = lstdat[j];
vc[cvc].pt = ptbf;
@@ -667,10 +682,16 @@
pagecnt = 1;
lncnt = 0;
+ if (delayfile && !delaypage)
+ delay(1);
+
/*
* loop by page
*/
for(;;) {
+ if (delaypage)
+ delay(1);
+
/*
* loop by line
*/
@@ -857,6 +878,9 @@
pagecnt = 1;
lncnt = 0;
+ if (delayfile && !delaypage)
+ delay(1);
+
/*
* continue to loop while any file still has data
*/
@@ -929,8 +953,12 @@
if ((j = lstdat - buf) <= offst)
break;
- if (!i && !nohead && prhead(hbuf, fname, pagecnt))
- return(1);
+ if (!i && !nohead) {
+ if (delaypage)
+ delay(1);
+ if (prhead(hbuf, fname, pagecnt))
+ return(1);
+ }
/*
* output line
@@ -960,6 +988,27 @@
}
/*
+ * delay(): delay page until carriage-return is entered on terminal
+ *
+ * alert: sound bell on standard error before pausing
+ */
+void
+delay(int alert)
+{
+ int ch;
+
+ if (tty) {
+ if (alert) {
+ fputc('\a', stderr);
+ fflush(stderr);
+ }
+ do {
+ ch = fgetc(tty);
+ } while (ch != EOF && ch != '\n');
+ }
+}
+
+/*
* inln(): input a line of data (unlimited length lines supported)
* Input is optionally expanded to spaces
*
@@ -967,7 +1016,7 @@
* buf: buffer
* lim: buffer length
* cps: column positon 1st char in buffer (large line support)
- * trnc: throw away data more than lim up to \n
+ * trnc: throw away data more than lim up to \n
* mor: set if more data in line (not truncated)
*/
int
@@ -1516,7 +1565,7 @@
return(1);
}
return(0);
- }
+ }
cnt += TAILLEN;
while (--cnt >= 0) {
if (putchar('\n') == EOF) {
@@ -1577,7 +1626,7 @@
(void)fputs(
" [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err);
(void)fputs(
- " [-s[ch]] [-w width] [-] [file ...]\n", err);
+ " [-s[ch]] [-w width] [-fp] [-] [file ...]\n", err);
}
/*
@@ -1605,7 +1654,7 @@
}
} else
err = stderr;
- while ((c = egetopt(argc, argv, "#adFmrte?h:i?l:n?o:s?T:w:")) != -1) {
+ while ((c = egetopt(argc, argv, "#adfFmrte?h:i?l:n?po:s?T:w:")) != -1) {
switch (c) {
case '+':
if ((pgnm = atoi(eoptarg)) < 1) {
@@ -1654,6 +1703,10 @@
case 'F':
++formfeed;
break;
+ case 'f':
+ ++formfeed;
+ ++delayfile;
+ break;
case 'h':
header = eoptarg;
break;
@@ -1719,6 +1772,9 @@
return(1);
}
break;
+ case 'p':
+ ++delaypage;
+ break;
case 'r':
++nodiag;
break;
@@ -1834,6 +1890,16 @@
if (lines & 1)
++addone;
lines /= 2;
+ }
+ }
+
+ /*
+ * open /dev/tty if we are to delay pages (only if stdout is a terminal)
+ */
+ if ((delayfile || delaypage) && isatty(fileno(stdout))) {
+ if ((tty = fopen("/dev/tty", "r")) == NULL) {
+ (void)fprintf(err, "pr: cannot open terminal\n");
+ return(1);
}
}
>Release-Note:
>Audit-Trail:
>Unformatted:
Using current source dated 19 Dec 2002.