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