revised to handle form feeds, bugs fixed etc
authorgrr <grr@openbsd.org>
Wed, 23 Apr 1997 08:08:28 +0000 (08:08 +0000)
committergrr <grr@openbsd.org>
Wed, 23 Apr 1997 08:08:28 +0000 (08:08 +0000)
usr.bin/pr/extern.h
usr.bin/pr/pr.1
usr.bin/pr/pr.c
usr.bin/pr/pr.h

index 71e3a74..1eed368 100644 (file)
@@ -1,4 +1,4 @@
-/* *   $OpenBSD: extern.h,v 1.2 1996/06/26 05:37:52 deraadt Exp $*/
+/* *   $OpenBSD: extern.h,v 1.3 1997/04/23 08:08:30 grr Exp $*/
 /*-
  * Copyright (c) 1991 Keith Muller.
  * Copyright (c) 1993
@@ -45,7 +45,7 @@ void   addnum __P((char *, int, int));
 int     egetopt __P((int, char * const *, const char *));
 void    flsh_errs __P((void));
 int     horzcol __P((int, char **));
-int     inln __P((FILE *, char *, int, int *, int, int *));
+int     inln __P((FILE *, char *, int, int *, int *, int, int *));
 int     inskip __P((FILE *, int, int));
 void    mfail __P((void));
 int     mulfile __P((int, char **));
index 62279b4..3f0767a 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: pr.1,v 1.2 1996/06/26 05:37:53 deraadt Exp $
+.\"    $OpenBSD: pr.1,v 1.3 1997/04/23 08:08:31 grr Exp $
 .\" Copyright (c) 1991 Keith Muller.
 .\" Copyright (c) 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -50,7 +50,7 @@
 .Bk -words
 .Op Fl Ar column
 .Ek
-.Op Fl adFmrt
+.Op Fl adfFmrt
 .Bk -words
 .Oo
 .Op Fl e
@@ -109,21 +109,45 @@ the pathname of the file.
 \(bu A 5-line trailer consisting of blank lines.
 .in -2
 .Pp
-If standard output is associated with a terminal,
-diagnostic messages are suppressed until the
+Optionally, the trailer can be replaced by a
+.Em <form-feed>
+where this is more appropriate for the output device being used and
+.Em <tab>s
+can be expanded to input relative
+.Em <spaces>s
+or
+.Em <space>s
+can contracted to output relative
+.Em <tab>s.
+The
 .Nm pr
-utility has completed processing.
+utility also interprets
+.Em <form-feed>s
+in the input as logical end of pages.
 .Pp
 When multiple column output is specified,
 text columns are of equal width.
 By default text columns are separated by at least one
-.Em <blank>.
-Input lines that do not fit into a text column are truncated.
-Lines are not truncated under single column output.
+.Em <blank> .
+Input lines that do not fit into a text column are truncated, except
+in the default single columns output mode.
+.Pp
+If standard output is associated with a terminal,
+diagnostic messages are suppressed until the
+.Nm pr
+utility has completed processing.
 .Sh OPTIONS
 .Pp
-In the following option descriptions, column, lines, offset, page, and
-width are positive decimal integers and gap is a nonnegative decimal integer.
+In the following option descriptions,
+.Em column ,
+.Em lines ,
+.Em offset ,
+.Em page ,
+and
+.Em width
+are positive decimal integers and
+.Em gap
+is a non-negative decimal integer.
 .Bl -tag -width 4n
 .It Ar \&+page
 Begin output at page number 
@@ -158,9 +182,13 @@ option.
 .It Fl d
 Produce output that is double spaced. An extra
 .Em <newline>
-character is output following every <newline> found in the input.
+character is output following every
+.Em <newline>
+found in the input.
 .It Fl e Ar \&[char\&]\&[gap\&]
-Expand each input <tab> to the next greater column
+Expand each input
+.Em <tab>
+to the next greater column
 position specified by the formula 
 .Ar n*gap+1 ,
 where 
@@ -185,6 +213,10 @@ instead of the default behavior that uses a
 sequence of
 .Em <newline>
 characters.
+.It Fl f
+Same as the
+.Fl F
+option.
 .It Fl h Ar header
 Use the string 
 .Ar header
@@ -192,8 +224,14 @@ to replace the
 .Ar file name
 in the header line.
 .It Fl i Ar \&[char\&]\&[gap\&]
-In output, replace multiple <space>s with <tab>s whenever two or more
-adjacent <space>s reach column positions
+In output, replace multiple
+.Em <space>s
+with
+.Em <tab>s
+whenever two or more
+adjacent
+.Em <space>s
+reach column positions
 .Ar gap+1 ,
 .Ar 2*gap+1 ,
 etc.
@@ -210,7 +248,7 @@ is specified, it is used as the output
 character.
 .It Fl l Ar lines
 Override the 66 line default and reset the page length to 
-.Ar lines.
+.Ar lines .
 If
 .Ar lines
 is not greater than the sum of both the header and trailer
@@ -336,12 +374,66 @@ utility exits 0 on success, and 1 if an error occurs.
 Error messages are written to standard error during the printing
 process (if output is redirected) or after all successful
 file printing is complete (when printing to a terminal).
+.Sh NOTES
+.Pp
+The interpretation of
+.Em <form-feed>s
+in the input stream is that they are special
+.Em <newline>s
+which have the side effect of causing a page break.  While this works
+correctly for all cases, strict interpretataion also implies that the
+common convention of placing a
+.Em <form-feed>
+on a line by itself is actually interpreted as a blank line, page break,
+blank line.
+.Sh RESTRICTIONS
+.Pp
+The
+.Nm pr
+utility is intended to paginate input containing basic
+.Xr ascii 7
+text formatting and input streams containing non-printing
+.Em <control-characters> ,
+.Em <escape-sequences>
+or long lines may result in formatting errors.
+.Pp
+The
+.Nm pr
+utility does not currently understand over-printing using
+.Em <back-space>
+or
+.Em <return>
+characters, and except in the case of unmodified single-column output,
+use of these characters will cause formatting errors.
+.Sh BUGS
+The lack of a line wrapping option, and the specification that truncation
+does not apply to single-column output frequently results in formatting
+errors when input lines are longer than actual line width of the output device.
+.Pp
+The default width of 72 is archaic and non-obvious since it is normally
+ignored in the default single column mode.  Using the
+.Fl m
+option with one column provides a way to truncate single column output but
+there's no way to wrap long times to a fixed line width.
+.Pp
+The default of
+.Em <tab>
+for the separator for the
+.Fl n
+and
+.Fl s
+options often results in lines apparently wider than expected.
 .Sh SEE ALSO
 .Xr cat 1 ,
-.Xr more 1
+.Xr more 1 ,
+.Xr ascii 7
 .Sh STANDARDS
 The
 .Nm pr
 utility is
 .St -p1003.2
-compatible.
+compatible, however that standard is is relatively silent concerning the
+handling of input characters beyond the behavior dictated by the
+.Nm pr
+required command
+options.
index a9cfc75..2bed739 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pr.c,v 1.4 1997/01/15 23:43:00 millert Exp $  */
+/*     $OpenBSD: pr.c,v 1.5 1997/04/23 08:08:28 grr Exp $      */
 
 /*-
  * Copyright (c) 1991 Keith Muller.
@@ -45,7 +45,7 @@ static char copyright[] =
 
 #ifndef lint
 /* from: static char sccsid[] = "@(#)pr.c      8.1 (Berkeley) 6/6/93"; */
-static char *rcsid = "$OpenBSD: pr.c,v 1.4 1997/01/15 23:43:00 millert Exp $";
+static char *rcsid = "$OpenBSD: pr.c,v 1.5 1997/04/23 08:08:28 grr Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -73,1747 +73,1917 @@ static char *rcsid = "$OpenBSD: pr.c,v 1.4 1997/01/15 23:43:00 millert Exp $";
  *     Complies with posix P1003.2/D11
  */
 
+/*
+ * 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
+ * in all four output modes required quite a bit of hacking and a few minor
+ * bugs were noted and fixed in the processs.  Some implementations have this
+ * as the as -f, some as -F so we accept either.
+ *
+ * The impelmentation of form feeds on top of the existing I/O structure is
+ * a bit ideosyncratic.  Basically they are treated as temporary end-of-file
+ * conditions and an additional level of "loop on form feed" is added to each
+ * of the output modes to continue after such a transient end-of-file's. This
+ * has the general benefit of making the existing header/trailer logic work
+ * and provides a usable framework for rational behavior in multi-column modes.
+ *
+ * The orginal "efficient" implementation of the "skip to page N" option was
+ * bogus and I substituted the basic inhibit printing until page N approach.
+ * This is still fairly bogus vis-a-vis numbering pages on multiple files
+ * restarting at one, but at least lets you consistantly reprint some large
+ * document starting in the middle, in any of the output modes.
+ *
+ * Additional support for overprinting via <back-space> or <return> would
+ * be nice, but is not trivial across tab interpretation, output formatting
+ * and the different operating modes.  Support for line-wrapping, either
+ * strict or word-wrapped would be really useful and not all that hard to
+ * kludge into the inln() implementation.  The general notion is that -wc n
+ * would specify width and wrapping with a marker character c and -Wc n
+ * would add word wrapping with a minimum width n and delimiters c, defaulting
+ * to tab, blank, and -, and column width.  Word wrapping always involves
+ * painful policy questions which are difficult to specify unless you just
+ * hardwire in some fixed rules. Think quotes, punctuation and white-space
+ * elimination and whether you'd do the same thing with a C program and
+ * something like columninated newspaper text.
+ *
+ *                             George Robbins <grr@tharsis.com> 4/22/97.
+ */
+
 /*
  * parameter variables
  */
-int    pgnm;                   /* starting page number */
-int    clcnt;                  /* number of columns */
-int    colwd;                  /* column data width - multiple columns */
-int    across;                 /* mult col flag; write across page */
-int    dspace;                 /* double space flag */
-char   inchar;                 /* expand input char */
-int    ingap;                  /* expand input gap */
-int    formfeed;               /* use formfeed as trailer */
-char   *header;                /* header name instead of file name */
-char   ochar;                  /* contract output char */
-int    ogap;                   /* contract output gap */
-int    lines;                  /* number of lines per page */
-int    merge;                  /* merge multiple files in output */
-char   nmchar;                 /* line numbering append char */
-int    nmwd;                   /* width of line number field */
-int    offst;                  /* number of page offset spaces */
-int    nodiag;                 /* do not report file open errors */
-char   schar;                  /* text column separation character */
-int    sflag;                  /* -s option for multiple columns */
-int    nohead;                 /* do not write head and trailer */
-int    pgwd;                   /* page width with multiple col output */
-char   *timefrmt;              /* time conversion string */
+int    pgnm;           /* starting page number */
+int    skipping;       /* we're skipping to page pgnum */
+int    clcnt;          /* number of columns */
+int    colwd;          /* column data width - multiple columns */
+int    across;         /* mult col flag; write across page */
+int    dspace;         /* double space flag */
+char   inchar;         /* expand input char */
+int    ingap;          /* expand input gap */
+int    formfeed;       /* use formfeed as trailer */
+int    inform;         /* grok formfeeds in input */
+char   *header;        /* header name instead of file name */
+char   ochar;          /* contract output char */
+int    ogap;           /* contract output gap */
+int    lines;          /* number of lines per page */
+int    merge;          /* merge multiple files in output */
+char   nmchar;         /* line numbering append char */
+int    nmwd;           /* width of line number field */
+int    offst;          /* number of page offset spaces */
+int    nodiag;         /* do not report file open errors */
+char   schar;          /* text column separation character */
+int    sflag;          /* -s option for multiple columns */
+int    nohead;         /* do not write head and trailer */
+int    pgwd;           /* page width with multiple col output */
+char   *timefrmt;      /* time conversion string */
 
 /*
  * misc globals
  */
-FILE   *err;                   /* error message file pointer */
-int    addone;                 /* page length is odd with double space */
-int    errcnt;                 /* error count on file processing */
+FILE   *err;           /* error message file pointer */
+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 */
 
 int
 main(argc, argv)
