1 #ifndef lint 2 static char sccsid[] = "@(#)old.bin.grep.c 4.8 (Berkeley) 01/21/88"; 3 #endif 4 5 /* 6 * grep -- print lines matching (or not matching) a pattern 7 * 8 * status returns: 9 * 0 - ok, and some matches 10 * 1 - ok, but no matches 11 * 2 - some error 12 */ 13 14 #include <stdio.h> 15 #include <ctype.h> 16 17 #define CBRA 1 18 #define CCHR 2 19 #define CDOT 4 20 #define CCL 6 21 #define NCCL 8 22 #define CDOL 10 23 #define CEOF 11 24 #define CKET 12 25 #define CBRC 14 26 #define CLET 15 27 #define CBACK 18 28 29 #define STAR 01 30 31 #define LBSIZE BUFSIZ 32 #define ESIZE 256 33 #define NBRA 9 34 35 char expbuf[ESIZE]; 36 long lnum; 37 char linebuf[LBSIZE+1]; 38 char ybuf[ESIZE]; 39 int bflag; 40 int lflag; 41 int nflag; 42 int cflag; 43 int vflag; 44 int nfile; 45 int hflag = 1; 46 int oflag; 47 int sflag; 48 int yflag; 49 int wflag; 50 int retcode = 0; 51 int circf; 52 int blkno; 53 long tln; 54 int nsucc; 55 char *braslist[NBRA]; 56 char *braelist[NBRA]; 57 char bittab[] = { 58 1, 59 2, 60 4, 61 8, 62 16, 63 32, 64 64, 65 128 66 }; 67 68 main(argc, argv) 69 int argc; 70 char **argv; 71 { 72 extern char *optarg; 73 extern int optind; 74 int ch; 75 76 while ((ch = getopt(argc, argv, "iywohsvblcne")) != EOF) 77 switch((char)ch) { 78 case 'i': 79 case 'y': 80 yflag++; 81 break; 82 case 'w': 83 wflag++; 84 break; 85 case 'o': 86 oflag++; 87 break; 88 case 'h': 89 hflag = 0; 90 break; 91 case 's': 92 sflag++; 93 break; 94 case 'v': 95 vflag++; 96 break; 97 case 'b': 98 bflag++; 99 break; 100 case 'l': 101 lflag++; 102 break; 103 case 'c': 104 cflag++; 105 break; 106 case 'n': 107 nflag++; 108 break; 109 case 'e': 110 argv += optind; 111 argc -= optind; 112 *argv = optarg; 113 goto out; 114 case '?': 115 default: 116 errexit("grep: unknown flag\n", (char *)NULL); 117 } 118 argv += optind; 119 argc -= optind; 120 121 out: 122 if (argc<=0) 123 exit(2); 124 if (yflag) { 125 register char *p, *s; 126 for (s = ybuf, p = *argv; *p; ) { 127 if (*p == '\\') { 128 *s++ = *p++; 129 if (*p) 130 *s++ = *p++; 131 } else if (*p == '[') { 132 while (*p != '\0' && *p != ']') 133 *s++ = *p++; 134 } else if (islower(*p)) { 135 *s++ = '['; 136 *s++ = toupper(*p); 137 *s++ = *p++; 138 *s++ = ']'; 139 } else 140 *s++ = *p++; 141 if (s >= ybuf+ESIZE-5) 142 errexit("grep: argument too long\n", (char *)NULL); 143 } 144 *s = '\0'; 145 *argv = ybuf; 146 } 147 compile(*argv); 148 nfile = --argc; 149 if (argc<=0) { 150 if (lflag) 151 exit(1); 152 execute((char *)NULL); 153 } else while (--argc >= 0) { 154 argv++; 155 execute(*argv); 156 } 157 exit(retcode != 0 ? retcode : nsucc == 0); 158 } 159 160 compile(astr) 161 char *astr; 162 { 163 register c; 164 register char *ep, *sp; 165 char *cstart; 166 char *lastep; 167 int cclcnt; 168 char bracket[NBRA], *bracketp; 169 int closed; 170 char numbra; 171 char neg; 172 173 ep = expbuf; 174 sp = astr; 175 lastep = 0; 176 bracketp = bracket; 177 closed = numbra = 0; 178 if (*sp == '^') { 179 circf++; 180 sp++; 181 } 182 if (wflag) 183 *ep++ = CBRC; 184 for (;;) { 185 if (ep >= &expbuf[ESIZE]) 186 goto cerror; 187 if ((c = *sp++) != '*') 188 lastep = ep; 189 switch (c) { 190 191 case '\0': 192 if (wflag) 193 *ep++ = CLET; 194 *ep++ = CEOF; 195 return; 196 197 case '.': 198 *ep++ = CDOT; 199 continue; 200 201 case '*': 202 if (lastep==0 || *lastep==CBRA || *lastep==CKET || 203 *lastep == CBRC || *lastep == CLET) 204 goto defchar; 205 *lastep |= STAR; 206 continue; 207 208 case '$': 209 if (*sp != '\0') 210 goto defchar; 211 *ep++ = CDOL; 212 continue; 213 214 case '[': 215 if(&ep[17] >= &expbuf[ESIZE]) 216 goto cerror; 217 *ep++ = CCL; 218 neg = 0; 219 if((c = *sp++) == '^') { 220 neg = 1; 221 c = *sp++; 222 } 223 cstart = sp; 224 do { 225 if (c=='\0') 226 goto cerror; 227 if (c=='-' && sp>cstart && *sp!=']') { 228 for (c = sp[-2]; c<*sp; c++) 229 ep[c>>3] |= bittab[c&07]; 230 sp++; 231 } 232 ep[c>>3] |= bittab[c&07]; 233 } while((c = *sp++) != ']'); 234 if(neg) { 235 for(cclcnt = 0; cclcnt < 16; cclcnt++) 236 ep[cclcnt] ^= -1; 237 ep[0] &= 0376; 238 } 239 240 ep += 16; 241 242 continue; 243 244 case '\\': 245 if((c = *sp++) == 0) 246 goto cerror; 247 if(c == '<') { 248 *ep++ = CBRC; 249 continue; 250 } 251 if(c == '>') { 252 *ep++ = CLET; 253 continue; 254 } 255 if(c == '(') { 256 if(numbra >= NBRA) { 257 goto cerror; 258 } 259 *bracketp++ = numbra; 260 *ep++ = CBRA; 261 *ep++ = numbra++; 262 continue; 263 } 264 if(c == ')') { 265 if(bracketp <= bracket) { 266 goto cerror; 267 } 268 *ep++ = CKET; 269 *ep++ = *--bracketp; 270 closed++; 271 continue; 272 } 273 274 if(c >= '1' && c <= '9') { 275 if((c -= '1') >= closed) 276 goto cerror; 277 *ep++ = CBACK; 278 *ep++ = c; 279 continue; 280 } 281 282 defchar: 283 default: 284 *ep++ = CCHR; 285 *ep++ = c; 286 } 287 } 288 cerror: 289 errexit("grep: RE error\n", (char *)NULL); 290 } 291 292 execute(file) 293 char *file; 294 { 295 register char *p1, *p2; 296 register c; 297 298 if (file) { 299 if (freopen(file, "r", stdin) == NULL) { 300 perror(file); 301 retcode = 2; 302 } 303 } 304 lnum = 0; 305 tln = 0; 306 for (;;) { 307 lnum++; 308 p1 = linebuf; 309 while ((c = getchar()) != '\n') { 310 if (c == EOF) { 311 if (cflag) { 312 if (nfile>1) 313 printf("%s:", file); 314 printf("%D\n", tln); 315 fflush(stdout); 316 } 317 return; 318 } 319 *p1++ = c; 320 if (p1 >= &linebuf[LBSIZE-1]) 321 break; 322 } 323 *p1++ = '\0'; 324 p1 = linebuf; 325 p2 = expbuf; 326 if (circf) { 327 if (advance(p1, p2)) 328 goto found; 329 goto nfound; 330 } 331 /* fast check for first character */ 332 if (*p2==CCHR) { 333 c = p2[1]; 334 do { 335 if (*p1!=c) 336 continue; 337 if (advance(p1, p2)) 338 goto found; 339 } while (*p1++); 340 goto nfound; 341 } 342 /* regular algorithm */ 343 do { 344 if (advance(p1, p2)) 345 goto found; 346 } while (*p1++); 347 nfound: 348 if (vflag) 349 succeed(file); 350 continue; 351 found: 352 if (vflag==0) 353 succeed(file); 354 } 355 } 356 357 advance(lp, ep) 358 register char *lp, *ep; 359 { 360 register char *curlp; 361 char c; 362 char *bbeg; 363 int ct; 364 365 for (;;) switch (*ep++) { 366 367 case CCHR: 368 if (*ep++ == *lp++) 369 continue; 370 return(0); 371 372 case CDOT: 373 if (*lp++) 374 continue; 375 return(0); 376 377 case CDOL: 378 if (*lp==0) 379 continue; 380 return(0); 381 382 case CEOF: 383 return(1); 384 385 case CCL: 386 c = *lp++ & 0177; 387 if(ep[c>>3] & bittab[c & 07]) { 388 ep += 16; 389 continue; 390 } 391 return(0); 392 case CBRA: 393 braslist[*ep++] = lp; 394 continue; 395 396 case CKET: 397 braelist[*ep++] = lp; 398 continue; 399 400 case CBACK: 401 bbeg = braslist[*ep]; 402 if (braelist[*ep]==0) 403 return(0); 404 ct = braelist[*ep++] - bbeg; 405 if(ecmp(bbeg, lp, ct)) { 406 lp += ct; 407 continue; 408 } 409 return(0); 410 411 case CBACK|STAR: 412 bbeg = braslist[*ep]; 413 if (braelist[*ep]==0) 414 return(0); 415 ct = braelist[*ep++] - bbeg; 416 curlp = lp; 417 while(ecmp(bbeg, lp, ct)) 418 lp += ct; 419 while(lp >= curlp) { 420 if(advance(lp, ep)) return(1); 421 lp -= ct; 422 } 423 return(0); 424 425 426 case CDOT|STAR: 427 curlp = lp; 428 while (*lp++); 429 goto star; 430 431 case CCHR|STAR: 432 curlp = lp; 433 while (*lp++ == *ep); 434 ep++; 435 goto star; 436 437 case CCL|STAR: 438 curlp = lp; 439 do { 440 c = *lp++ & 0177; 441 } while(ep[c>>3] & bittab[c & 07]); 442 ep += 16; 443 goto star; 444 445 star: 446 if(--lp == curlp) { 447 continue; 448 } 449 450 if(*ep == CCHR) { 451 c = ep[1]; 452 do { 453 if(*lp != c) 454 continue; 455 if(advance(lp, ep)) 456 return(1); 457 } while(lp-- > curlp); 458 return(0); 459 } 460 461 do { 462 if (advance(lp, ep)) 463 return(1); 464 } while (lp-- > curlp); 465 return(0); 466 467 case CBRC: 468 if (lp == expbuf) 469 continue; 470 #define uletter(c) (isalpha(c) || (c) == '_') 471 if (uletter(*lp) || isdigit(*lp)) 472 if (!uletter(lp[-1]) && !isdigit(lp[-1])) 473 continue; 474 return (0); 475 476 case CLET: 477 if (!uletter(*lp) && !isdigit(*lp)) 478 continue; 479 return (0); 480 481 default: 482 errexit("grep RE botch\n", (char *)NULL); 483 } 484 } 485 486 succeed(f) 487 char *f; 488 { 489 nsucc = 1; 490 if (sflag) 491 return; 492 if (cflag) { 493 tln++; 494 return; 495 } 496 if (lflag) { 497 printf("%s\n", f); 498 fflush(stdout); 499 fseek(stdin, 0l, 2); 500 return; 501 } 502 if (nfile > 1 && hflag || oflag) 503 printf("%s:", f); 504 if (bflag) 505 printf("%u:", blkno); 506 if (nflag) 507 printf("%ld:", lnum); 508 printf("%s\n", linebuf); 509 fflush(stdout); 510 } 511 512 ecmp(a, b, count) 513 char *a, *b; 514 { 515 register cc = count; 516 while(cc--) 517 if(*a++ != *b++) return(0); 518 return(1); 519 } 520 521 errexit(s, f) 522 char *s, *f; 523 { 524 fprintf(stderr, s, f); 525 exit(2); 526 } 527