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