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