[BACK]Return to pr.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / pr

Diff for /src/usr.bin/pr/pr.c between version 1.4 and 1.5

version 1.4, 1997/01/15 23:43:00 version 1.5, 1997/04/23 08:08:28
Line 74 
Line 74 
  */   */
   
 /*  /*
    * 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   * parameter variables
  */   */
 int     pgnm;                   /* starting page number */  int     pgnm;           /* starting page number */
 int     clcnt;                  /* number of columns */  int     skipping;       /* we're skipping to page pgnum */
 int     colwd;                  /* column data width - multiple columns */  int     clcnt;          /* number of columns */
 int     across;                 /* mult col flag; write across page */  int     colwd;          /* column data width - multiple columns */
 int     dspace;                 /* double space flag */  int     across;         /* mult col flag; write across page */
 char    inchar;                 /* expand input char */  int     dspace;         /* double space flag */
 int     ingap;                  /* expand input gap */  char    inchar;         /* expand input char */
 int     formfeed;               /* use formfeed as trailer */  int     ingap;          /* expand input gap */
 char    *header;                /* header name instead of file name */  int     formfeed;       /* use formfeed as trailer */
 char    ochar;                  /* contract output char */  int     inform;         /* grok formfeeds in input */
 int     ogap;                   /* contract output gap */  char    *header;        /* header name instead of file name */
 int     lines;                  /* number of lines per page */  char    ochar;          /* contract output char */
 int     merge;                  /* merge multiple files in output */  int     ogap;           /* contract output gap */
 char    nmchar;                 /* line numbering append char */  int     lines;          /* number of lines per page */
 int     nmwd;                   /* width of line number field */  int     merge;          /* merge multiple files in output */
 int     offst;                  /* number of page offset spaces */  char    nmchar;         /* line numbering append char */
 int     nodiag;                 /* do not report file open errors */  int     nmwd;           /* width of line number field */
 char    schar;                  /* text column separation character */  int     offst;          /* number of page offset spaces */
 int     sflag;                  /* -s option for multiple columns */  int     nodiag;         /* do not report file open errors */
 int     nohead;                 /* do not write head and trailer */  char    schar;          /* text column separation character */
 int     pgwd;                   /* page width with multiple col output */  int     sflag;          /* -s option for multiple columns */
 char    *timefrmt;              /* time conversion string */  int     nohead;         /* do not write head and trailer */
   int     pgwd;           /* page width with multiple col output */
   char    *timefrmt;      /* time conversion string */
   
 /*  /*
  * misc globals   * misc globals
  */   */
 FILE    *err;                   /* error message file pointer */  FILE    *err;           /* error message file pointer */
 int     addone;                 /* page length is odd with double space */  int     addone = 0;     /* page length is odd with double space */
 int     errcnt;                 /* error count on file processing */  int     errcnt = 0;     /* error count on file processing */
   int     beheaded = 0;   /* header / trailer link */
 char    digs[] = "0123456789";  /* page number translation map */  char    digs[] = "0123456789";  /* page number translation map */
   
 int  int
 main(argc, argv)  main(argc, argv)
         int argc;          int argc;
         char *argv[];          char *argv[];
 {  {
         int ret_val;      int ret_val;
   
         if (signal(SIGINT, SIG_IGN) != SIG_IGN)      if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                 (void)signal(SIGINT, terminate);          (void)signal(SIGINT, terminate);
         ret_val = setup(argc, argv);      ret_val = setup(argc, argv);
         if (!ret_val) {      if (!ret_val) {
                 /*          /*
                  * select the output format based on options           * select the output format based on options
                  */           */
                 if (merge)          if (merge)
                         ret_val = mulfile(argc, argv);              ret_val = mulfile(argc, argv);
                 else if (clcnt == 1)          else if (clcnt == 1)
                         ret_val = onecol(argc, argv);              ret_val = onecol(argc, argv);
                 else if (across)          else if (across)
                         ret_val = horzcol(argc, argv);              ret_val = horzcol(argc, argv);
                 else          else
                         ret_val = vertcol(argc, argv);              ret_val = vertcol(argc, argv);
         } else      } else
                 usage();          usage();
         flsh_errs();      flsh_errs();
         if (errcnt || ret_val)      if (errcnt || ret_val)
                 exit(1);          exit(1);
         return(0);      return(0);
 }  }
   
 /*  /*
  * onecol:      print files with only one column of output.   * onecol:    print files with only one column of output.
  *              Line length is unlimited.   *        Line length is unlimited.
  */   */
 int  int
 onecol(argc, argv)  onecol(argc, argv)
         int argc;      int argc;
         char *argv[];      char *argv[];
 {  {
         register int cnt = -1;      register int off;
         register int off;      register int lrgln;
         register int lrgln;      register int linecnt;
         register int linecnt;      register int num;
         register int num;      int cnt;
         int lncnt;      int rc;
         int pagecnt;      int lncnt;
         int ips;      int pagecnt;
         int ops;      int ips;
         int cps;      int ops;
         char *obuf;      int cps;
         char *lbuf;      char *obuf;
         char *nbuf;      char *lbuf;
         char *hbuf;      char *nbuf;
         char *ohbuf;      char *hbuf;
         FILE *inf;      char *ohbuf;
         char *fname;      FILE *inf;
         int mor;      char *fname;
       int mor;
   
         if (nmwd)      if (nmwd)
                 num = nmwd + 1;          num = nmwd + 1;
         else      else
                 num = 0;          num = 0;
         off = num + offst;      off = num + offst;
   
         /*      /*
          * allocate line buffer       * allocate line buffer
          */       */
         if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) {      if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
         /*  
          * allocate header buffer  
          */  
         if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {  
                 mfail();  
                 return(1);  
         }  
   
         ohbuf = hbuf + offst;      /*
         nbuf = obuf + offst;       * allocate header buffer
         lbuf = nbuf + num;       */
         if (num)      if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
                 nbuf[--num] = nmchar;          mfail();
         if (offst) {          return(1);
                 (void)memset(obuf, (int)' ', offst);      }
                 (void)memset(hbuf, (int)' ', offst);  
         }  
   
       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) {          for(;;) {
                 if (pgnm) {  
                         /*  
                          * skip to specified page  
                          */  
                         if (inskip(inf, pgnm, lines))  
                                 continue;  
                         pagecnt = pgnm;  
                 } else  
                         pagecnt = 1;  
                 lncnt = 0;  
   
               /*
                * loop by page
                */
               for(;;) {
                   linecnt = 0;
                   lrgln = 0;
                   ops = 0;
                   ips = 0;
                   cps = 0;
   
                 /*                  /*
                  * loop by page                   * loop by line
                  */                   */
                 for(;;) {                  while (linecnt < lines) {
                         linecnt = 0;  
                         lrgln = 0;  
                         ops = 0;  
                         ips = 0;  
                         cps = 0;  
   
                         /*                      /*
                          * loop by line                       * input next line
                          */                       */
                         while (linecnt < lines) {                      rc = inln(inf,lbuf,LBUF,&cnt,&cps,0,&mor);
                                 /*                      if (cnt >= 0) {
                                  * input next line                          if (!lrgln)
                                  */                              if (!linecnt && prhead(hbuf, fname, ++pagecnt))
                                 if ((cnt = inln(inf,lbuf,LBUF,&cps,0,&mor)) < 0)                                   return(1);
                                         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;  
                                 }  
   
                                 /*  
                                  * whole line rcvd. reset tab proc. state  
                                  */  
                                 ++linecnt;  
                                 lrgln = 0;  
                                 ops = 0;  
                                 ips = 0;  
                         }  
   
                         /*                          /*
                          * 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);                                  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)                          if (mor) {
                                 break;                              lrgln = 1;
                         ++pagecnt;                          } 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);          return(0);
 }  }
   
 /*  /*
  * vertcol:     print files with more than one column of output down a page   * 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  int
 vertcol(argc, argv)  vertcol(argc, argv)
         int argc;          int argc;
         char *argv[];          char *argv[];
 {  {
         register char *ptbf;      register char *ptbf;
         register char **lstdat;      register char **lstdat;
         register int i;      register int i;
         register int j;      register int j;
         register int cnt = -1;      register int pln;
         register int pln;      register int *indy;
         register int *indy;      int cnt;
         int cvc;      int rc;
         int *lindy;      int cvc;
         int lncnt;      int *lindy;
         int stp;      int lncnt;
         int pagecnt;      int stp;
         int col = colwd + 1;      int pagecnt;
         int mxlen = pgwd + offst + 1;      int col = colwd + 1;
         int mclcnt = clcnt - 1;      int mxlen = pgwd + offst + 1;
         struct vcol *vc;      int mclcnt = clcnt - 1;
         int mvc;      struct vcol *vc;
         int tvc;      int mvc;
         int cw = nmwd + 1;      int tvc;
         int fullcol;      int cw = nmwd + 1;
         char *buf;      int fullcol;
         char *hbuf;      char *buf;
         char *ohbuf;      char *hbuf;
         char *fname;      char *ohbuf;
         FILE *inf;      char *fname;
         int ips = 0;      FILE *inf;
         int cps = 0;      int ips = 0;
         int ops = 0;      int cps = 0;
         int mor = 0;      int ops = 0;
       int mor = 0;
   
         /*      /*
          * allocate page buffer       * allocate page buffer
          */       */
         if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) {      if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
   
         /*      /*
          * allocate page header       * allocate page header
          */       */
         if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {      if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
         ohbuf = hbuf + offst;  
         if (offst)  
                 (void)memset(hbuf, (int)' ', offst);  
   
         /*      ohbuf = hbuf + offst;
          * col pointers when no headers      if (offst)
          */          (void)memset(hbuf, (int)' ', offst);
         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       * col pointers when no headers
          */       */
         if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){      mvc = lines * clcnt;
                 mfail();      if ((vc=(struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) {
                 return(1);          mfail();
         }          return(1);
       }
   
         /*      /*
          * fast index lookups to locate start of lines       * pointer into page where last data per line is located
          */       */
         if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {      if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
         if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {  
                 mfail();  
                 return(1);  
         }  
   
         if (nmwd)      /*
                 fullcol = col + cw;       * fast index lookups to locate start of lines
         else       */
                 fullcol = col;      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)
          * initialize buffer lookup indexes and offset area          fullcol = col + cw;
          */      else
         for (j = 0; j < lines; ++j) {          fullcol = col;
                 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;  
         }  
   
       /*
        * 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;
   
         /*          /*
          * loop by file           * loop by "form"
          */           */
         while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {           for (;;) {
                 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;                          if (!i) {
                         for (i = 0; i < clcnt; ++i) {                              ptbf = buf + indy[j];
                                 j = 0;                              lstdat[j] = ptbf;
                                 /*                          } else
                                  * if last column, do not pad                              ptbf = lstdat[j];
                                  */                          vc[cvc].pt = ptbf;
                                 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;  
                         }  
   
                         /*                          /*
                          * when -t (no header) is specified the spec requires                           * add number
                          * 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 ......  
                          */                           */
                         --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)){                          rc = inln(inf,ptbf,colwd,&cnt,&cps,1,&mor);
                                 pln = cvc/clcnt;                          vc[cvc++].cnt = cnt;
                                 if (cvc % clcnt)                          if (cnt >= 0) {
                                         ++pln;                              ptbf += cnt;
   
                               /*
                                * pad all but last column on page
                                */
                               if (!stp) {
                                 /*                                  /*
                                  * print header                                   * pad to end of column
                                  */                                   */
                                 if (!nohead && prhead(hbuf, fname, pagecnt))                                  if (sflag)
                                         return(1);                                      *ptbf++ = schar;
                                 for (i = 0; i < pln; ++i) {                                  else if ((pln = col-cnt) > 0) {
                                         ips = 0;                                      (void)memset(ptbf,
                                         ops = 0;                                          (int)' ',pln);
                                         if (offst&& otln(buf,offst,&ips,&ops,1))                                      ptbf += pln;
                                                 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);  
                                 }                                  }
                               }
   
                               /*
                                * 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                                   * determine column length
                                  */                                   */
                                 if (prtail((lines - pln), 0))                                  if (j == mclcnt) {
                                         return(1);                                      /*
                                 /*                                       * last column
                                  * done with output, go to next file                                       */
                                  */                                      cnt = vc[tvc].cnt;
                                 break;                                      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                           * determine how many lines to output
                          */                           */
                         if (i > 0)                          if (i > 0)
                                 pln = lines;                              pln = lines;
                         else                          else
                                 pln = j;                              pln = j;
   
                         /*                          /*
                          * print header  
                          */  
                         if (pln && !nohead && prhead(hbuf, fname, pagecnt))  
                                 return(1);  
   
                         /*  
                          * output each line                           * output each line
                          */                           */
                         for (i = 0; i < pln; ++i) {                          for (i = 0; i < pln; ++i) {
                                 ptbf = buf + lindy[i];                              ptbf = buf + lindy[i];
                                 if ((j = lstdat[i] - ptbf) <= offst)                              if ((j = lstdat[i] - ptbf) <= offst)
                                         break;                                  break;
                               else {
                                   ips = 0;
                                   ops = 0;
                                 if (otln(ptbf, j, &ips, &ops, 0))                                  if (otln(ptbf, j, &ips, &ops, 0))
                                         return(1);                                      return(1);
                               }
                         }                          }
                       }
                   }
   
                         /*                  /*
                          * pad to end of page                   * pad to end of page
                          */                   */
                         if (pln && prtail((lines - pln), 0))                  if (prtail((lines - pln), 0))
                                 return(1);                      return(1);
   
                         /*                  /*
                          * if EOF go to next file                   * if FORM continue
                          */                   */
                         if (cnt < 0)                  if (rc != NORMAL)
                                 break;                      break;
                         ++pagecnt;              }
                 }  
                 if (inf != stdin)              /*
                         (void)fclose(inf);               * 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);          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  int
 horzcol(argc, argv)  horzcol(argc, argv)
         int argc;          int argc;
         char *argv[];          char *argv[];
 {  {
         register char *ptbf;      register char *ptbf;
         register int pln;      register int pln;
         register int cnt = -1;      register char *lstdat;
         register char *lstdat;      register int col = colwd + 1;
         register int col = colwd + 1;      register int j;
         register int j;      register int i;
         register int i;      int cnt;
         int lncnt;      int rc;
         int pagecnt;      int lncnt;
         char *buf;      int pagecnt;
         char *hbuf;      char *buf;
         char *ohbuf;      char *hbuf;
         char *fname;      char *ohbuf;
         FILE *inf;      char *fname;
         int ips = 0;      FILE *inf;
         int cps = 0;      int cps = 0;
         int ops = 0;      int mor = 0;
         int mor = 0;      int ips = 0;
       int ops = 0;
   
         if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {      if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
   
         /*      /*
          * page header       * page header
          */       */
         if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {      if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
         ohbuf = hbuf + offst;  
         if (offst) {  
                 (void)memset(buf, (int)' ', offst);  
                 (void)memset(hbuf, (int)' ', offst);  
         }  
   
       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;
   
         /*          /*
          * loop by file           * loop by form
          */           */
         while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {          for (;;) {
                 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) {                          rc = inln(inf,ptbf,colwd,&cnt,&cps,1, &mor);
                                 ptbf = buf + offst;                          if (cnt >= 0) {
                                 lstdat = ptbf;                              if (!i && !j && prhead(hbuf, fname, ++pagecnt))
                                 j = 0;                                  return(1);
                                 /*  
                                  * 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;  
   
                                         /*                              ptbf += cnt;
                                          * if last line skip padding                              lstdat = ptbf;
                                          */  
                                         if (++j >= clcnt)  
                                                 break;  
   
                                         /*                              /*
                                          * pad to end of column                               * if last line skip padding
                                          */                               */
                                         if (sflag)                              if (++j >= clcnt)
                                                 *ptbf++ = schar;                                  break;
                                         else if ((pln = col - cnt) > 0) {  
                                                 (void)memset(ptbf,(int)' ',pln);  
                                                 ptbf += pln;  
                                         }  
                                 }  
   
                                 /*                              /*
                                  * determine line length                               * pad to end of column
                                  */                               */
                                 if ((j = lstdat - buf) <= offst)                              if (sflag)
                                         break;                                  *ptbf++ = schar;
                                 if (!i && !nohead &&                              else if ((pln = col - cnt) > 0) {
                                         prhead(hbuf, fname, pagecnt))                                  (void)memset(ptbf,(int)' ',pln);
                                         return(1);                                  ptbf += pln;
                                 /*                              }
                                  * output line  
                                  */  
                                 if (otln(buf, j, &ips, &ops, 0))  
                                         return(1);  
                         }                          }
                           if (rc != NORMAL)
                               break;
                       }
   
                         /*                      /*
                          * pad to end of page                       * output line if any columns on it
                          */                       */
                         if (i && prtail(lines-i, 0))                      if (j) {
                                 return(1);                          if (otln(buf, lstdat-buf, &ips, &ops, 0))
                               return(1);
                       }
   
                         /*                      if (rc != NORMAL)
                          * if EOF go to next file                          break;
                          */  
                         if (cnt < 0)  
                                 break;  
                         ++pagecnt;  
                 }                  }
                 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)          if (inf != stdin)
                 return(1);              (void)fclose(inf);
         return(0);      }
       if (eoptind < argc)
           return(1);
       return(0);
 }  }
   
 /*  /*
  * mulfile:     print files with more than one column of output and   * mulfile:    print files with more than one column of output and
  *              more than one file concurrently   *        more than one file concurrently
  */   */
 int  int
 mulfile(argc, argv)  mulfile(argc, argv)
         int argc;      int argc;
         char *argv[];      char *argv[];
 {  {
         register char *ptbf;      register char *ptbf;
         register int j;      register int j;
         register int pln;      register int pln;
         register int cnt;      int *rc;
         register char *lstdat;      int cnt;
         register int i;      register char *lstdat;
         FILE **fbuf;      register int i;
         int actf;      FILE **fbuf;
         int lncnt;      int actf;
         int col;      int lncnt;
         int pagecnt;      int col;
         int fproc;      int pagecnt;
         char *buf;      int fproc;
         char *hbuf;      char *buf;
         char *ohbuf;      char *hbuf;
         char *fname;      char *ohbuf;
         int ips = 0;      char *fname;
         int cps = 0;      int ips = 0;
         int ops = 0;      int cps = 0;
         int mor = 0;      int ops = 0;
       int mor = 0;
   
         /*      /*
          * array of FILE *, one for each operand       * array of FILE *, one for each operand
          */       */
         if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) {      if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
   
         /*      /*
          * page header       * array of int *, one for each operand
          */       */
         if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {      if ((rc = (int *)malloc((unsigned)clcnt*sizeof(int))) == NULL) {
                 mfail();          mfail();
                 return(1);          return(1);
         }      }
         ohbuf = hbuf + offst;  
   
         /*      /*
          * do not know how many columns yet. The number of operands provide an       * page header
          * 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      if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
          * of the merge operation (-m) in relation to unsuccesful file opens          mfail();
          * is unspecified by posix.          return(1);
          */      }
         j = 0;      ohbuf = hbuf + offst;
         while (j < clcnt) {  
                 if ((fbuf[j] = nxtfile(argc, argv, &fname, ohbuf, 1)) == NULL)      /*
                         break;       * do not know how many columns yet. The number of operands provide an
                 if (pgnm && (inskip(fbuf[j], pgnm, lines)))       * upper bound on the number of columns. We use the number of files
                         fbuf[j] = NULL;       * we can open successfully to set the number of columns. The operation
                 ++j;       * 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++;
         }          }
       }
   
         /*      /*
          * if no files, exit       * if no files, exit
          */       */
         if (!j)      if (j)
                 return(1);  
   
         /*  
          * calculate page boundries based on open file count  
          */  
         clcnt = j;          clcnt = j;
         if (nmwd) {      else
                 colwd = (pgwd - clcnt - nmwd)/clcnt;          return(1);
                 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;  
   
         /*      /*
          * line buffer       * calculate page boundries based on open file count
          */       */
         if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {      if (nmwd) {
                 mfail();          colwd = (pgwd - clcnt - nmwd)/clcnt;
                 return(1);          pgwd = ((colwd + 1) * clcnt) - nmwd - 2;
         }      } else {
         if (offst) {          colwd = (pgwd + 1 - clcnt)/clcnt;
                 (void)memset(buf, (int)' ', offst);          pgwd = ((colwd + 1) * clcnt) - 1;
                 (void)memset(hbuf, (int)' ', offst);      }
         }      if (colwd < 1) {
         if (pgnm)          (void)fprintf(err,
                 pagecnt = pgnm;            "pr: page width too small for %d columns\n", clcnt);
         else          return(1);
                 pagecnt = 1;      }
         lncnt = 0;      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) {
   
         /*          /*
          * continue to loop while any file still has data           * loop on "form"
          */           */
         while (actf > 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;
                   }
   
                   fproc = 0;
                 /*                  /*
                  * loop by line                   * loop by column
                  */                   */
                 for (i = 0; i < lines; ++i) {                  for (j = 0; j < clcnt; ++j) {
                         ptbf = buf + offst;                      if (rc[j] == NORMAL ) {
                         lstdat = ptbf;                          rc[j] = inln(fbuf[j], ptbf, colwd, &cnt, &cps, 1, &mor);
                         if (nmwd) {                          if (cnt >= 0) {
                                 /*                              /*
                                  * add line number to line                               * process file data
                                  */                               */
                                 addnum(ptbf, nmwd, ++lncnt);                              ptbf += cnt;
                                 ptbf += nmwd;                              lstdat = ptbf;
                                 *ptbf++ = nmchar;                              fproc++;
                           } else
                               cnt = 0;
   
                           if (rc[j] == END) {
                               /*
                                * EOF close file
                                */
                               if (fbuf[j] != stdin)
                                   (void)fclose(fbuf[j]);
                               --actf;
                         }                          }
                         j = 0;                      } else
                         fproc = 0;                          cnt = 0;
   
                         /*                      /*
                          * loop by column                       * if last ACTIVE column, done with line
                          */                       */
                         for (j = 0; j < clcnt; ++j) {                      if (fproc >= actf)
                                 if (fbuf[j] == NULL) {                          break;
                                         /*  
                                          * 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                       * pad to end of column
                                  */                       */
                                 if (fproc >= actf)                      if (sflag) {
                                         break;                          *ptbf++ = schar;
                       } else {
                                 /*                          if (cnt >= 0)
                                  * pad to end of column                              pln = col - cnt;
                                  */                          else
                                 if (sflag) {                              pln = col;
                                         *ptbf++ = schar;                          if (pln > 0) {
                                 } else if ((pln = col - cnt) > 0) {                              (void)memset(ptbf, (int)' ', pln);
                                         (void)memset(ptbf, (int)' ', pln);                              ptbf += pln;
                                         ptbf += pln;  
                                 }  
                         }                          }
                       }
                         /*  
                          * 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 no more active files, done  
                          */  
                         if (actf <= 0) {  
                                 ++i;  
                                 break;  
                         }  
                 }                  }
   
                 /*                  /*
                  * 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);                          return(1);
                 ++pagecnt;  
         }                      /*
         if (eoptind < argc)                       * output line
                        */
                       if (otln(buf, lstdat-buf, &ips, &ops, 0))
                           return(1);
                   } else
                       break;
               }
   
               /*
                * pad to end of page
                */
               if (prtail(lines - i, 0))
                 return(1);                  return(1);
         return(0);  
               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)   * inln():    input a line of data (unlimited length lines supported)
  *              Input is optionally expanded to spaces   *        Input is optionally expanded to spaces
    *        Returns 0 if normal LF, FORM on Formfeed, and END on EOF
  *   *
  *      inf:    file   *    inf:    file
  *      buf:    buffer   *    buf:    buffer
  *      lim:    buffer length   *    lim:    buffer length
  *      cps:    column positon 1st char in buffer (large line support)   *    cnt:    line length or -1 if no line (EOF for example)
  *      trnc:   throw away data more than lim up to \n   *    cps:    column positon 1st char in buffer (large line support)
  *      mor:    set if more data in line (not truncated)   *    trnc:    throw away data more than lim up to \n
    *    mor:    set if more data in line (not truncated)
  */   */
 int  int
 inln(inf, buf, lim, cps, trnc, mor)  inln(inf, buf, lim, cnt, cps, trnc, mor)
         FILE *inf;      FILE *inf;
         char *buf;      char *buf;
         register int lim;      register int lim;
         int *cps;      int *cnt;
         int trnc;      int *cps;
         int *mor;      int trnc;
       int *mor;
 {  {
         register int col;      register int col;
         register int gap = ingap;      register int gap = ingap;
         register int ch = EOF;      register int ch = EOF;
         register char *ptbuf;      register char *ptbuf;
         register int chk = (int)inchar;      register int chk = (int)inchar;
   
         ptbuf = buf;      ptbuf = buf;
   
         if (gap) {      if (gap) {
           /*
            * expanding input option
            */
           while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
               /*
                * is this the input "tab" char
                */
               if (ch == chk) {
                 /*                  /*
                  * expanding input option                   * expand to number of spaces
                  */                   */
                 while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {                  col = (ptbuf - buf) + *cps;
                         /*                  col = gap - (col % gap);
                          * is this the input "tab" char  
                          */  
                         if (ch == chk) {  
                                 /*  
                                  * expand to number of spaces  
                                  */  
                                 col = (ptbuf - buf) + *cps;  
                                 col = gap - (col % gap);  
   
                                 /*  
                                  * if more than this line, push back  
                                  */  
                                 if ((col > lim) && (ungetc(ch, inf) == EOF))  
                                         return(1);  
   
                                 /*  
                                  * expand to spaces  
                                  */  
                                 while ((--col >= 0) && (--lim >= 0))  
                                         *ptbuf++ = ' ';  
                                 continue;  
                         }  
                         if (ch == '\n')  
                                 break;  
                         *ptbuf++ = ch;  
                 }  
         } else {  
                 /*                  /*
                  * no expansion                   * if more than this line, push back
                  */                   */
                 while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {                  if ((col > lim) && (ungetc(ch, inf) == EOF)) {
                         if (ch == '\n')                      *cnt = -1;
                                 break;                      return(END);    /* shouldn't happen */
                         *ptbuf++ = ch;  
                 }                  }
         }  
         col = ptbuf - buf;  
         if (ch == EOF) {  
                 *mor = 0;  
                 *cps = 0;  
                 if (!col)  
                         return(-1);  
                 return(col);  
         }  
         if (ch == '\n') {  
                 /*                  /*
                  * entire line processed                   * expand to spaces
                  */                   */
                 *mor = 0;                  while ((--col >= 0) && (--lim >= 0))
                 *cps = 0;                      *ptbuf++ = ' ';
                 return(col);                  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) {
         /*          /*
          * line was larger than limit           * throw away rest of line
          */           */
         if (trnc) {          while ((ch = getc(inf)) != EOF) {
                 /*              if (ch == '\n')
                  * throw away rest of line                  break;
                  */  
                 while ((ch = getc(inf)) != EOF) {  
                         if (ch == '\n')  
                                 break;  
                 }  
                 *cps = 0;  
                 *mor = 0;  
         } else {  
                 /*  
                  * save column offset if not truncated  
                  */  
                 *cps += col;  
                 *mor = 1;  
         }          }
           *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)   * otln():    output a line of data. (Supports unlimited length lines)
  *              output is optionally contracted to tabs   *        output is optionally contracted to tabs
  *   *
  *      buf:    output buffer with data   *    buf:    output buffer with data
  *      cnt:    number of chars of valid data in buf   *    cnt:    number of chars of valid data in buf
  *      svips:  buffer input column position (for large lines)   *    svips:    buffer input column position (for large lines)
  *      svops:  buffer output 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.   *    mor:    output line not complete in this buf; more data to come.
  *              1 is more, 0 is complete, -1 is no \n's   *        1 is more, 0 is complete, -1 is no \n's
  */   */
 int  int
 otln(buf, cnt, svips, svops, mor)  otln(buf, cnt, svips, svops, mor)
         register char *buf;      register char *buf;
         int cnt;      int cnt;
         int *svops;      int *svops;
         int *svips;      int *svips;
         int mor;      int mor;
 {  {
         register int ops;               /* last col output */      register int ops;        /* last col output */
         register int ips;               /* last col in buf examined */      register int ips;        /* last col in buf examined */
         register int gap = ogap;      register int gap = ogap;
         register int tbps;      register int tbps;
         register char *endbuf;      register char *endbuf;
   
         if (ogap) {      /* skipping is only changed at header time not mid-line! */
                 /*      if (skipping)
                  * contracting on output          return (0);
                  */  
                 endbuf = buf + cnt;  
                 ops = *svops;  
                 ips = *svips;  
                 while (buf < endbuf) {  
                         /*  
                          * count number of spaces and ochar in buffer  
                          */  
                         if (*buf == ' ') {  
                                 ++ips;  
                                 ++buf;  
                                 continue;  
                         }  
   
                         /*      if (ogap) {
                          * simulate ochar processing          /*
                          */           * contracting on output
                         if (*buf == ochar) {           */
                                 ips += gap - (ips % gap);          endbuf = buf + cnt;
                                 ++buf;          ops = *svops;
                                 continue;          ips = *svips;
                         }          while (buf < endbuf) {
               /*
                * count number of spaces and ochar in buffer
                */
               if (*buf == ' ') {
                   ++ips;
                   ++buf;
                   continue;
               }
   
                         /*              /*
                          * got a non space char; contract out spaces               * simulate ochar processing
                          */               */
                         while (ops < ips) {              if (*buf == ochar) {
                                 /*                  ips += gap - (ips % gap);
                                  * use as many ochar as will fit                  ++buf;
                                  */                  continue;
                                 if ((tbps = ops + gap - (ops % gap)) > ips)              }
                                         break;  
                                 if (putchar(ochar) == EOF) {  
                                         pfail();  
                                         return(1);  
                                 }  
                                 ops = tbps;  
                         }  
   
                         while (ops < ips) {              /*
                                 /*               * got a non space char; contract out spaces
                                  * finish off with spaces               */
                                  */              while (ops < ips) {
                                 if (putchar(' ') == EOF) {                  /*
                                         pfail();                   * use as many ochar as will fit
                                         return(1);                   */
                                 }                  if ((tbps = ops + gap - (ops % gap)) > ips)
                                 ++ops;                      break;
                         }                  if (putchar(ochar) == EOF) {
                       pfail();
                         /*                      return(1);
                          * output non space char  
                          */  
                         if (putchar(*buf++) == EOF) {  
                                 pfail();  
                                 return(1);  
                         }  
                         ++ips;  
                         ++ops;  
                 }                  }
                   ops = tbps;
               }
   
                 if (mor > 0) {              while (ops < ips) {
                         /*                  /*
                          * if incomplete line, save position counts                   * finish off with spaces
                          */                   */
                         *svops = ops;                  if (putchar(' ') == EOF) {
                         *svips = ips;                      pfail();
                         return(0);                      return(1);
                 }                  }
                   ++ops;
               }
   
                 if (mor < 0) {              /*
                         while (ops < ips) {               * output non space char
                                 /*               */
                                  * use as many ochar as will fit              if (putchar(*buf++) == EOF) {
                                  */                  pfail();
                                 if ((tbps = ops + gap - (ops % gap)) > ips)                  return(1);
                                         break;              }
                                 if (putchar(ochar) == EOF) {              ++ips;
                                         pfail();              ++ops;
                                         return(1);          }
                                 }  
                                 ops = tbps;          if (mor > 0) {
                         }              /*
                         while (ops < ips) {               * if incomplete line, save position counts
                                 /*               */
                                  * finish off with spaces              *svops = ops;
                                  */              *svips = ips;
                                 if (putchar(' ') == EOF) {              return(0);
                                         pfail();          }
                                         return(1);  
                                 }          if (mor < 0) {
                                 ++ops;              while (ops < ips) {
                         }                  /*
                         return(0);                   * 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)) {                  if (putchar(' ') == EOF) {
                         pfail();                      pfail();
                         return(1);                      return(1);
                 }                  }
                 if (mor != 0)                  ++ops;
                         return(0);              }
               return(0);
         }          }
       } else {
         /*          /*
          * process line end and double space as required           * output is not contracted
          */           */
         if ((putchar('\n') == EOF) || (dspace && (putchar('\n') == EOF))) {          if (cnt && (fwrite(buf, sizeof(char), cnt, stdout) <= 0)) {
                 pfail();              pfail();
                 return(1);              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   * inskip():    skip over pgcnt pages with lncnt lines per page
  *              file is closed at EOF (if not stdin).   *        file is closed at EOF (if not stdin).
  *   *
  *      inf     FILE * to read from   *    inf    FILE * to read from
  *      pgcnt   number of pages to skip   *    pgcnt    number of pages to skip
  *      lncnt   number of lines per page   *    lncnt    number of lines per page
  */   */
 int  int
 inskip(inf, pgcnt, lncnt)  inskip(inf, pgcnt, lncnt)
         FILE *inf;      FILE *inf;
         register int pgcnt;      register int pgcnt;
         register int lncnt;      register int lncnt;
 {  {
         register int c;      register int c;
         register int cnt;      register int cnt;
   
         while(--pgcnt > 0) {      while(--pgcnt > 0) {
                 cnt = lncnt;          cnt = lncnt;
                 while ((c = getc(inf)) != EOF) {          while ((c = getc(inf)) != EOF) {
                         if ((c == '\n') && (--cnt == 0))              if ((c == '\n') && (--cnt == 0))
                                 break;                  break;
                 }  
                 if (c == EOF) {  
                         if (inf != stdin)  
                                 (void)fclose(inf);  
                         return(1);  
                 }  
         }          }
         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   * nxtfile:    returns a FILE * to next file in arg list and sets the
  *              time field for this file (or current date).   *        time field for this file (or current date).
  *   *
  *      buf     array to store proper date for the header.   *    buf    array to store proper date for the header.
  *      dt      if set skips the date processing (used with -m)   *    dt    if set skips the date processing (used with -m)
  */   */
 FILE *  FILE *
 nxtfile(argc, argv, fname, buf, dt)  nxtfile(argc, argv, fname, buf, dt)
         int argc;      int argc;
         char **argv;      char **argv;
         char **fname;      char **fname;
         char *buf;      char *buf;
         int dt;      int dt;
 {  {
         FILE *inf = NULL;      FILE *inf = NULL;
         struct timeval tv;      struct timeval tv;
         struct timezone tz;      struct timezone tz;
         struct tm *timeptr = NULL;      struct tm *timeptr = NULL;
         struct stat statbuf;      struct stat statbuf;
         time_t curtime;      time_t curtime;
         static int twice = -1;      static int twice = -1;
   
         ++twice;      ++twice;
         if (eoptind >= argc) {      if (eoptind >= argc) {
                 /*          /*
                  * no file listed; default, use standard input           * no file listed; default, use standard input
                  */           */
                 if (twice)          if (twice)
                         return(NULL);              return(NULL);
                 clearerr(stdin);          clearerr(stdin);
                 inf = stdin;          inf = stdin;
                 if (header != NULL)          if (header != NULL)
                         *fname = header;              *fname = header;
                 else          else
                         *fname = FNAME;              *fname = FNAME;
                 if (nohead)          if (nohead)
                         return(inf);              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) {                  if (gettimeofday(&tv, &tz) < 0) {
                         ++errcnt;                      ++errcnt;
                         (void)fprintf(err, "pr: cannot get time of day, %s\n",                      (void)fprintf(err,
                                 strerror(errno));                           "pr: cannot get time of day, %s\n",
                         eoptind = argc - 1;                           strerror(errno));
                         return(NULL);                      return(NULL);
                 }                  }
                 curtime = tv.tv_sec;                  curtime = tv.tv_sec;
                 timeptr = localtime(&curtime);                  timeptr = localtime(&curtime);
         }              } else {
         for (; eoptind < argc; ++eoptind) {                  if (fstat(fileno(inf), &statbuf) < 0) {
                 if (strcmp(argv[eoptind], "-") == 0) {                      ++errcnt;
                         /*                      (void)fclose(inf);
                          * process a "-" for filename                      (void)fprintf(err,
                          */                          "pr: Cannot stat %s, %s\n",
                         clearerr(stdin);                          argv[eoptind], strerror(errno));
                         inf = stdin;                      return(NULL);
                         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));  
                         }  
                 }                  }
                 break;                  timeptr = localtime(&(statbuf.st_mtime));
               }
         }          }
         if (inf == NULL)          break;
                 return(NULL);      }
       if (inf == NULL)
           return(NULL);
   
         /*      /*
          * set up time field used in header       * set up time field used in header
          */       */
         if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) {      if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) {
                 ++errcnt;          ++errcnt;
                 if (inf != stdin)          if (inf != stdin)
                         (void)fclose(inf);              (void)fclose(inf);
                 (void)fputs("pr: time conversion failed\n", err);          (void)fputs("pr: time conversion failed\n", err);
                 return(NULL);          return(NULL);
         }      }
         return(inf);      return(inf);
 }  }
   
 /*  /*
  * addnum():    adds the line number to the column   * addnum():    adds the line number to the column
  *              Truncates from the front or pads with spaces as required.   *        Truncates from the front or pads with spaces as required.
  *              Numbers are right justified.   *        Numbers are right justified.
  *   *
  *      buf     buffer to store the number   *    buf    buffer to store the number
  *      wdth    width of buffer to fill   *    wdth    width of buffer to fill
  *      line    line number   *    line    line number
  *   *
  *              NOTE: numbers occupy part of the column. The posix   *        NOTE: numbers occupy part of the column. The posix
  *              spec does not specify if -i processing should or should not   *        spec does not specify if -i processing should or should not
  *              occur on number padding. The spec does say it occupies   *        occur on number padding. The spec does say it occupies
  *              part of the column. The usage of addnum currently treats   *        part of the column. The usage of addnum    currently treats
  *              numbers as part of the column so spaces may be replaced.   *        numbers as part of the column so spaces may be replaced.
  */   */
 void  void
 addnum(buf, wdth, line)  addnum(buf, wdth, line)
         register char *buf;      register char *buf;
         register int wdth;      register int wdth;
         register int line;      register int line;
 {  {
         register char *pt = buf + wdth;      register char *pt = buf + wdth;
   
         do {      do {
                 *--pt = digs[line % 10];          *--pt = digs[line % 10];
                 line /= 10;          line /= 10;
         } while (line && (pt > buf));      } while (line && (pt > buf));
   
         /*      /*
          * pad with space as required       * pad with space as required
          */       */
         while (pt > buf)      while (pt > buf)
                 *--pt = ' ';          *--pt = ' ';
 }  }
   
 /*  /*
  * prhead():    prints the top of page header   * prhead():    prints the top of page header
  *   *
  *      buf     buffer with time field (and offset)   *    buf    buffer with time field (and offset)
  *      cnt     number of chars in buf   *    cnt    number of chars in buf
  *      fname   fname field for header   *    fname    fname field for header
  *      pagcnt  page number   *    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  int
 prhead(buf, fname, pagcnt)  prhead(buf, fname, pagcnt)
         char *buf;      char *buf;
         char *fname;      char *fname;
         int pagcnt;      int pagcnt;
 {  {
         int ips = 0;      int ips = 0;
         int ops = 0;      int ops = 0;
   
         if ((putchar('\n') == EOF) || (putchar('\n') == EOF)) {      beheaded = 1;
                 pfail();  
                 return(1);      if (skipping && pagcnt >= pgnm)
         }          skipping = 0;
         /*  
          * posix is not clear if the header is subject to line length      if (nohead || skipping)
          * restrictions. The specification for header line format          return (0);
          * in the spec clearly does not limit length. No pr currently  
          * restricts header length. However if we need to truncate in      if ((putchar('\n') == EOF) || (putchar('\n') == EOF)) {
          * an reasonable way, adjust the length of the printf by          pfail();
          * changing HDFMT to allow a length max as an arguement printf.          return(1);
          * buf (which contains the offset spaces and time field could      }
          * also be trimmed      /*
          *       * posix is not clear if the header is subject to line length
          * note only the offset (if any) is processed for tab expansion       * restrictions. The specification for header line format
          */       * in the spec clearly does not limit length. No pr currently
         if (offst && otln(buf, offst, &ips, &ops, -1))       * restricts header length. However if we need to truncate in
                 return(1);       * an reasonable way, adjust the length of the printf by
         (void)printf(HDFMT,buf+offst, fname, pagcnt);       * changing HDFMT to allow a length max as an arguement printf.
         return(0);       * 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   * prtail():    pad page with empty lines (if required) and print page trailer
  *              if requested   *        if requested
  *   *
  *      cnt     number of lines of padding needed   *    cnt       number of lines of padding needed
  *      incomp  was a '\n' missing from last line output   *    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  int
 prtail(cnt, incomp)  prtail(cnt, incomp)
         register int cnt;      register int cnt;
         int incomp;      int incomp;
 {  {
         if (nohead) {      /*
                 /*       * if were's skipping to page N or haven't put out anything yet just exit
                  * only pad with no headers when incomplete last line       */
                  */      if (skipping || beheaded == 0)
                 if (incomp &&          return (0);
                     ((dspace && (putchar('\n') == EOF)) ||      beheaded = 0;
                      (putchar('\n') == EOF))) {  
                         pfail();      /*
                         return(1);       * if noheaders, only terminate an incomplete last line
        */
       if (nohead) {
   
           if (incomp) {
               if (dspace)
                   if (putchar('\n') == EOF) {
                       pfail();
                       return(1);
                 }                  }
                 /*              if (putchar('\n') == EOF) {
                  * but honor the formfeed request                  pfail();
                  */                  return(1);
                 if (formfeed) {               }
                         if (putchar('\f') == EOF) {  
                                 pfail();  
                                 return(1);  
                         }  
                 }  
                 return(0);  
         }          }
           /*
            * but honor the formfeed request
            */
           if (formfeed)
               if (putchar(OUTFF) == EOF) {
                   pfail();
                   return(1);
               }
   
       } else {
   
         /*          /*
          * if double space output two \n           * 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)          if (dspace)
                 cnt *= 2;              cnt *= 2;
   
         /*          /*
          * if an odd number of lines per page, add an extra \n           * if an odd number of lines per page, add an extra \n
          */           */
         if (addone)          if (addone)
                 ++cnt;              ++cnt;
   
         /*          /*
          * pad page           * either put out a form-feed or pad page with blanks
          */           */
         if (formfeed) {          if (formfeed) {
                 if ((incomp && (putchar('\n') == EOF)) ||              if (incomp)
                     (putchar('\f') == EOF)) {                  if (putchar('\n') == EOF) {
                         pfail();                      pfail();
                         return(1);                      return(1);
                 }                  }
                 return(0);              if (putchar(OUTFF) == EOF) {
         }                      pfail();
         cnt += TAILLEN;                      return(1);
         while (--cnt >= 0) {              }
   
           } else {
   
               if (incomp)
                   cnt++;
   
               cnt += TAILLEN;
               while (--cnt >= 0) {
                 if (putchar('\n') == EOF) {                  if (putchar('\n') == EOF) {
                         pfail();                      pfail();
                         return(1);                      return(1);
                 }                  }
               }
         }          }
         return(0);      }
   
       return(0);
 }  }
   
 /*  /*
  * terminate(): when a SIGINT is recvd   * terminate():    when a SIGINT is recvd
  */   */
 void  void
 terminate(which_sig)  terminate(which_sig)
         int which_sig;      int which_sig;
 {  {
         flsh_errs();      flsh_errs();
         exit(1);      exit(1);
 }  }
   
   
 /*  /*
  * flsh_errs(): output saved up diagnostic messages after all normal   * flsh_errs():    output saved up diagnostic messages after all normal
  *              processing has completed   *        processing has completed
  */   */
 void  void
 flsh_errs()  flsh_errs()
 {  {
         char buf[BUFSIZ];      char buf[BUFSIZ];
   
         (void)fflush(stdout);      (void)fflush(stdout);
         (void)fflush(err);      (void)fflush(err);
         if (err == stderr)      if (err == stderr)
                 return;          return;
         rewind(err);      rewind(err);
         while (fgets(buf, BUFSIZ, err) != NULL)      while (fgets(buf, BUFSIZ, err) != NULL)
                 (void)fputs(buf, stderr);          (void)fputs(buf, stderr);
 }  }
   
 void  void
 mfail()  mfail()
 {  {
         (void)fputs("pr: memory allocation failed\n", err);      (void)fputs("pr: memory allocation failed\n", err);
 }  }
   
 void  void
 pfail()  pfail()
 {  {
         (void)fprintf(err, "pr: write failure, %s\n", strerror(errno));      (void)fprintf(err, "pr: write failure, %s\n", strerror(errno));
 }  }
   
 void  void
 usage()  usage()
 {  {
         (void)fputs(      (void)fputs(
          "usage: pr [+page] [-col] [-adFmrt] [-e[ch][gap]] [-h header]\n",err);       "usage: pr [+page] [-col] [-adfFmrt] [-e[ch][gap]] [-h header]\n",err);
         (void)fputs(      (void)fputs(
          "          [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err);       "          [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err);
         (void)fputs(      (void)fputs(
          "          [-s[ch]] [-w width] [-] [file ...]\n", err);       "          [-s[ch]] [-w width] [-] [file ...]\n", err);
 }  }
   
 /*  /*
  * setup:       Validate command args, initialize and perform sanity   * setup:    Validate command args, initialize and perform sanity
  *              checks on options   *        checks on options
  */   */
 int  int
 setup(argc, argv)  setup(argc, argv)
         register int argc;      register int argc;
         register char **argv;      register char **argv;
 {  {
         register int c;      register int c;
         int eflag = 0;      int eflag = 0;
         int iflag = 0;      int iflag = 0;
         int wflag = 0;      int wflag = 0;
         int cflag = 0;      int cflag = 0;
   
         if (isatty(fileno(stdout))) {      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);  
                 }  
         }  
   
         /*          /*
          * default and sanity checks           * defer diagnostics until processing is done
          */           */
         if (!clcnt) {          if ((err = tmpfile()) == NULL) {
                 if (merge) {                 (void)fputs("Cannot defer diagnostic messages\n",stderr);
                         if ((clcnt = argc - eoptind) <= 1) {                 return(1);
                                 clcnt = CLCNT;  
                                 merge = 0;  
                         }  
                 } else  
                         clcnt = CLCNT;  
         }          }
         if (across) {      } else
                 if (clcnt == 1) {          err = stderr;
                         (void)fputs("pr: -a flag requires multiple columns\n",      while ((c = egetopt(argc, argv, "#adfFmrte?h:i?l:n?o:s?w:")) != EOF) {
                                 err);          switch (c) {
                         return(1);          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) {                  if (ingap == 0)
                         (void)fputs("pr: -m cannot be used with -a\n", err);                      ingap = INGAP;
                         return(1);              } 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       * default and sanity checks
                         pgwd = PGWD;       */
       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 (merge) {
                 if (!eflag) {              (void)fputs("pr: -m cannot be used with -a\n", err);
                         inchar = INCHAR;              return(1);
                         ingap = INGAP;  
                 }  
                 if (!iflag) {  
                         ochar = OCHAR;  
                         ogap = OGAP;  
                 }  
         }          }
         if (cflag) {      }
                 if (merge) {      if (!wflag) {
                         (void)fputs(          if (sflag)
                           "pr: -m cannot be used with multiple columns\n", err);              pgwd = SPGWD;
                         return(1);          else
                 }              pgwd = PGWD;
                 if (nmwd) {      }
                         colwd = (pgwd + 1 - (clcnt * (nmwd + 2)))/clcnt;      if (cflag || merge) {
                         pgwd = ((colwd + nmwd + 2) * clcnt) - 1;          if (!eflag) {
                 } else {              inchar = INCHAR;
                         colwd = (pgwd + 1 - clcnt)/clcnt;              ingap = INGAP;
                         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)          if (!iflag) {
                 lines = LINES;              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       * make sure long enough for headers. if not disable
          */       */
         if (lines <= HEADLEN + TAILLEN)      if (lines <= HEADLEN + TAILLEN)
                 ++nohead;          ++nohead;
         else if (!nohead)      else if (!nohead)
                 lines -= HEADLEN + TAILLEN;          lines -= HEADLEN + TAILLEN;
   
         /*      /*
          * adjust for double space on odd length pages       * adjust for double space on odd length pages
          */       */
         if (dspace) {      if (dspace) {
                 if (lines == 1)          if (lines == 1)
                         dspace = 0;              dspace = 0;
                 else {          else {
                         if (lines & 1)              if (lines & 1)
                                 ++addone;                  ++addone;
                         lines /= 2;              lines /= 2;
                 }  
         }          }
       }
   
         if ((timefrmt = getenv("LC_TIME")) == NULL)      if ((timefrmt = getenv("LC_TIME")) == NULL)
                 timefrmt = TIMEFMT;          timefrmt = TIMEFMT;
         return(0);      return(0);
 }  }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5