|
|
1.1 root 1: static char *sccsid = "@(#)pr.c 4.1 (Berkeley) 10/1/80";
2: /*
3: * print file with headings
4: * 2+head+2+page[56]+5
5: */
6:
7: #include <stdio.h>
8: #include <signal.h>
9: #include <sys/types.h>
10: #include <sys/stat.h>
11:
12: /* Making putcp a macro sped things up by 14%. */
13: #define putcp(c) if (page >= fpage) putchar(c)
14:
15: int ncol = 1;
16: char *header;
17: int col;
18: int icol;
19: FILE *file;
20: char *bufp;
21: #define BUFS 6720
22: char buffer[BUFS]; /* for multi-column output */
23: char obuf[BUFSIZ];
24: #define FF 014
25: int line;
26: char *colp[72];
27: int nofile;
28: char isclosed[10];
29: FILE *ifile[10];
30: char **lastarg;
31: int peekc;
32: int fpage;
33: int page;
34: int colw;
35: int nspace;
36: int width = 72;
37: int length = 66;
38: int plength = 61;
39: int margin = 10;
40: int ntflg;
41: int fflg;
42: int mflg;
43: int tabc;
44: char *tty;
45: int mode;
46: char *ttyname();
47: char *ctime();
48:
49: main(argc, argv)
50: char **argv;
51: {
52: int nfdone;
53: int onintr();
54:
55: setbuf(stdout, obuf);
56: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
57: signal(SIGINT, onintr);
58: lastarg = &argv[argc-1];
59: fixtty();
60: for (nfdone=0; argc>1; argc--) {
61: argv++;
62: if (**argv == '-') {
63: switch (*++*argv) {
64: case 'h':
65: if (argc>=2) {
66: header = *++argv;
67: argc--;
68: }
69: continue;
70:
71: case 't':
72: ntflg++;
73: continue;
74:
75: case 'f':
76: fflg++;
77: plength = 60;
78: continue;
79:
80: case 'l':
81: length = atoi(++*argv);
82: continue;
83:
84: case 'w':
85: width = atoi(++*argv);
86: continue;
87:
88: case 's':
89: if (*++*argv)
90: tabc = **argv;
91: else
92: tabc = '\t';
93: continue;
94:
95: case 'm':
96: mflg++;
97: continue;
98:
99: default:
100: ncol = atoi(*argv);
101: continue;
102: }
103: } else if (**argv == '+') {
104: fpage = atoi(++*argv);
105: } else {
106: print(*argv, argv);
107: nfdone++;
108: if (mflg)
109: break;
110: }
111: }
112: if (nfdone==0)
113: print((char *)0, (char **)0);
114: done();
115: }
116:
117: done()
118: {
119:
120: if (tty)
121: chmod(tty, mode);
122: exit(0);
123: }
124:
125: onintr()
126: {
127:
128: if (tty)
129: chmod(tty, mode);
130: _exit(1);
131: }
132:
133: fixtty()
134: {
135: struct stat sbuf;
136:
137: tty = ttyname(1);
138: if (tty == 0)
139: return;
140: stat(tty, &sbuf);
141: mode = sbuf.st_mode&0777;
142: chmod(tty, 0600);
143: }
144:
145: print(fp, argp)
146: char *fp;
147: char **argp;
148: {
149: extern char *sprintf();
150: struct stat sbuf;
151: register sncol;
152: register char *sheader;
153: register char *cbuf;
154: char linebuf[150], *cp;
155:
156: if (ntflg)
157: margin = 0;
158: else
159: margin = 10;
160: if (length <= margin)
161: length = 66;
162: if (width <= 0)
163: width = 72;
164: if (ncol>72 || ncol>width) {
165: fprintf(stderr, "pr: No room for columns.\n");
166: done();
167: }
168: if (mflg) {
169: mopen(argp);
170: ncol = nofile;
171: }
172: colw = width/(ncol==0? 1 : ncol);
173: sncol = ncol;
174: sheader = header;
175: plength = length-5;
176: if (ntflg)
177: plength = length;
178: if (--ncol<0)
179: ncol = 0;
180: if (mflg)
181: fp = 0;
182: if (fp) {
183: if((file=fopen(fp, "r"))==NULL) {
184: if (tty==NULL)
185: fprintf(stderr, "pr: can't open %s\n", fp);
186: ncol = sncol;
187: header = sheader;
188: return;
189: }
190: stat(fp, &sbuf);
191: } else {
192: file = stdin;
193: time(&sbuf.st_mtime);
194: }
195: if (header == 0)
196: header = fp?fp:"";
197: cbuf = ctime(&sbuf.st_mtime);
198: cbuf[16] = '\0';
199: cbuf[24] = '\0';
200: page = 1;
201: icol = 0;
202: colp[ncol] = bufp = buffer;
203: if (mflg==0)
204: nexbuf();
205: while (mflg&&nofile || (!mflg)&&tpgetc(ncol)>0) {
206: if (mflg==0) {
207: colp[ncol]--;
208: if (colp[ncol] < buffer)
209: colp[ncol] = &buffer[BUFS];
210: }
211: line = 0;
212: if (ntflg==0) {
213: if (fflg) {
214: /* Assume a ff takes two blank lines at the
215: top of the page. */
216: line = 2;
217: sprintf(linebuf, "%s %s %s Page %d\n\n\n",
218: cbuf+4, cbuf+20, header, page);
219: } else
220: sprintf(linebuf, "\n\n%s %s %s Page %d\n\n\n",
221: cbuf+4, cbuf+20, header, page);
222: for(cp=linebuf;*cp;) put(*cp++);
223: }
224: putpage();
225: if (ntflg==0) {
226: if (fflg)
227: put('\f');
228: else
229: while(line<length)
230: put('\n');
231: }
232: page++;
233: }
234: fclose(file);
235: ncol = sncol;
236: header = sheader;
237: }
238:
239: mopen(ap)
240: char **ap;
241: {
242: register char **p, *p1;
243:
244: p = ap;
245: while((p1 = *p) && p++ <= lastarg) {
246: if((ifile[nofile]=fopen(p1, "r")) == NULL){
247: isclosed[nofile] = 1;
248: nofile--;
249: }
250: else
251: isclosed[nofile] = 0;
252: if(++nofile>=10) {
253: fprintf(stderr, "pr: Too many args\n");
254: done();
255: }
256: }
257: }
258:
259: putpage()
260: {
261: register int lastcol, i, c;
262: int j;
263:
264: if (ncol==0) {
265: while (line<plength) {
266: while((c = tpgetc(0)) && c!='\n' && c!=FF)
267: putcp(c);
268: putcp('\n');
269: line++;
270: if (c==FF)
271: break;
272: }
273: return;
274: }
275: colp[0] = colp[ncol];
276: if (mflg==0) for (i=1; i<=ncol; i++) {
277: colp[i] = colp[i-1];
278: for (j = margin; j<length; j++)
279: while((c=tpgetc(i))!='\n')
280: if (c==0)
281: break;
282: }
283: while (line<plength) {
284: lastcol = colw;
285: for (i=0; i<ncol; i++) {
286: while ((c=pgetc(i)) && c!='\n')
287: if (col<lastcol || tabc!=0)
288: put(c);
289: if (c==0)
290: continue;
291: if (tabc)
292: put(tabc);
293: else while (col<lastcol)
294: put(' ');
295: lastcol += colw;
296: }
297: while ((c = pgetc(ncol)) && c!='\n')
298: put(c);
299: put('\n');
300: }
301: }
302:
303: nexbuf()
304: {
305: register int n;
306: register char *rbufp;
307:
308: rbufp = bufp;
309: n = &buffer[BUFS] - rbufp;
310: if (n>512)
311: n = 512;
312: if((n=fread(rbufp,1,n,file)) <= 0){
313: fclose(file);
314: *rbufp = 0376;
315: }
316: else {
317: rbufp += n;
318: if (rbufp >= &buffer[BUFS])
319: rbufp = buffer;
320: *rbufp = 0375;
321: }
322: bufp = rbufp;
323: }
324:
325: tpgetc(ai)
326: {
327: register char **p;
328: register int c, i;
329:
330: i = ai;
331: if (mflg) {
332: if((c=getc(ifile[i])) == EOF) {
333: if (isclosed[i]==0) {
334: isclosed[i] = 1;
335: if (--nofile <= 0)
336: return(0);
337: }
338: return('\n');
339: }
340: if (c==FF && ncol>0)
341: c = '\n';
342: return(c);
343: }
344: loop:
345: c = **(p = &colp[i]) & 0377;
346: if (c == 0375) {
347: nexbuf();
348: c = **p & 0377;
349: }
350: if (c == 0376)
351: return(0);
352: (*p)++;
353: if (*p >= &buffer[BUFS])
354: *p = buffer;
355: if (c==0)
356: goto loop;
357: return(c);
358: }
359:
360: pgetc(i)
361: {
362: register int c;
363:
364: if (peekc) {
365: c = peekc;
366: peekc = 0;
367: } else
368: c = tpgetc(i);
369: if (tabc)
370: return(c);
371: switch (c) {
372:
373: case '\t':
374: icol++;
375: if ((icol&07) != 0)
376: peekc = '\t';
377: return(' ');
378:
379: case '\n':
380: icol = 0;
381: break;
382:
383: case 010:
384: case 033:
385: icol--;
386: break;
387: }
388: if (c >= ' ')
389: icol++;
390: return(c);
391: }
392: put(ac)
393: {
394: register int ns, c;
395:
396: c = ac;
397: if (tabc) {
398: putcp(c);
399: if (c=='\n')
400: line++;
401: return;
402: }
403: switch (c) {
404:
405: case ' ':
406: nspace++;
407: col++;
408: return;
409:
410: case '\n':
411: col = 0;
412: nspace = 0;
413: line++;
414: break;
415:
416: case 010:
417: case 033:
418: if (--col<0)
419: col = 0;
420: if (--nspace<0)
421: nspace = 0;
422:
423: }
424: while(nspace) {
425: if (nspace>2 && col > (ns=((col-nspace)|07))) {
426: nspace = col-ns-1;
427: putcp('\t');
428: } else {
429: nspace--;
430: putcp(' ');
431: }
432: }
433: if (c >= ' ')
434: col++;
435: putcp(c);
436: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.