19b50d902SRodney W. Grimes /*-
2*5f034518SEitan Adler * SPDX-License-Identifier: BSD-4-Clause
3df57947fSPedro F. Giffuni *
49b50d902SRodney W. Grimes * Copyright (c) 1991 Keith Muller.
59b50d902SRodney W. Grimes * Copyright (c) 1993
69b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved.
79b50d902SRodney W. Grimes *
89b50d902SRodney W. Grimes * This code is derived from software contributed to Berkeley by
99b50d902SRodney W. Grimes * Keith Muller of the University of California, San Diego.
109b50d902SRodney W. Grimes *
119b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without
129b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions
139b50d902SRodney W. Grimes * are met:
149b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright
159b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer.
169b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright
179b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the
189b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution.
19*5f034518SEitan Adler * 3. All advertising materials mentioning features or use of this software
20*5f034518SEitan Adler * must display the following acknowledgement:
21*5f034518SEitan Adler * This product includes software developed by the University of
22*5f034518SEitan Adler * California, Berkeley and its contributors.
23*5f034518SEitan Adler * 4. Neither the name of the University nor the names of its contributors
249b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software
259b50d902SRodney W. Grimes * without specific prior written permission.
269b50d902SRodney W. Grimes *
279b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
289b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
299b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
309b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
319b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
329b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
339b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
349b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
359b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
369b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
379b50d902SRodney W. Grimes * SUCH DAMAGE.
389b50d902SRodney W. Grimes */
399b50d902SRodney W. Grimes
409b50d902SRodney W. Grimes #include <sys/types.h>
419b50d902SRodney W. Grimes #include <sys/time.h>
429b50d902SRodney W. Grimes #include <sys/stat.h>
439b50d902SRodney W. Grimes
449b50d902SRodney W. Grimes #include <ctype.h>
459b50d902SRodney W. Grimes #include <errno.h>
4677b898c4SAndrey A. Chernov #include <langinfo.h>
47b5076d91SAndrey A. Chernov #include <locale.h>
489b50d902SRodney W. Grimes #include <signal.h>
499b50d902SRodney W. Grimes #include <stdio.h>
509b50d902SRodney W. Grimes #include <stdlib.h>
519b50d902SRodney W. Grimes #include <string.h>
529b50d902SRodney W. Grimes #include <unistd.h>
539b50d902SRodney W. Grimes
549b50d902SRodney W. Grimes #include "pr.h"
559b50d902SRodney W. Grimes #include "extern.h"
569b50d902SRodney W. Grimes
579b50d902SRodney W. Grimes /*
589b50d902SRodney W. Grimes * pr: a printing and pagination filter. If multiple input files
599b50d902SRodney W. Grimes * are specified, each is read, formatted, and written to standard
601a6e52d0SJeroen Ruigrok van der Werven * output. By default, input is separated into 66-line pages, each
619b50d902SRodney W. Grimes * with a header that includes the page number, date, time and the
629b50d902SRodney W. Grimes * files pathname.
639b50d902SRodney W. Grimes *
649b50d902SRodney W. Grimes * Complies with posix P1003.2/D11
659b50d902SRodney W. Grimes */
669b50d902SRodney W. Grimes
679b50d902SRodney W. Grimes /*
689b50d902SRodney W. Grimes * parameter variables
699b50d902SRodney W. Grimes */
704f5e9a1aSEd Schouten static int pgnm; /* starting page number */
714f5e9a1aSEd Schouten static int clcnt; /* number of columns */
724f5e9a1aSEd Schouten static int colwd; /* column data width - multiple columns */
734f5e9a1aSEd Schouten static int across; /* mult col flag; write across page */
744f5e9a1aSEd Schouten static int dspace; /* double space flag */
754f5e9a1aSEd Schouten static char inchar; /* expand input char */
764f5e9a1aSEd Schouten static int ingap; /* expand input gap */
774f5e9a1aSEd Schouten static int pausefst; /* Pause before first page */
784f5e9a1aSEd Schouten static int pauseall; /* Pause before each page */
794f5e9a1aSEd Schouten static int formfeed; /* use formfeed as trailer */
804f5e9a1aSEd Schouten static char *header; /* header name instead of file name */
814f5e9a1aSEd Schouten static char ochar; /* contract output char */
824f5e9a1aSEd Schouten static int ogap; /* contract output gap */
834f5e9a1aSEd Schouten static int lines; /* number of lines per page */
844f5e9a1aSEd Schouten static int merge; /* merge multiple files in output */
854f5e9a1aSEd Schouten static char nmchar; /* line numbering append char */
864f5e9a1aSEd Schouten static int nmwd; /* width of line number field */
874f5e9a1aSEd Schouten static int offst; /* number of page offset spaces */
884f5e9a1aSEd Schouten static int nodiag; /* do not report file open errors */
894f5e9a1aSEd Schouten static char schar; /* text column separation character */
904f5e9a1aSEd Schouten static int sflag; /* -s option for multiple columns */
914f5e9a1aSEd Schouten static int nohead; /* do not write head and trailer */
924f5e9a1aSEd Schouten static int pgwd; /* page width with multiple col output */
936dc025eaSAlan Somers static char *timefrmt; /* time conversion string */
949b50d902SRodney W. Grimes
959b50d902SRodney W. Grimes /*
969b50d902SRodney W. Grimes * misc globals
979b50d902SRodney W. Grimes */
984f5e9a1aSEd Schouten static FILE *err; /* error message file pointer */
994f5e9a1aSEd Schouten static int addone; /* page length is odd with double space */
1004f5e9a1aSEd Schouten static int errcnt; /* error count on file processing */
1014f5e9a1aSEd Schouten static char digs[] = "0123456789"; /* page number translation map */
1029b50d902SRodney W. Grimes
1034f5e9a1aSEd Schouten static char fnamedefault[] = FNAME;
104e0761ab1SMark Murray
1059b50d902SRodney W. Grimes int
main(int argc,char * argv[])106e0761ab1SMark Murray main(int argc, char *argv[])
1079b50d902SRodney W. Grimes {
1089b50d902SRodney W. Grimes int ret_val;
1099b50d902SRodney W. Grimes
1109b50d902SRodney W. Grimes if (signal(SIGINT, SIG_IGN) != SIG_IGN)
1119b50d902SRodney W. Grimes (void)signal(SIGINT, terminate);
1129b50d902SRodney W. Grimes ret_val = setup(argc, argv);
1139b50d902SRodney W. Grimes if (!ret_val) {
1149b50d902SRodney W. Grimes /*
1159b50d902SRodney W. Grimes * select the output format based on options
1169b50d902SRodney W. Grimes */
1179b50d902SRodney W. Grimes if (merge)
1189b50d902SRodney W. Grimes ret_val = mulfile(argc, argv);
1199b50d902SRodney W. Grimes else if (clcnt == 1)
1209b50d902SRodney W. Grimes ret_val = onecol(argc, argv);
1219b50d902SRodney W. Grimes else if (across)
1229b50d902SRodney W. Grimes ret_val = horzcol(argc, argv);
1239b50d902SRodney W. Grimes else
1249b50d902SRodney W. Grimes ret_val = vertcol(argc, argv);
1256dc025eaSAlan Somers free(timefrmt);
1269b50d902SRodney W. Grimes } else
1279b50d902SRodney W. Grimes usage();
1289b50d902SRodney W. Grimes flsh_errs();
1299b50d902SRodney W. Grimes if (errcnt || ret_val)
1309b50d902SRodney W. Grimes exit(1);
1319b50d902SRodney W. Grimes return(0);
1329b50d902SRodney W. Grimes }
1339b50d902SRodney W. Grimes
1349b50d902SRodney W. Grimes /*
135032b32adSJuli Mallett * Check if we should pause and write an alert character and wait for a
136032b32adSJuli Mallett * carriage return on /dev/tty.
137032b32adSJuli Mallett */
138e0761ab1SMark Murray static void
ttypause(int pagecnt)139e0761ab1SMark Murray ttypause(int pagecnt)
140032b32adSJuli Mallett {
141032b32adSJuli Mallett int pch;
142032b32adSJuli Mallett FILE *ttyfp;
143032b32adSJuli Mallett
144032b32adSJuli Mallett if ((pauseall || (pausefst && pagecnt == 1)) &&
145032b32adSJuli Mallett isatty(STDOUT_FILENO)) {
146032b32adSJuli Mallett if ((ttyfp = fopen("/dev/tty", "r")) != NULL) {
147032b32adSJuli Mallett (void)putc('\a', stderr);
148032b32adSJuli Mallett while ((pch = getc(ttyfp)) != '\n' && pch != EOF)
149032b32adSJuli Mallett ;
150032b32adSJuli Mallett (void)fclose(ttyfp);
151032b32adSJuli Mallett }
152032b32adSJuli Mallett }
153032b32adSJuli Mallett }
154032b32adSJuli Mallett
155032b32adSJuli Mallett /*
1569b50d902SRodney W. Grimes * onecol: print files with only one column of output.
1579b50d902SRodney W. Grimes * Line length is unlimited.
1589b50d902SRodney W. Grimes */
1599b50d902SRodney W. Grimes int
onecol(int argc,char * argv[])160e0761ab1SMark Murray onecol(int argc, char *argv[])
1619b50d902SRodney W. Grimes {
162e0761ab1SMark Murray int cnt = -1;
163e0761ab1SMark Murray int off;
164e0761ab1SMark Murray int lrgln;
165e0761ab1SMark Murray int linecnt;
166e0761ab1SMark Murray int num;
1679b50d902SRodney W. Grimes int lncnt;
1689b50d902SRodney W. Grimes int pagecnt;
1699b50d902SRodney W. Grimes int ips;
1709b50d902SRodney W. Grimes int ops;
1719b50d902SRodney W. Grimes int cps;
1729b50d902SRodney W. Grimes char *obuf;
1739b50d902SRodney W. Grimes char *lbuf;
1749b50d902SRodney W. Grimes char *nbuf;
1759b50d902SRodney W. Grimes char *hbuf;
1769b50d902SRodney W. Grimes char *ohbuf;
1779b50d902SRodney W. Grimes FILE *inf;
178f4ac32deSDavid Malone const char *fname;
1799b50d902SRodney W. Grimes int mor;
1809b50d902SRodney W. Grimes
1819b50d902SRodney W. Grimes if (nmwd)
1829b50d902SRodney W. Grimes num = nmwd + 1;
1839b50d902SRodney W. Grimes else
1849b50d902SRodney W. Grimes num = 0;
1859b50d902SRodney W. Grimes off = num + offst;
1869b50d902SRodney W. Grimes
1879b50d902SRodney W. Grimes /*
1889b50d902SRodney W. Grimes * allocate line buffer
1899b50d902SRodney W. Grimes */
1909b50d902SRodney W. Grimes if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) {
1919b50d902SRodney W. Grimes mfail();
1929b50d902SRodney W. Grimes return(1);
1939b50d902SRodney W. Grimes }
1949b50d902SRodney W. Grimes /*
1959b50d902SRodney W. Grimes * allocate header buffer
1969b50d902SRodney W. Grimes */
1979b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
1986dc025eaSAlan Somers free(obuf);
1999b50d902SRodney W. Grimes mfail();
2009b50d902SRodney W. Grimes return(1);
2019b50d902SRodney W. Grimes }
2029b50d902SRodney W. Grimes
2039b50d902SRodney W. Grimes ohbuf = hbuf + offst;
2049b50d902SRodney W. Grimes nbuf = obuf + offst;
2059b50d902SRodney W. Grimes lbuf = nbuf + num;
2069b50d902SRodney W. Grimes if (num)
2079b50d902SRodney W. Grimes nbuf[--num] = nmchar;
2089b50d902SRodney W. Grimes if (offst) {
2099b50d902SRodney W. Grimes (void)memset(obuf, (int)' ', offst);
2109b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst);
2119b50d902SRodney W. Grimes }
2129b50d902SRodney W. Grimes
2139b50d902SRodney W. Grimes /*
2149b50d902SRodney W. Grimes * loop by file
2159b50d902SRodney W. Grimes */
2169b50d902SRodney W. Grimes while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
2179b50d902SRodney W. Grimes if (pgnm) {
2189b50d902SRodney W. Grimes /*
2199b50d902SRodney W. Grimes * skip to specified page
2209b50d902SRodney W. Grimes */
2219b50d902SRodney W. Grimes if (inskip(inf, pgnm, lines))
2229b50d902SRodney W. Grimes continue;
2239b50d902SRodney W. Grimes pagecnt = pgnm;
2249b50d902SRodney W. Grimes } else
2259b50d902SRodney W. Grimes pagecnt = 1;
2269b50d902SRodney W. Grimes lncnt = 0;
2279b50d902SRodney W. Grimes
2289b50d902SRodney W. Grimes /*
2299b50d902SRodney W. Grimes * loop by page
2309b50d902SRodney W. Grimes */
2319b50d902SRodney W. Grimes for(;;) {
2329b50d902SRodney W. Grimes linecnt = 0;
2339b50d902SRodney W. Grimes lrgln = 0;
2349b50d902SRodney W. Grimes ops = 0;
2359b50d902SRodney W. Grimes ips = 0;
2369b50d902SRodney W. Grimes cps = 0;
2379b50d902SRodney W. Grimes
238032b32adSJuli Mallett ttypause(pagecnt);
239032b32adSJuli Mallett
2409b50d902SRodney W. Grimes /*
2419b50d902SRodney W. Grimes * loop by line
2429b50d902SRodney W. Grimes */
2439b50d902SRodney W. Grimes while (linecnt < lines) {
2449b50d902SRodney W. Grimes /*
2459b50d902SRodney W. Grimes * input next line
2469b50d902SRodney W. Grimes */
2479b50d902SRodney W. Grimes if ((cnt = inln(inf,lbuf,LBUF,&cps,0,&mor)) < 0)
2489b50d902SRodney W. Grimes break;
2499b50d902SRodney W. Grimes if (!linecnt && !nohead &&
2509b50d902SRodney W. Grimes prhead(hbuf, fname, pagecnt))
2516dc025eaSAlan Somers goto err;
2529b50d902SRodney W. Grimes
2539b50d902SRodney W. Grimes /*
2549b50d902SRodney W. Grimes * start of new line.
2559b50d902SRodney W. Grimes */
2569b50d902SRodney W. Grimes if (!lrgln) {
2579b50d902SRodney W. Grimes if (num)
2589b50d902SRodney W. Grimes addnum(nbuf, num, ++lncnt);
2599b50d902SRodney W. Grimes if (otln(obuf,cnt+off, &ips, &ops, mor))
2606dc025eaSAlan Somers goto err;
2619b50d902SRodney W. Grimes } else if (otln(lbuf, cnt, &ips, &ops, mor))
2626dc025eaSAlan Somers goto err;
2639b50d902SRodney W. Grimes
2649b50d902SRodney W. Grimes /*
2659b50d902SRodney W. Grimes * if line bigger than buffer, get more
2669b50d902SRodney W. Grimes */
2679b50d902SRodney W. Grimes if (mor) {
2689b50d902SRodney W. Grimes lrgln = 1;
2699b50d902SRodney W. Grimes continue;
2709b50d902SRodney W. Grimes }
2719b50d902SRodney W. Grimes
2729b50d902SRodney W. Grimes /*
2739b50d902SRodney W. Grimes * whole line rcvd. reset tab proc. state
2749b50d902SRodney W. Grimes */
2759b50d902SRodney W. Grimes ++linecnt;
2769b50d902SRodney W. Grimes lrgln = 0;
2779b50d902SRodney W. Grimes ops = 0;
2789b50d902SRodney W. Grimes ips = 0;
2799b50d902SRodney W. Grimes }
2809b50d902SRodney W. Grimes
2819b50d902SRodney W. Grimes /*
2829b50d902SRodney W. Grimes * fill to end of page
2839b50d902SRodney W. Grimes */
2849b50d902SRodney W. Grimes if (linecnt && prtail(lines-linecnt-lrgln, lrgln))
2856dc025eaSAlan Somers goto err;
2869b50d902SRodney W. Grimes
2879b50d902SRodney W. Grimes /*
2889b50d902SRodney W. Grimes * On EOF go to next file
2899b50d902SRodney W. Grimes */
2909b50d902SRodney W. Grimes if (cnt < 0)
2919b50d902SRodney W. Grimes break;
2929b50d902SRodney W. Grimes ++pagecnt;
2939b50d902SRodney W. Grimes }
2949b50d902SRodney W. Grimes if (inf != stdin)
2959b50d902SRodney W. Grimes (void)fclose(inf);
2969b50d902SRodney W. Grimes }
2979b50d902SRodney W. Grimes if (eoptind < argc)
2986dc025eaSAlan Somers goto err;
2996dc025eaSAlan Somers free(hbuf);
3006dc025eaSAlan Somers free(obuf);
3019b50d902SRodney W. Grimes return(0);
3026dc025eaSAlan Somers err:
3036dc025eaSAlan Somers free(hbuf);
3046dc025eaSAlan Somers free(obuf);
3056dc025eaSAlan Somers return(1);
3069b50d902SRodney W. Grimes }
3079b50d902SRodney W. Grimes
3089b50d902SRodney W. Grimes /*
3099b50d902SRodney W. Grimes * vertcol: print files with more than one column of output down a page
3109b50d902SRodney W. Grimes */
3119b50d902SRodney W. Grimes int
vertcol(int argc,char * argv[])312e0761ab1SMark Murray vertcol(int argc, char *argv[])
3139b50d902SRodney W. Grimes {
314e0761ab1SMark Murray char *ptbf;
3156dc025eaSAlan Somers char **lstdat = NULL;
316e0761ab1SMark Murray int i;
317e0761ab1SMark Murray int j;
318e0761ab1SMark Murray int cnt = -1;
319e0761ab1SMark Murray int pln;
3206dc025eaSAlan Somers int *indy = NULL;
3219b50d902SRodney W. Grimes int cvc;
3226dc025eaSAlan Somers int *lindy = NULL;
3239b50d902SRodney W. Grimes int lncnt;
3249b50d902SRodney W. Grimes int stp;
3259b50d902SRodney W. Grimes int pagecnt;
3269b50d902SRodney W. Grimes int col = colwd + 1;
3279b50d902SRodney W. Grimes int mxlen = pgwd + offst + 1;
3289b50d902SRodney W. Grimes int mclcnt = clcnt - 1;
3296dc025eaSAlan Somers struct vcol *vc = NULL;
3309b50d902SRodney W. Grimes int mvc;
3319b50d902SRodney W. Grimes int tvc;
3329b50d902SRodney W. Grimes int cw = nmwd + 1;
3339b50d902SRodney W. Grimes int fullcol;
3346dc025eaSAlan Somers char *buf = NULL;
3356dc025eaSAlan Somers char *hbuf = NULL;
3369b50d902SRodney W. Grimes char *ohbuf;
337f4ac32deSDavid Malone const char *fname;
3389b50d902SRodney W. Grimes FILE *inf;
3399b50d902SRodney W. Grimes int ips = 0;
3409b50d902SRodney W. Grimes int cps = 0;
3419b50d902SRodney W. Grimes int ops = 0;
3429b50d902SRodney W. Grimes int mor = 0;
3436dc025eaSAlan Somers int retval = 1;
3449b50d902SRodney W. Grimes
3459b50d902SRodney W. Grimes /*
3469b50d902SRodney W. Grimes * allocate page buffer
3479b50d902SRodney W. Grimes */
3489b50d902SRodney W. Grimes if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) {
3499b50d902SRodney W. Grimes mfail();
3509b50d902SRodney W. Grimes return(1);
3519b50d902SRodney W. Grimes }
3529b50d902SRodney W. Grimes
3539b50d902SRodney W. Grimes /*
3549b50d902SRodney W. Grimes * allocate page header
3559b50d902SRodney W. Grimes */
3569b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
3579b50d902SRodney W. Grimes mfail();
3586dc025eaSAlan Somers goto out;
3599b50d902SRodney W. Grimes }
3609b50d902SRodney W. Grimes ohbuf = hbuf + offst;
3619b50d902SRodney W. Grimes if (offst)
3629b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst);
3639b50d902SRodney W. Grimes
3649b50d902SRodney W. Grimes /*
3659b50d902SRodney W. Grimes * col pointers when no headers
3669b50d902SRodney W. Grimes */
3679b50d902SRodney W. Grimes mvc = lines * clcnt;
3689b50d902SRodney W. Grimes if ((vc =
3699b50d902SRodney W. Grimes (struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) {
3709b50d902SRodney W. Grimes mfail();
3716dc025eaSAlan Somers goto out;
3729b50d902SRodney W. Grimes }
3739b50d902SRodney W. Grimes
3749b50d902SRodney W. Grimes /*
3759b50d902SRodney W. Grimes * pointer into page where last data per line is located
3769b50d902SRodney W. Grimes */
3779b50d902SRodney W. Grimes if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){
3789b50d902SRodney W. Grimes mfail();
3796dc025eaSAlan Somers goto out;
3809b50d902SRodney W. Grimes }
3819b50d902SRodney W. Grimes
3829b50d902SRodney W. Grimes /*
3839b50d902SRodney W. Grimes * fast index lookups to locate start of lines
3849b50d902SRodney W. Grimes */
3859b50d902SRodney W. Grimes if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
3869b50d902SRodney W. Grimes mfail();
3876dc025eaSAlan Somers goto out;
3889b50d902SRodney W. Grimes }
3899b50d902SRodney W. Grimes if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) {
3909b50d902SRodney W. Grimes mfail();
3916dc025eaSAlan Somers goto out;
3929b50d902SRodney W. Grimes }
3939b50d902SRodney W. Grimes
3949b50d902SRodney W. Grimes if (nmwd)
3959b50d902SRodney W. Grimes fullcol = col + cw;
3969b50d902SRodney W. Grimes else
3979b50d902SRodney W. Grimes fullcol = col;
3989b50d902SRodney W. Grimes
3999b50d902SRodney W. Grimes /*
4009b50d902SRodney W. Grimes * initialize buffer lookup indexes and offset area
4019b50d902SRodney W. Grimes */
4029b50d902SRodney W. Grimes for (j = 0; j < lines; ++j) {
4039b50d902SRodney W. Grimes lindy[j] = j * mxlen;
4049b50d902SRodney W. Grimes indy[j] = lindy[j] + offst;
4059b50d902SRodney W. Grimes if (offst) {
4069b50d902SRodney W. Grimes ptbf = buf + lindy[j];
4079b50d902SRodney W. Grimes (void)memset(ptbf, (int)' ', offst);
4089b50d902SRodney W. Grimes ptbf += offst;
4099b50d902SRodney W. Grimes } else
4109b50d902SRodney W. Grimes ptbf = buf + indy[j];
4119b50d902SRodney W. Grimes lstdat[j] = ptbf;
4129b50d902SRodney W. Grimes }
4139b50d902SRodney W. Grimes
4149b50d902SRodney W. Grimes /*
4159b50d902SRodney W. Grimes * loop by file
4169b50d902SRodney W. Grimes */
4179b50d902SRodney W. Grimes while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
4189b50d902SRodney W. Grimes if (pgnm) {
4199b50d902SRodney W. Grimes /*
4209b50d902SRodney W. Grimes * skip to requested page
4219b50d902SRodney W. Grimes */
4229b50d902SRodney W. Grimes if (inskip(inf, pgnm, lines))
4239b50d902SRodney W. Grimes continue;
4249b50d902SRodney W. Grimes pagecnt = pgnm;
4259b50d902SRodney W. Grimes } else
4269b50d902SRodney W. Grimes pagecnt = 1;
4279b50d902SRodney W. Grimes lncnt = 0;
4289b50d902SRodney W. Grimes
4299b50d902SRodney W. Grimes /*
4309b50d902SRodney W. Grimes * loop by page
4319b50d902SRodney W. Grimes */
4329b50d902SRodney W. Grimes for(;;) {
433032b32adSJuli Mallett ttypause(pagecnt);
434032b32adSJuli Mallett
4359b50d902SRodney W. Grimes /*
4369b50d902SRodney W. Grimes * loop by column
4379b50d902SRodney W. Grimes */
4389b50d902SRodney W. Grimes cvc = 0;
4399b50d902SRodney W. Grimes for (i = 0; i < clcnt; ++i) {
4409b50d902SRodney W. Grimes j = 0;
4419b50d902SRodney W. Grimes /*
4429b50d902SRodney W. Grimes * if last column, do not pad
4439b50d902SRodney W. Grimes */
4449b50d902SRodney W. Grimes if (i == mclcnt)
4459b50d902SRodney W. Grimes stp = 1;
4469b50d902SRodney W. Grimes else
4479b50d902SRodney W. Grimes stp = 0;
4489b50d902SRodney W. Grimes /*
4499b50d902SRodney W. Grimes * loop by line
4509b50d902SRodney W. Grimes */
4519b50d902SRodney W. Grimes for(;;) {
4529b50d902SRodney W. Grimes /*
4539b50d902SRodney W. Grimes * is this first column
4549b50d902SRodney W. Grimes */
4559b50d902SRodney W. Grimes if (!i) {
4569b50d902SRodney W. Grimes ptbf = buf + indy[j];
4579b50d902SRodney W. Grimes lstdat[j] = ptbf;
4589b50d902SRodney W. Grimes } else
4599b50d902SRodney W. Grimes ptbf = lstdat[j];
4609b50d902SRodney W. Grimes vc[cvc].pt = ptbf;
4619b50d902SRodney W. Grimes
4629b50d902SRodney W. Grimes /*
4639b50d902SRodney W. Grimes * add number
4649b50d902SRodney W. Grimes */
4659b50d902SRodney W. Grimes if (nmwd) {
4669b50d902SRodney W. Grimes addnum(ptbf, nmwd, ++lncnt);
4679b50d902SRodney W. Grimes ptbf += nmwd;
4689b50d902SRodney W. Grimes *ptbf++ = nmchar;
4699b50d902SRodney W. Grimes }
4709b50d902SRodney W. Grimes
4719b50d902SRodney W. Grimes /*
4729b50d902SRodney W. Grimes * input next line
4739b50d902SRodney W. Grimes */
4749b50d902SRodney W. Grimes cnt = inln(inf,ptbf,colwd,&cps,1,&mor);
4759b50d902SRodney W. Grimes vc[cvc++].cnt = cnt;
4769b50d902SRodney W. Grimes if (cnt < 0)
4779b50d902SRodney W. Grimes break;
4789b50d902SRodney W. Grimes ptbf += cnt;
4799b50d902SRodney W. Grimes
4809b50d902SRodney W. Grimes /*
4819b50d902SRodney W. Grimes * pad all but last column on page
4829b50d902SRodney W. Grimes */
4839b50d902SRodney W. Grimes if (!stp) {
4849b50d902SRodney W. Grimes /*
4859b50d902SRodney W. Grimes * pad to end of column
4869b50d902SRodney W. Grimes */
4879b50d902SRodney W. Grimes if (sflag)
4889b50d902SRodney W. Grimes *ptbf++ = schar;
4899b50d902SRodney W. Grimes else if ((pln = col-cnt) > 0) {
4909b50d902SRodney W. Grimes (void)memset(ptbf,
4919b50d902SRodney W. Grimes (int)' ',pln);
4929b50d902SRodney W. Grimes ptbf += pln;
4939b50d902SRodney W. Grimes }
4949b50d902SRodney W. Grimes }
4959b50d902SRodney W. Grimes /*
4969b50d902SRodney W. Grimes * remember last char in line
4979b50d902SRodney W. Grimes */
4989b50d902SRodney W. Grimes lstdat[j] = ptbf;
4999b50d902SRodney W. Grimes if (++j >= lines)
5009b50d902SRodney W. Grimes break;
5019b50d902SRodney W. Grimes }
5029b50d902SRodney W. Grimes if (cnt < 0)
5039b50d902SRodney W. Grimes break;
5049b50d902SRodney W. Grimes }
5059b50d902SRodney W. Grimes
5069b50d902SRodney W. Grimes /*
5079b50d902SRodney W. Grimes * when -t (no header) is specified the spec requires
5089b50d902SRodney W. Grimes * the min number of lines. The last page may not have
5099b50d902SRodney W. Grimes * balanced length columns. To fix this we must reorder
5109b50d902SRodney W. Grimes * the columns. This is a very slow technique so it is
5119b50d902SRodney W. Grimes * only used under limited conditions. Without -t, the
5129b50d902SRodney W. Grimes * balancing of text columns is unspecified. To NOT
5139b50d902SRodney W. Grimes * balance the last page, add the global variable
5149b50d902SRodney W. Grimes * nohead to the if statement below e.g.
5159b50d902SRodney W. Grimes *
5169b50d902SRodney W. Grimes * if ((cnt < 0) && nohead && cvc ......
5179b50d902SRodney W. Grimes */
5189b50d902SRodney W. Grimes --cvc;
5199b50d902SRodney W. Grimes
5209b50d902SRodney W. Grimes /*
5219b50d902SRodney W. Grimes * check to see if last page needs to be reordered
5229b50d902SRodney W. Grimes */
5239b50d902SRodney W. Grimes if ((cnt < 0) && cvc && ((mvc-cvc) >= clcnt)){
5249b50d902SRodney W. Grimes pln = cvc/clcnt;
5259b50d902SRodney W. Grimes if (cvc % clcnt)
5269b50d902SRodney W. Grimes ++pln;
5279b50d902SRodney W. Grimes
5289b50d902SRodney W. Grimes /*
5299b50d902SRodney W. Grimes * print header
5309b50d902SRodney W. Grimes */
5319b50d902SRodney W. Grimes if (!nohead && prhead(hbuf, fname, pagecnt))
5326dc025eaSAlan Somers goto out;
5339b50d902SRodney W. Grimes for (i = 0; i < pln; ++i) {
5349b50d902SRodney W. Grimes ips = 0;
5359b50d902SRodney W. Grimes ops = 0;
5366dc025eaSAlan Somers if (offst &&
5376dc025eaSAlan Somers otln(buf,offst,&ips,&ops,1))
5386dc025eaSAlan Somers goto out;
5399b50d902SRodney W. Grimes tvc = i;
5409b50d902SRodney W. Grimes
5419b50d902SRodney W. Grimes for (j = 0; j < clcnt; ++j) {
5429b50d902SRodney W. Grimes /*
5439b50d902SRodney W. Grimes * determine column length
5449b50d902SRodney W. Grimes */
5459b50d902SRodney W. Grimes if (j == mclcnt) {
5469b50d902SRodney W. Grimes /*
5479b50d902SRodney W. Grimes * last column
5489b50d902SRodney W. Grimes */
5499b50d902SRodney W. Grimes cnt = vc[tvc].cnt;
5509b50d902SRodney W. Grimes if (nmwd)
5519b50d902SRodney W. Grimes cnt += cw;
5529b50d902SRodney W. Grimes } else if (sflag) {
5539b50d902SRodney W. Grimes /*
5549b50d902SRodney W. Grimes * single ch between
5559b50d902SRodney W. Grimes */
5569b50d902SRodney W. Grimes cnt = vc[tvc].cnt + 1;
5579b50d902SRodney W. Grimes if (nmwd)
5589b50d902SRodney W. Grimes cnt += cw;
5599b50d902SRodney W. Grimes } else
5609b50d902SRodney W. Grimes cnt = fullcol;
5619b50d902SRodney W. Grimes if (otln(vc[tvc].pt, cnt, &ips,
5629b50d902SRodney W. Grimes &ops, 1))
5636dc025eaSAlan Somers goto out;
5649b50d902SRodney W. Grimes tvc += pln;
5659b50d902SRodney W. Grimes if (tvc >= cvc)
5669b50d902SRodney W. Grimes break;
5679b50d902SRodney W. Grimes }
5689b50d902SRodney W. Grimes /*
5699b50d902SRodney W. Grimes * terminate line
5709b50d902SRodney W. Grimes */
5719b50d902SRodney W. Grimes if (otln(buf, 0, &ips, &ops, 0))
5726dc025eaSAlan Somers goto out;
5739b50d902SRodney W. Grimes }
5749b50d902SRodney W. Grimes /*
5759b50d902SRodney W. Grimes * pad to end of page
5769b50d902SRodney W. Grimes */
5779b50d902SRodney W. Grimes if (prtail((lines - pln), 0))
5786dc025eaSAlan Somers goto out;
5799b50d902SRodney W. Grimes /*
5809b50d902SRodney W. Grimes * done with output, go to next file
5819b50d902SRodney W. Grimes */
5829b50d902SRodney W. Grimes break;
5839b50d902SRodney W. Grimes }
5849b50d902SRodney W. Grimes
5859b50d902SRodney W. Grimes /*
5869b50d902SRodney W. Grimes * determine how many lines to output
5879b50d902SRodney W. Grimes */
5889b50d902SRodney W. Grimes if (i > 0)
5899b50d902SRodney W. Grimes pln = lines;
5909b50d902SRodney W. Grimes else
5919b50d902SRodney W. Grimes pln = j;
5929b50d902SRodney W. Grimes
5939b50d902SRodney W. Grimes /*
5949b50d902SRodney W. Grimes * print header
5959b50d902SRodney W. Grimes */
5969b50d902SRodney W. Grimes if (pln && !nohead && prhead(hbuf, fname, pagecnt))
5976dc025eaSAlan Somers goto out;
5989b50d902SRodney W. Grimes
5999b50d902SRodney W. Grimes /*
6009b50d902SRodney W. Grimes * output each line
6019b50d902SRodney W. Grimes */
6029b50d902SRodney W. Grimes for (i = 0; i < pln; ++i) {
6039b50d902SRodney W. Grimes ptbf = buf + lindy[i];
6049b50d902SRodney W. Grimes if ((j = lstdat[i] - ptbf) <= offst)
6059b50d902SRodney W. Grimes break;
6069b50d902SRodney W. Grimes if (otln(ptbf, j, &ips, &ops, 0))
6076dc025eaSAlan Somers goto out;
6089b50d902SRodney W. Grimes }
6099b50d902SRodney W. Grimes
6109b50d902SRodney W. Grimes /*
6119b50d902SRodney W. Grimes * pad to end of page
6129b50d902SRodney W. Grimes */
6139b50d902SRodney W. Grimes if (pln && prtail((lines - pln), 0))
6146dc025eaSAlan Somers goto out;
6159b50d902SRodney W. Grimes
6169b50d902SRodney W. Grimes /*
6179b50d902SRodney W. Grimes * if EOF go to next file
6189b50d902SRodney W. Grimes */
6199b50d902SRodney W. Grimes if (cnt < 0)
6209b50d902SRodney W. Grimes break;
6219b50d902SRodney W. Grimes ++pagecnt;
6229b50d902SRodney W. Grimes }
6239b50d902SRodney W. Grimes if (inf != stdin)
6249b50d902SRodney W. Grimes (void)fclose(inf);
6259b50d902SRodney W. Grimes }
6269b50d902SRodney W. Grimes if (eoptind < argc)
6276dc025eaSAlan Somers goto out;
6286dc025eaSAlan Somers retval = 0;
6296dc025eaSAlan Somers out:
6306dc025eaSAlan Somers free(lindy);
6316dc025eaSAlan Somers free(indy);
6326dc025eaSAlan Somers free(lstdat);
6336dc025eaSAlan Somers free(vc);
6346dc025eaSAlan Somers free(hbuf);
6356dc025eaSAlan Somers free(buf);
6366dc025eaSAlan Somers return(retval);
6379b50d902SRodney W. Grimes }
6389b50d902SRodney W. Grimes
6399b50d902SRodney W. Grimes /*
6409b50d902SRodney W. Grimes * horzcol: print files with more than one column of output across a page
6419b50d902SRodney W. Grimes */
6429b50d902SRodney W. Grimes int
horzcol(int argc,char * argv[])643e0761ab1SMark Murray horzcol(int argc, char *argv[])
6449b50d902SRodney W. Grimes {
645e0761ab1SMark Murray char *ptbf;
646e0761ab1SMark Murray int pln;
647e0761ab1SMark Murray int cnt = -1;
648e0761ab1SMark Murray char *lstdat;
649e0761ab1SMark Murray int col = colwd + 1;
650e0761ab1SMark Murray int j;
651e0761ab1SMark Murray int i;
6529b50d902SRodney W. Grimes int lncnt;
6539b50d902SRodney W. Grimes int pagecnt;
6549b50d902SRodney W. Grimes char *buf;
6559b50d902SRodney W. Grimes char *hbuf;
6569b50d902SRodney W. Grimes char *ohbuf;
657f4ac32deSDavid Malone const char *fname;
6589b50d902SRodney W. Grimes FILE *inf;
6599b50d902SRodney W. Grimes int ips = 0;
6609b50d902SRodney W. Grimes int cps = 0;
6619b50d902SRodney W. Grimes int ops = 0;
6629b50d902SRodney W. Grimes int mor = 0;
6639b50d902SRodney W. Grimes
6649b50d902SRodney W. Grimes if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
6659b50d902SRodney W. Grimes mfail();
6669b50d902SRodney W. Grimes return(1);
6679b50d902SRodney W. Grimes }
6689b50d902SRodney W. Grimes
6699b50d902SRodney W. Grimes /*
6709b50d902SRodney W. Grimes * page header
6719b50d902SRodney W. Grimes */
6729b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
6736dc025eaSAlan Somers free(buf);
6749b50d902SRodney W. Grimes mfail();
6759b50d902SRodney W. Grimes return(1);
6769b50d902SRodney W. Grimes }
6779b50d902SRodney W. Grimes ohbuf = hbuf + offst;
6789b50d902SRodney W. Grimes if (offst) {
6799b50d902SRodney W. Grimes (void)memset(buf, (int)' ', offst);
6809b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst);
6819b50d902SRodney W. Grimes }
6829b50d902SRodney W. Grimes
6839b50d902SRodney W. Grimes /*
6849b50d902SRodney W. Grimes * loop by file
6859b50d902SRodney W. Grimes */
6869b50d902SRodney W. Grimes while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) {
6879b50d902SRodney W. Grimes if (pgnm) {
6889b50d902SRodney W. Grimes if (inskip(inf, pgnm, lines))
6899b50d902SRodney W. Grimes continue;
6909b50d902SRodney W. Grimes pagecnt = pgnm;
6919b50d902SRodney W. Grimes } else
6929b50d902SRodney W. Grimes pagecnt = 1;
6939b50d902SRodney W. Grimes lncnt = 0;
6949b50d902SRodney W. Grimes
6959b50d902SRodney W. Grimes /*
6969b50d902SRodney W. Grimes * loop by page
6979b50d902SRodney W. Grimes */
6989b50d902SRodney W. Grimes for(;;) {
699032b32adSJuli Mallett ttypause(pagecnt);
700032b32adSJuli Mallett
7019b50d902SRodney W. Grimes /*
7029b50d902SRodney W. Grimes * loop by line
7039b50d902SRodney W. Grimes */
7049b50d902SRodney W. Grimes for (i = 0; i < lines; ++i) {
7059b50d902SRodney W. Grimes ptbf = buf + offst;
7069b50d902SRodney W. Grimes lstdat = ptbf;
7079b50d902SRodney W. Grimes j = 0;
7089b50d902SRodney W. Grimes /*
7099b50d902SRodney W. Grimes * loop by col
7109b50d902SRodney W. Grimes */
7119b50d902SRodney W. Grimes for(;;) {
7129b50d902SRodney W. Grimes if (nmwd) {
7139b50d902SRodney W. Grimes /*
7149b50d902SRodney W. Grimes * add number to column
7159b50d902SRodney W. Grimes */
7169b50d902SRodney W. Grimes addnum(ptbf, nmwd, ++lncnt);
7179b50d902SRodney W. Grimes ptbf += nmwd;
7189b50d902SRodney W. Grimes *ptbf++ = nmchar;
7199b50d902SRodney W. Grimes }
7209b50d902SRodney W. Grimes /*
7219b50d902SRodney W. Grimes * input line
7229b50d902SRodney W. Grimes */
7239b50d902SRodney W. Grimes if ((cnt = inln(inf,ptbf,colwd,&cps,1,
7249b50d902SRodney W. Grimes &mor)) < 0)
7259b50d902SRodney W. Grimes break;
7269b50d902SRodney W. Grimes ptbf += cnt;
7279b50d902SRodney W. Grimes lstdat = ptbf;
7289b50d902SRodney W. Grimes
7299b50d902SRodney W. Grimes /*
7309b50d902SRodney W. Grimes * if last line skip padding
7319b50d902SRodney W. Grimes */
7329b50d902SRodney W. Grimes if (++j >= clcnt)
7339b50d902SRodney W. Grimes break;
7349b50d902SRodney W. Grimes
7359b50d902SRodney W. Grimes /*
7369b50d902SRodney W. Grimes * pad to end of column
7379b50d902SRodney W. Grimes */
7389b50d902SRodney W. Grimes if (sflag)
7399b50d902SRodney W. Grimes *ptbf++ = schar;
7409b50d902SRodney W. Grimes else if ((pln = col - cnt) > 0) {
7419b50d902SRodney W. Grimes (void)memset(ptbf,(int)' ',pln);
7429b50d902SRodney W. Grimes ptbf += pln;
7439b50d902SRodney W. Grimes }
7449b50d902SRodney W. Grimes }
7459b50d902SRodney W. Grimes
7469b50d902SRodney W. Grimes /*
7479b50d902SRodney W. Grimes * determine line length
7489b50d902SRodney W. Grimes */
7499b50d902SRodney W. Grimes if ((j = lstdat - buf) <= offst)
7509b50d902SRodney W. Grimes break;
7519b50d902SRodney W. Grimes if (!i && !nohead &&
7529b50d902SRodney W. Grimes prhead(hbuf, fname, pagecnt))
7536dc025eaSAlan Somers goto err;
7549b50d902SRodney W. Grimes /*
7559b50d902SRodney W. Grimes * output line
7569b50d902SRodney W. Grimes */
7579b50d902SRodney W. Grimes if (otln(buf, j, &ips, &ops, 0))
7586dc025eaSAlan Somers goto err;
7599b50d902SRodney W. Grimes }
7609b50d902SRodney W. Grimes
7619b50d902SRodney W. Grimes /*
7629b50d902SRodney W. Grimes * pad to end of page
7639b50d902SRodney W. Grimes */
7649b50d902SRodney W. Grimes if (i && prtail(lines-i, 0))
7656dc025eaSAlan Somers goto err;
7669b50d902SRodney W. Grimes
7679b50d902SRodney W. Grimes /*
7689b50d902SRodney W. Grimes * if EOF go to next file
7699b50d902SRodney W. Grimes */
7709b50d902SRodney W. Grimes if (cnt < 0)
7719b50d902SRodney W. Grimes break;
7729b50d902SRodney W. Grimes ++pagecnt;
7739b50d902SRodney W. Grimes }
7749b50d902SRodney W. Grimes if (inf != stdin)
7759b50d902SRodney W. Grimes (void)fclose(inf);
7769b50d902SRodney W. Grimes }
7779b50d902SRodney W. Grimes if (eoptind < argc)
7786dc025eaSAlan Somers goto err;
7796dc025eaSAlan Somers free(hbuf);
7806dc025eaSAlan Somers free(buf);
7819b50d902SRodney W. Grimes return(0);
7826dc025eaSAlan Somers err:
7836dc025eaSAlan Somers free(hbuf);
7846dc025eaSAlan Somers free(buf);
7856dc025eaSAlan Somers return(1);
7869b50d902SRodney W. Grimes }
7879b50d902SRodney W. Grimes
7889b50d902SRodney W. Grimes /*
7899b50d902SRodney W. Grimes * mulfile: print files with more than one column of output and
7909b50d902SRodney W. Grimes * more than one file concurrently
7919b50d902SRodney W. Grimes */
7929b50d902SRodney W. Grimes int
mulfile(int argc,char * argv[])793e0761ab1SMark Murray mulfile(int argc, char *argv[])
7949b50d902SRodney W. Grimes {
795e0761ab1SMark Murray char *ptbf;
796e0761ab1SMark Murray int j;
797e0761ab1SMark Murray int pln;
798e0761ab1SMark Murray int cnt;
799e0761ab1SMark Murray char *lstdat;
800e0761ab1SMark Murray int i;
8016dc025eaSAlan Somers FILE **fbuf = NULL;
8029b50d902SRodney W. Grimes int actf;
8039b50d902SRodney W. Grimes int lncnt;
8049b50d902SRodney W. Grimes int col;
8059b50d902SRodney W. Grimes int pagecnt;
8069b50d902SRodney W. Grimes int fproc;
8076dc025eaSAlan Somers char *buf = NULL;
8086dc025eaSAlan Somers char *hbuf = NULL;
8099b50d902SRodney W. Grimes char *ohbuf;
810f4ac32deSDavid Malone const char *fname;
8119b50d902SRodney W. Grimes int ips = 0;
8129b50d902SRodney W. Grimes int cps = 0;
8139b50d902SRodney W. Grimes int ops = 0;
8149b50d902SRodney W. Grimes int mor = 0;
8156dc025eaSAlan Somers int retval = 1;
8169b50d902SRodney W. Grimes
8179b50d902SRodney W. Grimes /*
8189b50d902SRodney W. Grimes * array of FILE *, one for each operand
8199b50d902SRodney W. Grimes */
8209b50d902SRodney W. Grimes if ((fbuf = (FILE **)malloc((unsigned)clcnt*sizeof(FILE *))) == NULL) {
8219b50d902SRodney W. Grimes mfail();
8226dc025eaSAlan Somers goto out;
8239b50d902SRodney W. Grimes }
8249b50d902SRodney W. Grimes
8259b50d902SRodney W. Grimes /*
8269b50d902SRodney W. Grimes * page header
8279b50d902SRodney W. Grimes */
8289b50d902SRodney W. Grimes if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) {
8299b50d902SRodney W. Grimes mfail();
8306dc025eaSAlan Somers goto out;
8319b50d902SRodney W. Grimes }
8329b50d902SRodney W. Grimes ohbuf = hbuf + offst;
8339b50d902SRodney W. Grimes
8349b50d902SRodney W. Grimes /*
8359b50d902SRodney W. Grimes * do not know how many columns yet. The number of operands provide an
8369b50d902SRodney W. Grimes * upper bound on the number of columns. We use the number of files
8379b50d902SRodney W. Grimes * we can open successfully to set the number of columns. The operation
838487ac9acSUlrich Spörlein * of the merge operation (-m) in relation to unsuccessful file opens
8399b50d902SRodney W. Grimes * is unspecified by posix.
8409b50d902SRodney W. Grimes */
8419b50d902SRodney W. Grimes j = 0;
8429b50d902SRodney W. Grimes while (j < clcnt) {
8439b50d902SRodney W. Grimes if ((fbuf[j] = nxtfile(argc, argv, &fname, ohbuf, 1)) == NULL)
8449b50d902SRodney W. Grimes break;
8459b50d902SRodney W. Grimes if (pgnm && (inskip(fbuf[j], pgnm, lines)))
8469b50d902SRodney W. Grimes fbuf[j] = NULL;
8479b50d902SRodney W. Grimes ++j;
8489b50d902SRodney W. Grimes }
8499b50d902SRodney W. Grimes
8509b50d902SRodney W. Grimes /*
8519b50d902SRodney W. Grimes * if no files, exit
8529b50d902SRodney W. Grimes */
8539b50d902SRodney W. Grimes if (!j)
8546dc025eaSAlan Somers goto out;
8559b50d902SRodney W. Grimes
8569b50d902SRodney W. Grimes /*
857487ac9acSUlrich Spörlein * calculate page boundaries based on open file count
8589b50d902SRodney W. Grimes */
8599b50d902SRodney W. Grimes clcnt = j;
8609b50d902SRodney W. Grimes if (nmwd) {
8619b50d902SRodney W. Grimes colwd = (pgwd - clcnt - nmwd)/clcnt;
8629b50d902SRodney W. Grimes pgwd = ((colwd + 1) * clcnt) - nmwd - 2;
8639b50d902SRodney W. Grimes } else {
8649b50d902SRodney W. Grimes colwd = (pgwd + 1 - clcnt)/clcnt;
8659b50d902SRodney W. Grimes pgwd = ((colwd + 1) * clcnt) - 1;
8669b50d902SRodney W. Grimes }
8679b50d902SRodney W. Grimes if (colwd < 1) {
8689b50d902SRodney W. Grimes (void)fprintf(err,
8699b50d902SRodney W. Grimes "pr: page width too small for %d columns\n", clcnt);
8706dc025eaSAlan Somers goto out;
8719b50d902SRodney W. Grimes }
8729b50d902SRodney W. Grimes actf = clcnt;
8739b50d902SRodney W. Grimes col = colwd + 1;
8749b50d902SRodney W. Grimes
8759b50d902SRodney W. Grimes /*
8769b50d902SRodney W. Grimes * line buffer
8779b50d902SRodney W. Grimes */
8789b50d902SRodney W. Grimes if ((buf = malloc((unsigned)(pgwd+offst+1)*sizeof(char))) == NULL) {
8799b50d902SRodney W. Grimes mfail();
8806dc025eaSAlan Somers goto out;
8819b50d902SRodney W. Grimes }
8829b50d902SRodney W. Grimes if (offst) {
8839b50d902SRodney W. Grimes (void)memset(buf, (int)' ', offst);
8849b50d902SRodney W. Grimes (void)memset(hbuf, (int)' ', offst);
8859b50d902SRodney W. Grimes }
8869b50d902SRodney W. Grimes if (pgnm)
8879b50d902SRodney W. Grimes pagecnt = pgnm;
8889b50d902SRodney W. Grimes else
8899b50d902SRodney W. Grimes pagecnt = 1;
8909b50d902SRodney W. Grimes lncnt = 0;
8919b50d902SRodney W. Grimes
8929b50d902SRodney W. Grimes /*
8939b50d902SRodney W. Grimes * continue to loop while any file still has data
8949b50d902SRodney W. Grimes */
8959b50d902SRodney W. Grimes while (actf > 0) {
896032b32adSJuli Mallett ttypause(pagecnt);
897032b32adSJuli Mallett
8989b50d902SRodney W. Grimes /*
8999b50d902SRodney W. Grimes * loop by line
9009b50d902SRodney W. Grimes */
9019b50d902SRodney W. Grimes for (i = 0; i < lines; ++i) {
9029b50d902SRodney W. Grimes ptbf = buf + offst;
9039b50d902SRodney W. Grimes lstdat = ptbf;
9049b50d902SRodney W. Grimes if (nmwd) {
9059b50d902SRodney W. Grimes /*
9069b50d902SRodney W. Grimes * add line number to line
9079b50d902SRodney W. Grimes */
9089b50d902SRodney W. Grimes addnum(ptbf, nmwd, ++lncnt);
9099b50d902SRodney W. Grimes ptbf += nmwd;
9109b50d902SRodney W. Grimes *ptbf++ = nmchar;
9119b50d902SRodney W. Grimes }
9129b50d902SRodney W. Grimes j = 0;
9139b50d902SRodney W. Grimes fproc = 0;
9149b50d902SRodney W. Grimes
9159b50d902SRodney W. Grimes /*
9169b50d902SRodney W. Grimes * loop by column
9179b50d902SRodney W. Grimes */
9189b50d902SRodney W. Grimes for (j = 0; j < clcnt; ++j) {
9199b50d902SRodney W. Grimes if (fbuf[j] == NULL) {
9209b50d902SRodney W. Grimes /*
9219b50d902SRodney W. Grimes * empty column; EOF
9229b50d902SRodney W. Grimes */
9239b50d902SRodney W. Grimes cnt = 0;
9249b50d902SRodney W. Grimes } else if ((cnt = inln(fbuf[j], ptbf, colwd,
9259b50d902SRodney W. Grimes &cps, 1, &mor)) < 0) {
9269b50d902SRodney W. Grimes /*
9279b50d902SRodney W. Grimes * EOF hit; no data
9289b50d902SRodney W. Grimes */
9299b50d902SRodney W. Grimes if (fbuf[j] != stdin)
9309b50d902SRodney W. Grimes (void)fclose(fbuf[j]);
9319b50d902SRodney W. Grimes fbuf[j] = NULL;
9329b50d902SRodney W. Grimes --actf;
9339b50d902SRodney W. Grimes cnt = 0;
9349b50d902SRodney W. Grimes } else {
9359b50d902SRodney W. Grimes /*
9369b50d902SRodney W. Grimes * process file data
9379b50d902SRodney W. Grimes */
9389b50d902SRodney W. Grimes ptbf += cnt;
9399b50d902SRodney W. Grimes lstdat = ptbf;
9409b50d902SRodney W. Grimes fproc++;
9419b50d902SRodney W. Grimes }
9429b50d902SRodney W. Grimes
9439b50d902SRodney W. Grimes /*
9449b50d902SRodney W. Grimes * if last ACTIVE column, done with line
9459b50d902SRodney W. Grimes */
9469b50d902SRodney W. Grimes if (fproc >= actf)
9479b50d902SRodney W. Grimes break;
9489b50d902SRodney W. Grimes
9499b50d902SRodney W. Grimes /*
9509b50d902SRodney W. Grimes * pad to end of column
9519b50d902SRodney W. Grimes */
9529b50d902SRodney W. Grimes if (sflag) {
9539b50d902SRodney W. Grimes *ptbf++ = schar;
9549b50d902SRodney W. Grimes } else if ((pln = col - cnt) > 0) {
9559b50d902SRodney W. Grimes (void)memset(ptbf, (int)' ', pln);
9569b50d902SRodney W. Grimes ptbf += pln;
9579b50d902SRodney W. Grimes }
9589b50d902SRodney W. Grimes }
9599b50d902SRodney W. Grimes
9609b50d902SRodney W. Grimes /*
9619b50d902SRodney W. Grimes * calculate data in line
9629b50d902SRodney W. Grimes */
9639b50d902SRodney W. Grimes if ((j = lstdat - buf) <= offst)
9649b50d902SRodney W. Grimes break;
9659b50d902SRodney W. Grimes
9669b50d902SRodney W. Grimes if (!i && !nohead && prhead(hbuf, fname, pagecnt))
9676dc025eaSAlan Somers goto out;
9689b50d902SRodney W. Grimes
9699b50d902SRodney W. Grimes /*
9709b50d902SRodney W. Grimes * output line
9719b50d902SRodney W. Grimes */
9729b50d902SRodney W. Grimes if (otln(buf, j, &ips, &ops, 0))
9736dc025eaSAlan Somers goto out;
9749b50d902SRodney W. Grimes
9759b50d902SRodney W. Grimes /*
9769b50d902SRodney W. Grimes * if no more active files, done
9779b50d902SRodney W. Grimes */
9789b50d902SRodney W. Grimes if (actf <= 0) {
9799b50d902SRodney W. Grimes ++i;
9809b50d902SRodney W. Grimes break;
9819b50d902SRodney W. Grimes }
9829b50d902SRodney W. Grimes }
9839b50d902SRodney W. Grimes
9849b50d902SRodney W. Grimes /*
9859b50d902SRodney W. Grimes * pad to end of page
9869b50d902SRodney W. Grimes */
9879b50d902SRodney W. Grimes if (i && prtail(lines-i, 0))
9886dc025eaSAlan Somers goto out;
9899b50d902SRodney W. Grimes ++pagecnt;
9909b50d902SRodney W. Grimes }
9919b50d902SRodney W. Grimes if (eoptind < argc)
9926dc025eaSAlan Somers goto out;
9936dc025eaSAlan Somers retval = 0;
9946dc025eaSAlan Somers out:
9956dc025eaSAlan Somers free(buf);
9966dc025eaSAlan Somers free(hbuf);
9976dc025eaSAlan Somers free(fbuf);
9986dc025eaSAlan Somers return(retval);
9999b50d902SRodney W. Grimes }
10009b50d902SRodney W. Grimes
10019b50d902SRodney W. Grimes /*
10029b50d902SRodney W. Grimes * inln(): input a line of data (unlimited length lines supported)
10039b50d902SRodney W. Grimes * Input is optionally expanded to spaces
10049b50d902SRodney W. Grimes *
10059b50d902SRodney W. Grimes * inf: file
10069b50d902SRodney W. Grimes * buf: buffer
10079b50d902SRodney W. Grimes * lim: buffer length
1008487ac9acSUlrich Spörlein * cps: column position 1st char in buffer (large line support)
10099b50d902SRodney W. Grimes * trnc: throw away data more than lim up to \n
10109b50d902SRodney W. Grimes * mor: set if more data in line (not truncated)
10119b50d902SRodney W. Grimes */
10129b50d902SRodney W. Grimes int
inln(FILE * inf,char * buf,int lim,int * cps,int trnc,int * mor)1013e0761ab1SMark Murray inln(FILE *inf, char *buf, int lim, int *cps, int trnc, int *mor)
10149b50d902SRodney W. Grimes {
1015e0761ab1SMark Murray int col;
1016e0761ab1SMark Murray int gap = ingap;
1017e0761ab1SMark Murray int ch = EOF;
1018e0761ab1SMark Murray char *ptbuf;
1019e0761ab1SMark Murray int chk = (int)inchar;
10209b50d902SRodney W. Grimes
10219b50d902SRodney W. Grimes ptbuf = buf;
10229b50d902SRodney W. Grimes
10239b50d902SRodney W. Grimes if (gap) {
10249b50d902SRodney W. Grimes /*
10259b50d902SRodney W. Grimes * expanding input option
10269b50d902SRodney W. Grimes */
10279b50d902SRodney W. Grimes while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
10289b50d902SRodney W. Grimes /*
10299b50d902SRodney W. Grimes * is this the input "tab" char
10309b50d902SRodney W. Grimes */
10319b50d902SRodney W. Grimes if (ch == chk) {
10329b50d902SRodney W. Grimes /*
10339b50d902SRodney W. Grimes * expand to number of spaces
10349b50d902SRodney W. Grimes */
10359b50d902SRodney W. Grimes col = (ptbuf - buf) + *cps;
10369b50d902SRodney W. Grimes col = gap - (col % gap);
10379b50d902SRodney W. Grimes
10389b50d902SRodney W. Grimes /*
10399b50d902SRodney W. Grimes * if more than this line, push back
10409b50d902SRodney W. Grimes */
10419b50d902SRodney W. Grimes if ((col > lim) && (ungetc(ch, inf) == EOF))
10429b50d902SRodney W. Grimes return(1);
10439b50d902SRodney W. Grimes
10449b50d902SRodney W. Grimes /*
10459b50d902SRodney W. Grimes * expand to spaces
10469b50d902SRodney W. Grimes */
10479b50d902SRodney W. Grimes while ((--col >= 0) && (--lim >= 0))
10489b50d902SRodney W. Grimes *ptbuf++ = ' ';
10499b50d902SRodney W. Grimes continue;
10509b50d902SRodney W. Grimes }
10519b50d902SRodney W. Grimes if (ch == '\n')
10529b50d902SRodney W. Grimes break;
10539b50d902SRodney W. Grimes *ptbuf++ = ch;
10549b50d902SRodney W. Grimes }
10559b50d902SRodney W. Grimes } else {
10569b50d902SRodney W. Grimes /*
10579b50d902SRodney W. Grimes * no expansion
10589b50d902SRodney W. Grimes */
10599b50d902SRodney W. Grimes while ((--lim >= 0) && ((ch = getc(inf)) != EOF)) {
10609b50d902SRodney W. Grimes if (ch == '\n')
10619b50d902SRodney W. Grimes break;
10629b50d902SRodney W. Grimes *ptbuf++ = ch;
10639b50d902SRodney W. Grimes }
10649b50d902SRodney W. Grimes }
10659b50d902SRodney W. Grimes col = ptbuf - buf;
10669b50d902SRodney W. Grimes if (ch == EOF) {
10679b50d902SRodney W. Grimes *mor = 0;
10689b50d902SRodney W. Grimes *cps = 0;
10699b50d902SRodney W. Grimes if (!col)
10709b50d902SRodney W. Grimes return(-1);
10719b50d902SRodney W. Grimes return(col);
10729b50d902SRodney W. Grimes }
10739b50d902SRodney W. Grimes if (ch == '\n') {
10749b50d902SRodney W. Grimes /*
10759b50d902SRodney W. Grimes * entire line processed
10769b50d902SRodney W. Grimes */
10779b50d902SRodney W. Grimes *mor = 0;
10789b50d902SRodney W. Grimes *cps = 0;
10799b50d902SRodney W. Grimes return(col);
10809b50d902SRodney W. Grimes }
10819b50d902SRodney W. Grimes
10829b50d902SRodney W. Grimes /*
10839b50d902SRodney W. Grimes * line was larger than limit
10849b50d902SRodney W. Grimes */
10859b50d902SRodney W. Grimes if (trnc) {
10869b50d902SRodney W. Grimes /*
10879b50d902SRodney W. Grimes * throw away rest of line
10889b50d902SRodney W. Grimes */
10899b50d902SRodney W. Grimes while ((ch = getc(inf)) != EOF) {
10909b50d902SRodney W. Grimes if (ch == '\n')
10919b50d902SRodney W. Grimes break;
10929b50d902SRodney W. Grimes }
10939b50d902SRodney W. Grimes *cps = 0;
10949b50d902SRodney W. Grimes *mor = 0;
10959b50d902SRodney W. Grimes } else {
10969b50d902SRodney W. Grimes /*
10979b50d902SRodney W. Grimes * save column offset if not truncated
10989b50d902SRodney W. Grimes */
10999b50d902SRodney W. Grimes *cps += col;
11009b50d902SRodney W. Grimes *mor = 1;
11019b50d902SRodney W. Grimes }
11029b50d902SRodney W. Grimes
11039b50d902SRodney W. Grimes return(col);
11049b50d902SRodney W. Grimes }
11059b50d902SRodney W. Grimes
11069b50d902SRodney W. Grimes /*
11079b50d902SRodney W. Grimes * otln(): output a line of data. (Supports unlimited length lines)
11089b50d902SRodney W. Grimes * output is optionally contracted to tabs
11099b50d902SRodney W. Grimes *
11109b50d902SRodney W. Grimes * buf: output buffer with data
11119b50d902SRodney W. Grimes * cnt: number of chars of valid data in buf
11129b50d902SRodney W. Grimes * svips: buffer input column position (for large lines)
11139b50d902SRodney W. Grimes * svops: buffer output column position (for large lines)
11149b50d902SRodney W. Grimes * mor: output line not complete in this buf; more data to come.
11159b50d902SRodney W. Grimes * 1 is more, 0 is complete, -1 is no \n's
11169b50d902SRodney W. Grimes */
11179b50d902SRodney W. Grimes int
otln(char * buf,int cnt,int * svips,int * svops,int mor)1118e0761ab1SMark Murray otln(char *buf, int cnt, int *svips, int *svops, int mor)
11199b50d902SRodney W. Grimes {
1120e0761ab1SMark Murray int ops; /* last col output */
1121e0761ab1SMark Murray int ips; /* last col in buf examined */
1122e0761ab1SMark Murray int gap = ogap;
1123e0761ab1SMark Murray int tbps;
1124e0761ab1SMark Murray char *endbuf;
11259b50d902SRodney W. Grimes
11269b50d902SRodney W. Grimes if (ogap) {
11279b50d902SRodney W. Grimes /*
11289b50d902SRodney W. Grimes * contracting on output
11299b50d902SRodney W. Grimes */
11309b50d902SRodney W. Grimes endbuf = buf + cnt;
11319b50d902SRodney W. Grimes ops = *svops;
11329b50d902SRodney W. Grimes ips = *svips;
11339b50d902SRodney W. Grimes while (buf < endbuf) {
11349b50d902SRodney W. Grimes /*
11359b50d902SRodney W. Grimes * count number of spaces and ochar in buffer
11369b50d902SRodney W. Grimes */
11379b50d902SRodney W. Grimes if (*buf == ' ') {
11389b50d902SRodney W. Grimes ++ips;
11399b50d902SRodney W. Grimes ++buf;
11409b50d902SRodney W. Grimes continue;
11419b50d902SRodney W. Grimes }
11429b50d902SRodney W. Grimes
11439b50d902SRodney W. Grimes /*
11449b50d902SRodney W. Grimes * simulate ochar processing
11459b50d902SRodney W. Grimes */
11469b50d902SRodney W. Grimes if (*buf == ochar) {
11479b50d902SRodney W. Grimes ips += gap - (ips % gap);
11489b50d902SRodney W. Grimes ++buf;
11499b50d902SRodney W. Grimes continue;
11509b50d902SRodney W. Grimes }
11519b50d902SRodney W. Grimes
11529b50d902SRodney W. Grimes /*
11539b50d902SRodney W. Grimes * got a non space char; contract out spaces
11549b50d902SRodney W. Grimes */
115506b95991STim J. Robbins while (ips - ops > 1) {
11569b50d902SRodney W. Grimes /*
11579b50d902SRodney W. Grimes * use as many ochar as will fit
11589b50d902SRodney W. Grimes */
11599b50d902SRodney W. Grimes if ((tbps = ops + gap - (ops % gap)) > ips)
11609b50d902SRodney W. Grimes break;
11619b50d902SRodney W. Grimes if (putchar(ochar) == EOF) {
11629b50d902SRodney W. Grimes pfail();
11639b50d902SRodney W. Grimes return(1);
11649b50d902SRodney W. Grimes }
11659b50d902SRodney W. Grimes ops = tbps;
11669b50d902SRodney W. Grimes }
11679b50d902SRodney W. Grimes
11689b50d902SRodney W. Grimes while (ops < ips) {
11699b50d902SRodney W. Grimes /*
11709b50d902SRodney W. Grimes * finish off with spaces
11719b50d902SRodney W. Grimes */
11729b50d902SRodney W. Grimes if (putchar(' ') == EOF) {
11739b50d902SRodney W. Grimes pfail();
11749b50d902SRodney W. Grimes return(1);
11759b50d902SRodney W. Grimes }
11769b50d902SRodney W. Grimes ++ops;
11779b50d902SRodney W. Grimes }
11789b50d902SRodney W. Grimes
11799b50d902SRodney W. Grimes /*
11809b50d902SRodney W. Grimes * output non space char
11819b50d902SRodney W. Grimes */
11829b50d902SRodney W. Grimes if (putchar(*buf++) == EOF) {
11839b50d902SRodney W. Grimes pfail();
11849b50d902SRodney W. Grimes return(1);
11859b50d902SRodney W. Grimes }
11869b50d902SRodney W. Grimes ++ips;
11879b50d902SRodney W. Grimes ++ops;
11889b50d902SRodney W. Grimes }
11899b50d902SRodney W. Grimes
11909b50d902SRodney W. Grimes if (mor > 0) {
11919b50d902SRodney W. Grimes /*
11929b50d902SRodney W. Grimes * if incomplete line, save position counts
11939b50d902SRodney W. Grimes */
11949b50d902SRodney W. Grimes *svops = ops;
11959b50d902SRodney W. Grimes *svips = ips;
11969b50d902SRodney W. Grimes return(0);
11979b50d902SRodney W. Grimes }
11989b50d902SRodney W. Grimes
11999b50d902SRodney W. Grimes if (mor < 0) {
120006b95991STim J. Robbins while (ips - ops > 1) {
12019b50d902SRodney W. Grimes /*
12029b50d902SRodney W. Grimes * use as many ochar as will fit
12039b50d902SRodney W. Grimes */
12049b50d902SRodney W. Grimes if ((tbps = ops + gap - (ops % gap)) > ips)
12059b50d902SRodney W. Grimes break;
12069b50d902SRodney W. Grimes if (putchar(ochar) == EOF) {
12079b50d902SRodney W. Grimes pfail();
12089b50d902SRodney W. Grimes return(1);
12099b50d902SRodney W. Grimes }
12109b50d902SRodney W. Grimes ops = tbps;
12119b50d902SRodney W. Grimes }
12129b50d902SRodney W. Grimes while (ops < ips) {
12139b50d902SRodney W. Grimes /*
12149b50d902SRodney W. Grimes * finish off with spaces
12159b50d902SRodney W. Grimes */
12169b50d902SRodney W. Grimes if (putchar(' ') == EOF) {
12179b50d902SRodney W. Grimes pfail();
12189b50d902SRodney W. Grimes return(1);
12199b50d902SRodney W. Grimes }
12209b50d902SRodney W. Grimes ++ops;
12219b50d902SRodney W. Grimes }
12229b50d902SRodney W. Grimes return(0);
12239b50d902SRodney W. Grimes }
12249b50d902SRodney W. Grimes } else {
12259b50d902SRodney W. Grimes /*
12269b50d902SRodney W. Grimes * output is not contracted
12279b50d902SRodney W. Grimes */
12289b50d902SRodney W. Grimes if (cnt && (fwrite(buf, sizeof(char), cnt, stdout) <= 0)) {
12299b50d902SRodney W. Grimes pfail();
12309b50d902SRodney W. Grimes return(1);
12319b50d902SRodney W. Grimes }
12329b50d902SRodney W. Grimes if (mor != 0)
12339b50d902SRodney W. Grimes return(0);
12349b50d902SRodney W. Grimes }
12359b50d902SRodney W. Grimes
12369b50d902SRodney W. Grimes /*
12379b50d902SRodney W. Grimes * process line end and double space as required
12389b50d902SRodney W. Grimes */
12399b50d902SRodney W. Grimes if ((putchar('\n') == EOF) || (dspace && (putchar('\n') == EOF))) {
12409b50d902SRodney W. Grimes pfail();
12419b50d902SRodney W. Grimes return(1);
12429b50d902SRodney W. Grimes }
12439b50d902SRodney W. Grimes return(0);
12449b50d902SRodney W. Grimes }
12459b50d902SRodney W. Grimes
12469b50d902SRodney W. Grimes /*
12479b50d902SRodney W. Grimes * inskip(): skip over pgcnt pages with lncnt lines per page
12489b50d902SRodney W. Grimes * file is closed at EOF (if not stdin).
12499b50d902SRodney W. Grimes *
12509b50d902SRodney W. Grimes * inf FILE * to read from
12519b50d902SRodney W. Grimes * pgcnt number of pages to skip
12529b50d902SRodney W. Grimes * lncnt number of lines per page
12539b50d902SRodney W. Grimes */
12549b50d902SRodney W. Grimes int
inskip(FILE * inf,int pgcnt,int lncnt)1255e0761ab1SMark Murray inskip(FILE *inf, int pgcnt, int lncnt)
12569b50d902SRodney W. Grimes {
1257e0761ab1SMark Murray int c;
1258e0761ab1SMark Murray int cnt;
12599b50d902SRodney W. Grimes
12609b50d902SRodney W. Grimes while(--pgcnt > 0) {
12619b50d902SRodney W. Grimes cnt = lncnt;
12629b50d902SRodney W. Grimes while ((c = getc(inf)) != EOF) {
12639b50d902SRodney W. Grimes if ((c == '\n') && (--cnt == 0))
12649b50d902SRodney W. Grimes break;
12659b50d902SRodney W. Grimes }
12669b50d902SRodney W. Grimes if (c == EOF) {
12679b50d902SRodney W. Grimes if (inf != stdin)
12689b50d902SRodney W. Grimes (void)fclose(inf);
12699b50d902SRodney W. Grimes return(1);
12709b50d902SRodney W. Grimes }
12719b50d902SRodney W. Grimes }
12729b50d902SRodney W. Grimes return(0);
12739b50d902SRodney W. Grimes }
12749b50d902SRodney W. Grimes
12759b50d902SRodney W. Grimes /*
12769b50d902SRodney W. Grimes * nxtfile: returns a FILE * to next file in arg list and sets the
12779b50d902SRodney W. Grimes * time field for this file (or current date).
12789b50d902SRodney W. Grimes *
12799b50d902SRodney W. Grimes * buf array to store proper date for the header.
12809b50d902SRodney W. Grimes * dt if set skips the date processing (used with -m)
12819b50d902SRodney W. Grimes */
12829b50d902SRodney W. Grimes FILE *
nxtfile(int argc,char ** argv,const char ** fname,char * buf,int dt)1283f4ac32deSDavid Malone nxtfile(int argc, char **argv, const char **fname, char *buf, int dt)
12849b50d902SRodney W. Grimes {
12859b50d902SRodney W. Grimes FILE *inf = NULL;
1286375557fcSBruce Evans time_t tv_sec;
12879b50d902SRodney W. Grimes struct tm *timeptr = NULL;
12889b50d902SRodney W. Grimes struct stat statbuf;
12899b50d902SRodney W. Grimes static int twice = -1;
12909b50d902SRodney W. Grimes
12919b50d902SRodney W. Grimes ++twice;
12929b50d902SRodney W. Grimes if (eoptind >= argc) {
12939b50d902SRodney W. Grimes /*
12949b50d902SRodney W. Grimes * no file listed; default, use standard input
12959b50d902SRodney W. Grimes */
12969b50d902SRodney W. Grimes if (twice)
12979b50d902SRodney W. Grimes return(NULL);
12989b50d902SRodney W. Grimes clearerr(stdin);
12999b50d902SRodney W. Grimes inf = stdin;
13009b50d902SRodney W. Grimes if (header != NULL)
13019b50d902SRodney W. Grimes *fname = header;
13029b50d902SRodney W. Grimes else
1303e0761ab1SMark Murray *fname = fnamedefault;
13049b50d902SRodney W. Grimes if (nohead)
13059b50d902SRodney W. Grimes return(inf);
130681d01f89SEd Schouten if ((tv_sec = time(NULL)) == -1) {
13079b50d902SRodney W. Grimes ++errcnt;
13089b50d902SRodney W. Grimes (void)fprintf(err, "pr: cannot get time of day, %s\n",
13099b50d902SRodney W. Grimes strerror(errno));
13109b50d902SRodney W. Grimes eoptind = argc - 1;
13119b50d902SRodney W. Grimes return(NULL);
13129b50d902SRodney W. Grimes }
1313375557fcSBruce Evans timeptr = localtime(&tv_sec);
13149b50d902SRodney W. Grimes }
13159b50d902SRodney W. Grimes for (; eoptind < argc; ++eoptind) {
13169b50d902SRodney W. Grimes if (strcmp(argv[eoptind], "-") == 0) {
13179b50d902SRodney W. Grimes /*
13189b50d902SRodney W. Grimes * process a "-" for filename
13199b50d902SRodney W. Grimes */
13209b50d902SRodney W. Grimes clearerr(stdin);
13219b50d902SRodney W. Grimes inf = stdin;
13229b50d902SRodney W. Grimes if (header != NULL)
13239b50d902SRodney W. Grimes *fname = header;
13249b50d902SRodney W. Grimes else
1325e0761ab1SMark Murray *fname = fnamedefault;
13269b50d902SRodney W. Grimes ++eoptind;
13279b50d902SRodney W. Grimes if (nohead || (dt && twice))
13289b50d902SRodney W. Grimes return(inf);
132981d01f89SEd Schouten if ((tv_sec = time(NULL)) == -1) {
13309b50d902SRodney W. Grimes ++errcnt;
13319b50d902SRodney W. Grimes (void)fprintf(err,
13329b50d902SRodney W. Grimes "pr: cannot get time of day, %s\n",
13339b50d902SRodney W. Grimes strerror(errno));
13349b50d902SRodney W. Grimes return(NULL);
13359b50d902SRodney W. Grimes }
1336375557fcSBruce Evans timeptr = localtime(&tv_sec);
13379b50d902SRodney W. Grimes } else {
13389b50d902SRodney W. Grimes /*
13399b50d902SRodney W. Grimes * normal file processing
13409b50d902SRodney W. Grimes */
13419b50d902SRodney W. Grimes if ((inf = fopen(argv[eoptind], "r")) == NULL) {
13429b50d902SRodney W. Grimes ++errcnt;
13439b50d902SRodney W. Grimes if (nodiag)
13449b50d902SRodney W. Grimes continue;
1345bd5de413SPhilippe Charnier (void)fprintf(err, "pr: cannot open %s, %s\n",
13469b50d902SRodney W. Grimes argv[eoptind], strerror(errno));
13479b50d902SRodney W. Grimes continue;
13489b50d902SRodney W. Grimes }
13499b50d902SRodney W. Grimes if (header != NULL)
13509b50d902SRodney W. Grimes *fname = header;
13519b50d902SRodney W. Grimes else if (dt)
1352e0761ab1SMark Murray *fname = fnamedefault;
13539b50d902SRodney W. Grimes else
13549b50d902SRodney W. Grimes *fname = argv[eoptind];
13559b50d902SRodney W. Grimes ++eoptind;
13569b50d902SRodney W. Grimes if (nohead || (dt && twice))
13579b50d902SRodney W. Grimes return(inf);
13589b50d902SRodney W. Grimes
13599b50d902SRodney W. Grimes if (dt) {
136081d01f89SEd Schouten if ((tv_sec = time(NULL)) == -1) {
13619b50d902SRodney W. Grimes ++errcnt;
13629b50d902SRodney W. Grimes (void)fprintf(err,
13639b50d902SRodney W. Grimes "pr: cannot get time of day, %s\n",
13649b50d902SRodney W. Grimes strerror(errno));
13656dc025eaSAlan Somers fclose(inf);
13669b50d902SRodney W. Grimes return(NULL);
13679b50d902SRodney W. Grimes }
1368375557fcSBruce Evans timeptr = localtime(&tv_sec);
13699b50d902SRodney W. Grimes } else {
13709b50d902SRodney W. Grimes if (fstat(fileno(inf), &statbuf) < 0) {
13719b50d902SRodney W. Grimes ++errcnt;
13729b50d902SRodney W. Grimes (void)fclose(inf);
13739b50d902SRodney W. Grimes (void)fprintf(err,
1374bd5de413SPhilippe Charnier "pr: cannot stat %s, %s\n",
13759b50d902SRodney W. Grimes argv[eoptind], strerror(errno));
13769b50d902SRodney W. Grimes return(NULL);
13779b50d902SRodney W. Grimes }
13789b50d902SRodney W. Grimes timeptr = localtime(&(statbuf.st_mtime));
13799b50d902SRodney W. Grimes }
13809b50d902SRodney W. Grimes }
13819b50d902SRodney W. Grimes break;
13829b50d902SRodney W. Grimes }
13839b50d902SRodney W. Grimes if (inf == NULL)
13849b50d902SRodney W. Grimes return(NULL);
13859b50d902SRodney W. Grimes
13869b50d902SRodney W. Grimes /*
13879b50d902SRodney W. Grimes * set up time field used in header
13889b50d902SRodney W. Grimes */
13899b50d902SRodney W. Grimes if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) {
13909b50d902SRodney W. Grimes ++errcnt;
13919b50d902SRodney W. Grimes if (inf != stdin)
13929b50d902SRodney W. Grimes (void)fclose(inf);
13939b50d902SRodney W. Grimes (void)fputs("pr: time conversion failed\n", err);
13949b50d902SRodney W. Grimes return(NULL);
13959b50d902SRodney W. Grimes }
13969b50d902SRodney W. Grimes return(inf);
13979b50d902SRodney W. Grimes }
13989b50d902SRodney W. Grimes
13999b50d902SRodney W. Grimes /*
14009b50d902SRodney W. Grimes * addnum(): adds the line number to the column
14019b50d902SRodney W. Grimes * Truncates from the front or pads with spaces as required.
14029b50d902SRodney W. Grimes * Numbers are right justified.
14039b50d902SRodney W. Grimes *
14049b50d902SRodney W. Grimes * buf buffer to store the number
14059b50d902SRodney W. Grimes * wdth width of buffer to fill
14069b50d902SRodney W. Grimes * line line number
14079b50d902SRodney W. Grimes *
14089b50d902SRodney W. Grimes * NOTE: numbers occupy part of the column. The posix
14099b50d902SRodney W. Grimes * spec does not specify if -i processing should or should not
14109b50d902SRodney W. Grimes * occur on number padding. The spec does say it occupies
14119b50d902SRodney W. Grimes * part of the column. The usage of addnum currently treats
14129b50d902SRodney W. Grimes * numbers as part of the column so spaces may be replaced.
14139b50d902SRodney W. Grimes */
14149b50d902SRodney W. Grimes void
addnum(char * buf,int wdth,int line)1415e0761ab1SMark Murray addnum(char *buf, int wdth, int line)
14169b50d902SRodney W. Grimes {
1417e0761ab1SMark Murray char *pt = buf + wdth;
14189b50d902SRodney W. Grimes
14199b50d902SRodney W. Grimes do {
14209b50d902SRodney W. Grimes *--pt = digs[line % 10];
14219b50d902SRodney W. Grimes line /= 10;
14229b50d902SRodney W. Grimes } while (line && (pt > buf));
14239b50d902SRodney W. Grimes
14249b50d902SRodney W. Grimes /*
14259b50d902SRodney W. Grimes * pad with space as required
14269b50d902SRodney W. Grimes */
14279b50d902SRodney W. Grimes while (pt > buf)
14289b50d902SRodney W. Grimes *--pt = ' ';
14299b50d902SRodney W. Grimes }
14309b50d902SRodney W. Grimes
14319b50d902SRodney W. Grimes /*
14329b50d902SRodney W. Grimes * prhead(): prints the top of page header
14339b50d902SRodney W. Grimes *
14349b50d902SRodney W. Grimes * buf buffer with time field (and offset)
14359b50d902SRodney W. Grimes * cnt number of chars in buf
14369b50d902SRodney W. Grimes * fname fname field for header
14379b50d902SRodney W. Grimes * pagcnt page number
14389b50d902SRodney W. Grimes */
14399b50d902SRodney W. Grimes int
prhead(char * buf,const char * fname,int pagcnt)1440f4ac32deSDavid Malone prhead(char *buf, const char *fname, int pagcnt)
14419b50d902SRodney W. Grimes {
14429b50d902SRodney W. Grimes int ips = 0;
14439b50d902SRodney W. Grimes int ops = 0;
14449b50d902SRodney W. Grimes
14459b50d902SRodney W. Grimes if ((putchar('\n') == EOF) || (putchar('\n') == EOF)) {
14469b50d902SRodney W. Grimes pfail();
14479b50d902SRodney W. Grimes return(1);
14489b50d902SRodney W. Grimes }
14499b50d902SRodney W. Grimes /*
14509b50d902SRodney W. Grimes * posix is not clear if the header is subject to line length
14519b50d902SRodney W. Grimes * restrictions. The specification for header line format
14529b50d902SRodney W. Grimes * in the spec clearly does not limit length. No pr currently
14539b50d902SRodney W. Grimes * restricts header length. However if we need to truncate in
1454d64ada50SJens Schweikhardt * a reasonable way, adjust the length of the printf by
1455444ec0d5SJohn Baldwin * changing HDFMT to allow a length max as an argument to printf.
14569b50d902SRodney W. Grimes * buf (which contains the offset spaces and time field could
14579b50d902SRodney W. Grimes * also be trimmed
14589b50d902SRodney W. Grimes *
14599b50d902SRodney W. Grimes * note only the offset (if any) is processed for tab expansion
14609b50d902SRodney W. Grimes */
14619b50d902SRodney W. Grimes if (offst && otln(buf, offst, &ips, &ops, -1))
14629b50d902SRodney W. Grimes return(1);
14639b50d902SRodney W. Grimes (void)printf(HDFMT,buf+offst, fname, pagcnt);
14649b50d902SRodney W. Grimes return(0);
14659b50d902SRodney W. Grimes }
14669b50d902SRodney W. Grimes
14679b50d902SRodney W. Grimes /*
14689b50d902SRodney W. Grimes * prtail(): pad page with empty lines (if required) and print page trailer
14699b50d902SRodney W. Grimes * if requested
14709b50d902SRodney W. Grimes *
14719b50d902SRodney W. Grimes * cnt number of lines of padding needed
14729b50d902SRodney W. Grimes * incomp was a '\n' missing from last line output
14739b50d902SRodney W. Grimes */
14749b50d902SRodney W. Grimes int
prtail(int cnt,int incomp)1475e0761ab1SMark Murray prtail(int cnt, int incomp)
14769b50d902SRodney W. Grimes {
14779b50d902SRodney W. Grimes if (nohead) {
14789b50d902SRodney W. Grimes /*
14799b50d902SRodney W. Grimes * only pad with no headers when incomplete last line
14809b50d902SRodney W. Grimes */
1481ebcf24fbSMarc G. Fournier if (incomp &&
1482ebcf24fbSMarc G. Fournier ((dspace && (putchar('\n') == EOF)) ||
1483ebcf24fbSMarc G. Fournier (putchar('\n') == EOF))) {
14849b50d902SRodney W. Grimes pfail();
14859b50d902SRodney W. Grimes return(1);
14869b50d902SRodney W. Grimes }
1487ebcf24fbSMarc G. Fournier /*
1488ebcf24fbSMarc G. Fournier * but honor the formfeed request
1489ebcf24fbSMarc G. Fournier */
1490ebcf24fbSMarc G. Fournier if (formfeed) {
1491ebcf24fbSMarc G. Fournier if (putchar('\f') == EOF) {
1492ebcf24fbSMarc G. Fournier pfail();
1493ebcf24fbSMarc G. Fournier return(1);
1494ebcf24fbSMarc G. Fournier }
1495ebcf24fbSMarc G. Fournier }
14969b50d902SRodney W. Grimes return(0);
14979b50d902SRodney W. Grimes }
14989b50d902SRodney W. Grimes /*
14999b50d902SRodney W. Grimes * if double space output two \n
15009b50d902SRodney W. Grimes */
15019b50d902SRodney W. Grimes if (dspace)
15029b50d902SRodney W. Grimes cnt *= 2;
15039b50d902SRodney W. Grimes
15049b50d902SRodney W. Grimes /*
15059b50d902SRodney W. Grimes * if an odd number of lines per page, add an extra \n
15069b50d902SRodney W. Grimes */
15079b50d902SRodney W. Grimes if (addone)
15089b50d902SRodney W. Grimes ++cnt;
15099b50d902SRodney W. Grimes
15109b50d902SRodney W. Grimes /*
15119b50d902SRodney W. Grimes * pad page
15129b50d902SRodney W. Grimes */
15139b50d902SRodney W. Grimes if (formfeed) {
15149b50d902SRodney W. Grimes if ((incomp && (putchar('\n') == EOF)) ||
15159b50d902SRodney W. Grimes (putchar('\f') == EOF)) {
15169b50d902SRodney W. Grimes pfail();
15179b50d902SRodney W. Grimes return(1);
15189b50d902SRodney W. Grimes }
15199b50d902SRodney W. Grimes return(0);
15209b50d902SRodney W. Grimes }
15219b50d902SRodney W. Grimes cnt += TAILLEN;
15229b50d902SRodney W. Grimes while (--cnt >= 0) {
15239b50d902SRodney W. Grimes if (putchar('\n') == EOF) {
15249b50d902SRodney W. Grimes pfail();
15259b50d902SRodney W. Grimes return(1);
15269b50d902SRodney W. Grimes }
15279b50d902SRodney W. Grimes }
15289b50d902SRodney W. Grimes return(0);
15299b50d902SRodney W. Grimes }
15309b50d902SRodney W. Grimes
15319b50d902SRodney W. Grimes /*
15329b50d902SRodney W. Grimes * terminate(): when a SIGINT is recvd
15339b50d902SRodney W. Grimes */
15349b50d902SRodney W. Grimes void
terminate(int which_sig __unused)1535e0761ab1SMark Murray terminate(int which_sig __unused)
15369b50d902SRodney W. Grimes {
15379b50d902SRodney W. Grimes flsh_errs();
15389b50d902SRodney W. Grimes exit(1);
15399b50d902SRodney W. Grimes }
15409b50d902SRodney W. Grimes
15419b50d902SRodney W. Grimes
15429b50d902SRodney W. Grimes /*
15439b50d902SRodney W. Grimes * flsh_errs(): output saved up diagnostic messages after all normal
15449b50d902SRodney W. Grimes * processing has completed
15459b50d902SRodney W. Grimes */
15469b50d902SRodney W. Grimes void
flsh_errs(void)1547e0761ab1SMark Murray flsh_errs(void)
15489b50d902SRodney W. Grimes {
15499b50d902SRodney W. Grimes char buf[BUFSIZ];
15509b50d902SRodney W. Grimes
15519b50d902SRodney W. Grimes (void)fflush(stdout);
15529b50d902SRodney W. Grimes (void)fflush(err);
15539b50d902SRodney W. Grimes if (err == stderr)
15549b50d902SRodney W. Grimes return;
15559b50d902SRodney W. Grimes rewind(err);
15569b50d902SRodney W. Grimes while (fgets(buf, BUFSIZ, err) != NULL)
15579b50d902SRodney W. Grimes (void)fputs(buf, stderr);
15589b50d902SRodney W. Grimes }
15599b50d902SRodney W. Grimes
15609b50d902SRodney W. Grimes void
mfail(void)1561e0761ab1SMark Murray mfail(void)
15629b50d902SRodney W. Grimes {
15639b50d902SRodney W. Grimes (void)fputs("pr: memory allocation failed\n", err);
15649b50d902SRodney W. Grimes }
15659b50d902SRodney W. Grimes
15669b50d902SRodney W. Grimes void
pfail(void)1567e0761ab1SMark Murray pfail(void)
15689b50d902SRodney W. Grimes {
15699b50d902SRodney W. Grimes (void)fprintf(err, "pr: write failure, %s\n", strerror(errno));
15709b50d902SRodney W. Grimes }
15719b50d902SRodney W. Grimes
15729b50d902SRodney W. Grimes void
usage(void)1573e0761ab1SMark Murray usage(void)
15749b50d902SRodney W. Grimes {
15759b50d902SRodney W. Grimes (void)fputs(
1576032b32adSJuli Mallett "usage: pr [+page] [-col] [-adFfmprt] [-e[ch][gap]] [-h header]\n",
1577032b32adSJuli Mallett err);
15789b50d902SRodney W. Grimes (void)fputs(
15799b50d902SRodney W. Grimes " [-i[ch][gap]] [-l line] [-n[ch][width]] [-o offset]\n",err);
15809b50d902SRodney W. Grimes (void)fputs(
15814bf9895eSAndrey A. Chernov " [-L locale] [-s[ch]] [-w width] [-] [file ...]\n", err);
15829b50d902SRodney W. Grimes }
15839b50d902SRodney W. Grimes
15849b50d902SRodney W. Grimes /*
15859b50d902SRodney W. Grimes * setup: Validate command args, initialize and perform sanity
15869b50d902SRodney W. Grimes * checks on options
15879b50d902SRodney W. Grimes */
15889b50d902SRodney W. Grimes int
setup(int argc,char * argv[])1589e0761ab1SMark Murray setup(int argc, char *argv[])
15909b50d902SRodney W. Grimes {
1591e0761ab1SMark Murray int c;
159277b898c4SAndrey A. Chernov int d_first;
15939b50d902SRodney W. Grimes int eflag = 0;
15949b50d902SRodney W. Grimes int iflag = 0;
15959b50d902SRodney W. Grimes int wflag = 0;
15969b50d902SRodney W. Grimes int cflag = 0;
15974bf9895eSAndrey A. Chernov char *Lflag = NULL;
15989b50d902SRodney W. Grimes
15999b50d902SRodney W. Grimes if (isatty(fileno(stdout))) {
16009b50d902SRodney W. Grimes /*
16019b50d902SRodney W. Grimes * defer diagnostics until processing is done
16029b50d902SRodney W. Grimes */
16039b50d902SRodney W. Grimes if ((err = tmpfile()) == NULL) {
160496c066ccSChris D. Faulhaber err = stderr;
16059b50d902SRodney W. Grimes (void)fputs("Cannot defer diagnostic messages\n",stderr);
16069b50d902SRodney W. Grimes return(1);
16079b50d902SRodney W. Grimes }
16089b50d902SRodney W. Grimes } else
16099b50d902SRodney W. Grimes err = stderr;
1610032b32adSJuli Mallett while ((c = egetopt(argc, argv, "#adFfmrte?h:i?L:l:n?o:ps?w:")) != -1) {
16119b50d902SRodney W. Grimes switch (c) {
16129b50d902SRodney W. Grimes case '+':
16139b50d902SRodney W. Grimes if ((pgnm = atoi(eoptarg)) < 1) {
16149b50d902SRodney W. Grimes (void)fputs("pr: +page number must be 1 or more\n",
16159b50d902SRodney W. Grimes err);
16169b50d902SRodney W. Grimes return(1);
16179b50d902SRodney W. Grimes }
16189b50d902SRodney W. Grimes break;
16199b50d902SRodney W. Grimes case '-':
16209b50d902SRodney W. Grimes if ((clcnt = atoi(eoptarg)) < 1) {
16219b50d902SRodney W. Grimes (void)fputs("pr: -columns must be 1 or more\n",err);
16229b50d902SRodney W. Grimes return(1);
16239b50d902SRodney W. Grimes }
16249b50d902SRodney W. Grimes if (clcnt > 1)
16259b50d902SRodney W. Grimes ++cflag;
16269b50d902SRodney W. Grimes break;
16279b50d902SRodney W. Grimes case 'a':
16289b50d902SRodney W. Grimes ++across;
16299b50d902SRodney W. Grimes break;
16309b50d902SRodney W. Grimes case 'd':
16319b50d902SRodney W. Grimes ++dspace;
16329b50d902SRodney W. Grimes break;
16339b50d902SRodney W. Grimes case 'e':
16349b50d902SRodney W. Grimes ++eflag;
1635b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && !isdigit((unsigned char)*eoptarg))
16369b50d902SRodney W. Grimes inchar = *eoptarg++;
16379b50d902SRodney W. Grimes else
16389b50d902SRodney W. Grimes inchar = INCHAR;
1639b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && isdigit((unsigned char)*eoptarg)) {
16409b50d902SRodney W. Grimes if ((ingap = atoi(eoptarg)) < 0) {
16419b50d902SRodney W. Grimes (void)fputs(
16429b50d902SRodney W. Grimes "pr: -e gap must be 0 or more\n", err);
16439b50d902SRodney W. Grimes return(1);
16449b50d902SRodney W. Grimes }
16459b50d902SRodney W. Grimes if (ingap == 0)
16469b50d902SRodney W. Grimes ingap = INGAP;
16479b50d902SRodney W. Grimes } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
16489b50d902SRodney W. Grimes (void)fprintf(err,
16499b50d902SRodney W. Grimes "pr: invalid value for -e %s\n", eoptarg);
16509b50d902SRodney W. Grimes return(1);
16519b50d902SRodney W. Grimes } else
16529b50d902SRodney W. Grimes ingap = INGAP;
16539b50d902SRodney W. Grimes break;
1654032b32adSJuli Mallett case 'f':
1655032b32adSJuli Mallett ++pausefst;
1656032b32adSJuli Mallett /*FALLTHROUGH*/
16579b50d902SRodney W. Grimes case 'F':
16589b50d902SRodney W. Grimes ++formfeed;
16599b50d902SRodney W. Grimes break;
16609b50d902SRodney W. Grimes case 'h':
16619b50d902SRodney W. Grimes header = eoptarg;
16629b50d902SRodney W. Grimes break;
16639b50d902SRodney W. Grimes case 'i':
16649b50d902SRodney W. Grimes ++iflag;
1665b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && !isdigit((unsigned char)*eoptarg))
16669b50d902SRodney W. Grimes ochar = *eoptarg++;
16679b50d902SRodney W. Grimes else
16689b50d902SRodney W. Grimes ochar = OCHAR;
1669b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && isdigit((unsigned char)*eoptarg)) {
16709b50d902SRodney W. Grimes if ((ogap = atoi(eoptarg)) < 0) {
16719b50d902SRodney W. Grimes (void)fputs(
16729b50d902SRodney W. Grimes "pr: -i gap must be 0 or more\n", err);
16739b50d902SRodney W. Grimes return(1);
16749b50d902SRodney W. Grimes }
16759b50d902SRodney W. Grimes if (ogap == 0)
16769b50d902SRodney W. Grimes ogap = OGAP;
16779b50d902SRodney W. Grimes } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
16789b50d902SRodney W. Grimes (void)fprintf(err,
16799b50d902SRodney W. Grimes "pr: invalid value for -i %s\n", eoptarg);
16809b50d902SRodney W. Grimes return(1);
16819b50d902SRodney W. Grimes } else
16829b50d902SRodney W. Grimes ogap = OGAP;
16839b50d902SRodney W. Grimes break;
1684b5076d91SAndrey A. Chernov case 'L':
16854bf9895eSAndrey A. Chernov Lflag = eoptarg;
1686b5076d91SAndrey A. Chernov break;
16879b50d902SRodney W. Grimes case 'l':
1688b5076d91SAndrey A. Chernov if (!isdigit((unsigned char)*eoptarg) || ((lines=atoi(eoptarg)) < 1)) {
16899b50d902SRodney W. Grimes (void)fputs(
1690bd5de413SPhilippe Charnier "pr: number of lines must be 1 or more\n",err);
16919b50d902SRodney W. Grimes return(1);
16929b50d902SRodney W. Grimes }
16939b50d902SRodney W. Grimes break;
16949b50d902SRodney W. Grimes case 'm':
16959b50d902SRodney W. Grimes ++merge;
16969b50d902SRodney W. Grimes break;
16979b50d902SRodney W. Grimes case 'n':
1698b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && !isdigit((unsigned char)*eoptarg))
16999b50d902SRodney W. Grimes nmchar = *eoptarg++;
17009b50d902SRodney W. Grimes else
17019b50d902SRodney W. Grimes nmchar = NMCHAR;
1702b5076d91SAndrey A. Chernov if ((eoptarg != NULL) && isdigit((unsigned char)*eoptarg)) {
17039b50d902SRodney W. Grimes if ((nmwd = atoi(eoptarg)) < 1) {
17049b50d902SRodney W. Grimes (void)fputs(
17059b50d902SRodney W. Grimes "pr: -n width must be 1 or more\n",err);
17069b50d902SRodney W. Grimes return(1);
17079b50d902SRodney W. Grimes }
17089b50d902SRodney W. Grimes } else if ((eoptarg != NULL) && (*eoptarg != '\0')) {
17099b50d902SRodney W. Grimes (void)fprintf(err,
17109b50d902SRodney W. Grimes "pr: invalid value for -n %s\n", eoptarg);
17119b50d902SRodney W. Grimes return(1);
17129b50d902SRodney W. Grimes } else
17139b50d902SRodney W. Grimes nmwd = NMWD;
17149b50d902SRodney W. Grimes break;
17159b50d902SRodney W. Grimes case 'o':
1716b5076d91SAndrey A. Chernov if (!isdigit((unsigned char)*eoptarg) || ((offst = atoi(eoptarg))< 1)){
17179b50d902SRodney W. Grimes (void)fputs("pr: -o offset must be 1 or more\n",
17189b50d902SRodney W. Grimes err);
17199b50d902SRodney W. Grimes return(1);
17209b50d902SRodney W. Grimes }
17219b50d902SRodney W. Grimes break;
1722032b32adSJuli Mallett case 'p':
1723032b32adSJuli Mallett ++pauseall;
1724032b32adSJuli Mallett break;
17259b50d902SRodney W. Grimes case 'r':
17269b50d902SRodney W. Grimes ++nodiag;
17279b50d902SRodney W. Grimes break;
17289b50d902SRodney W. Grimes case 's':
17299b50d902SRodney W. Grimes ++sflag;
17309b50d902SRodney W. Grimes if (eoptarg == NULL)
17319b50d902SRodney W. Grimes schar = SCHAR;
1732d68e2acdSKris Kennaway else {
17339b50d902SRodney W. Grimes schar = *eoptarg++;
17349b50d902SRodney W. Grimes if (*eoptarg != '\0') {
17359b50d902SRodney W. Grimes (void)fprintf(err,
1736d68e2acdSKris Kennaway "pr: invalid value for -s %s\n",
1737d68e2acdSKris Kennaway eoptarg);
17389b50d902SRodney W. Grimes return(1);
17399b50d902SRodney W. Grimes }
1740d68e2acdSKris Kennaway }
17419b50d902SRodney W. Grimes break;
17429b50d902SRodney W. Grimes case 't':
17439b50d902SRodney W. Grimes ++nohead;
17449b50d902SRodney W. Grimes break;
17459b50d902SRodney W. Grimes case 'w':
17469b50d902SRodney W. Grimes ++wflag;
17476dc025eaSAlan Somers if ((eoptarg == NULL ) ||
17486dc025eaSAlan Somers !isdigit((unsigned char)*eoptarg) ||
17496dc025eaSAlan Somers ((pgwd = atoi(eoptarg)) < 1)){
17509b50d902SRodney W. Grimes (void)fputs(
17519b50d902SRodney W. Grimes "pr: -w width must be 1 or more \n",err);
17529b50d902SRodney W. Grimes return(1);
17539b50d902SRodney W. Grimes }
17549b50d902SRodney W. Grimes break;
17559b50d902SRodney W. Grimes case '?':
17569b50d902SRodney W. Grimes default:
17579b50d902SRodney W. Grimes return(1);
17589b50d902SRodney W. Grimes }
17599b50d902SRodney W. Grimes }
17609b50d902SRodney W. Grimes
17619b50d902SRodney W. Grimes /*
17629b50d902SRodney W. Grimes * default and sanity checks
17639b50d902SRodney W. Grimes */
17649b50d902SRodney W. Grimes if (!clcnt) {
17659b50d902SRodney W. Grimes if (merge) {
17669b50d902SRodney W. Grimes if ((clcnt = argc - eoptind) <= 1) {
17679b50d902SRodney W. Grimes clcnt = CLCNT;
17689b50d902SRodney W. Grimes merge = 0;
17699b50d902SRodney W. Grimes }
17709b50d902SRodney W. Grimes } else
17719b50d902SRodney W. Grimes clcnt = CLCNT;
17729b50d902SRodney W. Grimes }
17739b50d902SRodney W. Grimes if (across) {
17749b50d902SRodney W. Grimes if (clcnt == 1) {
17759b50d902SRodney W. Grimes (void)fputs("pr: -a flag requires multiple columns\n",
17769b50d902SRodney W. Grimes err);
17779b50d902SRodney W. Grimes return(1);
17789b50d902SRodney W. Grimes }
17799b50d902SRodney W. Grimes if (merge) {
17809b50d902SRodney W. Grimes (void)fputs("pr: -m cannot be used with -a\n", err);
17819b50d902SRodney W. Grimes return(1);
17829b50d902SRodney W. Grimes }
17839b50d902SRodney W. Grimes }
17849b50d902SRodney W. Grimes if (!wflag) {
17859b50d902SRodney W. Grimes if (sflag)
17869b50d902SRodney W. Grimes pgwd = SPGWD;
17879b50d902SRodney W. Grimes else
17889b50d902SRodney W. Grimes pgwd = PGWD;
17899b50d902SRodney W. Grimes }
17909b50d902SRodney W. Grimes if (cflag || merge) {
17919b50d902SRodney W. Grimes if (!eflag) {
17929b50d902SRodney W. Grimes inchar = INCHAR;
17939b50d902SRodney W. Grimes ingap = INGAP;
17949b50d902SRodney W. Grimes }
17959b50d902SRodney W. Grimes if (!iflag) {
17969b50d902SRodney W. Grimes ochar = OCHAR;
17979b50d902SRodney W. Grimes ogap = OGAP;
17989b50d902SRodney W. Grimes }
17999b50d902SRodney W. Grimes }
18009b50d902SRodney W. Grimes if (cflag) {
18019b50d902SRodney W. Grimes if (merge) {
18029b50d902SRodney W. Grimes (void)fputs(
18039b50d902SRodney W. Grimes "pr: -m cannot be used with multiple columns\n", err);
18049b50d902SRodney W. Grimes return(1);
18059b50d902SRodney W. Grimes }
18069b50d902SRodney W. Grimes if (nmwd) {
18079b50d902SRodney W. Grimes colwd = (pgwd + 1 - (clcnt * (nmwd + 2)))/clcnt;
18089b50d902SRodney W. Grimes pgwd = ((colwd + nmwd + 2) * clcnt) - 1;
18099b50d902SRodney W. Grimes } else {
18109b50d902SRodney W. Grimes colwd = (pgwd + 1 - clcnt)/clcnt;
18119b50d902SRodney W. Grimes pgwd = ((colwd + 1) * clcnt) - 1;
18129b50d902SRodney W. Grimes }
18139b50d902SRodney W. Grimes if (colwd < 1) {
18149b50d902SRodney W. Grimes (void)fprintf(err,
18159b50d902SRodney W. Grimes "pr: page width is too small for %d columns\n",clcnt);
18169b50d902SRodney W. Grimes return(1);
18179b50d902SRodney W. Grimes }
18189b50d902SRodney W. Grimes }
18199b50d902SRodney W. Grimes if (!lines)
18209b50d902SRodney W. Grimes lines = LINES;
18219b50d902SRodney W. Grimes
18229b50d902SRodney W. Grimes /*
18239b50d902SRodney W. Grimes * make sure long enough for headers. if not disable
18249b50d902SRodney W. Grimes */
18259b50d902SRodney W. Grimes if (lines <= HEADLEN + TAILLEN)
18269b50d902SRodney W. Grimes ++nohead;
18279b50d902SRodney W. Grimes else if (!nohead)
18289b50d902SRodney W. Grimes lines -= HEADLEN + TAILLEN;
18299b50d902SRodney W. Grimes
18309b50d902SRodney W. Grimes /*
18319b50d902SRodney W. Grimes * adjust for double space on odd length pages
18329b50d902SRodney W. Grimes */
18339b50d902SRodney W. Grimes if (dspace) {
18349b50d902SRodney W. Grimes if (lines == 1)
18359b50d902SRodney W. Grimes dspace = 0;
18369b50d902SRodney W. Grimes else {
18379b50d902SRodney W. Grimes if (lines & 1)
18389b50d902SRodney W. Grimes ++addone;
18399b50d902SRodney W. Grimes lines /= 2;
18409b50d902SRodney W. Grimes }
18419b50d902SRodney W. Grimes }
18429b50d902SRodney W. Grimes
18434bf9895eSAndrey A. Chernov (void) setlocale(LC_TIME, (Lflag != NULL) ? Lflag : "");
1844b5076d91SAndrey A. Chernov
184577b898c4SAndrey A. Chernov d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
1846e0761ab1SMark Murray timefrmt = strdup(d_first ? TIMEFMTD : TIMEFMTM);
184777b898c4SAndrey A. Chernov
18489b50d902SRodney W. Grimes return(0);
18499b50d902SRodney W. Grimes }
1850