1 static char *sccsid = "@(#)old.fgrep.c 4.4 (Berkeley) 10/07/87"; 2 /* 3 * fgrep -- print all lines containing any of a set of keywords 4 * 5 * status returns: 6 * 0 - ok, and some matches 7 * 1 - ok, but no matches 8 * 2 - some error 9 */ 10 11 #include <stdio.h> 12 #include <ctype.h> 13 #include <sys/param.h> 14 #include <sys/stat.h> 15 16 #define BLKSIZE 8192 17 #define MAXSIZ 6000 18 #define QSIZE 400 19 struct words { 20 char inp; 21 char out; 22 struct words *nst; 23 struct words *link; 24 struct words *fail; 25 } w[MAXSIZ], *smax, *q; 26 27 long lnum; 28 int bflag, cflag, fflag, lflag, nflag, vflag, xflag, yflag; 29 int hflag = 1; 30 int oflag; 31 int sflag; 32 int retcode = 0; 33 int nfile; 34 long blkno; 35 int nsucc; 36 long tln; 37 FILE *wordf; 38 char *argptr; 39 40 main(argc, argv) 41 char **argv; 42 { 43 while (--argc > 0 && (++argv)[0][0]=='-') 44 switch (argv[0][1]) { 45 46 case 's': 47 sflag++; 48 continue; 49 50 case 'h': 51 hflag = 0; 52 continue; 53 54 case 'o': 55 oflag++; 56 continue; 57 58 case 'b': 59 bflag++; 60 continue; 61 62 case 'c': 63 cflag++; 64 continue; 65 66 case 'e': 67 argc--; 68 argv++; 69 goto out; 70 71 case 'f': 72 fflag++; 73 continue; 74 75 case 'l': 76 lflag++; 77 continue; 78 79 case 'n': 80 nflag++; 81 continue; 82 83 case 'v': 84 vflag++; 85 continue; 86 87 case 'x': 88 xflag++; 89 continue; 90 91 case 'i': /* Berkeley */ 92 case 'y': /* Btl */ 93 yflag++; 94 continue; 95 default: 96 fprintf(stderr, "fgrep: unknown flag\n"); 97 continue; 98 } 99 out: 100 if (argc<=0) 101 exit(2); 102 if (fflag) { 103 wordf = fopen(*argv, "r"); 104 if (wordf==NULL) { 105 fprintf(stderr, "fgrep: can't open %s\n", *argv); 106 exit(2); 107 } 108 } 109 else argptr = *argv; 110 argc--; 111 argv++; 112 113 cgotofn(); 114 cfail(); 115 nfile = argc; 116 if (argc<=0) { 117 if (lflag) exit(1); 118 execute((char *)NULL); 119 } 120 else while (--argc >= 0) { 121 execute(*argv); 122 argv++; 123 } 124 exit(retcode != 0 ? retcode : nsucc == 0); 125 } 126 127 # define ccomp(a,b) (yflag ? lca(a)==lca(b) : a==b) 128 # define lca(x) (isupper(x) ? tolower(x) : x) 129 execute(file) 130 char *file; 131 { 132 register struct words *c; 133 register ccount; 134 register char ch; 135 register char *p; 136 static char *buf; 137 static int blksize; 138 struct stat stb; 139 int f; 140 int failed; 141 char *nlp; 142 if (file) { 143 if ((f = open(file, 0)) < 0) { 144 fprintf(stderr, "fgrep: can't open %s\n", file); 145 retcode = 2; 146 return; 147 } 148 } 149 else f = 0; 150 if (buf == NULL) { 151 if (fstat(f, &stb) > 0 && stb.st_blksize > 0) 152 blksize = stb.st_blksize; 153 else 154 blksize = BLKSIZE; 155 buf = (char *)malloc(2*blksize); 156 if (buf == NULL) { 157 fprintf(stderr, "egrep: no memory for %s\n", file); 158 retcode = 2; 159 return; 160 } 161 } 162 ccount = 0; 163 failed = 0; 164 lnum = 1; 165 tln = 0; 166 blkno = 0; 167 p = buf; 168 nlp = p; 169 c = w; 170 for (;;) { 171 if (--ccount <= 0) { 172 if (p == &buf[2*blksize]) p = buf; 173 if (p > &buf[blksize]) { 174 if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 175 } 176 else if ((ccount = read(f, p, blksize)) <= 0) break; 177 blkno += ccount; 178 } 179 nstate: 180 if (ccomp(c->inp, *p)) { 181 c = c->nst; 182 } 183 else if (c->link != 0) { 184 c = c->link; 185 goto nstate; 186 } 187 else { 188 c = c->fail; 189 failed = 1; 190 if (c==0) { 191 c = w; 192 istate: 193 if (ccomp(c->inp , *p)) { 194 c = c->nst; 195 } 196 else if (c->link != 0) { 197 c = c->link; 198 goto istate; 199 } 200 } 201 else goto nstate; 202 } 203 if (c->out) { 204 while (*p++ != '\n') { 205 if (--ccount <= 0) { 206 if (p == &buf[2*blksize]) p = buf; 207 if (p > &buf[blksize]) { 208 if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break; 209 } 210 else if ((ccount = read(f, p, blksize)) <= 0) break; 211 blkno += ccount; 212 } 213 } 214 if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) ) 215 goto nomatch; 216 succeed: nsucc = 1; 217 if (cflag) tln++; 218 else if (sflag) 219 ; /* ugh */ 220 else if (lflag) { 221 printf("%s\n", file); 222 close(f); 223 return; 224 } 225 else { 226 if (nfile > 1 && hflag || oflag) printf("%s:", file); 227 if (bflag) printf("%ld:", (blkno-ccount-1)/DEV_BSIZE); 228 if (nflag) printf("%ld:", lnum); 229 if (p <= nlp) { 230 while (nlp < &buf[2*blksize]) putchar(*nlp++); 231 nlp = buf; 232 } 233 while (nlp < p) putchar(*nlp++); 234 } 235 nomatch: lnum++; 236 nlp = p; 237 c = w; 238 failed = 0; 239 continue; 240 } 241 if (*p++ == '\n') 242 if (vflag) goto succeed; 243 else { 244 lnum++; 245 nlp = p; 246 c = w; 247 failed = 0; 248 } 249 } 250 close(f); 251 if (cflag) { 252 if (nfile > 1) 253 printf("%s:", file); 254 printf("%ld\n", tln); 255 } 256 } 257 258 getargc() 259 { 260 register c; 261 if (wordf) 262 return(getc(wordf)); 263 if ((c = *argptr++) == '\0') 264 return(EOF); 265 return(c); 266 } 267 268 cgotofn() { 269 register c; 270 register struct words *s; 271 272 s = smax = w; 273 nword: for(;;) { 274 c = getargc(); 275 if (c==EOF) 276 return; 277 if (c == '\n') { 278 if (xflag) { 279 for(;;) { 280 if (s->inp == c) { 281 s = s->nst; 282 break; 283 } 284 if (s->inp == 0) goto nenter; 285 if (s->link == 0) { 286 if (smax >= &w[MAXSIZ -1]) overflo(); 287 s->link = ++smax; 288 s = smax; 289 goto nenter; 290 } 291 s = s->link; 292 } 293 } 294 s->out = 1; 295 s = w; 296 } else { 297 loop: if (s->inp == c) { 298 s = s->nst; 299 continue; 300 } 301 if (s->inp == 0) goto enter; 302 if (s->link == 0) { 303 if (smax >= &w[MAXSIZ - 1]) overflo(); 304 s->link = ++smax; 305 s = smax; 306 goto enter; 307 } 308 s = s->link; 309 goto loop; 310 } 311 } 312 313 enter: 314 do { 315 s->inp = c; 316 if (smax >= &w[MAXSIZ - 1]) overflo(); 317 s->nst = ++smax; 318 s = smax; 319 } while ((c = getargc()) != '\n' && c!=EOF); 320 if (xflag) { 321 nenter: s->inp = '\n'; 322 if (smax >= &w[MAXSIZ -1]) overflo(); 323 s->nst = ++smax; 324 } 325 smax->out = 1; 326 s = w; 327 if (c != EOF) 328 goto nword; 329 } 330 331 overflo() { 332 fprintf(stderr, "wordlist too large\n"); 333 exit(2); 334 } 335 cfail() { 336 struct words *queue[QSIZE]; 337 struct words **front, **rear; 338 struct words *state; 339 int bstart; 340 register char c; 341 register struct words *s; 342 s = w; 343 front = rear = queue; 344 init: if ((s->inp) != 0) { 345 *rear++ = s->nst; 346 if (rear >= &queue[QSIZE - 1]) overflo(); 347 } 348 if ((s = s->link) != 0) { 349 goto init; 350 } 351 352 while (rear!=front) { 353 s = *front; 354 if (front == &queue[QSIZE-1]) 355 front = queue; 356 else front++; 357 cloop: if ((c = s->inp) != 0) { 358 bstart = 0; 359 *rear = (q = s->nst); 360 if (front < rear) 361 if (rear >= &queue[QSIZE-1]) 362 if (front == queue) overflo(); 363 else rear = queue; 364 else rear++; 365 else 366 if (++rear == front) overflo(); 367 state = s->fail; 368 floop: if (state == 0) { 369 state = w; 370 bstart = 1; 371 } 372 if (state->inp == c) { 373 qloop: q->fail = state->nst; 374 if ((state->nst)->out == 1) q->out = 1; 375 if ((q = q->link) != 0) goto qloop; 376 } 377 else if ((state = state->link) != 0) 378 goto floop; 379 else if(bstart == 0){ 380 state = 0; 381 goto floop; 382 } 383 } 384 if ((s = s->link) != 0) 385 goto cloop; 386 } 387 } 388