1*11274Slayer static char *sccsid = "@(#)pr.c 4.3 (Berkeley) 02/24/83"; 28789Smckusick 31063Sbill /* 41063Sbill * print file with headings 51063Sbill * 2+head+2+page[56]+5 61063Sbill */ 71063Sbill 81063Sbill #include <stdio.h> 91063Sbill #include <signal.h> 101063Sbill #include <sys/types.h> 111063Sbill #include <sys/stat.h> 121063Sbill 131063Sbill /* Making putcp a macro sped things up by 14%. */ 141063Sbill #define putcp(c) if (page >= fpage) putchar(c) 151063Sbill 161063Sbill int ncol = 1; 171063Sbill char *header; 181063Sbill int col; 191063Sbill int icol; 201063Sbill FILE *file; 211063Sbill char *bufp; 221063Sbill #define BUFS 6720 231063Sbill char buffer[BUFS]; /* for multi-column output */ 241063Sbill char obuf[BUFSIZ]; 251063Sbill #define FF 014 261063Sbill int line; 271063Sbill char *colp[72]; 281063Sbill int nofile; 291063Sbill char isclosed[10]; 301063Sbill FILE *ifile[10]; 311063Sbill char **lastarg; 321063Sbill int peekc; 331063Sbill int fpage; 341063Sbill int page; 351063Sbill int colw; 361063Sbill int nspace; 371063Sbill int width = 72; 381063Sbill int length = 66; 391063Sbill int plength = 61; 401063Sbill int margin = 10; 411063Sbill int ntflg; 421063Sbill int fflg; 431063Sbill int mflg; 441063Sbill int tabc; 451063Sbill char *tty; 461063Sbill int mode; 471063Sbill char *ttyname(); 481063Sbill char *ctime(); 491063Sbill 501063Sbill main(argc, argv) 511063Sbill char **argv; 521063Sbill { 531063Sbill int nfdone; 541063Sbill int onintr(); 551063Sbill 561063Sbill setbuf(stdout, obuf); 571063Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 581063Sbill signal(SIGINT, onintr); 591063Sbill lastarg = &argv[argc-1]; 601063Sbill fixtty(); 611063Sbill for (nfdone=0; argc>1; argc--) { 621063Sbill argv++; 631063Sbill if (**argv == '-') { 641063Sbill switch (*++*argv) { 658789Smckusick case 'h': /* define page header */ 661063Sbill if (argc>=2) { 671063Sbill header = *++argv; 681063Sbill argc--; 691063Sbill } 701063Sbill continue; 711063Sbill 728789Smckusick case 't': /* don't print page headers */ 731063Sbill ntflg++; 741063Sbill continue; 751063Sbill 768789Smckusick case 'f': /* use form feeds */ 771063Sbill fflg++; 781063Sbill plength = 60; 791063Sbill continue; 801063Sbill 818789Smckusick case 'l': /* length of page */ 821063Sbill length = atoi(++*argv); 831063Sbill continue; 841063Sbill 858789Smckusick case 'w': /* width of page */ 861063Sbill width = atoi(++*argv); 871063Sbill continue; 881063Sbill 898789Smckusick case 's': /* col separator */ 901063Sbill if (*++*argv) 911063Sbill tabc = **argv; 921063Sbill else 931063Sbill tabc = '\t'; 941063Sbill continue; 951063Sbill 968789Smckusick case 'm': /* all files at once */ 971063Sbill mflg++; 981063Sbill continue; 991063Sbill 1001063Sbill default: 1018789Smckusick if (numeric(*argv)) { /* # of cols */ 1028789Smckusick if ((ncol = atoi(*argv)) == 0) { 1038789Smckusick fprintf(stderr, "can't print 0 cols, using 1 instead.\n"); 1048789Smckusick ncol = 1; 1058789Smckusick } 1068789Smckusick } else { 1078789Smckusick fprintf(stderr, "pr: bad key %s\n", *argv); 1088789Smckusick exit(1); 1098789Smckusick } 1101063Sbill continue; 1111063Sbill } 1128789Smckusick } else if (**argv == '+') { /* start at page ++*argv */ 1131063Sbill fpage = atoi(++*argv); 1141063Sbill } else { 1151063Sbill print(*argv, argv); 1161063Sbill nfdone++; 1171063Sbill if (mflg) 1181063Sbill break; 1191063Sbill } 1201063Sbill } 1211063Sbill if (nfdone==0) 1221063Sbill print((char *)0, (char **)0); 1231063Sbill done(); 1241063Sbill } 1251063Sbill 1261063Sbill done() 1271063Sbill { 1281063Sbill 1291063Sbill if (tty) 1301063Sbill chmod(tty, mode); 1311063Sbill exit(0); 1321063Sbill } 1331063Sbill 1348789Smckusick /* numeric -- returns 1 if str is numeric, elsewise 0 */ 1358789Smckusick numeric(str) 1368789Smckusick char *str; 1378789Smckusick { 1388789Smckusick for (; *str ; str++) { 1398789Smckusick if (*str > '9' || *str < '0') { 1408789Smckusick return(0); 1418789Smckusick } 1428789Smckusick } 1438789Smckusick return(1); 1448789Smckusick } 1458789Smckusick 1461063Sbill onintr() 1471063Sbill { 1481063Sbill 1491063Sbill if (tty) 1501063Sbill chmod(tty, mode); 1511063Sbill _exit(1); 1521063Sbill } 1531063Sbill 1541063Sbill fixtty() 1551063Sbill { 1561063Sbill struct stat sbuf; 1571063Sbill 1581063Sbill tty = ttyname(1); 1591063Sbill if (tty == 0) 1601063Sbill return; 1611063Sbill stat(tty, &sbuf); 1621063Sbill mode = sbuf.st_mode&0777; 1631063Sbill chmod(tty, 0600); 1641063Sbill } 1651063Sbill 1668789Smckusick /* print -- print file */ 1671063Sbill print(fp, argp) 1681063Sbill char *fp; 1691063Sbill char **argp; 1701063Sbill { 1711063Sbill extern char *sprintf(); 1721063Sbill struct stat sbuf; 1731063Sbill register sncol; 1741063Sbill register char *sheader; 1751063Sbill register char *cbuf; 1761063Sbill char linebuf[150], *cp; 1771063Sbill 1781063Sbill if (ntflg) 1791063Sbill margin = 0; 1801063Sbill else 1811063Sbill margin = 10; 1821063Sbill if (length <= margin) 1831063Sbill length = 66; 1841063Sbill if (width <= 0) 1851063Sbill width = 72; 1861063Sbill if (ncol>72 || ncol>width) { 1871063Sbill fprintf(stderr, "pr: No room for columns.\n"); 1881063Sbill done(); 1891063Sbill } 1901063Sbill if (mflg) { 1911063Sbill mopen(argp); 1921063Sbill ncol = nofile; 1931063Sbill } 1941063Sbill colw = width/(ncol==0? 1 : ncol); 1951063Sbill sncol = ncol; 1961063Sbill sheader = header; 1971063Sbill plength = length-5; 1981063Sbill if (ntflg) 1991063Sbill plength = length; 2001063Sbill if (--ncol<0) 2011063Sbill ncol = 0; 2021063Sbill if (mflg) 2031063Sbill fp = 0; 2041063Sbill if (fp) { 2051063Sbill if((file=fopen(fp, "r"))==NULL) { 2061063Sbill if (tty==NULL) 2071063Sbill fprintf(stderr, "pr: can't open %s\n", fp); 2081063Sbill ncol = sncol; 2091063Sbill header = sheader; 2101063Sbill return; 2111063Sbill } 2121063Sbill stat(fp, &sbuf); 2131063Sbill } else { 2141063Sbill file = stdin; 2151063Sbill time(&sbuf.st_mtime); 2161063Sbill } 2171063Sbill if (header == 0) 2181063Sbill header = fp?fp:""; 2191063Sbill cbuf = ctime(&sbuf.st_mtime); 2201063Sbill cbuf[16] = '\0'; 2211063Sbill cbuf[24] = '\0'; 2221063Sbill page = 1; 2231063Sbill icol = 0; 2241063Sbill colp[ncol] = bufp = buffer; 2251063Sbill if (mflg==0) 2261063Sbill nexbuf(); 2271063Sbill while (mflg&&nofile || (!mflg)&&tpgetc(ncol)>0) { 2281063Sbill if (mflg==0) { 2291063Sbill colp[ncol]--; 2301063Sbill if (colp[ncol] < buffer) 2311063Sbill colp[ncol] = &buffer[BUFS]; 2321063Sbill } 2331063Sbill line = 0; 2341063Sbill if (ntflg==0) { 2351063Sbill if (fflg) { 2361063Sbill /* Assume a ff takes two blank lines at the 2371063Sbill top of the page. */ 2381063Sbill line = 2; 2391063Sbill sprintf(linebuf, "%s %s %s Page %d\n\n\n", 2401063Sbill cbuf+4, cbuf+20, header, page); 2411063Sbill } else 2421063Sbill sprintf(linebuf, "\n\n%s %s %s Page %d\n\n\n", 2431063Sbill cbuf+4, cbuf+20, header, page); 2441063Sbill for(cp=linebuf;*cp;) put(*cp++); 2451063Sbill } 2461063Sbill putpage(); 2471063Sbill if (ntflg==0) { 2481063Sbill if (fflg) 2491063Sbill put('\f'); 2501063Sbill else 2511063Sbill while(line<length) 2521063Sbill put('\n'); 2531063Sbill } 2541063Sbill page++; 2551063Sbill } 2561063Sbill fclose(file); 2571063Sbill ncol = sncol; 2581063Sbill header = sheader; 2591063Sbill } 2601063Sbill 2611063Sbill mopen(ap) 2621063Sbill char **ap; 2631063Sbill { 2641063Sbill register char **p, *p1; 2651063Sbill 2661063Sbill p = ap; 2671063Sbill while((p1 = *p) && p++ <= lastarg) { 2681063Sbill if((ifile[nofile]=fopen(p1, "r")) == NULL){ 2691063Sbill isclosed[nofile] = 1; 2701063Sbill nofile--; 2711063Sbill } 2721063Sbill else 2731063Sbill isclosed[nofile] = 0; 2741063Sbill if(++nofile>=10) { 2751063Sbill fprintf(stderr, "pr: Too many args\n"); 2761063Sbill done(); 2771063Sbill } 2781063Sbill } 2791063Sbill } 2801063Sbill 2811063Sbill putpage() 2821063Sbill { 2831063Sbill register int lastcol, i, c; 2841063Sbill int j; 2851063Sbill 2861063Sbill if (ncol==0) { 2871063Sbill while (line<plength) { 2881063Sbill while((c = tpgetc(0)) && c!='\n' && c!=FF) 2891063Sbill putcp(c); 290*11274Slayer if (c==0) break; 2911063Sbill putcp('\n'); 2921063Sbill line++; 2931063Sbill if (c==FF) 2941063Sbill break; 2951063Sbill } 2961063Sbill return; 2971063Sbill } 2981063Sbill colp[0] = colp[ncol]; 2991063Sbill if (mflg==0) for (i=1; i<=ncol; i++) { 3001063Sbill colp[i] = colp[i-1]; 3011063Sbill for (j = margin; j<length; j++) 3021063Sbill while((c=tpgetc(i))!='\n') 3031063Sbill if (c==0) 3041063Sbill break; 3051063Sbill } 3061063Sbill while (line<plength) { 3071063Sbill lastcol = colw; 3081063Sbill for (i=0; i<ncol; i++) { 3091063Sbill while ((c=pgetc(i)) && c!='\n') 3101063Sbill if (col<lastcol || tabc!=0) 3111063Sbill put(c); 3121063Sbill if (c==0) 3131063Sbill continue; 3141063Sbill if (tabc) 3151063Sbill put(tabc); 3161063Sbill else while (col<lastcol) 3171063Sbill put(' '); 3181063Sbill lastcol += colw; 3191063Sbill } 3201063Sbill while ((c = pgetc(ncol)) && c!='\n') 3211063Sbill put(c); 3221063Sbill put('\n'); 3231063Sbill } 3241063Sbill } 3251063Sbill 3261063Sbill nexbuf() 3271063Sbill { 3281063Sbill register int n; 3291063Sbill register char *rbufp; 3301063Sbill 3311063Sbill rbufp = bufp; 3321063Sbill n = &buffer[BUFS] - rbufp; 3331063Sbill if (n>512) 3341063Sbill n = 512; 3351063Sbill if((n=fread(rbufp,1,n,file)) <= 0){ 3361063Sbill fclose(file); 3371063Sbill *rbufp = 0376; 3381063Sbill } 3391063Sbill else { 3401063Sbill rbufp += n; 3411063Sbill if (rbufp >= &buffer[BUFS]) 3421063Sbill rbufp = buffer; 3431063Sbill *rbufp = 0375; 3441063Sbill } 3451063Sbill bufp = rbufp; 3461063Sbill } 3471063Sbill 3481063Sbill tpgetc(ai) 3491063Sbill { 3501063Sbill register char **p; 3511063Sbill register int c, i; 3521063Sbill 3531063Sbill i = ai; 3541063Sbill if (mflg) { 3551063Sbill if((c=getc(ifile[i])) == EOF) { 3561063Sbill if (isclosed[i]==0) { 3571063Sbill isclosed[i] = 1; 3581063Sbill if (--nofile <= 0) 3591063Sbill return(0); 3601063Sbill } 3611063Sbill return('\n'); 3621063Sbill } 3631063Sbill if (c==FF && ncol>0) 3641063Sbill c = '\n'; 3651063Sbill return(c); 3661063Sbill } 3671063Sbill loop: 3681063Sbill c = **(p = &colp[i]) & 0377; 3691063Sbill if (c == 0375) { 3701063Sbill nexbuf(); 3711063Sbill c = **p & 0377; 3721063Sbill } 3731063Sbill if (c == 0376) 3741063Sbill return(0); 3751063Sbill (*p)++; 3761063Sbill if (*p >= &buffer[BUFS]) 3771063Sbill *p = buffer; 3781063Sbill if (c==0) 3791063Sbill goto loop; 3801063Sbill return(c); 3811063Sbill } 3821063Sbill 3831063Sbill pgetc(i) 3841063Sbill { 3851063Sbill register int c; 3861063Sbill 3871063Sbill if (peekc) { 3881063Sbill c = peekc; 3891063Sbill peekc = 0; 3901063Sbill } else 3911063Sbill c = tpgetc(i); 3921063Sbill if (tabc) 3931063Sbill return(c); 3941063Sbill switch (c) { 3951063Sbill 3961063Sbill case '\t': 3971063Sbill icol++; 3981063Sbill if ((icol&07) != 0) 3991063Sbill peekc = '\t'; 4001063Sbill return(' '); 4011063Sbill 4021063Sbill case '\n': 4031063Sbill icol = 0; 4041063Sbill break; 4051063Sbill 4061063Sbill case 010: 4071063Sbill case 033: 4081063Sbill icol--; 4091063Sbill break; 4101063Sbill } 4111063Sbill if (c >= ' ') 4121063Sbill icol++; 4131063Sbill return(c); 4141063Sbill } 4151063Sbill put(ac) 4161063Sbill { 4171063Sbill register int ns, c; 4181063Sbill 4191063Sbill c = ac; 4201063Sbill if (tabc) { 4211063Sbill putcp(c); 4221063Sbill if (c=='\n') 4231063Sbill line++; 4241063Sbill return; 4251063Sbill } 4261063Sbill switch (c) { 4271063Sbill 4281063Sbill case ' ': 4291063Sbill nspace++; 4301063Sbill col++; 4311063Sbill return; 4321063Sbill 4331063Sbill case '\n': 4341063Sbill col = 0; 4351063Sbill nspace = 0; 4361063Sbill line++; 4371063Sbill break; 4381063Sbill 4391063Sbill case 010: 4401063Sbill case 033: 4411063Sbill if (--col<0) 4421063Sbill col = 0; 4431063Sbill if (--nspace<0) 4441063Sbill nspace = 0; 4451063Sbill 4461063Sbill } 4471063Sbill while(nspace) { 4481063Sbill if (nspace>2 && col > (ns=((col-nspace)|07))) { 4491063Sbill nspace = col-ns-1; 4501063Sbill putcp('\t'); 4511063Sbill } else { 4521063Sbill nspace--; 4531063Sbill putcp(' '); 4541063Sbill } 4551063Sbill } 4561063Sbill if (c >= ' ') 4571063Sbill col++; 4581063Sbill putcp(c); 4591063Sbill } 460