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