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