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