1 /* old.ucb.grep.c 4.1 82/05/07 */ 2 3 #include <stdio.h> 4 /* 5 * grep -- print lines matching (or not matching) a pattern 6 */ 7 8 #define CCHR 2 9 #define CDOT 4 10 #define CCL 6 11 #define NCCL 8 12 #define CDOL 10 13 #define CEOF 11 14 15 #define CBRC 14 16 #define CLET 15 17 #define STAR 01 18 19 #define LBSIZE BUFSIZ 20 #define ESIZE 256 21 22 char expbuf[ESIZE]; 23 long lnum; 24 char linebuf[LBSIZE+1]; 25 int bflag; 26 int nflag; 27 int cflag; 28 int vflag; 29 int nfile; 30 int iflag; 31 int lflag; 32 int wflag; 33 int sflag; 34 int nsucc; 35 int circf; 36 int blkno; 37 char ibuf[BUFSIZ]; 38 long tln; 39 40 main(argc, argv) 41 char **argv; 42 { 43 char obuf[BUFSIZ]; 44 45 setbuf(stdout, obuf); 46 while (--argc > 0 && (++argv)[0][0]=='-') { 47 char *cp = argv[0] + 1; 48 while (*cp) switch (*cp++) { 49 50 case 'v': 51 vflag++; 52 continue; 53 54 case 'b': 55 bflag++; 56 continue; 57 58 case 'i': 59 case 'y': /* -y for compatibility with btl grep */ 60 iflag++; 61 continue; 62 63 case 'l': 64 lflag++; 65 case 'c': 66 cflag++; 67 continue; 68 69 case 'w': 70 wflag++; 71 continue; 72 73 case 's': 74 sflag++; 75 continue; 76 77 case 'n': 78 nflag++; 79 continue; 80 81 case 'e': 82 --argc; 83 ++argv; 84 goto out; 85 86 default: 87 fprintf(stderr, "Unknown flag\n"); 88 continue; 89 } 90 } 91 out: 92 if (argc<=0) 93 exit(2); 94 compile(*argv); 95 nfile = --argc; 96 if (argc<=0) { 97 if (lflag) 98 exit(1); 99 execute(0); 100 } 101 else while (--argc >= 0) { 102 argv++; 103 execute(*argv); 104 } 105 exit(nsucc == 0); 106 } 107 108 compile(astr) 109 char *astr; 110 { 111 register c; 112 register char *ep, *sp; 113 char *lastep; 114 int cclcnt; 115 116 ep = expbuf; 117 sp = astr; 118 if (*sp == '^') { 119 circf++; 120 sp++; 121 } 122 if (wflag) 123 *ep++ = CBRC; 124 for (;;) { 125 if (ep >= &expbuf[ESIZE]) 126 goto cerror; 127 if ((c = *sp++) != '*') 128 lastep = ep; 129 switch (c) { 130 131 case '\0': 132 if (wflag) 133 *ep++ = CLET; 134 *ep++ = CEOF; 135 return; 136 137 case '.': 138 *ep++ = CDOT; 139 continue; 140 141 case '*': 142 if (lastep==0) 143 goto defchar; 144 *lastep |= STAR; 145 continue; 146 147 case '$': 148 if (*sp != '\0') 149 goto defchar; 150 *ep++ = CDOL; 151 continue; 152 153 case '[': 154 *ep++ = CCL; 155 *ep++ = 0; 156 cclcnt = 1; 157 if ((c = *sp++) == '^') { 158 c = *sp++; 159 ep[-2] = NCCL; 160 } 161 do { 162 *ep++ = c; 163 cclcnt++; 164 if (c=='\0' || ep >= &expbuf[ESIZE]) 165 goto cerror; 166 } while ((c = *sp++) != ']'); 167 lastep[1] = cclcnt; 168 continue; 169 170 case '\\': 171 if ((c = *sp++) == '\0') 172 goto cerror; 173 if (c == '<') { 174 *ep++ = CBRC; 175 continue; 176 } 177 if (c == '>') { 178 *ep++ = CLET; 179 continue; 180 } 181 defchar: 182 default: 183 *ep++ = CCHR; 184 *ep++ = c; 185 } 186 } 187 cerror: 188 fprintf(stderr, "RE error\n"); 189 } 190 191 same(a, b) 192 register int a, b; 193 { 194 195 return (a == b || iflag && (a ^ b) == ' ' && letter(a) == letter(b)); 196 } 197 198 letter(c) 199 register int c; 200 { 201 202 if (c >= 'a' && c <= 'z') 203 return (c); 204 if (c >= 'A' && c <= 'Z') 205 return (c + 'a' - 'A'); 206 return (0); 207 } 208 209 execute(file) 210 { 211 register char *p1, *p2; 212 register c; 213 int f; 214 char *ebp, *cbp; 215 216 if (file) { 217 if ((f = open(file, 0)) < 0) { 218 fprintf(stderr, "Can't open %s\n", file); 219 } 220 } else 221 f = 0; 222 ebp = ibuf; 223 cbp = ibuf; 224 lnum = 0; 225 tln = 0; 226 blkno = -1; 227 for (;;) { 228 lnum++; 229 if((lnum&0377) == 0) 230 fflush(stdout); 231 p1 = linebuf; 232 p2 = cbp; 233 for (;;) { 234 if (p2 >= ebp) { 235 if ((c = read(f, ibuf, BUFSIZ)) <= 0) { 236 close(f); 237 if (cflag) { 238 if (lflag) { 239 if (tln) 240 printf("%s\n", file); 241 } else { 242 if (nfile > 1) 243 printf("%s:", file); 244 printf("%ld\n", tln); 245 } 246 } 247 return; 248 } 249 blkno++; 250 p2 = ibuf; 251 ebp = ibuf+c; 252 } 253 if ((c = *p2++) == '\n') 254 break; 255 if(c) 256 if (p1 < &linebuf[LBSIZE-1]) 257 *p1++ = c; 258 } 259 *p1++ = 0; 260 cbp = p2; 261 p1 = linebuf; 262 p2 = expbuf; 263 if (circf) { 264 if (advance(p1, p2)) 265 goto found; 266 goto nfound; 267 } 268 /* fast check for first character */ 269 if (*p2==CCHR) { 270 c = p2[1]; 271 do { 272 if (*p1!=c && (!iflag || (c ^ *p1) != ' ' 273 || letter(c) != letter(*p1))) 274 continue; 275 if (advance(p1, p2)) 276 goto found; 277 } while (*p1++); 278 goto nfound; 279 } 280 /* regular algorithm */ 281 do { 282 if (advance(p1, p2)) 283 goto found; 284 } while (*p1++); 285 nfound: 286 if (vflag) 287 succeed(file); 288 continue; 289 found: 290 if (vflag==0) 291 succeed(file); 292 } 293 } 294 295 advance(alp, aep) 296 char *alp, *aep; 297 { 298 register char *lp, *ep, *curlp; 299 char *nextep; 300 301 lp = alp; 302 ep = aep; 303 for (;;) switch (*ep++) { 304 305 case CCHR: 306 if (!same(*ep, *lp)) 307 return (0); 308 ep++, lp++; 309 continue; 310 311 case CDOT: 312 if (*lp++) 313 continue; 314 return(0); 315 316 case CDOL: 317 if (*lp==0) 318 continue; 319 return(0); 320 321 case CEOF: 322 return(1); 323 324 case CCL: 325 if (cclass(ep, *lp++, 1)) { 326 ep += *ep; 327 continue; 328 } 329 return(0); 330 331 case NCCL: 332 if (cclass(ep, *lp++, 0)) { 333 ep += *ep; 334 continue; 335 } 336 return(0); 337 338 case CDOT|STAR: 339 curlp = lp; 340 while (*lp++); 341 goto star; 342 343 case CCHR|STAR: 344 curlp = lp; 345 while (same(*lp, *ep)) 346 lp++; 347 lp++; 348 ep++; 349 goto star; 350 351 case CCL|STAR: 352 case NCCL|STAR: 353 curlp = lp; 354 while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); 355 ep += *ep; 356 goto star; 357 358 star: 359 do { 360 lp--; 361 if (advance(lp, ep)) 362 return(1); 363 } while (lp > curlp); 364 return(0); 365 366 case CBRC: 367 if (lp == expbuf) 368 continue; 369 #define uletter(c) (letter(c) || c == '_') 370 if ( ( uletter(*lp) || digit ( * lp ) ) && !uletter(lp[-1]) && !digit(lp[-1])) 371 continue; 372 return (0); 373 374 case CLET: 375 if (!uletter(*lp) && !digit(*lp)) 376 continue; 377 return (0); 378 379 default: 380 fprintf(stderr, "RE botch\n"); 381 } 382 } 383 384 cclass(aset, ac, af) 385 char *aset; 386 { 387 register char *set, c; 388 register n; 389 390 set = aset; 391 if ((c = ac) == 0) 392 return(0); 393 n = *set++; 394 while (--n) 395 if (n > 2 && set[1] == '-') { 396 if (c >= (set[0] & 0177) && c <= (set[2] & 0177)) 397 return (af); 398 set += 3; 399 n -= 2; 400 } else 401 if ((*set++ & 0177) == c) 402 return(af); 403 return(!af); 404 } 405 406 succeed(f) 407 { 408 nsucc = 1; 409 if (sflag) 410 return; 411 if (cflag) { 412 tln++; 413 return; 414 } 415 if (nfile > 1) 416 printf("%s:", f); 417 if (bflag) 418 printf("%d:", blkno); 419 if (nflag) 420 printf("%ld:", lnum); 421 printf("%s\n", linebuf); 422 } 423 424 digit(c) 425 char c; 426 { 427 return (c>='0' && c<='9'); 428 } 429