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