19b50d902SRodney W. Grimes /*- 29b50d902SRodney W. Grimes * Copyright (c) 1991 Keith Muller. 39b50d902SRodney W. Grimes * Copyright (c) 1993 49b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 59b50d902SRodney W. Grimes * 69b50d902SRodney W. Grimes * This code is derived from software contributed to Berkeley by 79b50d902SRodney W. Grimes * Keith Muller of the University of California, San Diego. 89b50d902SRodney W. Grimes * 99b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 109b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 119b50d902SRodney W. Grimes * are met: 129b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 139b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 149b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 159b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 169b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 179b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 189b50d902SRodney W. Grimes * must display the following acknowledgement: 199b50d902SRodney W. Grimes * This product includes software developed by the University of 209b50d902SRodney W. Grimes * California, Berkeley and its contributors. 219b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 229b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 239b50d902SRodney W. Grimes * without specific prior written permission. 249b50d902SRodney W. Grimes * 259b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 269b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 279b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 289b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 299b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 309b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 319b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 329b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 339b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 349b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 359b50d902SRodney W. Grimes * SUCH DAMAGE. 36b5076d91SAndrey A. Chernov * 37b5076d91SAndrey A. Chernov * $FreeBSD$ 389b50d902SRodney W. Grimes */ 399b50d902SRodney W. Grimes 409b50d902SRodney W. Grimes #ifndef lint 419b50d902SRodney W. Grimes static char copyright[] = 429b50d902SRodney W. Grimes "@(#) Copyright (c) 1993\n\ 439b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 449b50d902SRodney W. Grimes #endif /* not lint */ 459b50d902SRodney W. Grimes 469b50d902SRodney W. Grimes #ifndef lint 479b50d902SRodney W. Grimes static char sccsid[] = "@(#)pr.c 8.2 (Berkeley) 4/16/94"; 489b50d902SRodney W. Grimes #endif /* not lint */ 499b50d902SRodney W. Grimes 509b50d902SRodney W. Grimes #include <sys/types.h> 519b50d902SRodney W. Grimes #include <sys/time.h> 529b50d902SRodney W. Grimes #include <sys/stat.h> 539b50d902SRodney W. Grimes 549b50d902SRodney W. Grimes #include <ctype.h> 559b50d902SRodney W. Grimes #include <errno.h> 5677b898c4SAndrey A. Chernov #include <langinfo.h> 57b5076d91SAndrey A. Chernov #include <locale.h> 589b50d902SRodney W. Grimes #include <signal.h> 599b50d902SRodney W. Grimes #include <stdio.h> 609b50d902SRodney W. Grimes #include <stdlib.h> 619b50d902SRodney W. Grimes #include <string.h> 629b50d902SRodney W. Grimes #include <unistd.h> 639b50d902SRodney W. Grimes 649b50d902SRodney W. Grimes #include "pr.h" 659b50d902SRodney W. Grimes #include "extern.h" 669b50d902SRodney W. Grimes 679b50d902SRodney W. Grimes /* 689b50d902SRodney W. Grimes * pr: a printing and pagination filter. If multiple input files 699b50d902SRodney W. Grimes * are specified, each is read, formatted, and written to standard 701a6e52d0SJeroen Ruigrok van der Werven * output. By default, input is separated into 66-line pages, each 719b50d902SRodney W. Grimes * with a header that includes the page number, date, time and the 729b50d902SRodney W. Grimes * files pathname. 739b50d902SRodney W. Grimes * 749b50d902SRodney W. Grimes * Complies with posix P1003.2/D11 759b50d902SRodney W. Grimes */ 769b50d902SRodney W. Grimes 779b50d902SRodney W. Grimes /* 789b50d902SRodney W. Grimes * parameter variables 799b50d902SRodney W. Grimes */ 809b50d902SRodney W. Grimes int pgnm; /* starting page number */ 819b50d902SRodney W. Grimes int clcnt; /* number of columns */ 829b50d902SRodney W. Grimes int colwd; /* column data width - multiple columns */ 839b50d902SRodney W. Grimes int across; /* mult col flag; write across page */ 849b50d902SRodney W. Grimes int dspace; /* double space flag */ 859b50d902SRodney W. Grimes char inchar; /* expand input char */ 869b50d902SRodney W. Grimes int ingap; /* expand input gap */ 87032b32adSJuli Mallett int pausefst; /* Pause before first page */ 88032b32adSJuli Mallett int pauseall; /* Pause before each page */ 899b50d902SRodney W. Grimes int formfeed; /* use formfeed as trailer */ 909b50d902SRodney W. Grimes char *header; /* header name instead of file name */ 919b50d902SRodney W. Grimes char ochar; /* contract output char */ 929b50d902SRodney W. Grimes int ogap; /* contract output gap */ 939b50d902SRodney W. Grimes int lines; /* number of lines per page */ 949b50d902SRodney W. Grimes int merge; /* merge multiple files in output */ 959b50d902SRodney W. Grimes char nmchar; /* line numbering append char */ 969b50d902SRodney W. Grimes int nmwd; /* width of line number field */ 979b50d902SRodney W. Grimes int offst; /* number of page offset spaces */ 989b50d902SRodney W. Grimes int nodiag; /* do not report file open errors */ 999b50d902SRodney W. Grimes char schar; /* text column separation character */ 1009b50d902SRodney W. Grimes int sflag; /* -s option for multiple columns */ 1019b50d902SRodney W. Grimes int nohead; /* do not write head and trailer */ 1029b50d902SRodney W. Grimes int pgwd; /* page width with multiple col output */ 1039b50d902SRodney W. Grimes char *timefrmt; /* time conversion string */ 1049b50d902SRodney W. Grimes 1059b50d902SRodney W. Grimes /* 1069b50d902SRodney W. Grimes * misc globals 1079b50d902SRodney W. Grimes */ 1089b50d902SRodney W. Grimes FILE *err; /* error message file pointer */ 1099b50d902SRodney W. Grimes int addone; /* page length is odd with double space */ 1109b50d902SRodney W. Grimes int errcnt; /* error count on file processing */ 1119b50d902SRodney W. Grimes char digs[] = "0123456789"; /* page number translation map */ 1129b50d902SRodney W. Grimes 1139b50d902SRodney W. Grimes int 1149b50d902SRodney W. Grimes main(argc, argv) 1159b50d902SRodney W. Grimes int argc; 1169b50d902SRodney W. Grimes char *argv[]; 1179b50d902SRodney W. Grimes { 1189b50d902SRodney W. Grimes int ret_val; 1199b50d902SRodney W. Grimes 1209b50d902SRodney W. Grimes if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1219b50d902SRodney W. Grimes (void)signal(SIGINT, terminate); 1229b50d902SRodney W. Grimes ret_val = setup(argc, argv); 1239b50d902SRodney W. Grimes if (!ret_val) { 1249b50d902SRodney W. Grimes /* 1259b50d902SRodney W. Grimes * select the output format based on options 1269b50d902SRodney W. Grimes */ 1279b50d902SRodney W. Grimes if (merge) 1289b50d902SRodney W. Grimes ret_val = mulfile(argc, argv); 1299b50d902SRodney W. Grimes else if (clcnt == 1) 1309b50d902SRodney W. Grimes ret_val = onecol(argc, argv); 1319b50d902SRodney W. Grimes else if (across) 1329b50d902SRodney W. Grimes ret_val = horzcol(argc, argv); 1339b50d902SRodney W. Grimes else 1349b50d902SRodney W. Grimes ret_val = vertcol(argc, argv); 1359b50d902SRodney W. Grimes } else 1369b50d902SRodney W. Grimes usage(); 1379b50d902SRodney W. Grimes flsh_errs(); 1389b50d902SRodney W. Grimes if (errcnt || ret_val) 1399b50d902SRodney W. Grimes exit(1); 1409b50d902SRodney W. Grimes return(0); 1419b50d902SRodney W. Grimes } 1429b50d902SRodney W. Grimes 1439b50d902SRodney W. Grimes /* 144032b32adSJuli Mallett * Check if we should pause and write an alert character and wait for a 145032b32adSJuli Mallett * carriage return on /dev/tty. 146032b32adSJuli Mallett */ 147032b32adSJuli Mallett void 148032b32adSJuli Mallett ttypause(pagecnt) 149032b32adSJuli Mallett int pagecnt; 150032b32adSJuli Mallett { 151032b32adSJuli Mallett int pch; 152032b32adSJuli Mallett FILE *ttyfp; 153032b32adSJuli Mallett 154032b32adSJuli Mallett if ((pauseall || (pausefst && pagecnt == 1)) && 155032b32adSJuli Mallett isatty(STDOUT_FILENO)) { 156032b32adSJuli Mallett if ((ttyfp = fopen("/dev/tty", "r")) != NULL) { 157032b32adSJuli Mallett (void)putc('\a', stderr); 158032b32adSJuli Mallett while ((pch = getc(ttyfp)) != '\n' && pch != EOF) 159032b32adSJuli Mallett ; 160032b32adSJuli Mallett (void)fclose(ttyfp); 161032b32adSJuli Mallett } 162032b32adSJuli Mallett } 163032b32adSJuli Mallett } 164032b32adSJuli Mallett 165032b32adSJuli Mallett /* 1669b50d902SRodney W. Grimes * onecol: print files with only one column of output. 1679b50d902SRodney W. Grimes * Line length is unlimited. 1689b50d902SRodney W. Grimes */ 1699b50d902SRodney W. Grimes int 1709b50d902SRodney W. Grimes onecol(argc, argv) 1719b50d902SRodney W. Grimes int argc; 1729b50d902SRodney W. Grimes char *argv[]; 1739b50d902SRodney W. Grimes { 1749b50d902SRodney W. Grimes register int cnt = -1; 1759b50d902SRodney W. Grimes register int off; 1769b50d902SRodney W. Grimes register int lrgln; 1779b50d902SRodney W. Grimes register int linecnt; 1789b50d902SRodney W. Grimes register int num; 1799b50d902SRodney W. Grimes int lncnt; 1809b50d902SRodney W. Grimes int pagecnt; 1819b50d902SRodney W. Grimes int ips; 1829b50d902SRodney W. Grimes int ops; 1839b50d902SRodney W. Grimes int cps; 1849b50d902SRodney W. Grimes char *obuf; 1859b50d902SRodney W. Grimes char *lbuf; 1869b50d902SRodney W. Grimes char *nbuf; 1879b50d902SRodney W. Grimes char *hbuf; 1889b50d902SRodney W. Grimes char *ohbuf; 1899b50d902SRodney W. Grimes FILE *inf; 1909b50d902SRodney W. Grimes char *fname; 1919b50d902SRodney W. Grimes int mor; 1929b50d902SRodney W. Grimes 1939b50d902SRodney W. Grimes if (nmwd) 1949b50d902SRodney W. Grimes num = nmwd + 1; 1959b50d902SRodney W. Grimes else 1969b50d902SRodney W. Grimes num = 0; 1979b50d902SRodney W. Grimes off = num + offst; 1989b50d902SRodney W. Grimes 1999b50d902SRodney W. Grimes /* 2009b50d902SRodney W. Grimes * allocate line buffer 2019b50d902SRodney W. Grimes */ 2029b50d902SRodney W. Grimes if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) { 2039b50d902SRodney W. Grimes mfail(); 2049b50d902SRodney W. Grimes return(1); 2059b50d902SRodney W. Grimes } 2069b50d902SRodney W. Grimes /* 2079b50d902SRodney W. Grimes * allocate header buffer 2089b50d902SRodney W. Grimes */ 2099b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) { 2109b50d902SRodney W. Grimes mfail(); 2119b50d902SRodney W. Grimes return(1); 2129b50d902SRodney W. Grimes } 2139b50d902SRodney W. Grimes 2149b50d902SRodney W. Grimes ohbuf = hbuf + offst; 2159b50d902SRodney W. Grimes nbuf = obuf + offst; 2169b50d902SRodney W. Grimes lbuf = nbuf + num; 2179b50d902SRodney W. Grimes if (num) 2189b50d902SRodney W. Grimes nbuf[--num] = nmchar; 2199b50d902SRodney W. Grimes if (offst) { 2209b50d902SRodney W. Grimes (void)memset(obuf, (int)' ', offst); 2219b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst); 2229b50d902SRodney W. Grimes } 2239b50d902SRodney W. Grimes 2249b50d902SRodney W. Grimes /* 2259b50d902SRodney W. Grimes * loop by file 2269b50d902SRodney W. Grimes */ 2279b50d902SRodney W. Grimes while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) { 2289b50d902SRodney W. Grimes if (pgnm) { 2299b50d902SRodney W. Grimes /* 2309b50d902SRodney W. Grimes * skip to specified page 2319b50d902SRodney W. Grimes */ 2329b50d902SRodney W. Grimes if (inskip(inf, pgnm, lines)) 2339b50d902SRodney W. Grimes continue; 2349b50d902SRodney W. Grimes pagecnt = pgnm; 2359b50d902SRodney W. Grimes } else 2369b50d902SRodney W. Grimes pagecnt = 1; 2379b50d902SRodney W. Grimes lncnt = 0; 2389b50d902SRodney W. Grimes 2399b50d902SRodney W. Grimes /* 2409b50d902SRodney W. Grimes * loop by page 2419b50d902SRodney W. Grimes */ 2429b50d902SRodney W. Grimes for(;;) { 2439b50d902SRodney W. Grimes linecnt = 0; 2449b50d902SRodney W. Grimes lrgln = 0; 2459b50d902SRodney W. Grimes ops = 0; 2469b50d902SRodney W. Grimes ips = 0; 2479b50d902SRodney W. Grimes cps = 0; 2489b50d902SRodney W. Grimes 249032b32adSJuli Mallett ttypause(pagecnt); 250032b32adSJuli Mallett 2519b50d902SRodney W. Grimes /* 2529b50d902SRodney W. Grimes * loop by line 2539b50d902SRodney W. Grimes */ 2549b50d902SRodney W. Grimes while (linecnt < lines) { 2559b50d902SRodney W. Grimes /* 2569b50d902SRodney W. Grimes * input next line 2579b50d902SRodney W. Grimes */ 2589b50d902SRodney W. Grimes if ((cnt = inln(inf,lbuf,LBUF,&cps,0,&mor)) < 0) 2599b50d902SRodney W. Grimes break; 2609b50d902SRodney W. Grimes if (!linecnt && !nohead && 2619b50d902SRodney W. Grimes prhead(hbuf, fname, pagecnt)) 2629b50d902SRodney W. Grimes return(1); 2639b50d902SRodney W. Grimes 2649b50d902SRodney W. Grimes /* 2659b50d902SRodney W. Grimes * start of new line. 2669b50d902SRodney W. Grimes */ 2679b50d902SRodney W. Grimes if (!lrgln) { 2689b50d902SRodney W. Grimes if (num) 2699b50d902SRodney W. Grimes addnum(nbuf, num, ++lncnt); 2709b50d902SRodney W. Grimes if (otln(obuf,cnt+off, &ips, &ops, mor)) 2719b50d902SRodney W. Grimes return(1); 2729b50d902SRodney W. Grimes } else if (otln(lbuf, cnt, &ips, &ops, mor)) 2739b50d902SRodney W. Grimes return(1); 2749b50d902SRodney W. Grimes 2759b50d902SRodney W. Grimes /* 2769b50d902SRodney W. Grimes * if line bigger than buffer, get more 2779b50d902SRodney W. Grimes */ 2789b50d902SRodney W. Grimes if (mor) { 2799b50d902SRodney W. Grimes lrgln = 1; 2809b50d902SRodney W. Grimes continue; 2819b50d902SRodney W. Grimes } 2829b50d902SRodney W. Grimes 2839b50d902SRodney W. Grimes /* 2849b50d902SRodney W. Grimes * whole line rcvd. reset tab proc. state 2859b50d902SRodney W. Grimes */ 2869b50d902SRodney W. Grimes ++linecnt; 2879b50d902SRodney W. Grimes lrgln = 0; 2889b50d902SRodney W. Grimes ops = 0; 2899b50d902SRodney W. Grimes ips = 0; 2909b50d902SRodney W. Grimes } 2919b50d902SRodney W. Grimes 2929b50d902SRodney W. Grimes /* 2939b50d902SRodney W. Grimes * fill to end of page 2949b50d902SRodney W. Grimes */ 2959b50d902SRodney W. Grimes if (linecnt && prtail(lines-linecnt-lrgln, lrgln)) 2969b50d902SRodney W. Grimes return(1); 2979b50d902SRodney W. Grimes 2989b50d902SRodney W. Grimes /* 2999b50d902SRodney W. Grimes * On EOF go to next file 3009b50d902SRodney W. Grimes */ 3019b50d902SRodney W. Grimes if (cnt < 0) 3029b50d902SRodney W. Grimes break; 3039b50d902SRodney W. Grimes ++pagecnt; 3049b50d902SRodney W. Grimes } 3059b50d902SRodney W. Grimes if (inf != stdin) 3069b50d902SRodney W. Grimes (void)fclose(inf); 3079b50d902SRodney W. Grimes } 3089b50d902SRodney W. Grimes if (eoptind < argc) 3099b50d902SRodney W. Grimes return(1); 3109b50d902SRodney W. Grimes return(0); 3119b50d902SRodney W. Grimes } 3129b50d902SRodney W. Grimes 3139b50d902SRodney W. Grimes /* 3149b50d902SRodney W. Grimes * vertcol: print files with more than one column of output down a page 3159b50d902SRodney W. Grimes */ 3169b50d902SRodney W. Grimes int 3179b50d902SRodney W. Grimes vertcol(argc, argv) 3189b50d902SRodney W. Grimes int argc; 3199b50d902SRodney W. Grimes char *argv[]; 3209b50d902SRodney W. Grimes { 3219b50d902SRodney W. Grimes register char *ptbf; 3229b50d902SRodney W. Grimes register char **lstdat; 3239b50d902SRodney W. Grimes register int i; 3249b50d902SRodney W. Grimes register int j; 3259b50d902SRodney W. Grimes register int cnt = -1; 3269b50d902SRodney W. Grimes register int pln; 3279b50d902SRodney W. Grimes register int *indy; 3289b50d902SRodney W. Grimes int cvc; 3299b50d902SRodney W. Grimes int *lindy; 3309b50d902SRodney W. Grimes int lncnt; 3319b50d902SRodney W. Grimes int stp; 3329b50d902SRodney W. Grimes int pagecnt; 3339b50d902SRodney W. Grimes int col = colwd + 1; 3349b50d902SRodney W. Grimes int mxlen = pgwd + offst + 1; 3359b50d902SRodney W. Grimes int mclcnt = clcnt - 1; 3369b50d902SRodney W. Grimes struct vcol *vc; 3379b50d902SRodney W. Grimes int mvc; 3389b50d902SRodney W. Grimes int tvc; 3399b50d902SRodney W. Grimes int cw = nmwd + 1; 3409b50d902SRodney W. Grimes int fullcol; 3419b50d902SRodney W. Grimes char *buf; 3429b50d902SRodney W. Grimes char *hbuf; 3439b50d902SRodney W. Grimes char *ohbuf; 3449b50d902SRodney W. Grimes char *fname; 3459b50d902SRodney W. Grimes FILE *inf; 3469b50d902SRodney W. Grimes int ips = 0; 3479b50d902SRodney W. Grimes int cps = 0; 3489b50d902SRodney W. Grimes int ops = 0; 3499b50d902SRodney W. Grimes int mor = 0; 3509b50d902SRodney W. Grimes 3519b50d902SRodney W. Grimes /* 3529b50d902SRodney W. Grimes * allocate page buffer 3539b50d902SRodney W. Grimes */ 3549b50d902SRodney W. Grimes if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) { 3559b50d902SRodney W. Grimes mfail(); 3569b50d902SRodney W. Grimes return(1); 3579b50d902SRodney W. Grimes } 3589b50d902SRodney W. Grimes 3599b50d902SRodney W. Grimes /* 3609b50d902SRodney W. Grimes * allocate page header 3619b50d902SRodney W. Grimes */ 3629b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) { 3639b50d902SRodney W. Grimes mfail(); 3649b50d902SRodney W. Grimes return(1); 3659b50d902SRodney W. Grimes } 3669b50d902SRodney W. Grimes ohbuf = hbuf + offst; 3679b50d902SRodney W. Grimes if (offst) 3689b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst); 3699b50d902SRodney W. Grimes 3709b50d902SRodney W. Grimes /* 3719b50d902SRodney W. Grimes * col pointers when no headers 3729b50d902SRodney W. Grimes */ 3739b50d902SRodney W. Grimes mvc = lines * clcnt; 3749b50d902SRodney W. Grimes if ((vc = 3759b50d902SRodney W. Grimes (struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) { 3769b50d902SRodney W. Grimes mfail(); 3779b50d902SRodney W. Grimes return(1); 3789b50d902SRodney W. Grimes } 3799b50d902SRodney W. Grimes 3809b50d902SRodney W. Grimes /* 3819b50d902SRodney W. Grimes * pointer into page where last data per line is located 3829b50d902SRodney W. Grimes */ 3839b50d902SRodney W. Grimes if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){ 3849b50d902SRodney W. Grimes mfail(); 3859b50d902SRodney W. Grimes return(1); 3869b50d902SRodney W. Grimes } 3879b50d902SRodney W. Grimes 3889b50d902SRodney W. Grimes /* 3899b50d902SRodney W. Grimes * fast index lookups to locate start of lines 3909b50d902SRodney W. Grimes */ 3919b50d902SRodney W. Grimes if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) { 3929b50d902SRodney W. Grimes mfail(); 3939b50d902SRodney W. Grimes return(1); 3949b50d902SRodney W. Grimes } 3959b50d902SRodney W. Grimes if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) { 3969b50d902SRodney W. Grimes mfail(); 3979b50d902SRodney W. Grimes return(1); 3989b50d902SRodney W. Grimes } 3999b50d902SRodney W. Grimes 4009b50d902SRodney W. Grimes if (nmwd) 4019b50d902SRodney W. Grimes fullcol = col + cw; 4029b50d902SRodney W. Grimes else 4039b50d902SRodney W. Grimes fullcol = col; 4049b50d902SRodney W. Grimes 4059b50d902SRodney W. Grimes /* 4069b50d902SRodney W. Grimes * initialize buffer lookup indexes and offset area 4079b50d902SRodney W. Grimes */ 4089b50d902SRodney W. Grimes for (j = 0; j < lines; ++j) { 4099b50d902SRodney W. Grimes lindy[j] = j * mxlen; 4109b50d902SRodney W. Grimes indy[j] = lindy[j] + offst; 4119b50d902SRodney W. Grimes if (offst) { 4129b50d902SRodney W. Grimes ptbf = buf + lindy[j]; 4139b50d902SRodney W. Grimes (void)memset(ptbf, (int)' ', offst); 4149b50d902SRodney W. Grimes ptbf += offst; 4159b50d902SRodney W. Grimes } else 4169b50d902SRodney W. Grimes ptbf = buf + indy[j]; 4179b50d902SRodney W. Grimes lstdat[j] = ptbf; 4189b50d902SRodney W. Grimes } 4199b50d902SRodney W. Grimes 4209b50d902SRodney W. Grimes /* 4219b50d902SRodney W. Grimes * loop by file 4229b50d902SRodney W. Grimes */ 4239b50d902SRodney W. Grimes while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) { 4249b50d902SRodney W. Grimes if (pgnm) { 4259b50d902SRodney W. Grimes /* 4269b50d902SRodney W. Grimes * skip to requested page 4279b50d902SRodney W. Grimes */ 4289b50d902SRodney W. Grimes if (inskip(inf, pgnm, lines)) 4299b50d902SRodney W. Grimes continue; 4309b50d902SRodney W. Grimes pagecnt = pgnm; 4319b50d902SRodney W. Grimes } else 4329b50d902SRodney W. Grimes pagecnt = 1; 4339b50d902SRodney W. Grimes lncnt = 0; 4349b50d902SRodney W. Grimes 4359b50d902SRodney W. Grimes /* 4369b50d902SRodney W. Grimes * loop by page 4379b50d902SRodney W. Grimes */ 4389b50d902SRodney W. Grimes for(;;) { 439032b32adSJuli Mallett ttypause(pagecnt); 440032b32adSJuli Mallett 4419b50d902SRodney W. Grimes /* 4429b50d902SRodney W. Grimes * loop by column 4439b50d902SRodney W. Grimes */ 4449b50d902SRodney W. Grimes cvc = 0; 4459b50d902SRodney W. Grimes for (i = 0; i < clcnt; ++i) { 4469b50d902SRodney W. Grimes j = 0; 4479b50d902SRodney W. Grimes /* 4489b50d902SRodney W. Grimes * if last column, do not pad 4499b50d902SRodney W. Grimes */ 4509b50d902SRodney W. Grimes if (i == mclcnt) 4519b50d902SRodney W. Grimes stp = 1; 4529b50d902SRodney W. Grimes else 4539b50d902SRodney W. Grimes stp = 0; 4549b50d902SRodney W. Grimes /* 4559b50d902SRodney W. Grimes * loop by line 4569b50d902SRodney W. Grimes */ 4579b50d902SRodney W. Grimes for(;;) { 4589b50d902SRodney W. Grimes /* 4599b50d902SRodney W. Grimes * is this first column 4609b50d902SRodney W. Grimes */ 4619b50d902SRodney W. Grimes if (!i) { 4629b50d902SRodney W. Grimes ptbf = buf + indy[j]; 4639b50d902SRodney W. Grimes lstdat[j] = ptbf; 4649b50d902SRodney W. Grimes } else 4659b50d902SRodney W. Grimes ptbf = lstdat[j]; 4669b50d902SRodney W. Grimes vc[cvc].pt = ptbf; 4679b50d902SRodney W. Grimes 4689b50d902SRodney W. Grimes /* 4699b50d902SRodney W. Grimes * add number 4709b50d902SRodney W. Grimes */ 4719b50d902SRodney W. Grimes if (nmwd) { 4729b50d902SRodney W. Grimes addnum(ptbf, nmwd, ++lncnt); 4739b50d902SRodney W. Grimes ptbf += nmwd; 4749b50d902SRodney W. Grimes *ptbf++ = nmchar; 4759b50d902SRodney W. Grimes } 4769b50d902SRodney W. Grimes 4779b50d902SRodney W. Grimes /* 4789b50d902SRodney W. Grimes * input next line 4799b50d902SRodney W. Grimes */ 4809b50d902SRodney W. Grimes cnt = inln(inf,ptbf,colwd,&cps,1,&mor); 4819b50d902SRodney W. Grimes vc[cvc++].cnt = cnt; 4829b50d902SRodney W. Grimes if (cnt < 0) 4839b50d902SRodney W. Grimes break; 4849b50d902SRodney W. Grimes ptbf += cnt; 4859b50d902SRodney W. Grimes 4869b50d902SRodney W. Grimes /* 4879b50d902SRodney W. Grimes * pad all but last column on page 4889b50d902SRodney W. Grimes */ 4899b50d902SRodney W. Grimes if (!stp) { 4909b50d902SRodney W. Grimes /* 4919b50d902SRodney W. Grimes * pad to end of column 4929b50d902SRodney W. Grimes */ 4939b50d902SRodney W. Grimes if (sflag) 4949b50d902SRodney W. Grimes *ptbf++ = schar; 4959b50d902SRodney W. Grimes else if ((pln = col-cnt) > 0) { 4969b50d902SRodney W. Grimes (void)memset(ptbf, 4979b50d902SRodney W. Grimes (int)' ',pln); 4989b50d902SRodney W. Grimes ptbf += pln; 4999b50d902SRodney W. Grimes } 5009b50d902SRodney W. Grimes } 5019b50d902SRodney W. Grimes /* 5029b50d902SRodney W. Grimes * remember last char in line 5039b50d902SRodney W. Grimes */ 5049b50d902SRodney W. Grimes lstdat[j] = ptbf; 5059b50d902SRodney W. Grimes if (++j >= lines) 5069b50d902SRodney W. Grimes break; 5079b50d902SRodney W. Grimes } 5089b50d902SRodney W. Grimes if (cnt < 0) 5099b50d902SRodney W. Grimes break; 5109b50d902SRodney W. Grimes } 5119b50d902SRodney W. Grimes 5129b50d902SRodney W. Grimes /* 5139b50d902SRodney W. Grimes * when -t (no header) is specified the spec requires 5149b50d902SRodney W. Grimes * the min number of lines. The last page may not have 5159b50d902SRodney W. Grimes * balanced length columns. To fix this we must reorder 5169b50d902SRodney W. Grimes * the columns. This is a very slow technique so it is 5179b50d902SRodney W. Grimes * only used under limited conditions. Without -t, the 5189b50d902SRodney W. Grimes * balancing of text columns is unspecified. To NOT 5199b50d902SRodney W. Grimes * balance the last page, add the global variable 5209b50d902SRodney W. Grimes * nohead to the if statement below e.g. 5219b50d902SRodney W. Grimes * 5229b50d902SRodney W. Grimes * if ((cnt < 0) && nohead && cvc ...... 5239b50d902SRodney W. Grimes */ 5249b50d902SRodney W. Grimes --cvc; 5259b50d902SRodney W. Grimes 5269b50d902SRodney W. Grimes /* 5279b50d902SRodney W. Grimes * check to see if last page needs to be reordered 5289b50d902SRodney W. Grimes */ 5299b50d902SRodney W. Grimes if ((cnt < 0) && cvc && ((mvc-cvc) >= clcnt)){ 5309b50d902SRodney W. Grimes pln = cvc/clcnt; 5319b50d902SRodney W. Grimes if (cvc % clcnt) 5329b50d902SRodney W. Grimes ++pln; 5339b50d902SRodney W. Grimes 5349b50d902SRodney W. Grimes /* 5359b50d902SRodney W. Grimes * print header 5369b50d902SRodney W. Grimes */ 5379b50d902SRodney W. Grimes if (!nohead && prhead(hbuf, fname, pagecnt)) 5389b50d902SRodney W. Grimes return(1); 5399b50d902SRodney W. Grimes for (i = 0; i < pln; ++i) { 5409b50d902SRodney W. Grimes ips = 0; 5419b50d902SRodney W. Grimes ops = 0; 5429b50d902SRodney W. Grimes if (offst&& otln(buf,offst,&ips,&ops,1)) 5439b50d902SRodney W. Grimes return(1); 5449b50d902SRodney W. Grimes tvc = i; 5459b50d902SRodney W. Grimes 5469b50d902SRodney W. Grimes for (j = 0; j < clcnt; ++j) { 5479b50d902SRodney W. Grimes /* 5489b50d902SRodney W. Grimes * determine column length 5499b50d902SRodney W. Grimes */ 5509b50d902SRodney W. Grimes if (j == mclcnt) { 5519b50d902SRodney W. Grimes /* 5529b50d902SRodney W. Grimes * last column 5539b50d902SRodney W. Grimes */ 5549b50d902SRodney W. Grimes cnt = vc[tvc].cnt; 5559b50d902SRodney W. Grimes if (nmwd) 5569b50d902SRodney W. Grimes cnt += cw; 5579b50d902SRodney W. Grimes } else if (sflag) { 5589b50d902SRodney W. Grimes /* 5599b50d902SRodney W. Grimes * single ch between 5609b50d902SRodney W. Grimes */ 5619b50d902SRodney W. Grimes cnt = vc[tvc].cnt + 1; 5629b50d902SRodney W. Grimes if (nmwd) 5639b50d902SRodney W. Grimes cnt += cw; 5649b50d902SRodney W. Grimes } else 5659b50d902SRodney W. Grimes cnt = fullcol; 5669b50d902SRodney W. Grimes if (otln(vc[tvc].pt, cnt, &ips, 5679b50d902SRodney W. Grimes &ops, 1)) 5689b50d902SRodney W. Grimes return(1); 5699b50d902SRodney W. Grimes tvc += pln; 5709b50d902SRodney W. Grimes if (tvc >= cvc) 5719b50d902SRodney W. Grimes break; 5729b50d902SRodney W. Grimes } 5739b50d902SRodney W. Grimes /* 5749b50d902SRodney W. Grimes * terminate line 5759b50d902SRodney W. Grimes */ 5769b50d902SRodney W. Grimes if (otln(buf, 0, &ips, &ops, 0)) 5779b50d902SRodney W. Grimes return(1); 5789b50d902SRodney W. Grimes } 5799b50d902SRodney W. Grimes /* 5809b50d902SRodney W. Grimes * pad to end of page 5819b50d902SRodney W. Grimes */ 5829b50d902SRodney W. Grimes if (prtail((lines - pln), 0)) 5839b50d902SRodney W. Grimes return(1); 5849b50d902SRodney W. Grimes /* 5859b50d902SRodney W. Grimes * done with output, go to next file 5869b50d902SRodney W. Grimes */ 5879b50d902SRodney W. Grimes break; 5889b50d902SRodney W. Grimes } 5899b50d902SRodney W. Grimes 5909b50d902SRodney W. Grimes /* 5919b50d902SRodney W. Grimes * determine how many lines to output 5929b50d902SRodney W. Grimes */ 5939b50d902SRodney W. Grimes if (i > 0) 5949b50d902SRodney W. Grimes pln = lines; 5959b50d902SRodney W. Grimes else 5969b50d902SRodney W. Grimes pln = j; 5979b50d902SRodney W. Grimes 5989b50d902SRodney W. Grimes /* 5999b50d902SRodney W. Grimes * print header 6009b50d902SRodney W. Grimes */ 6019b50d902SRodney W. Grimes if (pln && !nohead && prhead(hbuf, fname, pagecnt)) 6029b50d902SRodney W. Grimes return(1); 6039b50d902SRodney W. Grimes 6049b50d902SRodney W. Grimes /* 6059b50d902SRodney W. Grimes * output each line 6069b50d902SRodney W. Grimes */ 6079b50d902SRodney W. Grimes for (i = 0; i < pln; ++i) { 6089b50d902SRodney W. Grimes ptbf = buf + lindy[i]; 6099b50d902SRodney W. Grimes if ((j = lstdat[i] - ptbf) <= offst) 6109b50d902SRodney W. Grimes break; 6119b50d902SRodney W. Grimes if (otln(ptbf, j, &ips, &ops, 0)) 6129b50d902SRodney W. Grimes return(1); 6139b50d902SRodney W. Grimes } 6149b50d902SRodney W. Grimes 6159b50d902SRodney W. Grimes /* 6169b50d902SRodney W. Grimes * pad to end of page 6179b50d902SRodney W. Grimes */ 6189b50d902SRodney W. Grimes if (pln && prtail((lines - pln), 0)) 6199b50d902SRodney W. Grimes return(1); 6209b50d902SRodney W. Grimes 6219b50d902SRodney W. Grimes /* 6229b50d902SRodney W. Grimes * if EOF go to next file 6239b50d902SRodney W. Grimes */ 6249b50d902SRodney W. Grimes if (cnt < 0) 6259b50d902SRodney W. Grimes break; 6269b50d902SRodney W. Grimes ++pagecnt; 6279b50d902SRodney W. Grimes } 6289b50d902SRodney W. Grimes if (inf != stdin) 6299b50d902SRodney W. Grimes (void)fclose(inf); 6309b50d902SRodney W. Grimes } 6319b50d902SRodney W. Grimes if (eoptind < argc) 6329b50d902SRodney W. Grimes return(1); 6339b50d902SRodney W. Grimes return(0); 6349b50d902SRodney W. Grimes } 6359b50d902SRodney W. Grimes 6369b50d902SRodney W. Grimes /* 6379b50d902SRodney W. Grimes * horzcol: print files with more than one column of output across a page 6389b50d902SRodney W. Grimes */ 6399b50d902SRodney W. Grimes int 6409b50d902SRodney W. Grimes horzcol(argc, argv) 6419b50d902SRodney W. Grimes int argc; 6429b50d902SRodney W. Grimes char *argv[]; 6439b50d902SRodney W. Grimes { 6449b50d902SRodney W. Grimes register char *ptbf; 6459b50d902SRodney W. Grimes register int pln; 6469b50d902SRodney W. Grimes register int cnt = -1; 6479b50d902SRodney W. Grimes register char *lstdat; 6489b50d902SRodney W. Grimes register int col = colwd + 1; 6499b50d902SRodney W. Grimes register int j; 6509b50d902SRodney W. Grimes register int i; 6519b50d902SRodney W. Grimes int lncnt; 6529b50d902SRodney W. Grimes int pagecnt; 6539b50d902SRodney W. Grimes char *buf; 6549b50d902SRodney W. Grimes char *hbuf; 6559b50d902SRodney W. Grimes char *ohbuf; 6569b50d902SRodney W. Grimes char *fname; 6579b50d902SRodney W. Grimes FILE *inf; 6589b50d902SRodney W. Grimes int ips = 0; 6599b50d902SRodney W. Grimes int cps = 0; 6609b50d902SRodney W. Grimes int ops = 0; 6619b50d902SRodney W. Grimes int mor = 0; 6629b50d902SRodney W. Grimes 6639b50d902SRodney W. Grimes if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) { 6649b50d902SRodney W. Grimes mfail(); 6659b50d902SRodney W. Grimes return(1); 6669b50d902SRodney W. Grimes } 6679b50d902SRodney W. Grimes 6689b50d902SRodney W. Grimes /* 6699b50d902SRodney W. Grimes * page header 6709b50d902SRodney W. Grimes */ 6719b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) { 6729b50d902SRodney W. Grimes mfail(); 6739b50d902SRodney W. Grimes return(1); 6749b50d902SRodney W. Grimes } 6759b50d902SRodney W. Grimes ohbuf = hbuf + offst; 6769b50d902SRodney W. Grimes if (offst) { 6779b50d902SRodney W. Grimes (void)memset(buf, (int)' ', offst); 6789b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst); 6799b50d902SRodney W. Grimes } 6809b50d902SRodney W. Grimes 6819b50d902SRodney W. Grimes /* 6829b50d902SRodney W. Grimes * loop by file 6839b50d902SRodney W. Grimes */ 6849b50d902SRodney W. Grimes while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) { 6859b50d902SRodney W. Grimes if (pgnm) { 6869b50d902SRodney W. Grimes if (inskip(inf, pgnm, lines)) 6879b50d902SRodney W. Grimes continue; 6889b50d902SRodney W. Grimes pagecnt = pgnm; 6899b50d902SRodney W. Grimes } else 6909b50d902SRodney W. Grimes pagecnt = 1; 6919b50d902SRodney W. Grimes lncnt = 0; 6929b50d902SRodney W. Grimes 6939b50d902SRodney W. Grimes /* 6949b50d902SRodney W. Grimes * loop by page 6959b50d902SRodney W. Grimes */ 6969b50d902SRodney W. Grimes for(;;) { 697032b32adSJuli Mallett ttypause(pagecnt); 698032b32adSJuli Mallett 6999b50d902SRodney W. Grimes /* 7009b50d902SRodney W. Grimes * loop by line 7019b50d902SRodney W. Grimes */ 7029b50d902SRodney W. Grimes for (i = 0; i < lines; ++i) { 7039b50d902SRodney W. Grimes ptbf = buf + offst; 7049b50d902SRodney W. Grimes lstdat = ptbf; 7059b50d902SRodney W. Grimes j = 0; 7069b50d902SRodney W. Grimes /* 7079b50d902SRodney W. Grimes * loop by col 7089b50d902SRodney W. Grimes */ 7099b50d902SRodney W. Grimes for(;;) { 7109b50d902SRodney W. Grimes if (nmwd) { 7119b50d902SRodney W. Grimes /* 7129b50d902SRodney W. Grimes * add number to column 7139b50d902SRodney W. Grimes */ 7149b50d902SRodney W. Grimes addnum(ptbf, nmwd, ++lncnt); 7159b50d902SRodney W. Grimes ptbf += nmwd; 7169b50d902SRodney W. Grimes *ptbf++ = nmchar; 7179b50d902SRodney W. Grimes } 7189b50d902SRodney W. Grimes /* 7199b50d902SRodney W. Grimes * input line 7209b50d902SRodney W. Grimes */ 7219b50d902SRodney W. Grimes if ((cnt = inln(inf,ptbf,colwd,&cps,1, 7229b50d902SRodney W. Grimes &mor)) < 0) 7239b50d902SRodney W. Grimes break; 7249b50d902SRodney W. Grimes ptbf += cnt; 7259b50d902SRodney W. Grimes lstdat = ptbf; 7269b50d902SRodney W. Grimes 7279b50d902SRodney W. Grimes /* 7289b50d902SRodney W. Grimes * if last line skip padding 7299b50d902SRodney W. Grimes */ 7309b50d902SRodney W. Grimes if (++j >= clcnt) 7319b50d902SRodney W. Grimes break; 7329b50d902SRodney W. Grimes 7339b50d902SRodney W. Grimes /* 7349b50d902SRodney W. Grimes * pad to end of column 7359b50d902SRodney W. Grimes */ 7369b50d902SRodney W. Grimes if (sflag) 7379b50d902SRodney W. Grimes *ptbf++ = schar; 7389b50d902SRodney W. Grimes else if ((pln = col - cnt) > 0) { 7399b50d902SRodney W. Grimes (void)memset(ptbf,(int)' ',pln); 7409b50d902SRodney W. Grimes ptbf += pln; 7419b50d902SRodney W. Grimes } 7429b50d902SRodney W. Grimes } 7439b50d902SRodney W. Grimes 7449b50d902SRodney W. Grimes /* 7459b50d902SRodney W. Grimes * determine line length 7469b50d902SRodney W. Grimes */ 7479b50d902SRodney W. Grimes if ((j = lstdat - buf) <= offst) 7489b50d902SRodney W. Grimes break; 7499b50d902SRodney W. Grimes if (!i && !nohead && 7509b50d902SRodney W. Grimes prhead(hbuf, fname, pagecnt)) 7519b50d902SRodney W. Grimes return(1); 7529b50d902SRodney W. Grimes /* 7539b50d902SRodney W. Grimes * output line 7549b50d902SRodney W. Grimes */ 7559b50d902SRodney W. Grimes if (otln(buf, j, &ips, &ops, 0)) 7569b50d902SRodney W. Grimes return(1); 7579b50d902SRodney W. Grimes } 7589b50d902SRodney W. Grimes 7599b50d902SRodney W. Grimes /* 7609b50d902SRodney W. Grimes * pad to end of page 7619b50d902SRodney W. Grimes */ 7629b50d902SRodney W. Grimes if (i && prtail(lines-i, 0)) 7639b50d902SRodney W. Grimes return(1); 7649b50d902SRodney W. Grimes 7659b50d902SRodney W. Grimes /* 7669b50d902SRodney W. Grimes * if EOF go to next file 7679b50d902SRodney W. Grimes */ 7689b50d902SRodney W. Grimes if (cnt < 0) 7699b50d902SRodney W. Grimes break; 7709b50d902SRodney W. Grimes ++pagecnt; 7719b50d902SRodney W. Grimes } 7729b50d902SRodney W. Grimes if (inf != stdin) 7739b50d902SRodney W. Grimes (void)fclose(inf); 7749b50d902SRodney W. Grimes } 7759b50d902SRodney W. Grimes if (eoptind < argc) 7769b50d902SRodney W. Grimes return(1); 7779b50d902SRodney W. Grimes return(0); 7789b50d902SRodney W. Grimes } 7799b50d902SRodney W. Grimes 7809b50d902SRodney W. Grimes /* 7819b50d902SRodney W. Grimes * mulfile: print files with more than one column of output and 7829b50d902SRodney W. Grimes * more than one file concurrently 7839b50d902SRodney W. Grimes */ 7849b50d902SRodney W. Grimes int 7859b50d902SRodney W. Grimes mulfile(argc, argv) 7869b50d902SRodney W. Grimes int argc; 7879b50d902SRodney W. Grimes char *argv[]; 7889b50d902SRodney W. Grimes { 7899b50d902SRodney W. Grimes register char *ptbf; 7909b50d902SRodney W. Grimes register int j; 7919b50d902SRodney W. Grimes register int pln; 7929b50d902SRodney W. Grimes register int cnt; 7939b50d902SRodney W. Grimes register char *lstdat; 7949b50d902SRodney W. Grimes register int i; 7959b50d902SRodney W. Grimes FILE **fbuf; 7969b50d902SRodney W. Grimes int actf; 7979b50d902SRodney W. Grimes int lncnt; 7989b50d902SRodney W. Grimes int col; 7999b50d902SRodney W. Grimes int pagecnt; 8009b50d902SRodney W. Grimes int fproc; 8019b50d902SRodney W. Grimes char *buf; 8029b50d902SRodney W. Grimes char *hbuf; 8039b50d902SRodney W. Grimes char *ohbuf; 8049b50d902SRodney W. Grimes char *fname; 8059b50d902SRodney W. Grimes int ips = 0; 8069b50d902SRodney W. Grimes int cps = 0; 8079b50d902SRodney W. Grimes int ops = 0; 8089b50d902SRodney W. Grimes int mor = 0; 8099b50d902SRodney W. Grimes 8109b50d902SRodney W. Grimes /* 8119b50d902SRodney W. Grimes * array of FILE *, one for each operand 8129b50d902SRodney W. Grimes */ 8139b50d902SRodney W. Grimes if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) { 8149b50d902SRodney W. Grimes mfail(); 8159b50d902SRodney W. Grimes return(1); 8169b50d902SRodney W. Grimes } 8179b50d902SRodney W. Grimes 8189b50d902SRodney W. Grimes /* 8199b50d902SRodney W. Grimes * page header 8209b50d902SRodney W. Grimes */ 8219b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) { 8229b50d902SRodney W. Grimes mfail(); 8239b50d902SRodney W. Grimes return(1); 8249b50d902SRodney W. Grimes } 8259b50d902SRodney W. Grimes ohbuf = hbuf + offst; 8269b50d902SRodney W. Grimes 8279b50d902SRodney W. Grimes /* 8289b50d902SRodney W. Grimes * do not know how many columns yet. The number of operands provide an 8299b50d902SRodney W. Grimes * upper bound on the number of columns. We use the number of files 8309b50d902SRodney W. Grimes * we can open successfully to set the number of columns. The operation 8319b50d902SRodney W. Grimes * of the merge operation (-m) in relation to unsuccesful file opens 8329b50d902SRodney W. Grimes * is unspecified by posix. 8339b50d902SRodney W. Grimes */ 8349b50d902SRodney W. Grimes j = 0; 8359b50d902SRodney W. Grimes while (j < clcnt) { 8369b50d902SRodney W. Grimes if ((fbuf[j] = nxtfile(argc, argv, &fname, ohbuf, 1)) == NULL) 8379b50d902SRodney W. Grimes break; 8389b50d902SRodney W. Grimes if (pgnm && (inskip(fbuf[j], pgnm, lines))) 8399b50d902SRodney W. Grimes fbuf[j] = NULL; 8409b50d902SRodney W. Grimes ++j; 8419b50d902SRodney W. Grimes } 8429b50d902SRodney W. Grimes 8439b50d902SRodney W. Grimes /* 8449b50d902SRodney W. Grimes * if no files, exit 8459b50d902SRodney W. Grimes */ 8469b50d902SRodney W. Grimes if (!j) 8479b50d902SRodney W. Grimes return(1); 8489b50d902SRodney W. Grimes 8499b50d902SRodney W. Grimes /* 8509b50d902SRodney W. Grimes * calculate page boundries based on open file count 8519b50d902SRodney W. Grimes */ 8529b50d902SRodney W. Grimes clcnt = j; 8539b50d902SRodney W. Grimes if (nmwd) { 8549b50d902SRodney W. Grimes colwd = (pgwd - clcnt - nmwd)/clcnt; 8559b50d902SRodney W. Grimes pgwd = ((colwd + 1) * clcnt) - nmwd - 2; 8569b50d902SRodney W. Grimes } else { 8579b50d902SRodney W. Grimes colwd = (pgwd + 1 - clcnt)/clcnt; 8589b50d902SRodney W. Grimes pgwd = ((colwd + 1) * clcnt) - 1; 8599b50d902SRodney W. Grimes } 8609b50d902SRodney W. Grimes if (colwd < 1) { 8619b50d902SRodney W. Grimes (void)fprintf(err, 8629b50d902SRodney W. Grimes "pr: page width too small for %d columns\n", clcnt); 8639b50d902SRodney W. Grimes return(1); 8649b50d902SRodney W. Grimes } 8659b50d902SRodney W. Grimes actf = clcnt; 8669b50d902SRodney W. Grimes col = colwd + 1; 8679b50d902SRodney W. Grimes 8689b50d902SRodney W. Grimes /* 8699b50d902SRodney W. Grimes * line buffer 8709b50d902SRodney W. Grimes */ 8719b50d902SRodney W. Grimes if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) { 8729b50d902SRodney W. Grimes mfail(); 8739b50d902SRodney W. Grimes return(1); 8749b50d902SRodney W. Grimes } 8759b50d902SRodney W. Grimes if (offst) { 8769b50d902SRodney W. Grimes (void)memset(buf, (int)' ', offst); 8779b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst); 8789b50d902SRodney W. Grimes } 8799b50d902SRodney W. Grimes if (pgnm) 8809b50d902SRodney W. Grimes pagecnt = pgnm; 8819b50d902SRodney W. Grimes else 8829b50d902SRodney W. Grimes pagecnt = 1; 8839b50d902SRodney W. Grimes lncnt = 0; 8849b50d902SRodney W. Grimes 8859b50d902SRodney W. Grimes /* 8869b50d902SRodney W. Grimes * continue to loop while any file still has data 8879b50d902SRodney W. Grimes */ 8889b50d902SRodney W. Grimes while (actf > 0) { 889032b32adSJuli Mallett ttypause(pagecnt); 890032b32adSJuli Mallett 8919b50d902SRodney W. Grimes /* 8929b50d902SRodney W. Grimes * loop by line 8939b50d902SRodney W. Grimes */ 8949b50d902SRodney W. Grimes for (i = 0; i < lines; ++i) { 8959b50d902SRodney W. Grimes ptbf = buf + offst; 8969b50d902SRodney W. Grimes lstdat = ptbf; 8979b50d902SRodney W. Grimes if (nmwd) { 8989b50d902SRodney W. Grimes /* 8999b50d902SRodney W. Grimes * add line number to line 9009b50d902SRodney W. Grimes */ 9019b50d902SRodney W. Grimes addnum(ptbf, nmwd, ++lncnt); 9029b50d902SRodney W. Grimes ptbf += nmwd; 9039b50d902SRodney W. Grimes *ptbf++ = nmchar; 9049b50d902SRodney W. Grimes } 9059b50d902SRodney W. Grimes j = 0; 9069b50d902SRodney W. Grimes fproc = 0; 9079b50d902SRodney W. Grimes 9089b50d902SRodney W. Grimes /* 9099b50d902SRodney W. Grimes * loop by column 9109b50d902SRodney W. Grimes */ 9119b50d902SRodney W. Grimes for (j = 0; j < clcnt; ++j) { 9129b50d902SRodney W. Grimes if (fbuf[j] == NULL) { 9139b50d902SRodney W. Grimes /* 9149b50d902SRodney W. Grimes * empty column; EOF 9159b50d902SRodney W. Grimes */ 9169b50d902SRodney W. Grimes cnt = 0; 9179b50d902SRodney W. Grimes } else if ((cnt = inln(fbuf[j], ptbf, colwd, 9189b50d902SRodney W. Grimes &cps, 1, &mor)) < 0) { 9199b50d902SRodney W. Grimes /* 9209b50d902SRodney W. Grimes * EOF hit; no data 9219b50d902SRodney W. Grimes */ 9229b50d902SRodney W. Grimes if (fbuf[j] != stdin) 9239b50d902SRodney W. Grimes (void)fclose(fbuf[j]); 9249b50d902SRodney W. Grimes fbuf[j] = NULL; 9259b50d902SRodney W. Grimes --actf; 9269b50d902SRodney W. Grimes cnt = 0; 9279b50d902SRodney W. Grimes } else { 9289b50d902SRodney W. Grimes /* 9299b50d902SRodney W. Grimes * process file data 9309b50d902SRodney W. Grimes */ 9319b50d902SRodney W. Grimes ptbf += cnt; 9329b50d902SRodney W. Grimes lstdat = ptbf; 9339b50d902SRodney W. Grimes fproc++; 9349b50d902SRodney W. Grimes } 9359b50d902SRodney W. Grimes 9369b50d902SRodney W. Grimes /* 9379b50d902SRodney W. Grimes * if last ACTIVE column, done with line 9389b50d902SRodney W. Grimes */ 9399b50d902SRodney W. Grimes if (fproc >= actf) 9409b50d902SRodney W. Grimes break; 9419b50d902SRodney W. Grimes 9429b50d902SRodney W. Grimes /* 9439b50d902SRodney W. Grimes * pad to end of column 9449b50d902SRodney W. Grimes */ 9459b50d902SRodney W. Grimes if (sflag) { 9469b50d902SRodney W. Grimes *ptbf++ = schar; 9479b50d902SRodney W. Grimes } else if ((pln = col - cnt) > 0) { 9489b50d902SRodney W. Grimes (void)memset(ptbf, (int)' ', pln); 9499b50d902SRodney W. Grimes ptbf += pln; 9509b50d902SRodney W. Grimes } 9519b50d902SRodney W. Grimes } 9529b50d902SRodney W. Grimes 9539b50d902SRodney W. Grimes /* 9549b50d902SRodney W. Grimes * calculate data in line 9559b50d902SRodney W. Grimes */ 9569b50d902SRodney W. Grimes if ((j = lstdat - buf) <= offst) 9579b50d902SRodney W. Grimes break; 9589b50d902SRodney W. Grimes 9599b50d902SRodney W. Grimes if (!i && !nohead && prhead(hbuf, fname, pagecnt)) 9609b50d902SRodney W. Grimes return(1); 9619b50d902SRodney W. Grimes 9629b50d902SRodney W. Grimes /* 9639b50d902SRodney W. Grimes * output line 9649b50d902SRodney W. Grimes */ 9659b50d902SRodney W. Grimes if (otln(buf, j, &ips, &ops, 0)) 9669b50d902SRodney W. Grimes return(1); 9679b50d902SRodney W. Grimes 9689b50d902SRodney W. Grimes /* 9699b50d902SRodney W. Grimes * if no more active files, done 9709b50d902SRodney W. Grimes */ 9719b50d902SRodney W. Grimes if (actf <= 0) { 9729b50d902SRodney W. Grimes ++i; 9739b50d902SRodney W. Grimes break; 9749b50d902SRodney W. Grimes } 9759b50d902SRodney W. Grimes } 9769b50d902SRodney W. Grimes 9779b50d902SRodney W. Grimes /* 9789b50d902SRodney W. Grimes * pad to end of page 9799b50d902SRodney W. Grimes */ 9809b50d902SRodney W. Grimes if (i && prtail(lines-i, 0)) 9819b50d902SRodney W. Grimes return(1); 9829b50d902SRodney W. Grimes ++pagecnt; 9839b50d902SRodney W. Grimes } 9849b50d902SRodney W. Grimes if (eoptind < argc) 9859b50d902SRodney W. Grimes return(1); 9869b50d902SRodney W. Grimes return(0); 9879b50d902SRodney W. Grimes } 9889b50d902SRodney W. Grimes 9899b50d902SRodney W. Grimes /* 9909b50d902SRodney W. Grimes * inln(): input a line of data (unlimited length lines supported) 9919b50d902SRodney W. Grimes * Input is optionally expanded to spaces 9929b50d902SRodney W. Grimes * 9939b50d902SRodney W. Grimes * inf: file 9949b50d902SRodney W. Grimes * buf: buffer 9959b50d902SRodney W. Grimes * lim: buffer length 9969b50d902SRodney W. Grimes * cps: column positon 1st char in buffer (large line support) 9979b50d902SRodney W. Grimes * trnc: throw away data more than lim up to \n 9989b50d902SRodney W. Grimes * mor: set if more data in line (not truncated) 9999b50d902SRodney W. Grimes */ 10009b50d902SRodney W. Grimes int 10019b50d902SRodney W. Grimes inln(inf, buf, lim, cps, trnc, mor) 10029b50d902SRodney W. Grimes FILE *inf; 10039b50d902SRodney W. Grimes char *buf; 10049b50d902SRodney W. Grimes register int lim; 10059b50d902SRodney W. Grimes int *cps; 10069b50d902SRodney W. Grimes int trnc; 10079b50d902SRodney W. Grimes int *mor; 10089b50d902SRodney W. Grimes { 10099b50d902SRodney W. Grimes register int col; 10109b50d902SRodney W. Grimes register int gap = ingap; 10119b50d902SRodney W. Grimes register int ch = EOF; 10129b50d902SRodney W. Grimes register char *ptbuf; 10139b50d902SRodney W. Grimes register int chk = (int)inchar; 10149b50d902SRodney W. Grimes 10159b50d902SRodney W. Grimes ptbuf = buf; 10169b50d902SRodney W. Grimes 10179b50d902SRodney W. Grimes if (gap) { 10189b50d902SRodney W. Grimes /* 10199b50d902SRodney W. Grimes * expanding input option 10209b50d902SRodney W. Grimes */ 10219b50d902SRodney W. Grimes while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) { 10229b50d902SRodney W. Grimes /* 10239b50d902SRodney W. Grimes * is this the input "tab" char 10249b50d902SRodney W. Grimes */ 10259b50d902SRodney W. Grimes if (ch == chk) { 10269b50d902SRodney W. Grimes /* 10279b50d902SRodney W. Grimes * expand to number of spaces 10289b50d902SRodney W. Grimes */ 10299b50d902SRodney W. Grimes col = (ptbuf - buf) + *cps; 10309b50d902SRodney W. Grimes col = gap - (col % gap); 10319b50d902SRodney W. Grimes 10329b50d902SRodney W. Grimes /* 10339b50d902SRodney W. Grimes * if more than this line, push back 10349b50d902SRodney W. Grimes */ 10359b50d902SRodney W. Grimes if ((col > lim) && (ungetc(ch, inf) == EOF)) 10369b50d902SRodney W. Grimes return(1); 10379b50d902SRodney W. Grimes 10389b50d902SRodney W. Grimes /* 10399b50d902SRodney W. Grimes * expand to spaces 10409b50d902SRodney W. Grimes */ 10419b50d902SRodney W. Grimes while ((--col >= 0) && (--lim >= 0)) 10429b50d902SRodney W. Grimes *ptbuf++ = ' '; 10439b50d902SRodney W. Grimes continue; 10449b50d902SRodney W. Grimes } 10459b50d902SRodney W. Grimes if (ch == '\n') 10469b50d902SRodney W. Grimes break; 10479b50d902SRodney W. Grimes *ptbuf++ = ch; 10489b50d902SRodney W. Grimes } 10499b50d902SRodney W. Grimes } else { 10509b50d902SRodney W. Grimes /* 10519b50d902SRodney W. Grimes * no expansion 10529b50d902SRodney W. Grimes */ 10539b50d902SRodney W. Grimes while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) { 10549b50d902SRodney W. Grimes if (ch == '\n') 10559b50d902SRodney W. Grimes break; 10569b50d902SRodney W. Grimes *ptbuf++ = ch; 10579b50d902SRodney W. Grimes } 10589b50d902SRodney W. Grimes } 10599b50d902SRodney W. Grimes col = ptbuf - buf; 10609b50d902SRodney W. Grimes if (ch == EOF) { 10619b50d902SRodney W. Grimes *mor = 0; 10629b50d902SRodney W. Grimes *cps = 0; 10639b50d902SRodney W. Grimes if (!col) 10649b50d902SRodney W. Grimes return(-1); 10659b50d902SRodney W. Grimes return(col); 10669b50d902SRodney W. Grimes } 10679b50d902SRodney W. Grimes if (ch == '\n') { 10689b50d902SRodney W. Grimes /* 10699b50d902SRodney W. Grimes * entire line processed 10709b50d902SRodney W. Grimes */ 10719b50d902SRodney W. Grimes *mor = 0; 10729b50d902SRodney W. Grimes *cps = 0; 10739b50d902SRodney W. Grimes return(col); 10749b50d902SRodney W. Grimes } 10759b50d902SRodney W. Grimes 10769b50d902SRodney W. Grimes /* 10779b50d902SRodney W. Grimes * line was larger than limit 10789b50d902SRodney W. Grimes */ 10799b50d902SRodney W. Grimes if (trnc) { 10809b50d902SRodney W. Grimes /* 10819b50d902SRodney W. Grimes * throw away rest of line 10829b50d902SRodney W. Grimes */ 10839b50d902SRodney W. Grimes while ((ch = getc(inf)) != EOF) { 10849b50d902SRodney W. Grimes if (ch == '\n') 10859b50d902SRodney W. Grimes break; 10869b50d902SRodney W. Grimes } 10879b50d902SRodney W. Grimes *cps = 0; 10889b50d902SRodney W. Grimes *mor = 0; 10899b50d902SRodney W. Grimes } else { 10909b50d902SRodney W. Grimes /* 10919b50d902SRodney W. Grimes * save column offset if not truncated 10929b50d902SRodney W. Grimes */ 10939b50d902SRodney W. Grimes *cps += col; 10949b50d902SRodney W. Grimes *mor = 1; 10959b50d902SRodney W. Grimes } 10969b50d902SRodney W. Grimes 10979b50d902SRodney W. Grimes return(col); 10989b50d902SRodney W. Grimes } 10999b50d902SRodney W. Grimes 11009b50d902SRodney W. Grimes /* 11019b50d902SRodney W. Grimes * otln(): output a line of data. (Supports unlimited length lines) 11029b50d902SRodney W. Grimes * output is optionally contracted to tabs 11039b50d902SRodney W. Grimes * 11049b50d902SRodney W. Grimes * buf: output buffer with data 11059b50d902SRodney W. Grimes * cnt: number of chars of valid data in buf 11069b50d902SRodney W. Grimes * svips: buffer input column position (for large lines) 11079b50d902SRodney W. Grimes * svops: buffer output column position (for large lines) 11089b50d902SRodney W. Grimes * mor: output line not complete in this buf; more data to come. 11099b50d902SRodney W. Grimes * 1 is more, 0 is complete, -1 is no \n's 11109b50d902SRodney W. Grimes */ 11119b50d902SRodney W. Grimes int 11129b50d902SRodney W. Grimes otln(buf, cnt, svips, svops, mor) 11139b50d902SRodney W. Grimes register char *buf; 11149b50d902SRodney W. Grimes int cnt; 11159b50d902SRodney W. Grimes int *svops; 11169b50d902SRodney W. Grimes int *svips; 11179b50d902SRodney W. Grimes int mor; 11189b50d902SRodney W. Grimes { 11199b50d902SRodney W. Grimes register int ops; /* last col output */ 11209b50d902SRodney W. Grimes register int ips; /* last col in buf examined */ 11219b50d902SRodney W. Grimes register int gap = ogap; 11229b50d902SRodney W. Grimes register int tbps; 11239b50d902SRodney W. Grimes register char *endbuf; 11249b50d902SRodney W. Grimes 11259b50d902SRodney W. Grimes if (ogap) { 11269b50d902SRodney W. Grimes /* 11279b50d902SRodney W. Grimes * contracting on output 11289b50d902SRodney W. Grimes */ 11299b50d902SRodney W. Grimes endbuf = buf + cnt; 11309b50d902SRodney W. Grimes ops = *svops; 11319b50d902SRodney W. Grimes ips = *svips; 11329b50d902SRodney W. Grimes while (buf < endbuf) { 11339b50d902SRodney W. Grimes /* 11349b50d902SRodney W. Grimes * count number of spaces and ochar in buffer 11359b50d902SRodney W. Grimes */ 11369b50d902SRodney W. Grimes if (*buf == ' ') { 11379b50d902SRodney W. Grimes ++ips; 11389b50d902SRodney W. Grimes ++buf; 11399b50d902SRodney W. Grimes continue; 11409b50d902SRodney W. Grimes } 11419b50d902SRodney W. Grimes 11429b50d902SRodney W. Grimes /* 11439b50d902SRodney W. Grimes * simulate ochar processing 11449b50d902SRodney W. Grimes */ 11459b50d902SRodney W. Grimes if (*buf == ochar) { 11469b50d902SRodney W. Grimes ips += gap - (ips % gap); 11479b50d902SRodney W. Grimes ++buf; 11489b50d902SRodney W. Grimes continue; 11499b50d902SRodney W. Grimes } 11509b50d902SRodney W. Grimes 11519b50d902SRodney W. Grimes /* 11529b50d902SRodney W. Grimes * got a non space char; contract out spaces 11539b50d902SRodney W. Grimes */ 115406b95991STim J. Robbins while (ips - ops > 1) { 11559b50d902SRodney W. Grimes /* 11569b50d902SRodney W. Grimes * use as many ochar as will fit 11579b50d902SRodney W. Grimes */ 11589b50d902SRodney W. Grimes if ((tbps = ops + gap - (ops % gap)) > ips) 11599b50d902SRodney W. Grimes break; 11609b50d902SRodney W. Grimes if (putchar(ochar) == EOF) { 11619b50d902SRodney W. Grimes pfail(); 11629b50d902SRodney W. Grimes return(1); 11639b50d902SRodney W. Grimes } 11649b50d902SRodney W. Grimes ops = tbps; 11659b50d902SRodney W. Grimes } 11669b50d902SRodney W. Grimes 11679b50d902SRodney W. Grimes while (ops < ips) { 11689b50d902SRodney W. Grimes /* 11699b50d902SRodney W. Grimes * finish off with spaces 11709b50d902SRodney W. Grimes */ 11719b50d902SRodney W. Grimes if (putchar(' ') == EOF) { 11729b50d902SRodney W. Grimes pfail(); 11739b50d902SRodney W. Grimes return(1); 11749b50d902SRodney W. Grimes } 11759b50d902SRodney W. Grimes ++ops; 11769b50d902SRodney W. Grimes } 11779b50d902SRodney W. Grimes 11789b50d902SRodney W. Grimes /* 11799b50d902SRodney W. Grimes * output non space char 11809b50d902SRodney W. Grimes */ 11819b50d902SRodney W. Grimes if (putchar(*buf++) == EOF) { 11829b50d902SRodney W. Grimes pfail(); 11839b50d902SRodney W. Grimes return(1); 11849b50d902SRodney W. Grimes } 11859b50d902SRodney W. Grimes ++ips; 11869b50d902SRodney W. Grimes ++ops; 11879b50d902SRodney W. Grimes } 11889b50d902SRodney W. Grimes 11899b50d902SRodney W. Grimes if (mor > 0) { 11909b50d902SRodney W. Grimes /* 11919b50d902SRodney W. Grimes * if incomplete line, save position counts 11929b50d902SRodney W. Grimes */ 11939b50d902SRodney W. Grimes *svops = ops; 11949b50d902SRodney W. Grimes *svips = ips; 11959b50d902SRodney W. Grimes return(0); 11969b50d902SRodney W. Grimes } 11979b50d902SRodney W. Grimes 11989b50d902SRodney W. Grimes if (mor < 0) { 119906b95991STim J. Robbins while (ips - ops > 1) { 12009b50d902SRodney W. Grimes /* 12019b50d902SRodney W. Grimes * use as many ochar as will fit 12029b50d902SRodney W. Grimes */ 12039b50d902SRodney W. Grimes if ((tbps = ops + gap - (ops % gap)) > ips) 12049b50d902SRodney W. Grimes break; 12059b50d902SRodney W. Grimes if (putchar(ochar) == EOF) { 12069b50d902SRodney W. Grimes pfail(); 12079b50d902SRodney W. Grimes return(1); 12089b50d902SRodney W. Grimes } 12099b50d902SRodney W. Grimes ops = tbps; 12109b50d902SRodney W. Grimes } 12119b50d902SRodney W. Grimes while (ops < ips) { 12129b50d902SRodney W. Grimes /* 12139b50d902SRodney W. Grimes * finish off with spaces 12149b50d902SRodney W. Grimes */ 12159b50d902SRodney W. Grimes if (putchar(' ') == EOF) { 12169b50d902SRodney W. Grimes pfail(); 12179b50d902SRodney W. Grimes return(1); 12189b50d902SRodney W. Grimes } 12199b50d902SRodney W. Grimes ++ops; 12209b50d902SRodney W. Grimes } 12219b50d902SRodney W. Grimes return(0); 12229b50d902SRodney W. Grimes } 12239b50d902SRodney W. Grimes } else { 12249b50d902SRodney W. Grimes /* 12259b50d902SRodney W. Grimes * output is not contracted 12269b50d902SRodney W. Grimes */ 12279b50d902SRodney W. Grimes if (cnt && (fwrite(buf, sizeof(char), cnt, stdout) <= 0)) { 12289b50d902SRodney W. Grimes pfail(); 12299b50d902SRodney W. Grimes return(1); 12309b50d902SRodney W. Grimes } 12319b50d902SRodney W. Grimes if (mor != 0) 12329b50d902SRodney W. Grimes return(0); 12339b50d902SRodney W. Grimes } 12349b50d902SRodney W. Grimes 12359b50d902SRodney W. Grimes /* 12369b50d902SRodney W. Grimes * process line end and double space as required 12379b50d902SRodney W. Grimes */ 12389b50d902SRodney W. Grimes if ((putchar('\n') == EOF) || (dspace && (putchar('\n') == EOF))) { 12399b50d902SRodney W. Grimes pfail(); 12409b50d902SRodney W. Grimes return(1); 12419b50d902SRodney W. Grimes } 12429b50d902SRodney W. Grimes return(0); 12439b50d902SRodney W. Grimes } 12449b50d902SRodney W. Grimes 12459b50d902SRodney W. Grimes /* 12469b50d902SRodney W. Grimes * inskip(): skip over pgcnt pages with lncnt lines per page 12479b50d902SRodney W. Grimes * file is closed at EOF (if not stdin). 12489b50d902SRodney W. Grimes * 12499b50d902SRodney W. Grimes * inf FILE * to read from 12509b50d902SRodney W. Grimes * pgcnt number of pages to skip 12519b50d902SRodney W. Grimes * lncnt number of lines per page 12529b50d902SRodney W. Grimes */ 12539b50d902SRodney W. Grimes int 12549b50d902SRodney W. Grimes inskip(inf, pgcnt, lncnt) 12559b50d902SRodney W. Grimes FILE *inf; 12569b50d902SRodney W. Grimes register int pgcnt; 12579b50d902SRodney W. Grimes register int lncnt; 12589b50d902SRodney W. Grimes { 12599b50d902SRodney W. Grimes register int c; 12609b50d902SRodney W. Grimes register int cnt; 12619b50d902SRodney W. Grimes 12629b50d902SRodney W. Grimes while(--pgcnt > 0) { 12639b50d902SRodney W. Grimes cnt = lncnt; 12649b50d902SRodney W. Grimes while ((c = getc(inf)) != EOF) { 12659b50d902SRodney W. Grimes if ((c == '\n') && (--cnt == 0)) 12669b50d902SRodney W. Grimes break; 12679b50d902SRodney W. Grimes } 12689b50d902SRodney W. Grimes if (c == EOF) { 12699b50d902SRodney W. Grimes if (inf != stdin) 12709b50d902SRodney W. Grimes (void)fclose(inf); 12719b50d902SRodney W. Grimes return(1); 12729b50d902SRodney W. Grimes } 12739b50d902SRodney W. Grimes } 12749b50d902SRodney W. Grimes return(0); 12759b50d902SRodney W. Grimes } 12769b50d902SRodney W. Grimes 12779b50d902SRodney W. Grimes /* 12789b50d902SRodney W. Grimes * nxtfile: returns a FILE * to next file in arg list and sets the 12799b50d902SRodney W. Grimes * time field for this file (or current date). 12809b50d902SRodney W. Grimes * 12819b50d902SRodney W. Grimes * buf array to store proper date for the header. 12829b50d902SRodney W. Grimes * dt if set skips the date processing (used with -m) 12839b50d902SRodney W. Grimes */ 12849b50d902SRodney W. Grimes FILE * 12859b50d902SRodney W. Grimes nxtfile(argc, argv, fname, buf, dt) 12869b50d902SRodney W. Grimes int argc; 12879b50d902SRodney W. Grimes char **argv; 12889b50d902SRodney W. Grimes char **fname; 12899b50d902SRodney W. Grimes char *buf; 12909b50d902SRodney W. Grimes int dt; 12919b50d902SRodney W. Grimes { 12929b50d902SRodney W. Grimes FILE *inf = NULL; 12939b50d902SRodney W. Grimes struct timeval tv; 1294375557fcSBruce Evans time_t tv_sec; 12959b50d902SRodney W. Grimes struct timezone tz; 12969b50d902SRodney W. Grimes struct tm *timeptr = NULL; 12979b50d902SRodney W. Grimes struct stat statbuf; 12989b50d902SRodney W. Grimes static int twice = -1; 12999b50d902SRodney W. Grimes 13009b50d902SRodney W. Grimes ++twice; 13019b50d902SRodney W. Grimes if (eoptind >= argc) { 13029b50d902SRodney W. Grimes /* 13039b50d902SRodney W. Grimes * no file listed; default, use standard input 13049b50d902SRodney W. Grimes */ 13059b50d902SRodney W. Grimes if (twice) 13069b50d902SRodney W. Grimes return(NULL); 13079b50d902SRodney W. Grimes clearerr(stdin); 13089b50d902SRodney W. Grimes inf = stdin; 13099b50d902SRodney W. Grimes if (header != NULL) 13109b50d902SRodney W. Grimes *fname = header; 13119b50d902SRodney W. Grimes else 13129b50d902SRodney W. Grimes *fname = FNAME; 13139b50d902SRodney W. Grimes if (nohead) 13149b50d902SRodney W. Grimes return(inf); 13159b50d902SRodney W. Grimes if (gettimeofday(&tv, &tz) < 0) { 13169b50d902SRodney W. Grimes ++errcnt; 13179b50d902SRodney W. Grimes (void)fprintf(err, "pr: cannot get time of day, %s\n", 13189b50d902SRodney W. Grimes strerror(errno)); 13199b50d902SRodney W. Grimes eoptind = argc - 1; 13209b50d902SRodney W. Grimes return(NULL); 13219b50d902SRodney W. Grimes } 1322375557fcSBruce Evans tv_sec = tv.tv_sec; 1323375557fcSBruce Evans timeptr = localtime(&tv_sec); 13249b50d902SRodney W. Grimes } 13259b50d902SRodney W. Grimes for (; eoptind < argc; ++eoptind) { 13269b50d902SRodney W. Grimes if (strcmp(argv[eoptind], "-") == 0) { 13279b50d902SRodney W. Grimes /* 13289b50d902SRodney W. Grimes * process a "-" for filename 13299b50d902SRodney W. Grimes */ 13309b50d902SRodney W. Grimes clearerr(stdin); 13319b50d902SRodney W. Grimes inf = stdin; 13329b50d902SRodney W. Grimes if (header != NULL) 13339b50d902SRodney W. Grimes *fname = header; 13349b50d902SRodney W. Grimes else 13359b50d902SRodney W. Grimes *fname = FNAME; 13369b50d902SRodney W. Grimes ++eoptind; 13379b50d902SRodney W. Grimes if (nohead || (dt && twice)) 13389b50d902SRodney W. Grimes return(inf); 13399b50d902SRodney W. Grimes if (gettimeofday(&tv, &tz) < 0) { 13409b50d902SRodney W. Grimes ++errcnt; 13419b50d902SRodney W. Grimes (void)fprintf(err, 13429b50d902SRodney W. Grimes "pr: cannot get time of day, %s\n", 13439b50d902SRodney W. Grimes strerror(errno)); 13449b50d902SRodney W. Grimes return(NULL); 13459b50d902SRodney W. Grimes } 1346375557fcSBruce Evans tv_sec = tv.tv_sec; 1347375557fcSBruce Evans timeptr = localtime(&tv_sec); 13489b50d902SRodney W. Grimes } else { 13499b50d902SRodney W. Grimes /* 13509b50d902SRodney W. Grimes * normal file processing 13519b50d902SRodney W. Grimes */ 13529b50d902SRodney W. Grimes if ((inf = fopen(argv[eoptind], "r")) == NULL) { 13539b50d902SRodney W. Grimes ++errcnt; 13549b50d902SRodney W. Grimes if (nodiag) 13559b50d902SRodney W. Grimes continue; 13569b50d902SRodney W. Grimes (void)fprintf(err, "pr: Cannot open %s, %s\n", 13579b50d902SRodney W. Grimes argv[eoptind], strerror(errno)); 13589b50d902SRodney W. Grimes continue; 13599b50d902SRodney W. Grimes } 13609b50d902SRodney W. Grimes if (header != NULL) 13619b50d902SRodney W. Grimes *fname = header; 13629b50d902SRodney W. Grimes else if (dt) 13639b50d902SRodney W. Grimes *fname = FNAME; 13649b50d902SRodney W. Grimes else 13659b50d902SRodney W. Grimes *fname = argv[eoptind]; 13669b50d902SRodney W. Grimes ++eoptind; 13679b50d902SRodney W. Grimes if (nohead || (dt && twice)) 13689b50d902SRodney W. Grimes return(inf); 13699b50d902SRodney W. Grimes 13709b50d902SRodney W. Grimes if (dt) { 13719b50d902SRodney W. Grimes if (gettimeofday(&tv, &tz) < 0) { 13729b50d902SRodney W. Grimes ++errcnt; 13739b50d902SRodney W. Grimes (void)fprintf(err, 13749b50d902SRodney W. Grimes "pr: cannot get time of day, %s\n", 13759b50d902SRodney W. Grimes strerror(errno)); 13769b50d902SRodney W. Grimes return(NULL); 13779b50d902SRodney W. Grimes } 1378375557fcSBruce Evans tv_sec = tv.tv_sec; 1379375557fcSBruce Evans timeptr = localtime(&tv_sec); 13809b50d902SRodney W. Grimes } else { 13819b50d902SRodney W. Grimes if (fstat(fileno(inf), &statbuf) < 0) { 13829b50d902SRodney W. Grimes ++errcnt; 13839b50d902SRodney W. Grimes (void)fclose(inf); 13849b50d902SRodney W. Grimes (void)fprintf(err, 13859b50d902SRodney W. Grimes "pr: Cannot stat %s, %s\n", 13869b50d902SRodney W. Grimes argv[eoptind], strerror(errno)); 13879b50d902SRodney W. Grimes return(NULL); 13889b50d902SRodney W. Grimes } 13899b50d902SRodney W. Grimes timeptr = localtime(&(statbuf.st_mtime)); 13909b50d902SRodney W. Grimes } 13919b50d902SRodney W. Grimes } 13929b50d902SRodney W. Grimes break; 13939b50d902SRodney W. Grimes } 13949b50d902SRodney W. Grimes if (inf == NULL) 13959b50d902SRodney W. Grimes return(NULL); 13969b50d902SRodney W. Grimes 13979b50d902SRodney W. Grimes /* 13989b50d902SRodney W. Grimes * set up time field used in header 13999b50d902SRodney W. Grimes */ 14009b50d902SRodney W. Grimes if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) { 14019b50d902SRodney W. Grimes ++errcnt; 14029b50d902SRodney W. Grimes if (inf != stdin) 14039b50d902SRodney W. Grimes (void)fclose(inf); 14049b50d902SRodney W. Grimes (void)fputs("pr: time conversion failed\n", err); 14059b50d902SRodney W. Grimes return(NULL); 14069b50d902SRodney W. Grimes } 14079b50d902SRodney W. Grimes return(inf); 14089b50d902SRodney W. Grimes } 14099b50d902SRodney W. Grimes 14109b50d902SRodney W. Grimes /* 14119b50d902SRodney W. Grimes * addnum(): adds the line number to the column 14129b50d902SRodney W. Grimes * Truncates from the front or pads with spaces as required. 14139b50d902SRodney W. Grimes * Numbers are right justified. 14149b50d902SRodney W. Grimes * 14159b50d902SRodney W. Grimes * buf buffer to store the number 14169b50d902SRodney W. Grimes * wdth width of buffer to fill 14179b50d902SRodney W. Grimes * line line number 14189b50d902SRodney W. Grimes * 14199b50d902SRodney W. Grimes * NOTE: numbers occupy part of the column. The posix 14209b50d902SRodney W. Grimes * spec does not specify if -i processing should or should not 14219b50d902SRodney W. Grimes * occur on number padding. The spec does say it occupies 14229b50d902SRodney W. Grimes * part of the column. The usage of addnum currently treats 14239b50d902SRodney W. Grimes * numbers as part of the column so spaces may be replaced. 14249b50d902SRodney W. Grimes */ 14259b50d902SRodney W. Grimes void 14269b50d902SRodney W. Grimes addnum(buf, wdth, line) 14279b50d902SRodney W. Grimes register char *buf; 14289b50d902SRodney W. Grimes register int wdth; 14299b50d902SRodney W. Grimes register int line; 14309b50d902SRodney W. Grimes { 14319b50d902SRodney W. Grimes register char *pt = buf + wdth; 14329b50d902SRodney W. Grimes 14339b50d902SRodney W. Grimes do { 14349b50d902SRodney W. Grimes *--pt = digs[line % 10]; 14359b50d902SRodney W. Grimes line /= 10; 14369b50d902SRodney W. Grimes } while (line && (pt > buf)); 14379b50d902SRodney W. Grimes 14389b50d902SRodney W. Grimes /* 14399b50d902SRodney W. Grimes * pad with space as required 14409b50d902SRodney W. Grimes */ 14419b50d902SRodney W. Grimes while (pt > buf) 14429b50d902SRodney W. Grimes *--pt = ' '; 14439b50d902SRodney W. Grimes } 14449b50d902SRodney W. Grimes 14459b50d902SRodney W. Grimes /* 14469b50d902SRodney W. Grimes * prhead(): prints the top of page header 14479b50d902SRodney W. Grimes * 14489b50d902SRodney W. Grimes * buf buffer with time field (and offset) 14499b50d902SRodney W. Grimes * cnt number of chars in buf 14509b50d902SRodney W. Grimes * fname fname field for header 14519b50d902SRodney W. Grimes * pagcnt page number 14529b50d902SRodney W. Grimes */ 14539b50d902SRodney W. Grimes int 14549b50d902SRodney W. Grimes prhead(buf, fname, pagcnt) 14559b50d902SRodney W. Grimes char *buf; 14569b50d902SRodney W. Grimes char *fname; 14579b50d902SRodney W. Grimes int pagcnt; 14589b50d902SRodney W. Grimes { 14599b50d902SRodney W. Grimes int ips = 0; 14609b50d902SRodney W. Grimes int ops = 0; 14619b50d902SRodney W. Grimes 14629b50d902SRodney W. Grimes if ((putchar('\n') == EOF) || (putchar('\n') == EOF)) { 14639b50d902SRodney W. Grimes pfail(); 14649b50d902SRodney W. Grimes return(1); 14659b50d902SRodney W. Grimes } 14669b50d902SRodney W. Grimes /* 14679b50d902SRodney W. Grimes * posix is not clear if the header is subject to line length 14689b50d902SRodney W. Grimes * restrictions. The specification for header line format 14699b50d902SRodney W. Grimes * in the spec clearly does not limit length. No pr currently 14709b50d902SRodney W. Grimes * restricts header length. However if we need to truncate in 14719b50d902SRodney W. Grimes * an reasonable way, adjust the length of the printf by 14729b50d902SRodney W. Grimes * changing HDFMT to allow a length max as an arguement printf. 14739b50d902SRodney W. Grimes * buf (which contains the offset spaces and time field could 14749b50d902SRodney W. Grimes * also be trimmed 14759b50d902SRodney W. Grimes * 14769b50d902SRodney W. Grimes * note only the offset (if any) is processed for tab expansion 14779b50d902SRodney W. Grimes */ 14789b50d902SRodney W. Grimes if (offst && otln(buf, offst, &ips, &ops, -1)) 14799b50d902SRodney W. Grimes return(1); 14809b50d902SRodney W. Grimes (void)printf(HDFMT,buf+offst, fname, pagcnt); 14819b50d902SRodney W. Grimes return(0); 14829b50d902SRodney W. Grimes } 14839b50d902SRodney W. Grimes 14849b50d902SRodney W. Grimes /* 14859b50d902SRodney W. Grimes * prtail(): pad page with empty lines (if required) and print page trailer 14869b50d902SRodney W. Grimes * if requested 14879b50d902SRodney W. Grimes * 14889b50d902SRodney W. Grimes * cnt number of lines of padding needed 14899b50d902SRodney W. Grimes * incomp was a '\n' missing from last line output 14909b50d902SRodney W. Grimes */ 14919b50d902SRodney W. Grimes int 14929b50d902SRodney W. Grimes prtail(cnt, incomp) 14939b50d902SRodney W. Grimes register int cnt; 14949b50d902SRodney W. Grimes int incomp; 14959b50d902SRodney W. Grimes { 14969b50d902SRodney W. Grimes if (nohead) { 14979b50d902SRodney W. Grimes /* 14989b50d902SRodney W. Grimes * only pad with no headers when incomplete last line 14999b50d902SRodney W. Grimes */ 1500ebcf24fbSMarc G. Fournier if (incomp && 1501ebcf24fbSMarc G. Fournier ((dspace && (putchar('\n') == EOF)) || 1502ebcf24fbSMarc G. Fournier (putchar('\n') == EOF))) { 15039b50d902SRodney W. Grimes pfail(); 15049b50d902SRodney W. Grimes return(1); 15059b50d902SRodney W. Grimes } 1506ebcf24fbSMarc G. Fournier /* 1507ebcf24fbSMarc G. Fournier * but honor the formfeed request 1508ebcf24fbSMarc G. Fournier */ 1509ebcf24fbSMarc G. Fournier if (formfeed) { 1510ebcf24fbSMarc G. Fournier if (putchar('\f') == EOF) { 1511ebcf24fbSMarc G. Fournier pfail(); 1512ebcf24fbSMarc G. Fournier return(1); 1513ebcf24fbSMarc G. Fournier } 1514ebcf24fbSMarc G. Fournier } 15159b50d902SRodney W. Grimes return(0); 15169b50d902SRodney W. Grimes } 15179b50d902SRodney W. Grimes /* 15189b50d902SRodney W. Grimes * if double space output two \n 15199b50d902SRodney W. Grimes */ 15209b50d902SRodney W. Grimes if (dspace) 15219b50d902SRodney W. Grimes cnt *= 2; 15229b50d902SRodney W. Grimes 15239b50d902SRodney W. Grimes /* 15249b50d902SRodney W. Grimes * if an odd number of lines per page, add an extra \n 15259b50d902SRodney W. Grimes */ 15269b50d902SRodney W. Grimes if (addone) 15279b50d902SRodney W. Grimes ++cnt; 15289b50d902SRodney W. Grimes 15299b50d902SRodney W. Grimes /* 15309b50d902SRodney W. Grimes * pad page 15319b50d902SRodney W. Grimes */ 15329b50d902SRodney W. Grimes if (formfeed) { 15339b50d902SRodney W. Grimes if ((incomp && (putchar('\n') == EOF)) || 15349b50d902SRodney W. Grimes (putchar('\f') == EOF)) { 15359b50d902SRodney W. Grimes pfail(); 15369b50d902SRodney W. Grimes return(1); 15379b50d902SRodney W. Grimes } 15389b50d902SRodney W. Grimes return(0); 15399b50d902SRodney W. Grimes } 15409b50d902SRodney W. Grimes cnt += TAILLEN; 15419b50d902SRodney W. Grimes while (--cnt >= 0) { 15429b50d902SRodney W. Grimes if (putchar('\n') == EOF) { 15439b50d902SRodney W. Grimes pfail(); 15449b50d902SRodney W. Grimes return(1); 15459b50d902SRodney W. Grimes } 15469b50d902SRodney W. Grimes } 15479b50d902SRodney W. Grimes return(0); 15489b50d902SRodney W. Grimes } 15499b50d902SRodney W. Grimes 15509b50d902SRodney W. Grimes /* 15519b50d902SRodney W. Grimes * terminate(): when a SIGINT is recvd 15529b50d902SRodney W. Grimes */ 15539b50d902SRodney W. Grimes void 15549b50d902SRodney W. Grimes terminate(which_sig) 15559b50d902SRodney W. Grimes int which_sig; 15569b50d902SRodney W. Grimes { 15579b50d902SRodney W. Grimes flsh_errs(); 15589b50d902SRodney W. Grimes exit(1); 15599b50d902SRodney W. Grimes } 15609b50d902SRodney W. Grimes 15619b50d902SRodney W. Grimes 15629b50d902SRodney W. Grimes /* 15639b50d902SRodney W. Grimes * flsh_errs(): output saved up diagnostic messages after all normal 15649b50d902SRodney W. Grimes * processing has completed 15659b50d902SRodney W. Grimes */ 15669b50d902SRodney W. Grimes void 15679b50d902SRodney W. Grimes flsh_errs() 15689b50d902SRodney W. Grimes { 15699b50d902SRodney W. Grimes char buf[BUFSIZ]; 15709b50d902SRodney W. Grimes 15719b50d902SRodney W. Grimes (void)fflush(stdout); 15729b50d902SRodney W. Grimes (void)fflush(err); 15739b50d902SRodney W. Grimes if (err == stderr) 15749b50d902SRodney W. Grimes return; 15759b50d902SRodney W. Grimes rewind(err); 15769b50d902SRodney W. Grimes while (fgets(buf, BUFSIZ, err) != NULL) 15779b50d902SRodney W. Grimes (void)fputs(buf, stderr); 15789b50d902SRodney W. Grimes } 15799b50d902SRodney W. Grimes 15809b50d902SRodney W. Grimes void 15819b50d902SRodney W. Grimes mfail() 15829b50d902SRodney W. Grimes { 15839b50d902SRodney W. Grimes (void)fputs("pr: memory allocation failed\n", err); 15849b50d902SRodney W. Grimes } 15859b50d902SRodney W. Grimes 15869b50d902SRodney W. Grimes void 15879b50d902SRodney W. Grimes pfail() 15889b50d902SRodney W. Grimes { 15899b50d902SRodney W. Grimes (void)fprintf(err, "pr: write failure, %s\n", strerror(errno)); 15909b50d902SRodney W. Grimes } 15919b50d902SRodney W. Grimes 15929b50d902SRodney W. Grimes void 15939b50d902SRodney W. Grimes usage() 15949b50d902SRodney W. Grimes { 15959b50d902SRodney W. Grimes (void)fputs( 1596032b32adSJuli Mallett "usage: pr [+page] [-col] [-adFfmprt] [-e[ch][gap]] [-h header]\n", 1597032b32adSJuli Mallett err); 15989b50d902SRodney W. Grimes (void)fputs( 15999b50d902SRodney W. Grimes " [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err); 16009b50d902SRodney W. Grimes (void)fputs( 16014bf9895eSAndrey A. Chernov " [-L locale] [-s[ch]] [-w width] [-] [file ...]\n", err); 16029b50d902SRodney W. Grimes } 16039b50d902SRodney W. Grimes 16049b50d902SRodney W. Grimes /* 16059b50d902SRodney W. Grimes * setup: Validate command args, initialize and perform sanity 16069b50d902SRodney W. Grimes * checks on options 16079b50d902SRodney W. Grimes */ 16089b50d902SRodney W. Grimes int 16099b50d902SRodney W. Grimes setup(argc, argv) 16109b50d902SRodney W. Grimes register int argc; 16119b50d902SRodney W. Grimes register char **argv; 16129b50d902SRodney W. Grimes { 16139b50d902SRodney W. Grimes register int c; 161477b898c4SAndrey A. Chernov int d_first; 16159b50d902SRodney W. Grimes int eflag = 0; 16169b50d902SRodney W. Grimes int iflag = 0; 16179b50d902SRodney W. Grimes int wflag = 0; 16189b50d902SRodney W. Grimes int cflag = 0; 16194bf9895eSAndrey A. Chernov char *Lflag = NULL; 16209b50d902SRodney W. Grimes 16219b50d902SRodney W. Grimes if (isatty(fileno(stdout))) { 16229b50d902SRodney W. Grimes /* 16239b50d902SRodney W. Grimes * defer diagnostics until processing is done 16249b50d902SRodney W. Grimes */ 16259b50d902SRodney W. Grimes if ((err = tmpfile()) == NULL) { 162696c066ccSChris D. Faulhaber err = stderr; 16279b50d902SRodney W. Grimes (void)fputs("Cannot defer diagnostic messages\n",stderr); 16289b50d902SRodney W. Grimes return(1); 16299b50d902SRodney W. Grimes } 16309b50d902SRodney W. Grimes } else 16319b50d902SRodney W. Grimes err = stderr; 1632032b32adSJuli Mallett while ((c = egetopt(argc, argv, "#adFfmrte?h:i?L:l:n?o:ps?w:")) != -1) { 16339b50d902SRodney W. Grimes switch (c) { 16349b50d902SRodney W. Grimes case '+': 16359b50d902SRodney W. Grimes if ((pgnm = atoi(eoptarg)) < 1) { 16369b50d902SRodney W. Grimes (void)fputs("pr: +page number must be 1 or more\n", 16379b50d902SRodney W. Grimes err); 16389b50d902SRodney W. Grimes return(1); 16399b50d902SRodney W. Grimes } 16409b50d902SRodney W. Grimes break; 16419b50d902SRodney W. Grimes case '-': 16429b50d902SRodney W. Grimes if ((clcnt = atoi(eoptarg)) < 1) { 16439b50d902SRodney W. Grimes (void)fputs("pr: -columns must be 1 or more\n",err); 16449b50d902SRodney W. Grimes return(1); 16459b50d902SRodney W. Grimes } 16469b50d902SRodney W. Grimes if (clcnt > 1) 16479b50d902SRodney W. Grimes ++cflag; 16489b50d902SRodney W. Grimes break; 16499b50d902SRodney W. Grimes case 'a': 16509b50d902SRodney W. Grimes ++across; 16519b50d902SRodney W. Grimes break; 16529b50d902SRodney W. Grimes case 'd': 16539b50d902SRodney W. Grimes ++dspace; 16549b50d902SRodney W. Grimes break; 16559b50d902SRodney W. Grimes case 'e': 16569b50d902SRodney W. Grimes ++eflag; 1657b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && !isdigit((unsigned char)*eoptarg)) 16589b50d902SRodney W. Grimes inchar = *eoptarg++; 16599b50d902SRodney W. Grimes else 16609b50d902SRodney W. Grimes inchar = INCHAR; 1661b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && isdigit((unsigned char)*eoptarg)) { 16629b50d902SRodney W. Grimes if ((ingap = atoi(eoptarg)) < 0) { 16639b50d902SRodney W. Grimes (void)fputs( 16649b50d902SRodney W. Grimes "pr: -e gap must be 0 or more\n", err); 16659b50d902SRodney W. Grimes return(1); 16669b50d902SRodney W. Grimes } 16679b50d902SRodney W. Grimes if (ingap == 0) 16689b50d902SRodney W. Grimes ingap = INGAP; 16699b50d902SRodney W. Grimes } else if ((eoptarg != NULL) && (*eoptarg != '\0')) { 16709b50d902SRodney W. Grimes (void)fprintf(err, 16719b50d902SRodney W. Grimes "pr: invalid value for -e %s\n", eoptarg); 16729b50d902SRodney W. Grimes return(1); 16739b50d902SRodney W. Grimes } else 16749b50d902SRodney W. Grimes ingap = INGAP; 16759b50d902SRodney W. Grimes break; 1676032b32adSJuli Mallett case 'f': 1677032b32adSJuli Mallett ++pausefst; 1678032b32adSJuli Mallett /*FALLTHROUGH*/ 16799b50d902SRodney W. Grimes case 'F': 16809b50d902SRodney W. Grimes ++formfeed; 16819b50d902SRodney W. Grimes break; 16829b50d902SRodney W. Grimes case 'h': 16839b50d902SRodney W. Grimes header = eoptarg; 16849b50d902SRodney W. Grimes break; 16859b50d902SRodney W. Grimes case 'i': 16869b50d902SRodney W. Grimes ++iflag; 1687b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && !isdigit((unsigned char)*eoptarg)) 16889b50d902SRodney W. Grimes ochar = *eoptarg++; 16899b50d902SRodney W. Grimes else 16909b50d902SRodney W. Grimes ochar = OCHAR; 1691b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && isdigit((unsigned char)*eoptarg)) { 16929b50d902SRodney W. Grimes if ((ogap = atoi(eoptarg)) < 0) { 16939b50d902SRodney W. Grimes (void)fputs( 16949b50d902SRodney W. Grimes "pr: -i gap must be 0 or more\n", err); 16959b50d902SRodney W. Grimes return(1); 16969b50d902SRodney W. Grimes } 16979b50d902SRodney W. Grimes if (ogap == 0) 16989b50d902SRodney W. Grimes ogap = OGAP; 16999b50d902SRodney W. Grimes } else if ((eoptarg != NULL) && (*eoptarg != '\0')) { 17009b50d902SRodney W. Grimes (void)fprintf(err, 17019b50d902SRodney W. Grimes "pr: invalid value for -i %s\n", eoptarg); 17029b50d902SRodney W. Grimes return(1); 17039b50d902SRodney W. Grimes } else 17049b50d902SRodney W. Grimes ogap = OGAP; 17059b50d902SRodney W. Grimes break; 1706b5076d91SAndrey A. Chernov case 'L': 17074bf9895eSAndrey A. Chernov Lflag = eoptarg; 1708b5076d91SAndrey A. Chernov break; 17099b50d902SRodney W. Grimes case 'l': 1710b5076d91SAndrey A. Chernov if (!isdigit((unsigned char)*eoptarg) || ((lines=atoi(eoptarg)) < 1)) { 17119b50d902SRodney W. Grimes (void)fputs( 17129b50d902SRodney W. Grimes "pr: Number of lines must be 1 or more\n",err); 17139b50d902SRodney W. Grimes return(1); 17149b50d902SRodney W. Grimes } 17159b50d902SRodney W. Grimes break; 17169b50d902SRodney W. Grimes case 'm': 17179b50d902SRodney W. Grimes ++merge; 17189b50d902SRodney W. Grimes break; 17199b50d902SRodney W. Grimes case 'n': 1720b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && !isdigit((unsigned char)*eoptarg)) 17219b50d902SRodney W. Grimes nmchar = *eoptarg++; 17229b50d902SRodney W. Grimes else 17239b50d902SRodney W. Grimes nmchar = NMCHAR; 1724b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && isdigit((unsigned char)*eoptarg)) { 17259b50d902SRodney W. Grimes if ((nmwd = atoi(eoptarg)) < 1) { 17269b50d902SRodney W. Grimes (void)fputs( 17279b50d902SRodney W. Grimes "pr: -n width must be 1 or more\n",err); 17289b50d902SRodney W. Grimes return(1); 17299b50d902SRodney W. Grimes } 17309b50d902SRodney W. Grimes } else if ((eoptarg != NULL) && (*eoptarg != '\0')) { 17319b50d902SRodney W. Grimes (void)fprintf(err, 17329b50d902SRodney W. Grimes "pr: invalid value for -n %s\n", eoptarg); 17339b50d902SRodney W. Grimes return(1); 17349b50d902SRodney W. Grimes } else 17359b50d902SRodney W. Grimes nmwd = NMWD; 17369b50d902SRodney W. Grimes break; 17379b50d902SRodney W. Grimes case 'o': 1738b5076d91SAndrey A. Chernov if (!isdigit((unsigned char)*eoptarg) || ((offst = atoi(eoptarg))< 1)){ 17399b50d902SRodney W. Grimes (void)fputs("pr: -o offset must be 1 or more\n", 17409b50d902SRodney W. Grimes err); 17419b50d902SRodney W. Grimes return(1); 17429b50d902SRodney W. Grimes } 17439b50d902SRodney W. Grimes break; 1744032b32adSJuli Mallett case 'p': 1745032b32adSJuli Mallett ++pauseall; 1746032b32adSJuli Mallett break; 17479b50d902SRodney W. Grimes case 'r': 17489b50d902SRodney W. Grimes ++nodiag; 17499b50d902SRodney W. Grimes break; 17509b50d902SRodney W. Grimes case 's': 17519b50d902SRodney W. Grimes ++sflag; 17529b50d902SRodney W. Grimes if (eoptarg == NULL) 17539b50d902SRodney W. Grimes schar = SCHAR; 1754d68e2acdSKris Kennaway else { 17559b50d902SRodney W. Grimes schar = *eoptarg++; 17569b50d902SRodney W. Grimes if (*eoptarg != '\0') { 17579b50d902SRodney W. Grimes (void)fprintf(err, 1758d68e2acdSKris Kennaway "pr: invalid value for -s %s\n", 1759d68e2acdSKris Kennaway eoptarg); 17609b50d902SRodney W. Grimes return(1); 17619b50d902SRodney W. Grimes } 1762d68e2acdSKris Kennaway } 17639b50d902SRodney W. Grimes break; 17649b50d902SRodney W. Grimes case 't': 17659b50d902SRodney W. Grimes ++nohead; 17669b50d902SRodney W. Grimes break; 17679b50d902SRodney W. Grimes case 'w': 17689b50d902SRodney W. Grimes ++wflag; 1769b5076d91SAndrey A. Chernov if (!isdigit((unsigned char)*eoptarg) || ((pgwd = atoi(eoptarg)) < 1)){ 17709b50d902SRodney W. Grimes (void)fputs( 17719b50d902SRodney W. Grimes "pr: -w width must be 1 or more \n",err); 17729b50d902SRodney W. Grimes return(1); 17739b50d902SRodney W. Grimes } 17749b50d902SRodney W. Grimes break; 17759b50d902SRodney W. Grimes case '?': 17769b50d902SRodney W. Grimes default: 17779b50d902SRodney W. Grimes return(1); 17789b50d902SRodney W. Grimes } 17799b50d902SRodney W. Grimes } 17809b50d902SRodney W. Grimes 17819b50d902SRodney W. Grimes /* 17829b50d902SRodney W. Grimes * default and sanity checks 17839b50d902SRodney W. Grimes */ 17849b50d902SRodney W. Grimes if (!clcnt) { 17859b50d902SRodney W. Grimes if (merge) { 17869b50d902SRodney W. Grimes if ((clcnt = argc - eoptind) <= 1) { 17879b50d902SRodney W. Grimes clcnt = CLCNT; 17889b50d902SRodney W. Grimes merge = 0; 17899b50d902SRodney W. Grimes } 17909b50d902SRodney W. Grimes } else 17919b50d902SRodney W. Grimes clcnt = CLCNT; 17929b50d902SRodney W. Grimes } 17939b50d902SRodney W. Grimes if (across) { 17949b50d902SRodney W. Grimes if (clcnt == 1) { 17959b50d902SRodney W. Grimes (void)fputs("pr: -a flag requires multiple columns\n", 17969b50d902SRodney W. Grimes err); 17979b50d902SRodney W. Grimes return(1); 17989b50d902SRodney W. Grimes } 17999b50d902SRodney W. Grimes if (merge) { 18009b50d902SRodney W. Grimes (void)fputs("pr: -m cannot be used with -a\n", err); 18019b50d902SRodney W. Grimes return(1); 18029b50d902SRodney W. Grimes } 18039b50d902SRodney W. Grimes } 18049b50d902SRodney W. Grimes if (!wflag) { 18059b50d902SRodney W. Grimes if (sflag) 18069b50d902SRodney W. Grimes pgwd = SPGWD; 18079b50d902SRodney W. Grimes else 18089b50d902SRodney W. Grimes pgwd = PGWD; 18099b50d902SRodney W. Grimes } 18109b50d902SRodney W. Grimes if (cflag || merge) { 18119b50d902SRodney W. Grimes if (!eflag) { 18129b50d902SRodney W. Grimes inchar = INCHAR; 18139b50d902SRodney W. Grimes ingap = INGAP; 18149b50d902SRodney W. Grimes } 18159b50d902SRodney W. Grimes if (!iflag) { 18169b50d902SRodney W. Grimes ochar = OCHAR; 18179b50d902SRodney W. Grimes ogap = OGAP; 18189b50d902SRodney W. Grimes } 18199b50d902SRodney W. Grimes } 18209b50d902SRodney W. Grimes if (cflag) { 18219b50d902SRodney W. Grimes if (merge) { 18229b50d902SRodney W. Grimes (void)fputs( 18239b50d902SRodney W. Grimes "pr: -m cannot be used with multiple columns\n", err); 18249b50d902SRodney W. Grimes return(1); 18259b50d902SRodney W. Grimes } 18269b50d902SRodney W. Grimes if (nmwd) { 18279b50d902SRodney W. Grimes colwd = (pgwd + 1 - (clcnt * (nmwd + 2)))/clcnt; 18289b50d902SRodney W. Grimes pgwd = ((colwd + nmwd + 2) * clcnt) - 1; 18299b50d902SRodney W. Grimes } else { 18309b50d902SRodney W. Grimes colwd = (pgwd + 1 - clcnt)/clcnt; 18319b50d902SRodney W. Grimes pgwd = ((colwd + 1) * clcnt) - 1; 18329b50d902SRodney W. Grimes } 18339b50d902SRodney W. Grimes if (colwd < 1) { 18349b50d902SRodney W. Grimes (void)fprintf(err, 18359b50d902SRodney W. Grimes "pr: page width is too small for %d columns\n",clcnt); 18369b50d902SRodney W. Grimes return(1); 18379b50d902SRodney W. Grimes } 18389b50d902SRodney W. Grimes } 18399b50d902SRodney W. Grimes if (!lines) 18409b50d902SRodney W. Grimes lines = LINES; 18419b50d902SRodney W. Grimes 18429b50d902SRodney W. Grimes /* 18439b50d902SRodney W. Grimes * make sure long enough for headers. if not disable 18449b50d902SRodney W. Grimes */ 18459b50d902SRodney W. Grimes if (lines <= HEADLEN + TAILLEN) 18469b50d902SRodney W. Grimes ++nohead; 18479b50d902SRodney W. Grimes else if (!nohead) 18489b50d902SRodney W. Grimes lines -= HEADLEN + TAILLEN; 18499b50d902SRodney W. Grimes 18509b50d902SRodney W. Grimes /* 18519b50d902SRodney W. Grimes * adjust for double space on odd length pages 18529b50d902SRodney W. Grimes */ 18539b50d902SRodney W. Grimes if (dspace) { 18549b50d902SRodney W. Grimes if (lines == 1) 18559b50d902SRodney W. Grimes dspace = 0; 18569b50d902SRodney W. Grimes else { 18579b50d902SRodney W. Grimes if (lines & 1) 18589b50d902SRodney W. Grimes ++addone; 18599b50d902SRodney W. Grimes lines /= 2; 18609b50d902SRodney W. Grimes } 18619b50d902SRodney W. Grimes } 18629b50d902SRodney W. Grimes 18634bf9895eSAndrey A. Chernov (void) setlocale(LC_TIME, (Lflag != NULL) ? Lflag : ""); 1864b5076d91SAndrey A. Chernov 186577b898c4SAndrey A. Chernov d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); 186677b898c4SAndrey A. Chernov timefrmt = d_first ? TIMEFMTD : TIMEFMTM; 186777b898c4SAndrey A. Chernov 18689b50d902SRodney W. Grimes return(0); 18699b50d902SRodney W. Grimes } 1870