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