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