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