1 #ifndef lint 2 static char sccsid[] = "@(#)old.ucb.grep.c 4.3 (Berkeley) 08/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 } 431