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