added perror
[unix-history] / usr / src / usr.bin / grep / old.bin.grep / old.bin.grep.c
CommitLineData
78d90aa3 1/* old.bin.grep.c 4.3 83/04/29 */
49d08d24
KM
2
3/*
4 * grep -- print lines matching (or not matching) a pattern
5 *
6 * status returns:
7 * 0 - ok, and some matches
8 * 1 - ok, but no matches
9 * 2 - some error
10 */
11
12#include <stdio.h>
13#include <ctype.h>
14
15#define CBRA 1
16#define CCHR 2
17#define CDOT 4
18#define CCL 6
19#define NCCL 8
20#define CDOL 10
21#define CEOF 11
22#define CKET 12
23#define CBACK 18
24
25#define STAR 01
26
27#define LBSIZE BUFSIZ
28#define ESIZE 256
29#define NBRA 9
30
31char expbuf[ESIZE];
32long lnum;
33char linebuf[LBSIZE+1];
34char ybuf[ESIZE];
35int bflag;
36int lflag;
37int nflag;
38int cflag;
39int vflag;
40int nfile;
41int hflag = 1;
42int sflag;
43int yflag;
b6920e2a 44int retcode = 0;
49d08d24
KM
45int circf;
46int blkno;
47long tln;
48int nsucc;
49char *braslist[NBRA];
50char *braelist[NBRA];
51char bittab[] = {
52 1,
53 2,
54 4,
55 8,
56 16,
57 32,
58 64,
59 128
60};
61
62main(argc, argv)
63char **argv;
64{
65 extern char _sobuf[];
66 setbuf(stdout, _sobuf);
67 while (--argc > 0 && (++argv)[0][0]=='-')
68 switch (argv[0][1]) {
69
70 case 'y':
71 yflag++;
72 continue;
73
74 case 'h':
75 hflag = 0;
76 continue;
77
78 case 's':
79 sflag++;
80 continue;
81
82 case 'v':
83 vflag++;
84 continue;
85
86 case 'b':
87 bflag++;
88 continue;
89
90 case 'l':
91 lflag++;
92 continue;
93
94 case 'c':
95 cflag++;
96 continue;
97
98 case 'n':
99 nflag++;
100 continue;
101
102 case 'e':
103 --argc;
104 ++argv;
105 goto out;
106
107 default:
108 errexit("grep: unknown flag\n", (char *)NULL);
109 continue;
110 }
111out:
112 if (argc<=0)
113 exit(2);
114 if (yflag) {
115 register char *p, *s;
116 for (s = ybuf, p = *argv; *p; ) {
117 if (*p == '\\') {
118 *s++ = *p++;
119 if (*p)
120 *s++ = *p++;
121 } else if (*p == '[') {
122 while (*p != '\0' && *p != ']')
123 *s++ = *p++;
124 } else if (islower(*p)) {
125 *s++ = '[';
126 *s++ = toupper(*p);
127 *s++ = *p++;
128 *s++ = ']';
129 } else
130 *s++ = *p++;
131 if (s >= ybuf+ESIZE-5)
132 errexit("grep: argument too long\n", (char *)NULL);
133 }
134 *s = '\0';
135 *argv = ybuf;
136 }
137 compile(*argv);
138 nfile = --argc;
139 if (argc<=0) {
140 if (lflag)
141 exit(1);
142 execute((char *)NULL);
143 } else while (--argc >= 0) {
144 argv++;
145 execute(*argv);
146 }
b6920e2a 147 exit(retcode != 0 ? retcode : nsucc == 0);
49d08d24
KM
148}
149
150compile(astr)
151char *astr;
152{
153 register c;
154 register char *ep, *sp;
155 char *cstart;
156 char *lastep;
157 int cclcnt;
158 char bracket[NBRA], *bracketp;
159 int closed;
160 char numbra;
161 char neg;
162
163 ep = expbuf;
164 sp = astr;
165 lastep = 0;
166 bracketp = bracket;
167 closed = numbra = 0;
168 if (*sp == '^') {
169 circf++;
170 sp++;
171 }
172 for (;;) {
173 if (ep >= &expbuf[ESIZE])
174 goto cerror;
175 if ((c = *sp++) != '*')
176 lastep = ep;
177 switch (c) {
178
179 case '\0':
180 *ep++ = CEOF;
181 return;
182
183 case '.':
184 *ep++ = CDOT;
185 continue;
186
187 case '*':
188 if (lastep==0 || *lastep==CBRA || *lastep==CKET)
189 goto defchar;
190 *lastep |= STAR;
191 continue;
192
193 case '$':
194 if (*sp != '\0')
195 goto defchar;
196 *ep++ = CDOL;
197 continue;
198
199 case '[':
200 if(&ep[17] >= &expbuf[ESIZE])
201 goto cerror;
202 *ep++ = CCL;
203 neg = 0;
204 if((c = *sp++) == '^') {
205 neg = 1;
206 c = *sp++;
207 }
208 cstart = sp;
209 do {
210 if (c=='\0')
211 goto cerror;
212 if (c=='-' && sp>cstart && *sp!=']') {
213 for (c = sp[-2]; c<*sp; c++)
214 ep[c>>3] |= bittab[c&07];
215 sp++;
216 }
217 ep[c>>3] |= bittab[c&07];
218 } while((c = *sp++) != ']');
219 if(neg) {
220 for(cclcnt = 0; cclcnt < 16; cclcnt++)
221 ep[cclcnt] ^= -1;
222 ep[0] &= 0376;
223 }
224
225 ep += 16;
226
227 continue;
228
229 case '\\':
230 if((c = *sp++) == '(') {
231 if(numbra >= NBRA) {
232 goto cerror;
233 }
234 *bracketp++ = numbra;
235 *ep++ = CBRA;
236 *ep++ = numbra++;
237 continue;
238 }
239 if(c == ')') {
240 if(bracketp <= bracket) {
241 goto cerror;
242 }
243 *ep++ = CKET;
244 *ep++ = *--bracketp;
245 closed++;
246 continue;
247 }
248
249 if(c >= '1' && c <= '9') {
250 if((c -= '1') >= closed)
251 goto cerror;
252 *ep++ = CBACK;
253 *ep++ = c;
254 continue;
255 }
256
257 defchar:
258 default:
259 *ep++ = CCHR;
260 *ep++ = c;
261 }
262 }
263 cerror:
264 errexit("grep: RE error\n", (char *)NULL);
265}
266
267execute(file)
268char *file;
269{
270 register char *p1, *p2;
271 register c;
272
273 if (file) {
b6920e2a 274 if (freopen(file, "r", stdin) == NULL) {
78d90aa3 275 perror(file);
b6920e2a
EW
276 retcode = 2;
277 }
49d08d24
KM
278 }
279 lnum = 0;
280 tln = 0;
281 for (;;) {
282 lnum++;
283 p1 = linebuf;
284 while ((c = getchar()) != '\n') {
285 if (c == EOF) {
286 if (cflag) {
287 if (nfile>1)
288 printf("%s:", file);
289 printf("%D\n", tln);
290 fflush(stdout);
291 }
292 return;
293 }
294 *p1++ = c;
295 if (p1 >= &linebuf[LBSIZE-1])
296 break;
297 }
298 *p1++ = '\0';
299 p1 = linebuf;
300 p2 = expbuf;
301 if (circf) {
302 if (advance(p1, p2))
303 goto found;
304 goto nfound;
305 }
306 /* fast check for first character */
307 if (*p2==CCHR) {
308 c = p2[1];
309 do {
310 if (*p1!=c)
311 continue;
312 if (advance(p1, p2))
313 goto found;
314 } while (*p1++);
315 goto nfound;
316 }
317 /* regular algorithm */
318 do {
319 if (advance(p1, p2))
320 goto found;
321 } while (*p1++);
322 nfound:
323 if (vflag)
324 succeed(file);
325 continue;
326 found:
327 if (vflag==0)
328 succeed(file);
329 }
330}
331
332advance(lp, ep)
333register char *lp, *ep;
334{
335 register char *curlp;
336 char c;
337 char *bbeg;
338 int ct;
339
340 for (;;) switch (*ep++) {
341
342 case CCHR:
343 if (*ep++ == *lp++)
344 continue;
345 return(0);
346
347 case CDOT:
348 if (*lp++)
349 continue;
350 return(0);
351
352 case CDOL:
353 if (*lp==0)
354 continue;
355 return(0);
356
357 case CEOF:
358 return(1);
359
360 case CCL:
361 c = *lp++ & 0177;
362 if(ep[c>>3] & bittab[c & 07]) {
363 ep += 16;
364 continue;
365 }
366 return(0);
367 case CBRA:
368 braslist[*ep++] = lp;
369 continue;
370
371 case CKET:
372 braelist[*ep++] = lp;
373 continue;
374
375 case CBACK:
376 bbeg = braslist[*ep];
377 if (braelist[*ep]==0)
378 return(0);
379 ct = braelist[*ep++] - bbeg;
380 if(ecmp(bbeg, lp, ct)) {
381 lp += ct;
382 continue;
383 }
384 return(0);
385
386 case CBACK|STAR:
387 bbeg = braslist[*ep];
388 if (braelist[*ep]==0)
389 return(0);
390 ct = braelist[*ep++] - bbeg;
391 curlp = lp;
392 while(ecmp(bbeg, lp, ct))
393 lp += ct;
394 while(lp >= curlp) {
395 if(advance(lp, ep)) return(1);
396 lp -= ct;
397 }
398 return(0);
399
400
401 case CDOT|STAR:
402 curlp = lp;
403 while (*lp++);
404 goto star;
405
406 case CCHR|STAR:
407 curlp = lp;
408 while (*lp++ == *ep);
409 ep++;
410 goto star;
411
412 case CCL|STAR:
413 curlp = lp;
414 do {
415 c = *lp++ & 0177;
416 } while(ep[c>>3] & bittab[c & 07]);
417 ep += 16;
418 goto star;
419
420 star:
421 if(--lp == curlp) {
422 continue;
423 }
424
425 if(*ep == CCHR) {
426 c = ep[1];
427 do {
428 if(*lp != c)
429 continue;
430 if(advance(lp, ep))
431 return(1);
432 } while(lp-- > curlp);
433 return(0);
434 }
435
436 do {
437 if (advance(lp, ep))
438 return(1);
439 } while (lp-- > curlp);
440 return(0);
441
442 default:
443 errexit("grep RE botch\n", (char *)NULL);
444 }
445}
446
447succeed(f)
448char *f;
449{
450 nsucc = 1;
451 if (sflag)
452 return;
453 if (cflag) {
454 tln++;
455 return;
456 }
457 if (lflag) {
458 printf("%s\n", f);
459 fflush(stdout);
460 fseek(stdin, 0l, 2);
461 return;
462 }
463 if (nfile > 1 && hflag)
464 printf("%s:", f);
465 if (bflag)
466 printf("%u:", blkno);
467 if (nflag)
468 printf("%ld:", lnum);
469 printf("%s\n", linebuf);
470 fflush(stdout);
471}
472
473ecmp(a, b, count)
474char *a, *b;
475{
476 register cc = count;
477 while(cc--)
478 if(*a++ != *b++) return(0);
479 return(1);
480}
481
482errexit(s, f)
483char *s, *f;
484{
485 fprintf(stderr, s, f);
486 exit(2);
487}