-        int argc;
-        char *argv[];
+       int argc;
+       char *argv[];
 {
-       int ret_val;
+    int ret_val;
 
-       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
-               (void)signal(SIGINT, terminate);
-       ret_val = setup(argc, argv);
-       if (!ret_val) {
-               /*
-                * select the output format based on options
-                */
-               if (merge)
-                       ret_val = mulfile(argc, argv);
-               else if (clcnt == 1)
-                       ret_val = onecol(argc, argv);
-               else if (across)
-                       ret_val = horzcol(argc, argv);
-               else
-                       ret_val = vertcol(argc, argv);
-       } else
-               usage();
-       flsh_errs();
-       if (errcnt || ret_val)
-               exit(1);
-       return(0);
+    if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+       (void)signal(SIGINT, terminate);
+    ret_val = setup(argc, argv);
+    if (!ret_val) {
+       /*
+        * select the output format based on options
+        */
+       if (merge)
+           ret_val = mulfile(argc, argv);
+       else if (clcnt == 1)
+           ret_val = onecol(argc, argv);
+       else if (across)
+           ret_val = horzcol(argc, argv);
+       else
+           ret_val = vertcol(argc, argv);
+    } else
+       usage();
+    flsh_errs();
+    if (errcnt || ret_val)
+       exit(1);
+    return(0);
 }
 
 /*
- * onecol:     print files with only one column of output.
- *             Line length is unlimited.
+ * onecol:    print files with only one column of output.
+ *        Line length is unlimited.
  */
 int
 onecol(argc, argv)
-        int argc;
-        char *argv[];
+    int argc;
+    char *argv[];
 {
-       register int cnt = -1;
-       register int off;
-       register int lrgln;
-       register int linecnt;
-       register int num;
-       int lncnt;
-       int pagecnt;
-       int ips;
-       int ops;
-       int cps;
-       char *obuf;
-       char *lbuf;
-       char *nbuf;
-       char *hbuf;
-       char *ohbuf;
-       FILE *inf;
-       char *fname;
-       int mor;
-
-       if (nmwd)
-               num = nmwd + 1;
-       else
-               num = 0;
-       off = num + offst;
-
-       /*
-        * allocate line buffer
-        */
-       if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
-       /*
-        * allocate header buffer
-        */
-       if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
-
-       ohbuf = hbuf + offst;
-       nbuf = obuf + offst;
-       lbuf = nbuf + num;
-       if (num)
-               nbuf[--num] = nmchar;
-       if (offst) {
-               (void)memset(obuf, (int)' ', offst);
-               (void)memset(hbuf, (int)' ', offst);
-       }
+    register int off;
+    register int lrgln;
+    register int linecnt;
+    register int num;
+    int cnt;
+    int rc;
+    int lncnt;
+    int pagecnt;
+    int ips;
+    int ops;
+    int cps;
+    char *obuf;
+    char *lbuf;
+    char *nbuf;
+    char *hbuf;
+    char *ohbuf;
+    FILE *inf;
+    char *fname;
+    int mor;
+
+    if (nmwd)
+       num = nmwd + 1;
+    else
+       num = 0;
+    off = num + offst;
+
+    /*
+     * allocate line buffer
+     */
+    if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    /*
+     * allocate header buffer
+     */
+    if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    ohbuf = hbuf + offst;
+    nbuf = obuf + offst;
+    lbuf = nbuf + num;
+
+    if (num)
+       nbuf[--num] = nmchar;
+
+    if (offst) {
+       (void)memset(obuf, (int)' ', offst);
+       (void)memset(hbuf, (int)' ', offst);
+    }
+
+    /*
+     * loop by file
+     */
+    while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
+       pagecnt = 0;
+       lncnt = 0;
 
        /*
-        * loop by file
+        * loop by "form"
         */
-       while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
-               if (pgnm) {
-                       /*
-                        * skip to specified page
-                        */
-                       if (inskip(inf, pgnm, lines))
-                               continue;
-                       pagecnt = pgnm;
-               } else
-                       pagecnt = 1;
-               lncnt = 0;
+       for(;;) {
+
+           /*
+            * loop by page
+            */
+           for(;;) {
+               linecnt = 0;
+               lrgln = 0;
+               ops = 0;
+               ips = 0;
+               cps = 0;
 
                /*
-                * loop by page
+                * loop by line
                 */
-               for(;;) {
-                       linecnt = 0;
-                       lrgln = 0;
-                       ops = 0;
-                       ips = 0;
-                       cps = 0;
-
-                       /*
-                        * loop by line
-                        */
-                       while (linecnt < lines) {
-                               /*
-                                * input next line
-                                */
-                               if ((cnt = inln(inf,lbuf,LBUF,&cps,0,&mor)) < 0)
-                                       break;
-                               if (!linecnt && !nohead &&
-                                       prhead(hbuf, fname, pagecnt))
-                                       return(1);
-
-                               /*
-                                * start of new line.
-                                */
-                               if (!lrgln) {
-                                       if (num)
-                                               addnum(nbuf, num, ++lncnt);
-                                       if (otln(obuf,cnt+off, &ips, &ops, mor))
-                                               return(1);
-                               } else if (otln(lbuf, cnt, &ips, &ops, mor))
-                                       return(1);
-
-                               /*
-                                * if line bigger than buffer, get more
-                                */
-                               if (mor) {
-                                       lrgln = 1;
-                                       continue;
-                               }
+               while (linecnt < lines) {
 
-                               /*
-                                * whole line rcvd. reset tab proc. state
-                                */
-                               ++linecnt;
-                               lrgln = 0;
-                               ops = 0;
-                               ips = 0;
-                       }
+                   /*
+                    * input next line
+                    */
+                   rc = inln(inf,lbuf,LBUF,&cnt,&cps,0,&mor);
+                   if (cnt >= 0) {
+                       if (!lrgln)
+                           if (!linecnt && prhead(hbuf, fname, ++pagecnt))
+                                return(1);
 
                        /*
-                        * fill to end of page
+                        * start new line or continue a long one
                         */
-                       if (linecnt && prtail(lines-linecnt-lrgln, lrgln))
+                       if (!lrgln) {
+                           if (num)
+                               addnum(nbuf, num, ++lncnt);
+                           if (otln(obuf,cnt+off, &ips, &ops, mor))
+                               return(1);
+                       } else
+                           if (otln(lbuf, cnt, &ips, &ops, mor))
                                return(1);
 
                        /*
-                        * On EOF go to next file
+                        * if line bigger than buffer, get more
                         */
-                       if (cnt < 0)
-                               break;
-                       ++pagecnt;
+                       if (mor) {
+                           lrgln = 1;
+                       } else {
+                           /*
+                            * whole line rcvd. reset tab proc. state
+                            */
+                           ++linecnt;
+                           lrgln = 0;
+                           ops = 0;
+                           ips = 0;
+                       }
+                   }
+
+                   if (rc != NORMAL)
+                       break;
                }
-               if (inf != stdin)
-                       (void)fclose(inf);
+
+               /*
+                * fill to end of page
+                */
+               if (prtail(lines - linecnt, lrgln))
+                   return(1);
+
+               /*
+                * unless END continue
+                */
+               if (rc == END)
+                   break;
+           }
+
+           /*
+            * On EOF go to next file
+            */
+           if (rc == END)
+           break;
        }
-       if (eoptind < argc)
-               return(1);
+
+       if (inf != stdin)
+           (void)fclose(inf);
+    }
+    /*
+     * If we didn't process all the files, return error
+     */
+    if (eoptind < argc)
+       return(1);
+    else
        return(0);
 }
 
 /*
  * vertcol:    print files with more than one column of output down a page
+ *             the general approach is to buffer a page of data, then print
  */
 int
 vertcol(argc, argv)
