fix search loop
[unix-history] / usr / src / old / pr / pr.c
CommitLineData
51fd0f79
BJ
1static char *sccsid = "@(#)pr.c 4.1 (Berkeley) %G%";
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
15int ncol = 1;
16char *header;
17int col;
18int icol;
19FILE *file;
20char *bufp;
21#define BUFS 6720
22char buffer[BUFS]; /* for multi-column output */
23char obuf[BUFSIZ];
24#define FF 014
25int line;
26char *colp[72];
27int nofile;
28char isclosed[10];
29FILE *ifile[10];
30char **lastarg;
31int peekc;
32int fpage;
33int page;
34int colw;
35int nspace;
36int width = 72;
37int length = 66;
38int plength = 61;
39int margin = 10;
40int ntflg;
41int fflg;
42int mflg;
43int tabc;
44char *tty;
45int mode;
46char *ttyname();
47char *ctime();
48
49main(argc, argv)
50char **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
117done()
118{
119
120 if (tty)
121 chmod(tty, mode);
122 exit(0);
123}
124
125onintr()
126{
127
128 if (tty)
129 chmod(tty, mode);
130 _exit(1);
131}
132
133fixtty()
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
145print(fp, argp)
146char *fp;
147char **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
239mopen(ap)
240char **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
259putpage()
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
303nexbuf()
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
325tpgetc(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 }
344loop:
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
360pgetc(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}
392put(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}