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