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