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