-        int argc;
-        char *argv[];
+       int argc;
+       char *argv[];
 {
-       register char *ptbf;
-       register char **lstdat;
-       register int i;
-       register int j;
-       register int cnt = -1;
-       register int pln;
-       register int *indy;
-       int cvc;
-       int *lindy;
-       int lncnt;
-       int stp;
-       int pagecnt;
-       int col = colwd + 1;
-       int mxlen = pgwd + offst + 1;
-       int mclcnt = clcnt - 1;
-       struct vcol *vc;
-       int mvc;
-       int tvc;
-       int cw = nmwd + 1;
-       int fullcol;
-       char *buf;
-       char *hbuf;
-       char *ohbuf;
-       char *fname;
-       FILE *inf;
-       int ips = 0;
-       int cps = 0;
-       int ops = 0;
-       int mor = 0;
-
-       /*
-        * allocate page buffer
-        */
-       if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
-
-       /*
-        * allocate page header
-        */
-       if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
-       ohbuf = hbuf + offst;
-       if (offst)
-               (void)memset(hbuf, (int)' ', offst);
-
-       /*
-        * col pointers when no headers
-        */
-       mvc = lines * clcnt;
-       if ((vc =
-           (struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) {
-               mfail();
-               return(1);
-       }
-
-       /*
-        * pointer into page where last data per line is located
-        */
-       if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){
-               mfail();
-               return(1);
-       }
-
-       /*
-        * fast index lookups to locate start of lines
-        */
-       if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
-               mfail();
-               return(1);
-       }
-       if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
-               mfail();
-               return(1);
-       }
-
-       if (nmwd)
-               fullcol = col + cw;
-       else
-               fullcol = col;
+    register char *ptbf;
+    register char **lstdat;
+    register int i;
+    register int j;
+    register int pln;
+    register int *indy;
+    int cnt;
+    int rc;
+    int cvc;
+    int *lindy;
+    int lncnt;
+    int stp;
+    int pagecnt;
+    int col = colwd + 1;
+    int mxlen = pgwd + offst + 1;
+    int mclcnt = clcnt - 1;
+    struct vcol *vc;
+    int mvc;
+    int tvc;
+    int cw = nmwd + 1;
+    int fullcol;
+    char *buf;
+    char *hbuf;
+    char *ohbuf;
+    char *fname;
+    FILE *inf;
+    int ips = 0;
+    int cps = 0;
+    int ops = 0;
+    int mor = 0;
+
+    /*
+     * allocate page buffer
+     */
+    if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    /*
+     * allocate page header
+     */
+    if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    ohbuf = hbuf + offst;
+    if (offst)
+       (void)memset(hbuf, (int)' ', offst);
+
+    /*
+     * col pointers when no headers
+     */
+    mvc = lines * clcnt;
+    if ((vc=(struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    /*
+     * pointer into page where last data per line is located
+     */
+    if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){
+       mfail();
+       return(1);
+    }
+
+    /*
+     * fast index lookups to locate start of lines
+     */
+    if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
+       mfail();
+       return(1);
+    }
+    if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    if (nmwd)
+       fullcol = col + cw;
+    else
+       fullcol = col;
+
+    /*
+     * initialize buffer lookup indexes and offset area
+     */
+    for (j = 0; j < lines; ++j) {
+       lindy[j] = j * mxlen;
+       indy[j] = lindy[j] + offst;
+       if (offst) {
+           ptbf = buf + lindy[j];
+           (void)memset(ptbf, (int)' ', offst);
+           ptbf += offst;
+       } else
+           ptbf = buf + indy[j];
+       lstdat[j] = ptbf;
+    }
+
+    /*
+     * loop by file
+     */
+    while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
+       pagecnt = 0;
+       lncnt = 0;
 
        /*
-        * initialize buffer lookup indexes and offset area
+        * loop by "form"
         */
-       for (j = 0; j < lines; ++j) {
-               lindy[j] = j * mxlen;
-               indy[j] = lindy[j] + offst;
-               if (offst) {
-                       ptbf = buf + lindy[j];
-                       (void)memset(ptbf, (int)' ', offst);
-                       ptbf += offst;
-               } else
-                       ptbf = buf + indy[j];
-               lstdat[j] = ptbf;
-       }
+        for (;;) {
 
-       /*
-        * loop by file
-        */
-       while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
-               if (pgnm) {
-                       /*
-                        * skip to requested page
-                        */
-                       if (inskip(inf, pgnm, lines))
-                               continue;
-                       pagecnt = pgnm;
-               } else
-                       pagecnt = 1;
-               lncnt = 0;
+           /*
+            * loop by page
+            */
+           for(;;) {
 
                /*
-                * loop by page
+                * loop by column
                 */
-               for(;;) {
+               cvc = 0;
+               for (i = 0; i < clcnt; ++i) {
+                   j = 0;
+                   /*
+                    * if last column, do not pad
+                    */
+                   if (i == mclcnt)
+                       stp = 1;
+                   else
+                       stp = 0;
+
+                   /*
+                    * loop by line
+                    */
+                   for(;;) {
                        /*
-                        * loop by column
+                        * is this first column
                         */
-                       cvc = 0;
-                       for (i = 0; i < clcnt; ++i) {
-                               j = 0;
-                               /*
-                                * if last column, do not pad
-                                */
-                               if (i == mclcnt)
-                                       stp = 1;
-                               else
-                                       stp = 0;
-                               /*
-                                * loop by line
-                                */
-                               for(;;) {
-                                       /*
-                                        * is this first column
-                                        */
-                                       if (!i) {
-                                               ptbf = buf + indy[j];
-                                               lstdat[j] = ptbf;
-                                       } else 
-                                               ptbf = lstdat[j];
-                                       vc[cvc].pt = ptbf;
-
-                                       /*
-                                        * add number
-                                        */
-                                       if (nmwd) {
-                                               addnum(ptbf, nmwd, ++lncnt);
-                                               ptbf += nmwd;
-                                               *ptbf++ = nmchar;
-                                       }
-
-                                       /*
-                                        * input next line
-                                        */
-                                       cnt = inln(inf,ptbf,colwd,&cps,1,&mor);
-                                       vc[cvc++].cnt = cnt;
-                                       if (cnt < 0)
-                                               break;
-                                       ptbf += cnt;
-
-                                       /*
-                                        * pad all but last column on page
-                                        */
-                                       if (!stp) {
-                                               /*
-                                                * pad to end of column
-                                                */
-                                               if (sflag)
-                                                       *ptbf++ = schar;
-                                               else if ((pln = col-cnt) > 0) {
-                                                       (void)memset(ptbf,
-                                                               (int)' ',pln);
-                                                       ptbf += pln;
-                                               }
-                                       }
-                                       /*
-                                        * remember last char in line
-                                        */
-                                       lstdat[j] = ptbf;
-                                       if (++j >= lines)
-                                               break;
-                               }
-                               if (cnt < 0)
-                                       break;
-                       }
+                       if (!i) {
+                           ptbf = buf + indy[j];
+                           lstdat[j] = ptbf;
+                       } else 
+                           ptbf = lstdat[j];
+                       vc[cvc].pt = ptbf;
 
                        /*
-                        * when -t (no header) is specified the spec requires
-                        * the min number of lines. The last page may not have
-                        * balanced length columns. To fix this we must reorder
-                        * the columns. This is a very slow technique so it is
-                        * only used under limited conditions. Without -t, the
-                        * balancing of text columns is unspecified. To NOT
-                        * balance the last page, add the global variable
-                        * nohead to the if statement below e.g.
-                        *
-                        * if ((cnt < 0) && nohead && cvc ......
+                        * add number
                         */
-                       --cvc;
+                       if (nmwd) {
+                           addnum(ptbf, nmwd, ++lncnt);
+                           ptbf += nmwd;
+                           *ptbf++ = nmchar;
+                       }
 
                        /*
-                        * check to see if last page needs to be reordered
+                        * input next line
                         */
-                       if ((cnt < 0) && cvc && ((mvc-cvc) >= clcnt)){
-                               pln = cvc/clcnt;
-                               if (cvc % clcnt)
-                                       ++pln;
-
+                       rc = inln(inf,ptbf,colwd,&cnt,&cps,1,&mor);
+                       vc[cvc++].cnt = cnt;
+                       if (cnt >= 0) {
+                           ptbf += cnt;
+
+                           /*
+                            * pad all but last column on page
+                            */
+                           if (!stp) {
                                /*
-                                * print header
+                                * pad to end of column
                                 */
-                               if (!nohead && prhead(hbuf, fname, pagecnt))
-                                       return(1);
-                               for (i = 0; i < pln; ++i) {
-                                       ips = 0;
-                                       ops = 0;
-                                       if (offst&& otln(buf,offst,&ips,&ops,1))
-                                               return(1);
-                                       tvc = i;
-
-                                       for (j = 0; j < clcnt; ++j) {
-                                               /*
-                                                * determine column length
-                                                */
-                                               if (j == mclcnt) {
-                                                       /*
-                                                        * last column
-                                                        */
-                                                       cnt = vc[tvc].cnt;
-                                                       if (nmwd)
-                                                               cnt += cw;
-                                               } else if (sflag) {
-                                                       /*
-                                                        * single ch between
-                                                        */
-                                                       cnt = vc[tvc].cnt + 1;
-                                                       if (nmwd)
-                                                               cnt += cw;
-                                               } else
-                                                       cnt = fullcol;
-                                               if (otln(vc[tvc].pt, cnt, &ips,
-                                                               &ops, 1))
-                                                       return(1);
-                                               tvc += pln;
-                                               if (tvc >= cvc)
-                                                       break;
-                                       }
-                                       /*
-                                        * terminate line
-                                        */
-                                       if (otln(buf, 0, &ips, &ops, 0))
-                                               return(1);
+                               if (sflag)
+                                   *ptbf++ = schar;
+                               else if ((pln = col-cnt) > 0) {
+                                   (void)memset(ptbf,
+                                       (int)' ',pln);
+                                   ptbf += pln;
                                }
+                           }
+
+                           /*
+                            * remember last char in line
+                            */
+                           lstdat[j] = ptbf;
+                           if (++j >= lines)
+                               break;
+                       } /* end of if cnt >= 0 */
+
+                       if (rc != NORMAL)
+                           break;
+                   } /* end of for line */
+
+                   if (rc != NORMAL)
+                       break;
+               } /* end of for column */
+
+               /*
+                * when -t (no header) is specified the spec requires
+                * the min number of lines. The last page may not have
+                * balanced length columns. To fix this we must reorder
+                * the columns. This is a very slow technique so it is
+                * only used under limited conditions. Without -t, the
+                * balancing of text columns is unspecified. To NOT
+                * balance the last page, add the global variable
+                * nohead to the if statement below e.g.
+                */
+
+               /*
+                * print header iff we got anything on the first read
+                */
+               if (vc[0].cnt >= 0) {
+                   if (prhead(hbuf, fname, ++pagecnt))
+                       return(1);
+
+                   /*
+                    * check to see if "last" page needs to be reordered
+                    */
+                   --cvc;
+                   if ((rc != NORMAL) && cvc && ((mvc-cvc) >= clcnt)){
+                       pln = cvc/clcnt;
+                       if (cvc % clcnt)
+                           ++pln;
+
+                       for (i = 0; i < pln; ++i) {
+                           ips = 0;
+                           ops = 0;
+                           if (offst && otln(buf,offst,&ips,&ops,1))
+                               return(1);
+                           tvc = i;
+
+                           for (j = 0; j < clcnt; ++j) {
                                /*
-                                * pad to end of page
-                                */
-                               if (prtail((lines - pln), 0))
-                                       return(1);
-                               /*
-                                * done with output, go to next file
+                                * determine column length
                                 */
-                               break;
+                               if (j == mclcnt) {
+                                   /*
+                                    * last column
+                                    */
+                                   cnt = vc[tvc].cnt;
+                                   if (nmwd)
+                                       cnt += cw;
+                               } else if (sflag) {
+                                   /*
+                                    * single ch between
+                                    */
+                                   cnt = vc[tvc].cnt + 1;
+                                   if (nmwd)
+                                       cnt += cw;
+                               } else
+                                   cnt = fullcol;
+
+                               if (otln(vc[tvc].pt, cnt, &ips, &ops, 1))
+                                   return(1);
+                               tvc += pln;
+                               if (tvc > cvc)
+                                   break;
+                           }
+                           /*
+                            * terminate line
+                            */
+                           if (otln(buf, 0, &ips, &ops, 0))
+                               return(1);
                        }
 
+                   } else {
+
                        /*
+                        * just a normal page...
                         * determine how many lines to output
                         */
                        if (i > 0)
-                               pln = lines;
+                           pln = lines;
                        else
-                               pln = j;
-
-                       /*
-                        * print header
-                        */
-                       if (pln && !nohead && prhead(hbuf, fname, pagecnt))
-                               return(1);
+                           pln = j;
 
                        /*
                         * output each line
                         */
                        for (i = 0; i < pln; ++i) {
-                               ptbf = buf + lindy[i];
-                               if ((j = lstdat[i] - ptbf) <= offst)
-                                       break;
+                           ptbf = buf + lindy[i];
+                           if ((j = lstdat[i] - ptbf) <= offst)
+                               break;
+                           else {
+                               ips = 0;
+                               ops = 0;
                                if (otln(ptbf, j, &ips, &ops, 0))
-                                       return(1);
+                                   return(1);
+                           }
                        }
+                   }
+               }
 
-                       /*
-                        * pad to end of page
-                        */
-                       if (pln && prtail((lines - pln), 0))
-                               return(1);
+               /*
+                * pad to end of page
+                */
+               if (prtail((lines - pln), 0))
+                   return(1);
 
-                       /*
-                        * if EOF go to next file
-                        */
-                       if (cnt < 0)
-                               break;
-                       ++pagecnt;
-               }
-               if (inf != stdin)
-                       (void)fclose(inf);
+               /*
+                * if FORM continue
+                */
+               if (rc != NORMAL)
+                   break;
+           }
+
+           /*
+            * if EOF go to next file
+            */
+           if (rc == END)
+               break;
        }
-       if (eoptind < argc)
-               return(1);
+
+       if (inf != stdin)
+           (void)fclose(inf);
+    }
+
+    if (eoptind < argc)
+       return(1);
+    else
        return(0);
 }
 
 /*
- * horzcol:    print files with more than one column of output across a page
+ * horzcol:    print files with more than one column of output across a page
  */
 int
 horzcol(argc, argv)
-        int argc;
-        char *argv[];
+       int argc;
+       char *argv[];
 {
-       register char *ptbf;
-       register int pln;
-       register int cnt = -1;
-       register char *lstdat;
-       register int col = colwd + 1;
-       register int j;
-       register int i;
-       int lncnt;
-       int pagecnt;
-       char *buf;
-       char *hbuf;
-       char *ohbuf;
-       char *fname;
-       FILE *inf;
-       int ips = 0;
-       int cps = 0;
-       int ops = 0;
-       int mor = 0;
-
-       if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
+    register char *ptbf;
+    register int pln;
+    register char *lstdat;
+    register int col = colwd + 1;
+    register int j;
+    register int i;
+    int cnt;
+    int rc;
+    int lncnt;
+    int pagecnt;
+    char *buf;
+    char *hbuf;
+    char *ohbuf;
+    char *fname;
+    FILE *inf;
+    int cps = 0;
+    int mor = 0;
+    int ips = 0;
+    int ops = 0;
+
+    if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    /*
+     * page header
+     */
+    if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    ohbuf = hbuf + offst;
+    if (offst) {
+       (void)memset(buf, (int)' ', offst);
+       (void)memset(hbuf, (int)' ', offst);
+    }
+
+    /*
+     * loop by file
+     */
+    while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
+       pagecnt = 0;
+       lncnt = 0;
 
        /*
-        * page header
+        * loop by form
         */
-       if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
-       ohbuf = hbuf + offst;
-       if (offst) {
-               (void)memset(buf, (int)' ', offst);
-               (void)memset(hbuf, (int)' ', offst);
-       }
+       for (;;) {
 
-       /*
-        * loop by file
-        */
-       while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
-               if (pgnm) {
-                       if (inskip(inf, pgnm, lines))
-                               continue;
-                       pagecnt = pgnm;
-               } else
-                       pagecnt = 1;
-               lncnt = 0;
+           /*
+            * loop by page
+            */
+           for(;;) {
 
                /*
-                * loop by page
+                * loop by line
                 */
-               for(;;) {
+               for (i = 0; i < lines; ++i) {
+                   ptbf = buf + offst;
+                   lstdat = ptbf;
+                   j = 0;
+
+                   /*
+                    * loop by col
+                    */
+                   for(;;) {
+                       if (nmwd) {
+                           /*
+                            * add number to column
+                            */
+                           addnum(ptbf, nmwd, ++lncnt);
+                           ptbf += nmwd;
+                           *ptbf++ = nmchar;
+                       }
                        /*
-                        * loop by line
+                        * input line
                         */
-                       for (i = 0; i < lines; ++i) {
-                               ptbf = buf + offst;
-                               lstdat = ptbf;
-                               j = 0;
-                               /*
-                                * loop by col
-                                */
-                               for(;;) {
-                                       if (nmwd) {
-                                               /*
-                                                * add number to column
-                                                */
-                                               addnum(ptbf, nmwd, ++lncnt);
-                                               ptbf += nmwd;
-                                               *ptbf++ = nmchar;
-                                       }
-                                       /*
-                                        * input line
-                                        */
-                                       if ((cnt = inln(inf,ptbf,colwd,&cps,1,
-                                                       &mor)) < 0)
-                                               break;
-                                       ptbf += cnt;
-                                       lstdat = ptbf;
-
-                                       /*
-                                        * if last line skip padding
-                                        */
-                                       if (++j >= clcnt)
-                                               break;
-
-                                       /*
-                                        * pad to end of column
-                                        */
-                                       if (sflag)
-                                               *ptbf++ = schar;
-                                       else if ((pln = col - cnt) > 0) {
-                                               (void)memset(ptbf,(int)' ',pln);
-                                               ptbf += pln;
-                                       }
-                               }
+                       rc = inln(inf,ptbf,colwd,&cnt,&cps,1, &mor);
+                       if (cnt >= 0) {
+                           if (!i && !j && prhead(hbuf, fname, ++pagecnt))
+                               return(1);
+
+                           ptbf += cnt;
+                           lstdat = ptbf;
+
+                           /*
+                            * if last line skip padding
+                            */
+                           if (++j >= clcnt)
+                               break;
 
-                               /*
-                                * determine line length
-                                */
-                               if ((j = lstdat - buf) <= offst)
-                                       break;
-                               if (!i && !nohead &&
-                                       prhead(hbuf, fname, pagecnt))
-                                       return(1);
-                               /*
-                                * output line
-                                */
-                               if (otln(buf, j, &ips, &ops, 0))
-                                       return(1);
+                           /*
+                            * pad to end of column
+                            */
+                           if (sflag)
+                               *ptbf++ = schar;
+                           else if ((pln = col - cnt) > 0) {
+                               (void)memset(ptbf,(int)' ',pln);
+                               ptbf += pln;
+                           }
                        }
+                       if (rc != NORMAL)
+                           break;
+                   }
+
+                   /*
+                    * output line if any columns on it
+                    */
+                   if (j) {
+                       if (otln(buf, lstdat-buf, &ips, &ops, 0))
+                           return(1);
+                   }
 
-                       /*
-                        * pad to end of page
-                        */
-                       if (i && prtail(lines-i, 0))
-                               return(1);
-
-                       /*
-                        * if EOF go to next file
-                        */
-                       if (cnt < 0)
-                               break;
-                       ++pagecnt;
+                   if (rc != NORMAL)
+                       break;
                }
-               if (inf != stdin)
-                       (void)fclose(inf);
+
+               /*
+                * pad to end of page
+                */
+               if (prtail(lines - i, 0))
+                   return(1);
+
+               /*
+                * if FORM continue
+                */
+               if (rc == END)
+                   break;
+           }
+           /*
+            * if EOF go to next file
+            */
+           if (rc == END)
+               break;
        }
-       if (eoptind < argc)
-               return(1);
-       return(0);
+       if (inf != stdin)
+           (void)fclose(inf);
+    }
+    if (eoptind < argc)
+       return(1);
+    return(0);
 }
 
 /*
- * mulfile:    print files with more than one column of output and
- *             more than one file concurrently
+ * mulfile:    print files with more than one column of output and
+ *        more than one file concurrently
  */
 int
 mulfile(argc, argv)
-        int argc;
-        char *argv[];
+    int argc;
+    char *argv[];
 {
-       register char *ptbf;
-       register int j;
-       register int pln;
-       register int cnt;
-       register char *lstdat;
-       register int i;
-       FILE **fbuf;
-       int actf;
-       int lncnt;
-       int col;
-       int pagecnt;
-       int fproc;
-       char *buf;
-       char *hbuf;
-       char *ohbuf;
-       char *fname;
-       int ips = 0;
-       int cps = 0;
-       int ops = 0;
-       int mor = 0;
-
-       /*
-        * array of FILE *, one for each operand
-        */
-       if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) {
-               mfail();
-               return(1);
-       }
-
-       /*
-        * page header
-        */
-       if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
+    register char *ptbf;
+    register int j;
+    register int pln;
+    int *rc;
+    int cnt;
+    register char *lstdat;
+    register int i;
+    FILE **fbuf;
+    int actf;
+    int lncnt;
+    int col;
+    int pagecnt;
+    int fproc;
+    char *buf;
+    char *hbuf;
+    char *ohbuf;
+    char *fname;
+    int ips = 0;
+    int cps = 0;
+    int ops = 0;
+    int mor = 0;
+
+    /*
+     * array of FILE *, one for each operand
+     */
+    if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    /*
+     * array of int *, one for each operand
+     */
+    if ((rc = (int *)malloc((unsigned)clcnt*sizeof(int))) == NULL) {
+       mfail();
+       return(1);
+    }
+
+    /*
+     * page header
+     */
+    if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+    ohbuf = hbuf + offst;
+
+    /*
+     * do not know how many columns yet. The number of operands provide an
+     * upper bound on the number of columns. We use the number of files
+     * we can open successfully to set the number of columns. The operation
+     * of the merge operation (-m) in relation to unsuccesful file opens
+     * is unspecified by posix.
+     *
+     * XXX - this seems moderately bogus, you'd think that specifying
+     * "pr -2 a b c d" would run though all the files in pairs, but
+     * the existing code says up two files, or fewer if one is bogus.
+     * fixing it would require modifying the looping structure, so be it.
+     */
+    j = 0;
+    while (j < clcnt) {
+       if ((fbuf[j] = nxtfile(argc, argv, &fname, ohbuf, 1)) != NULL) {
+           rc[j] = NORMAL;
+           j++;
        }
-       ohbuf = hbuf + offst;
+    }
 
-       /*
-        * do not know how many columns yet. The number of operands provide an
-        * upper bound on the number of columns. We use the number of files
-        * we can open successfully to set the number of columns. The operation
-        * of the merge operation (-m) in relation to unsuccesful file opens
-        * is unspecified by posix.
-        */
-       j = 0;
-       while (j < clcnt) {
-               if ((fbuf[j] = nxtfile(argc, argv, &fname, ohbuf, 1)) == NULL)
-                       break;
-               if (pgnm && (inskip(fbuf[j], pgnm, lines)))
-                       fbuf[j] = NULL;
-               ++j;
-       }
-
-       /*
-        * if no files, exit
-        */
-       if (!j)
-               return(1);
-
-       /*
-        * calculate page boundries based on open file count
-        */
+    /*
+     * if no files, exit
+     */
+    if (j)
        clcnt = j;
-       if (nmwd) {
-               colwd = (pgwd - clcnt - nmwd)/clcnt;
-               pgwd = ((colwd + 1) * clcnt) - nmwd - 2;
-       } else {
-               colwd = (pgwd + 1 - clcnt)/clcnt;
-               pgwd = ((colwd + 1) * clcnt) - 1;
-       }
-       if (colwd < 1) {
-               (void)fprintf(err,
-                 "pr: page width too small for %d columns\n", clcnt);
-               return(1);
-       }
-       actf = clcnt;
-       col = colwd + 1;
+    else
+       return(1);
+
+    /*
+     * calculate page boundries based on open file count
+     */
+    if (nmwd) {
+       colwd = (pgwd - clcnt - nmwd)/clcnt;
+       pgwd = ((colwd + 1) * clcnt) - nmwd - 2;
+    } else {
+       colwd = (pgwd + 1 - clcnt)/clcnt;
+       pgwd = ((colwd + 1) * clcnt) - 1;
+    }
+    if (colwd < 1) {
+       (void)fprintf(err,
+         "pr: page width too small for %d columns\n", clcnt);
+       return(1);
+    }
+    col = colwd + 1;
+
+    /*
+     * line buffer
+     */
+    if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
+       mfail();
+       return(1);
+    }
+    if (offst) {
+       (void)memset(buf, (int)' ', offst);
+       (void)memset(hbuf, (int)' ', offst);
+    }
+
+    pagecnt = 0;
+    lncnt = 0;
+    actf = clcnt;
+
+    /*
+     * continue to loop while any file still has data
+     */
+    while (actf > 0) {
 
        /*
-        * line buffer
+        * loop on "form"
         */
-       if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
-               mfail();
-               return(1);
-       }
-       if (offst) {
-               (void)memset(buf, (int)' ', offst);
-               (void)memset(hbuf, (int)' ', offst);
-       }
-       if (pgnm)
-               pagecnt = pgnm;
-       else
-               pagecnt = 1;
-       lncnt = 0;
+       for (;;) {
+
+           /*
+            * loop by line
+            */
+           for (i = 0; i < lines; ++i) {
+               ptbf = buf + offst;
+               lstdat = ptbf;
+               if (nmwd) {
+                   /*
+                    * add line number to line
+                    */
+                   addnum(ptbf, nmwd, ++lncnt);
+                   ptbf += nmwd;
+                   *ptbf++ = nmchar;
+               }
 
-       /*
-        * continue to loop while any file still has data
-        */
-       while (actf > 0) {
+               fproc = 0;
                /*
-                * loop by line
+                * loop by column
                 */
-               for (i = 0; i < lines; ++i) {
-                       ptbf = buf + offst;
-                       lstdat = ptbf;
-                       if (nmwd) {
-                               /*
-                                * add line number to line
-                                */
-                               addnum(ptbf, nmwd, ++lncnt);
-                               ptbf += nmwd;
-                               *ptbf++ = nmchar;
-                       }
-                       j = 0;
-                       fproc = 0;
-
-                       /*
-                        * loop by column
-                        */
-                       for (j = 0; j < clcnt; ++j) {
-                               if (fbuf[j] == NULL) {
-                                       /*
-                                        * empty column; EOF
-                                        */
-                                       cnt = 0;
-                               } else if ((cnt = inln(fbuf[j], ptbf, colwd,
-                                                       &cps, 1, &mor)) < 0) {
-                                       /*
-                                        * EOF hit; no data
-                                        */
-                                       if (fbuf[j] != stdin)
-                                               (void)fclose(fbuf[j]);
-                                       fbuf[j] = NULL;
-                                       --actf;
-                                       cnt = 0;
-                               } else {
-                                       /*
-                                        * process file data
-                                        */
-                                       ptbf += cnt;
-                                       lstdat = ptbf;
-                                       fproc++;
-                               }
-
-                               /*
-                                * if last ACTIVE column, done with line
-                                */
-                               if (fproc >= actf)
-                                       break;
-
-                               /*
-                                * pad to end of column
-                                */
-                               if (sflag) {
-                                       *ptbf++ = schar;
-                               } else if ((pln = col - cnt) > 0) {
-                                       (void)memset(ptbf, (int)' ', pln);
-                                       ptbf += pln;
-                               }
+               for (j = 0; j < clcnt; ++j) {
+                   if (rc[j] == NORMAL ) {
+                       rc[j] = inln(fbuf[j], ptbf, colwd, &cnt, &cps, 1, &mor);
+                       if (cnt >= 0) {
+                           /*
+                            * process file data
+                            */
+                           ptbf += cnt;
+                           lstdat = ptbf;
+                           fproc++;
+                       } else
+                           cnt = 0;
+                       
+                       if (rc[j] == END) {
+                           /*
+                            * EOF close file
+                            */
+                           if (fbuf[j] != stdin)
+                               (void)fclose(fbuf[j]);
+                           --actf;
                        }
+                   } else
+                       cnt = 0;
 
-                       /*
-                        * calculate data in line
-                        */
-                       if ((j = lstdat - buf) <= offst)
-                               break;
-
-                       if (!i && !nohead && prhead(hbuf, fname, pagecnt))
-                               return(1);
-
-                       /*
-                        * output line
-                        */
-                       if (otln(buf, j, &ips, &ops, 0))
-                               return(1);
+                   /*
+                    * if last ACTIVE column, done with line
+                    */
+                   if (fproc >= actf)
+                       break;
 
-                       /*
-                        * if no more active files, done
-                        */
-                       if (actf <= 0) {
-                               ++i;
-                               break;
+                   /*
+                    * pad to end of column
+                    */
+                   if (sflag) {
+                       *ptbf++ = schar;
+                   } else {
+                       if (cnt >= 0)
+                           pln = col - cnt;
+                       else
+                           pln = col;
+                       if (pln > 0) {
+                           (void)memset(ptbf, (int)' ', pln);
+                           ptbf += pln;
                        }
+                   }
                }
 
                /*
-                * pad to end of page
+                * if there was anything to do, print it
                 */
-               if (i && prtail(lines-i, 0))
+               if (fproc != 0) {
+                   if (!i && prhead(hbuf, fname, ++pagecnt))
                        return(1);
-               ++pagecnt;
-       }
-       if (eoptind < argc)
-               return(1);
-       return(0);
-}
 
-/*
- * inln():     input a line of data (unlimited length lines supported)
- *             Input is optionally expanded to spaces
- *
- *     inf:    file
- *     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 
- *     mor:    set if more data in line (not truncated)
- */
-int
-inln(inf, buf, lim, cps, trnc, mor)
-       FILE *inf;
-       char *buf;
-       register int lim;
-       int *cps;
-       int trnc;
-       int *mor;
-{
-       register int col;
-       register int gap = ingap;
-       register int ch = EOF;
-       register char *ptbuf;
-       register int chk = (int)inchar;
-
-       ptbuf = buf;
-
-       if (gap) {
-               /*
-                * expanding input option
-                */
-               while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
-                       /*
-                        * is this the input "tab" char
-                        */
-                       if (ch == chk) {
-                               /*
-                                * expand to number of spaces
-                                */
-                               col = (ptbuf - buf) + *cps;
-                               col = gap - (col % gap);
+                   /*
+                    * output line
+                    */
+                   if (otln(buf, lstdat-buf, &ips, &ops, 0))
+                       return(1);
+               } else
+                   break;
+           }
 
-                               /*
-                                * if more than this line, push back
-                                */
-                               if ((col > lim) && (ungetc(ch, inf) == EOF))
-                                       return(1);
+           /*
+            * pad to end of page
+            */
+           if (prtail(lines - i, 0))
+               return(1);
 
-                               /*
-                                * expand to spaces
-                                */
-                               while ((--col >= 0) && (--lim >= 0))
-                                       *ptbuf++ = ' ';
-                               continue;
-                       }
-                       if (ch == '\n')
-                               break;
-                       *ptbuf++ = ch;
-               }
-       } else {
-               /*
-                * no expansion
-                */
-               while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
-                       if (ch == '\n')
-                               break;
-                       *ptbuf++ = ch;
-               }
-       }
-       col = ptbuf - buf;
-       if (ch == EOF) {
-               *mor = 0;
-               *cps = 0;
-               if (!col)
-                       return(-1);
-               return(col);
-       }
-       if (ch == '\n') {
-               /*
-                * entire line processed
-                */
-               *mor = 0;
-               *cps = 0;
-               return(col);
+           for (j = 0; j < clcnt; ++j)
+               if (rc[j] != END)
+                   rc[j] = NORMAL;
+
+           if (actf <= 0)
+               break;
        }
+       if (actf <= 0)
+       break;
+    }
+    if (eoptind < argc)
+       return(1);
+    return(0);
+}
+
+/*
+ * inln():    input a line of data (unlimited length lines supported)
+ *        Input is optionally expanded to spaces
+ *        Returns 0 if normal LF, FORM on Formfeed, and END on EOF
+ *
+ *    inf:    file
+ *    buf:    buffer
+ *    lim:    buffer length
+ *    cnt:    line length or -1 if no line (EOF for example)
+ *    cps:    column positon 1st char in buffer (large line support)
+ *    trnc:    throw away data more than lim up to \n 
+ *    mor:    set if more data in line (not truncated)
+ */
+int
+inln(inf, buf, lim, cnt, cps, trnc, mor)
+    FILE *inf;
+    char *buf;
+    register int lim;
+    int *cnt;
+    int *cps;
+    int trnc;
+    int *mor;
+{
+    register int col;
+    register int gap = ingap;
+    register int ch = EOF;
+    register char *ptbuf;
+    register int chk = (int)inchar;
+
+    ptbuf = buf;
 
+    if (gap) {
        /*
-        * line was larger than limit
+        * expanding input option
         */
-       if (trnc) {
+       while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
+           /*
+            * is this the input "tab" char
+            */
+           if (ch == chk) {
                /*
-                * throw away rest of line
+                * expand to number of spaces
                 */
-               while ((ch = getc(inf)) != EOF) {
-                       if (ch == '\n')
-                               break;
+               col = (ptbuf - buf) + *cps;
+               col = gap - (col % gap);
+
+               /*
+                * if more than this line, push back
+                */
+               if ((col > lim) && (ungetc(ch, inf) == EOF)) {
+                   *cnt = -1;
+                   return(END);    /* shouldn't happen */
                }
-               *cps = 0;
-               *mor = 0;
-       } else {
+
                /*
-                * save column offset if not truncated
+                * expand to spaces
                 */
-               *cps += col;
-               *mor = 1;
+               while ((--col >= 0) && (--lim >= 0))
+                   *ptbuf++ = ' ';
+               continue;
+           }
+           if (ch == '\n' || inform && ch == INFF)
+               break;
+           *ptbuf++ = ch;
+       }
+    } else {
+       /*
+        * no expansion
+        */
+       while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
+           if (ch == '\n' || inform && ch == INFF)
+               break;
+           *ptbuf++ = ch;
+       }
+    }
+    col = ptbuf - buf;
+    if (ch == EOF) {
+       *mor = 0;
+       *cps = 0;
+       *cnt = col ? col : -1;
+       return(END);
+    }
+    if (inform && ch == INFF) {
+       *mor = 0;
+       *cps = 0;
+       *cnt = col;
+       return(FORM);
+    }
+    if (ch == '\n') {
+       /*
+        * entire line processed
+        */
+       *mor = 0;
+       *cps = 0;
+       *cnt = col;
+       return(NORMAL);
+    }
+
+    /*
+     * line was larger than limit
+     */
+    if (trnc) {
+       /*
+        * throw away rest of line
+        */
+       while ((ch = getc(inf)) != EOF) {
+           if (ch == '\n')
+               break;
        }
+       *cps = 0;
+       *mor = 0;
+    } else {
+       /*
+        * save column offset if not truncated
+        */
+       *cps += col;
+       *mor = 1;
+    }
 
-       return(col);
+    *cnt = col;
+    return(NORMAL);
 }
 
 /*
- * otln():     output a line of data. (Supports unlimited length lines)
- *             output is optionally contracted to tabs
+ * otln():    output a line of data. (Supports unlimited length lines)
+ *        output is optionally contracted to tabs
  *
- *     buf:    output buffer with data
- *     cnt:    number of chars of valid data in buf
- *     svips:  buffer input column position (for large lines)
- *     svops:  buffer output column position (for large lines)
- *     mor:    output line not complete in this buf; more data to come.        
- *             1 is more, 0 is complete, -1 is no \n's
+ *    buf:    output buffer with data
+ *    cnt:    number of chars of valid data in buf
+ *    svips:    buffer input column position (for large lines)
+ *    svops:    buffer output column position (for large lines)
+ *    mor:    output line not complete in this buf; more data to come.    
+ *        1 is more, 0 is complete, -1 is no \n's
  */
 int
 otln(buf, cnt, svips, svops, mor)
-       register char *buf;
-       int cnt;
-       int *svops;
-       int *svips;
-       int mor;
+    register char *buf;
+    int cnt;
+    int *svops;
+    int *svips;
+    int mor;
 {
-       register int ops;               /* last col output */
-       register int ips;               /* last col in buf examined */
-       register int gap = ogap;
-       register int tbps;
-       register char *endbuf;
+    register int ops;        /* last col output */
+    register int ips;        /* last col in buf examined */
+    register int gap = ogap;
+    register int tbps;
+    register char *endbuf;
+
+    /* skipping is only changed at header time not mid-line! */
+    if (skipping)
+       return (0);
 
-       if (ogap) {
+    if (ogap) {
+       /*
+        * contracting on output
+        */
+       endbuf = buf + cnt;
+       ops = *svops;
+       ips = *svips;
+       while (buf < endbuf) {
+           /*
+            * count number of spaces and ochar in buffer
+            */
+           if (*buf == ' ') {
+               ++ips;
+               ++buf;
+               continue;
+           }
+
+           /*
+            * simulate ochar processing
+            */
+           if (*buf == ochar) {
+               ips += gap - (ips % gap);
+               ++buf;
+               continue;
+           }
+
+           /*
+            * got a non space char; contract out spaces
+            */
+           while (ops < ips) {
                /*
-                * contracting on output
+                * use as many ochar as will fit
                 */
-               endbuf = buf + cnt;
-               ops = *svops;
-               ips = *svips;
-               while (buf < endbuf) {
-                       /*
-                        * count number of spaces and ochar in buffer
-                        */
-                       if (*buf == ' ') {
-                               ++ips;
-                               ++buf;
-                               continue;
-                       }
-
-                       /*
-                        * simulate ochar processing
-                        */
-                       if (*buf == ochar) {
-                               ips += gap - (ips % gap);
-                               ++buf;
-                               continue;
-                       }
-
-                       /*
-                        * got a non space char; contract out spaces
-                        */
-                       while (ops < ips) {
-                               /*
-                                * use as many ochar as will fit
-                                */
-                               if ((tbps = ops + gap - (ops % gap)) > ips)
-                                       break;
-                               if (putchar(ochar) == EOF) {
-                                       pfail();
-                                       return(1);
-                               }
-                               ops = tbps;
-                       }
-
-                       while (ops < ips) {
-                               /*
-                                * finish off with spaces
-                                */
-                               if (putchar(' ') == EOF) {
-                                       pfail();
-                                       return(1);
-                               }
-                               ++ops;
-                       }
-
-                       /*
-                        * output non space char
-                        */
-                       if (putchar(*buf++) == EOF) {
-                               pfail();
-                               return(1);
-                       }
-                       ++ips;
-                       ++ops;
+               if ((tbps = ops + gap - (ops % gap)) > ips)
+                   break;
+               if (putchar(ochar) == EOF) {
+                   pfail();
+                   return(1);
                }
+               ops = tbps;
+           }
 
-               if (mor > 0) {
-                       /*
-                        * if incomplete line, save position counts
-                        */
-                       *svops = ops;
-                       *svips = ips;
-                       return(0);
+           while (ops < ips) {
+               /*
+                * finish off with spaces
+                */
+               if (putchar(' ') == EOF) {
+                   pfail();
+                   return(1);
                }
+               ++ops;
+           }
 
-               if (mor < 0) {
-                       while (ops < ips) {
-                               /*
-                                * use as many ochar as will fit
-                                */
-                               if ((tbps = ops + gap - (ops % gap)) > ips)
-                                       break;
-                               if (putchar(ochar) == EOF) {
-                                       pfail();
-                                       return(1);
-                               }
-                               ops = tbps;
-                       }
-                       while (ops < ips) {
-                               /*
-                                * finish off with spaces
-                                */
-                               if (putchar(' ') == EOF) {
-                                       pfail();
-                                       return(1);
-                               }
-                               ++ops;
-                       }
-                       return(0);
+           /*
+            * output non space char
+            */
+           if (putchar(*buf++) == EOF) {
+               pfail();
+               return(1);
+           }
+           ++ips;
+           ++ops;
+       }
+
+       if (mor > 0) {
+           /*
+            * if incomplete line, save position counts
+            */
+           *svops = ops;
+           *svips = ips;
+           return(0);
+       }
+
+       if (mor < 0) {
+           while (ops < ips) {
+               /*
+                * use as many ochar as will fit
+                */
+               if ((tbps = ops + gap - (ops % gap)) > ips)
+                   break;
+               if (putchar(ochar) == EOF) {
+                   pfail();
+                   return(1);
                }
-       } else {
+               ops = tbps;
+           }
+           while (ops < ips) {
                /*
-                * output is not contracted
+                * finish off with spaces
                 */
-               if (cnt && (fwrite(buf, sizeof(char), cnt, stdout) <= 0)) {
-                       pfail();
-                       return(1);
+               if (putchar(' ') == EOF) {
+                   pfail();
+                   return(1);
                }
-               if (mor != 0)
-                       return(0);
+               ++ops;
+           }
+           return(0);
        }
-
+    } else {
        /*
-        * process line end and double space as required
+        * output is not contracted
         */
-       if ((putchar('\n') == EOF) || (dspace && (putchar('\n') == EOF))) {
-               pfail();
-               return(1);
+       if (cnt && (fwrite(buf, sizeof(char), cnt, stdout) <= 0)) {
+           pfail();
+           return(1);
        }
-       return(0);
+       if (mor != 0)
+           return(0);
+    }
+
+    /*
+     * process line end and double space as required
+     */
+    if ((putchar('\n') == EOF) || (dspace && (putchar('\n') == EOF))) {
+       pfail();
+       return(1);
+    }
+    return(0);
 }
 
+#ifdef notused
 /*
- * inskip():   skip over pgcnt pages with lncnt lines per page
- *             file is closed at EOF (if not stdin).
+ * inskip():    skip over pgcnt pages with lncnt lines per page
+ *        file is closed at EOF (if not stdin).
  *
- *     inf     FILE * to read from
- *     pgcnt   number of pages to skip
- *     lncnt   number of lines per page
+ *    inf    FILE * to read from
+ *    pgcnt    number of pages to skip
+ *    lncnt    number of lines per page
  */
 int
 inskip(inf, pgcnt, lncnt)
-       FILE *inf;
-       register int pgcnt;
-       register int lncnt;
+    FILE *inf;
+    register int pgcnt;
+    register int lncnt;
 {
-       register int c;
-       register int cnt;
+    register int c;
+    register int cnt;
 
-       while(--pgcnt > 0) {
-               cnt = lncnt;
-               while ((c = getc(inf)) != EOF) {
-                       if ((c == '\n') && (--cnt == 0))
-                               break;
-               }
-               if (c == EOF) {
-                       if (inf != stdin)
-                               (void)fclose(inf);
-                       return(1);
-               }
+    while(--pgcnt > 0) {
+       cnt = lncnt;
+       while ((c = getc(inf)) != EOF) {
+           if ((c == '\n') && (--cnt == 0))
+               break;
        }
-       return(0);
+       if (c == EOF) {
+           if (inf != stdin)
+               (void)fclose(inf);
+           return(1);
+       }
+    }
+    return(0);
 }
+#endif
 
 /*
- * nxtfile:    returns a FILE * to next file in arg list and sets the
- *             time field for this file (or current date).
+ * nxtfile:    returns a FILE * to next file in arg list and sets the
+ *        time field for this file (or current date).
  *
- *     buf     array to store proper date for the header.
- *     dt      if set skips the date processing (used with -m)
+ *    buf    array to store proper date for the header.
+ *    dt    if set skips the date processing (used with -m)
  */
 FILE *
 nxtfile(argc, argv, fname, buf, dt)
-       int argc;
-       char **argv;
-       char **fname;
-       char *buf;
-       int dt;
+    int argc;
+    char **argv;
+    char **fname;
+    char *buf;
+    int dt;
 {
-       FILE *inf = NULL;
-       struct timeval tv;
-       struct timezone tz;
-       struct tm *timeptr = NULL;
-       struct stat statbuf;
-       time_t curtime;
-       static int twice = -1;
-
-       ++twice;
-       if (eoptind >= argc) {
-               /*
-                * no file listed; default, use standard input
-                */
-               if (twice)
-                       return(NULL);
-               clearerr(stdin);
-               inf = stdin;
-               if (header != NULL)
-                       *fname = header;
-               else
-                       *fname = FNAME;
-               if (nohead)
-                       return(inf);
+    FILE *inf = NULL;
+    struct timeval tv;
+    struct timezone tz;
+    struct tm *timeptr = NULL;
+    struct stat statbuf;
+    time_t curtime;
+    static int twice = -1;
+
+    ++twice;
+    if (eoptind >= argc) {
+       /*
+        * no file listed; default, use standard input
+        */
+       if (twice)
+           return(NULL);
+       clearerr(stdin);
+       inf = stdin;
+       if (header != NULL)
+           *fname = header;
+       else
+           *fname = FNAME;
+       if (nohead)
+           return(inf);
+       if (gettimeofday(&tv, &tz) < 0) {
+           ++errcnt;
+           (void)fprintf(err, "pr: cannot get time of day, %s\n",
+               strerror(errno));
+           eoptind = argc - 1;
+           return(NULL);
+       }
+       curtime = tv.tv_sec;
+       timeptr = localtime(&curtime);
+    }
+    for (; eoptind < argc; ++eoptind) {
+       if (strcmp(argv[eoptind], "-") == 0) {
+           /*
+            * process a "-" for filename
+            */
+           clearerr(stdin);
+           inf = stdin;
+           if (header != NULL)
+               *fname = header;
+           else
+               *fname = FNAME;
+           ++eoptind;
+           if (nohead || (dt && twice))
+               return(inf);
+           if (gettimeofday(&tv, &tz) < 0) {
+               ++errcnt;
+               (void)fprintf(err,
+                   "pr: cannot get time of day, %s\n",
+                   strerror(errno));
+               return(NULL);
+           }
+           curtime = tv.tv_sec;
+           timeptr = localtime(&curtime);
+       } else {
+           /*
+            * normal file processing
+            */
+           if ((inf = fopen(argv[eoptind], "r")) == NULL) {
+               ++errcnt;
+               if (nodiag)
+                   continue;
+               (void)fprintf(err, "pr: Cannot open %s, %s\n",
+                   argv[eoptind], strerror(errno));
+               continue;
+           }
+           if (header != NULL)
+               *fname = header;
+           else if (dt)
+               *fname = FNAME;
+           else
+               *fname = argv[eoptind];
+           ++eoptind;
+           if (nohead || (dt && twice))
+               return(inf);
+
+           if (dt) {
                if (gettimeofday(&tv, &tz) < 0) {
-                       ++errcnt;
-                       (void)fprintf(err, "pr: cannot get time of day, %s\n",
-                               strerror(errno));
-                       eoptind = argc - 1;
-                       return(NULL);
+                   ++errcnt;
+                   (void)fprintf(err,
+                        "pr: cannot get time of day, %s\n",
+                        strerror(errno));
+                   return(NULL);
                }
                curtime = tv.tv_sec;
                timeptr = localtime(&curtime);
-       }
-       for (; eoptind < argc; ++eoptind) {
-               if (strcmp(argv[eoptind], "-") == 0) {
-                       /*
-                        * process a "-" for filename
-                        */
-                       clearerr(stdin);
-                       inf = stdin;
-                       if (header != NULL)
-                               *fname = header;
-                       else
-                               *fname = FNAME;
-                       ++eoptind;
-                       if (nohead || (dt && twice))
-                               return(inf);
-                       if (gettimeofday(&tv, &tz) < 0) {
-                               ++errcnt;
-                               (void)fprintf(err,
-                                       "pr: cannot get time of day, %s\n",
-                                       strerror(errno));
-                               return(NULL);
-                       }
-                       curtime = tv.tv_sec;
-                       timeptr = localtime(&curtime);
-               } else {
-                       /*
-                        * normal file processing
-                        */
-                       if ((inf = fopen(argv[eoptind], "r")) == NULL) {
-                               ++errcnt;
-                               if (nodiag)
-                                       continue;
-                               (void)fprintf(err, "pr: Cannot open %s, %s\n",
-                                       argv[eoptind], strerror(errno));
-                               continue;
-                       }
-                       if (header != NULL)
-                               *fname = header;
-                       else if (dt)
-                               *fname = FNAME;
-                       else
-                               *fname = argv[eoptind];
-                       ++eoptind;
-                       if (nohead || (dt && twice))
-                               return(inf);
-
-                       if (dt) {
-                               if (gettimeofday(&tv, &tz) < 0) {
-                                       ++errcnt;
-                                       (void)fprintf(err,
-                                            "pr: cannot get time of day, %s\n",
-                                            strerror(errno));
-                                       return(NULL);
-                               }
-                               curtime = tv.tv_sec;
-                               timeptr = localtime(&curtime);
-                       } else {
-                               if (fstat(fileno(inf), &statbuf) < 0) {
-                                       ++errcnt;
-                                       (void)fclose(inf);
-                                       (void)fprintf(err, 
-                                               "pr: Cannot stat %s, %s\n",
-                                               argv[eoptind], strerror(errno));
-                                       return(NULL);
-                               }
-                               timeptr = localtime(&(statbuf.st_mtime));
-                       }
+           } else {
+               if (fstat(fileno(inf), &statbuf) < 0) {
+                   ++errcnt;
+                   (void)fclose(inf);
+                   (void)fprintf(err, 
+                       "pr: Cannot stat %s, %s\n",
+                       argv[eoptind], strerror(errno));
+                   return(NULL);
                }
-               break;
-       }
-       if (inf == NULL)
-               return(NULL);
-
-       /*
-        * set up time field used in header
-        */
-       if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) {
-               ++errcnt;
-               if (inf != stdin)
-                       (void)fclose(inf);
-               (void)fputs("pr: time conversion failed\n", err);
-               return(NULL);
+               timeptr = localtime(&(statbuf.st_mtime));
+           }
        }
-       return(inf);
+       break;
+    }
+    if (inf == NULL)
+       return(NULL);
+
+    /*
+     * set up time field used in header
+     */
+    if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) {
+       ++errcnt;
+       if (inf != stdin)
+           (void)fclose(inf);
+       (void)fputs("pr: time conversion failed\n", err);
+       return(NULL);
+    }
+    return(inf);
 }
 
 /*
- * addnum():   adds the line number to the column
- *             Truncates from the front or pads with spaces as required.
- *             Numbers are right justified.
+ * addnum():    adds the line number to the column
+ *        Truncates from the front or pads with spaces as required.
+ *        Numbers are right justified.
  *
- *     buf     buffer to store the number
- *     wdth    width of buffer to fill
- *     line    line number
+ *    buf    buffer to store the number
+ *    wdth    width of buffer to fill
+ *    line    line number
  *
- *             NOTE: numbers occupy part of the column. The posix
- *             spec does not specify if -i processing should or should not
- *             occur on number padding. The spec does say it occupies
- *             part of the column. The usage of addnum currently treats
- *             numbers as part of the column so spaces may be replaced.
+ *        NOTE: numbers occupy part of the column. The posix
+ *        spec does not specify if -i processing should or should not
+ *        occur on number padding. The spec does say it occupies
+ *        part of the column. The usage of addnum    currently treats
+ *        numbers as part of the column so spaces may be replaced.
  */
 void
 addnum(buf, wdth, line)
-       register char *buf;
-       register int wdth;
-       register int line;
+    register char *buf;
+    register int wdth;
+    register int line;
 {
-       register char *pt = buf + wdth;
-
-       do {
-               *--pt = digs[line % 10];
-               line /= 10;
-       } while (line && (pt > buf));
-
-       /*
-        * pad with space as required
-        */
-       while (pt > buf)
-               *--pt = ' ';
+    register char *pt = buf + wdth;
+
+    do {
+       *--pt = digs[line % 10];
+       line /= 10;
+    } while (line && (pt > buf));
+
+    /*
+     * pad with space as required
+     */
+    while (pt > buf)
+       *--pt = ' ';
 }
 
 /*
- * prhead():   prints the top of page header
+ * prhead():    prints the top of page header
  *
- *     buf     buffer with time field (and offset)
- *     cnt     number of chars in buf
- *     fname   fname field for header
- *     pagcnt  page number
+ *    buf    buffer with time field (and offset)
+ *    cnt    number of chars in buf
+ *    fname    fname field for header
+ *    pagcnt    page number
+ *
+ * prhead() should be used carefully, we don't want to print out headers
+ * for null input files or orphan headers at the end of files, and also
+ * trailer processing is typically conditional on whether you've called
+ * prhead() at least once for a file and incremented pagecnt..  Exactly
+ * how to determine whether to print a header is a little different in
+ * the context each output mode, but we let the caller figure that out.
  */
 int
 prhead(buf, fname, pagcnt)
-       char *buf;
-       char *fname;
-       int pagcnt;
+    char *buf;
+    char *fname;
+    int pagcnt;
 {
-       int ips = 0;
-       int ops = 0;
-
-       if ((putchar('\n') == EOF) || (putchar('\n') == EOF)) {
-               pfail();
-               return(1);
-       }
-       /*
-        * posix is not clear if the header is subject to line length
-        * restrictions. The specification for header line format
-        * in the spec clearly does not limit length. No pr currently
-        * restricts header length. However if we need to truncate in
-        * an reasonable way, adjust the length of the printf by
-        * changing HDFMT to allow a length max as an arguement printf.
-        * buf (which contains the offset spaces and time field could
-        * also be trimmed
-        *
-        * note only the offset (if any) is processed for tab expansion
-        */
-       if (offst && otln(buf, offst, &ips, &ops, -1))
-               return(1);
-       (void)printf(HDFMT,buf+offst, fname, pagcnt);
-       return(0);
+    int ips = 0;
+    int ops = 0;
+
+    beheaded = 1;
+
+    if (skipping && pagcnt >= pgnm)
+       skipping = 0;
+
+    if (nohead || skipping)
+       return (0);
+
+    if ((putchar('\n') == EOF) || (putchar('\n') == EOF)) {
+       pfail();
+       return(1);
+    }
+    /*
+     * posix is not clear if the header is subject to line length
+     * restrictions. The specification for header line format
+     * in the spec clearly does not limit length. No pr currently
+     * restricts header length. However if we need to truncate in
+     * an reasonable way, adjust the length of the printf by
+     * changing HDFMT to allow a length max as an arguement printf.
+     * buf (which contains the offset spaces and time field could
+     * also be trimmed
+     *
+     * note only the offset (if any) is processed for tab expansion
+     */
+    if (offst && otln(buf, offst, &ips, &ops, -1))
+       return(1);
+    (void)printf(HDFMT,buf+offst, fname, pagcnt);
+    return(0);
 }
 
 /*
- * prtail():   pad page with empty lines (if required) and print page trailer
- *             if requested
+ * prtail():    pad page with empty lines (if required) and print page trailer
+ *        if requested
  *
- *     cnt     number of lines of padding needed
- *     incomp  was a '\n' missing from last line output
+ *    cnt      number of lines of padding needed
+ *    incomp    was a '\n' missing from last line output
+ *
+ * prtail() can now be invoked unconditionally, with the notion that if
+ * we haven't printed a hearder, these no need for a trailer
  */
 int
 prtail(cnt, incomp)
-       register int cnt;
-       int incomp;
+    register int cnt;
+    int incomp;
 {
-       if (nohead) {
-               /*
-                * only pad with no headers when incomplete last line
-                */
-               if (incomp &&
-                   ((dspace && (putchar('\n') == EOF)) ||
-                    (putchar('\n') == EOF))) {
-                       pfail();
-                       return(1);
-               }
-               /*
-                * but honor the formfeed request
-                */
-               if (formfeed) {
-                       if (putchar('\f') == EOF) {
-                               pfail();
-                               return(1);
-                       }
+    /*
+     * if were's skipping to page N or haven't put out anything yet just exit
+     */
+    if (skipping || beheaded == 0)
+       return (0);
+    beheaded = 0;
+
+    /*
+     * if noheaders, only terminate an incomplete last line
+     */
+    if (nohead) {
+
+       if (incomp) {
+           if (dspace)
+               if (putchar('\n') == EOF) {
+                   pfail();
+                   return(1);
                }
-               return(0);
+           if (putchar('\n') == EOF) {
+               pfail();
+               return(1);
+            }
        }
+       /*
+        * but honor the formfeed request
+        */
+       if (formfeed)
+           if (putchar(OUTFF) == EOF) {
+               pfail();
+               return(1);
+           }
+
+    } else {
 
        /*
         * if double space output two \n
+        *
+        * XXX this all seems bogus, why are we doing it here???
+        * page length is in terms of output lines and only the input is
+        * supposed to be double spaced...  otln() users should be doing
+        * something like linect+=(dspace ? 2:1).
         */
        if (dspace)
-               cnt *= 2;
+           cnt *= 2;
 
        /*
         * if an odd number of lines per page, add an extra \n
         */
        if (addone)
-               ++cnt;
+           ++cnt;
 
        /*
-        * pad page
+        * either put out a form-feed or pad page with blanks
         */
        if (formfeed) {
-               if ((incomp && (putchar('\n') == EOF)) || 
-                   (putchar('\f') == EOF)) {
-                       pfail();
-                       return(1);
+           if (incomp)
+               if (putchar('\n') == EOF) {
+                   pfail();
+                   return(1);
                }
-               return(0);
-       } 
-       cnt += TAILLEN;
-       while (--cnt >= 0) {
+           if (putchar(OUTFF) == EOF) {
+                   pfail();
+                   return(1);
+           }
+
+       } else {
+
+           if (incomp)
+               cnt++;
+
+           cnt += TAILLEN;
+           while (--cnt >= 0) {
                if (putchar('\n') == EOF) {
-                       pfail();
-                       return(1);
+                   pfail();
+                   return(1);
                }
+           }
        }
-       return(0);
+    }
+
+    return(0);
 }
 
 /*
- * terminate():        when a SIGINT is recvd
+ * terminate():    when a SIGINT is recvd
  */
 void
 terminate(which_sig)
-       int which_sig;
+    int which_sig;
 {
-       flsh_errs();
-       exit(1);
+    flsh_errs();
+    exit(1);
 }
 
 
 /*
- * flsh_errs():        output saved up diagnostic messages after all normal
- *             processing has completed
+ * flsh_errs():    output saved up diagnostic messages after all normal
+ *        processing has completed
  */
 void
 flsh_errs()
 {
-       char buf[BUFSIZ];
-
-       (void)fflush(stdout);
-       (void)fflush(err);
-       if (err == stderr)
-               return;
-       rewind(err);
-       while (fgets(buf, BUFSIZ, err) != NULL)
-               (void)fputs(buf, stderr);
+    char buf[BUFSIZ];
+
+    (void)fflush(stdout);
+    (void)fflush(err);
+    if (err == stderr)
+       return;
+    rewind(err);
+    while (fgets(buf, BUFSIZ, err) != NULL)
+       (void)fputs(buf, stderr);
 }
 
 void
 mfail()
 {
-       (void)fputs("pr: memory allocation failed\n", err);
+    (void)fputs("pr: memory allocation failed\n", err);
 }
 
 void
 pfail()
 {
-       (void)fprintf(err, "pr: write failure, %s\n", strerror(errno));
+    (void)fprintf(err, "pr: write failure, %s\n", strerror(errno));
 }
 
 void
 usage()
 {
-       (void)fputs(
-        "usage: pr [+page] [-col] [-adFmrt] [-e[ch][gap]] [-h header]\n",err);
-       (void)fputs(
-        "          [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err);
-       (void)fputs(
-        "          [-s[ch]] [-w width] [-] [file ...]\n", err);
+    (void)fputs(
+     "usage: pr [+page] [-col] [-adfFmrt] [-e[ch][gap]] [-h header]\n",err);
+    (void)fputs(
+     "          [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err);
+    (void)fputs(
+     "          [-s[ch]] [-w width] [-] [file ...]\n", err);
 }
 
 /*
- * setup:      Validate command args, initialize and perform sanity 
- *             checks on options
+ * setup:    Validate command args, initialize and perform sanity 
+ *        checks on options
  */
 int
 setup(argc, argv)
-       register int argc;
-       register char **argv;
+    register int argc;
+    register char **argv;
 {
-       register int c;
-       int eflag = 0;
-       int iflag = 0;
-       int wflag = 0;
-       int cflag = 0;
-
-       if (isatty(fileno(stdout))) {
-               /*
-                * defer diagnostics until processing is done
-                */
-               if ((err = tmpfile()) == NULL) {
-                      (void)fputs("Cannot defer diagnostic messages\n",stderr);
-                      return(1);
-               }
-       } else
-               err = stderr;
-       while ((c = egetopt(argc, argv, "#adFmrte?h:i?l:n?o:s?w:")) != -1) {
-               switch (c) {
-               case '+':
-                       if ((pgnm = atoi(eoptarg)) < 1) {
-                           (void)fputs("pr: +page number must be 1 or more\n",
-                               err);
-                           return(1);
-                       }
-                       break;
-               case '-':
-                       if ((clcnt = atoi(eoptarg)) < 1) {
-                           (void)fputs("pr: -columns must be 1 or more\n",err);
-                           return(1);
-                       }
-                       if (clcnt > 1)
-                               ++cflag;
-                       break;
-               case 'a':
-                       ++across;
-                       break;
-               case 'd':
-                       ++dspace;
-                       break;
-               case 'e':
-                       ++eflag;
-                       if ((eoptarg != NULL) && !isdigit(*eoptarg))
-                               inchar = *eoptarg++;
-                       else
-                               inchar = INCHAR;
-                       if ((eoptarg != NULL) && isdigit(*eoptarg)) {
-                               if ((ingap = atoi(eoptarg)) < 0) {
-                                       (void)fputs(
-                                       "pr: -e gap must be 0 or more\n", err);
-                                       return(1);
-                               }
-                               if (ingap == 0)
-                                       ingap = INGAP;
-                       } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
-                               (void)fprintf(err,
-                                     "pr: invalid value for -e %s\n", eoptarg);
-                               return(1);
-                       } else
-                               ingap = INGAP;
-                       break;
-               case 'F':
-                       ++formfeed;
-                       break;
-               case 'h':
-                       header = eoptarg;
-                       break;
-               case 'i':
-                       ++iflag;
-                       if ((eoptarg != NULL) && !isdigit(*eoptarg))
-                               ochar = *eoptarg++;
-                       else
-                               ochar = OCHAR;
-                       if ((eoptarg != NULL) && isdigit(*eoptarg)) {
-                               if ((ogap = atoi(eoptarg)) < 0) {
-                                       (void)fputs(
-                                       "pr: -i gap must be 0 or more\n", err);
-                                       return(1);
-                               }
-                               if (ogap == 0)
-                                       ogap = OGAP;
-                       } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
-                               (void)fprintf(err,
-                                     "pr: invalid value for -i %s\n", eoptarg);
-                               return(1);
-                       } else
-                               ogap = OGAP;
-                       break;
-               case 'l':
-                       if (!isdigit(*eoptarg) || ((lines=atoi(eoptarg)) < 1)) {
-                               (void)fputs(
-                                "pr: Number of lines must be 1 or more\n",err);
-                               return(1);
-                       }
-                       break;
-               case 'm':
-                       ++merge;
-                       break;
-               case 'n':
-                       if ((eoptarg != NULL) && !isdigit(*eoptarg))
-                               nmchar = *eoptarg++;
-                       else
-                               nmchar = NMCHAR;
-                       if ((eoptarg != NULL) && isdigit(*eoptarg)) {
-                               if ((nmwd = atoi(eoptarg)) < 1) {
-                                       (void)fputs(
-                                       "pr: -n width must be 1 or more\n",err);
-                                       return(1);
-                               }
-                       } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
-                               (void)fprintf(err,
-                                     "pr: invalid value for -n %s\n", eoptarg);
-                               return(1);
-                       } else
-                               nmwd = NMWD;
-                       break;
-               case 'o':
-                       if (!isdigit(*eoptarg) || ((offst = atoi(eoptarg))< 1)){
-                               (void)fputs("pr: -o offset must be 1 or more\n",
-                                       err);
-                               return(1);
-                       }
-                       break;
-               case 'r':
-                       ++nodiag;
-                       break;
-               case 's':
-                       ++sflag;
-                       if (eoptarg == NULL)
-                               schar = SCHAR;
-                       else
-                               schar = *eoptarg++;
-                       if (*eoptarg != '\0') {
-                               (void)fprintf(err,
-                                     "pr: invalid value for -s %s\n", eoptarg);
-                               return(1);
-                       }
-                       break;
-               case 't':
-                       ++nohead;
-                       break;
-               case 'w':
-                       ++wflag;
-                       if (!isdigit(*eoptarg) || ((pgwd = atoi(eoptarg)) < 1)){
-                               (void)fputs(
-                                  "pr: -w width must be 1 or more \n",err);
-                               return(1);
-                       }
-                       break;
-               case '?':
-               default:
-                       return(1);
-               }
-       }
+    register int c;
+    int eflag = 0;
+    int iflag = 0;
+    int wflag = 0;
+    int cflag = 0;
 
+    if (isatty(fileno(stdout))) {
        /*
-        * default and sanity checks
+        * defer diagnostics until processing is done
         */
-       if (!clcnt) {
-               if (merge) {
-                       if ((clcnt = argc - eoptind) <= 1) {
-                               clcnt = CLCNT;
-                               merge = 0;
-                       }
-               } else
-                       clcnt = CLCNT;
+       if ((err = tmpfile()) == NULL) {
+              (void)fputs("Cannot defer diagnostic messages\n",stderr);
+              return(1);
        }
-       if (across) {
-               if (clcnt == 1) {
-                       (void)fputs("pr: -a flag requires multiple columns\n",
-                               err);
-                       return(1);
+    } else
+       err = stderr;
+    while ((c = egetopt(argc, argv, "#adfFmrte?h:i?l:n?o:s?w:")) != EOF) {
+       switch (c) {
+       case '+':
+           if ((pgnm = atoi(eoptarg)) < 1) {
+               (void)fputs("pr: +page number must be 1 or more\n",
+               err);
+               return(1);
+           }
+           ++skipping;
+           break;
+       case '-':
+           if ((clcnt = atoi(eoptarg)) < 1) {
+               (void)fputs("pr: -columns must be 1 or more\n",err);
+               return(1);
+           }
+           if (clcnt > 1)
+               ++cflag;
+           break;
+       case 'a':
+           ++across;
+           break;
+       case 'd':
+           ++dspace;
+           break;
+       case 'e':
+           ++eflag;
+           if ((eoptarg != NULL) && !isdigit(*eoptarg))
+               inchar = *eoptarg++;
+           else
+               inchar = INCHAR;
+           if ((eoptarg != NULL) && isdigit(*eoptarg)) {
+               if ((ingap = atoi(eoptarg)) < 0) {
+                   (void)fputs(
+                   "pr: -e gap must be 0 or more\n", err);
+                   return(1);
                }
-               if (merge) {
-                       (void)fputs("pr: -m cannot be used with -a\n", err);
-                       return(1);
+               if (ingap == 0)
+                   ingap = INGAP;
+           } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
+               (void)fprintf(err,
+                     "pr: invalid value for -e %s\n", eoptarg);
+               return(1);
+           } else
+               ingap = INGAP;
+           break;
+       case 'f':
+       case 'F':
+           ++formfeed;
+           break;
+       case 'h':
+           header = eoptarg;
+           break;
+       case 'i':
+           ++iflag;
+           if ((eoptarg != NULL) && !isdigit(*eoptarg))
+               ochar = *eoptarg++;
+           else
+               ochar = OCHAR;
+           if ((eoptarg != NULL) && isdigit(*eoptarg)) {
+               if ((ogap = atoi(eoptarg)) < 0) {
+                   (void)fputs(
+                   "pr: -i gap must be 0 or more\n", err);
+                   return(1);
+               }
+               if (ogap == 0)
+                   ogap = OGAP;
+           } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
+               (void)fprintf(err,
+                     "pr: invalid value for -i %s\n", eoptarg);
+               return(1);
+           } else
+               ogap = OGAP;
+           break;
+       case 'l':
+           if (!isdigit(*eoptarg) || ((lines=atoi(eoptarg)) < 1)) {
+               (void)fputs(
+                "pr: Number of lines must be 1 or more\n",err);
+               return(1);
+           }
+           break;
+       case 'm':
+           ++merge;
+           break;
+       case 'n':
+           if ((eoptarg != NULL) && !isdigit(*eoptarg))
+               nmchar = *eoptarg++;
+           else
+               nmchar = NMCHAR;
+           if ((eoptarg != NULL) && isdigit(*eoptarg)) {
+               if ((nmwd = atoi(eoptarg)) < 1) {
+                   (void)fputs(
+                   "pr: -n width must be 1 or more\n",err);
+                   return(1);
                }
+           } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
+               (void)fprintf(err,
+                     "pr: invalid value for -n %s\n", eoptarg);
+               return(1);
+           } else
+               nmwd = NMWD;
+           break;
+       case 'o':
+           if (!isdigit(*eoptarg) || ((offst = atoi(eoptarg))< 1)){
+               (void)fputs("pr: -o offset must be 1 or more\n",
+                   err);
+               return(1);
+           }
+           break;
+       case 'r':
+           ++nodiag;
+           break;
+       case 's':
+           ++sflag;
+           if (eoptarg == NULL)
+               schar = SCHAR;
+           else
+               schar = *eoptarg++;
+           if (*eoptarg != '\0') {
+               (void)fprintf(err,
+                     "pr: invalid value for -s %s\n", eoptarg);
+               return(1);
+           }
+           break;
+       case 't':
+           ++nohead;
+           break;
+       case 'w':
+           ++wflag;
+           if (!isdigit(*eoptarg) || ((pgwd = atoi(eoptarg)) < 1)){
+               (void)fputs(
+                  "pr: -w width must be 1 or more \n",err);
+               return(1);
+           }
+           break;
+       case '?':
+       default:
+           return(1);
        }
-       if (!wflag) {
-               if (sflag)
-                       pgwd = SPGWD;
-               else
-                       pgwd = PGWD;
+    }
+
+    /*
+     * default and sanity checks
+     */
+    inform++;
+
+    if (!clcnt) {
+       if (merge) {
+           if ((clcnt = argc - eoptind) <= 1) {
+               clcnt = CLCNT;
+#ifdef stupid
+               merge = 0;
+#endif
+           }
+       } else
+           clcnt = CLCNT;
+    }
+    if (across) {
+       if (clcnt == 1) {
+           (void)fputs("pr: -a flag requires multiple columns\n",
+               err);
+           return(1);
        }
-       if (cflag || merge) {
-               if (!eflag) {
-                       inchar = INCHAR;
-                       ingap = INGAP;
-               }
-               if (!iflag) {
-                       ochar = OCHAR;
-                       ogap = OGAP;
-               }
+       if (merge) {
+           (void)fputs("pr: -m cannot be used with -a\n", err);
+           return(1);
        }
-       if (cflag) {
-               if (merge) {
-                       (void)fputs(
-                         "pr: -m cannot be used with multiple columns\n", err);
-                       return(1);
-               }
-               if (nmwd) {
-                       colwd = (pgwd + 1 - (clcnt * (nmwd + 2)))/clcnt;
-                       pgwd = ((colwd + nmwd + 2) * clcnt) - 1;
-               } else {
-                       colwd = (pgwd + 1 - clcnt)/clcnt;
-                       pgwd = ((colwd + 1) * clcnt) - 1;
-               }
-               if (colwd < 1) {
-                       (void)fprintf(err,
-                         "pr: page width is too small for %d columns\n",clcnt);
-                       return(1);
-               }
+    }
+    if (!wflag) {
+       if (sflag)
+           pgwd = SPGWD;
+       else
+           pgwd = PGWD;
+    }
+    if (cflag || merge) {
+       if (!eflag) {
+           inchar = INCHAR;
+           ingap = INGAP;
        }
-       if (!lines)
-               lines = LINES;
-
-       /*
-        * make sure long enough for headers. if not disable
-        */
-       if (lines <= HEADLEN + TAILLEN)
-               ++nohead;       
-       else if (!nohead)
-               lines -= HEADLEN + TAILLEN;
-
-       /*
-        * adjust for double space on odd length pages
-        */
-       if (dspace) {
-               if (lines == 1)
-                       dspace = 0;
-               else {
-                       if (lines & 1)
-                               ++addone;
-                       lines /= 2;
-               }
+       if (!iflag) {
+           ochar = OCHAR;
+           ogap = OGAP;
        }
+    }
+    if (cflag) {
+       if (merge) {
+           (void)fputs(
+             "pr: -m cannot be used with multiple columns\n", err);
+           return(1);
+       }
+       if (nmwd) {
+           colwd = (pgwd + 1 - (clcnt * (nmwd + 2)))/clcnt;
+           pgwd = ((colwd + nmwd + 2) * clcnt) - 1;
+       } else {
+           colwd = (pgwd + 1 - clcnt)/clcnt;
+           pgwd = ((colwd + 1) * clcnt) - 1;
+       }
+       if (colwd < 1) {
+           (void)fprintf(err,
+             "pr: page width is too small for %d columns\n",clcnt);
+           return(1);
+       }
+    }
+    if (!lines)
+       lines = LINES;
+
+    /*
+     * make sure long enough for headers. if not disable
+     */
+    if (lines <= HEADLEN + TAILLEN)
+       ++nohead;    
+    else if (!nohead)
+       lines -= HEADLEN + TAILLEN;
+
+    /*
+     * adjust for double space on odd length pages
+     */
+    if (dspace) {
+       if (lines == 1)
+           dspace = 0;
+       else {
+           if (lines & 1)
+               ++addone;
+           lines /= 2;
+       }
+    }
 
-       if ((timefrmt = getenv("LC_TIME")) == NULL)
-               timefrmt = TIMEFMT;
-       return(0);
+    if ((timefrmt = getenv("LC_TIME")) == NULL)
+       timefrmt = TIMEFMT;
+    return(0);
 }
index 2bc3e11..cff4da2 100644 (file)
@@ -1,4 +1,4 @@
-/* *   $OpenBSD: pr.h,v 1.2 1996/06/26 05:37:55 deraadt Exp $*/
+/* *   $OpenBSD: pr.h,v 1.3 1997/04/23 08:08:29 grr Exp $*/
 /*-
  * Copyright (c) 1991 Keith Muller.
  * Copyright (c) 1993
 #define        FNAME           ""
 #define        LBUF            8192
 #define        HDBUF           512
+#define INFF           '\f'
+#define OUTFF          '\f'
+
+/*
+ * termination return code from inln (also returns a byte count)
+ */
+#define END            -1
+#define FORM           1
+#define NORMAL         0
 
 /*
  * structure for vertical columns. Used to balance cols on last page