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