1: #ifndef lint 2: static char *sccsid = "@(#)glue5.c 4.2 (Berkeley) 1/9/85"; 3: #endif 4: 5: #include <stdio.h> 6: #include <ctype.h> 7: /* 8: * fgrep -- print all lines containing any of a set of keywords 9: * 10: * status returns: 11: * 0 - ok, and some matches 12: * 1 - ok, but no matches 13: * 2 - some error 14: */ 15: #define MAXSIZ 700 16: #define QSIZE 400 17: struct words { 18: char inp; 19: char out; 20: struct words *nst; 21: struct words *link; 22: struct words *fail; 23: } 24: *www, *smax, *q; 25: 26: char buf[2*BUFSIZ]; 27: int nsucc; 28: int need; 29: char *instr; 30: int inct; 31: int rflag; 32: int xargc; 33: char **xargv; 34: int numwords; 35: int nfound; 36: static int flag = 0; 37: 38: fgrep(argc, argv) 39: char **argv; 40: { 41: nsucc = need = inct = rflag = numwords = nfound = 0; 42: instr = 0; 43: flag = 0; 44: if (www==0) 45: www = (struct words *) zalloc(MAXSIZ, sizeof (*www)); 46: if (www==NULL) 47: err("Can't get space for machines", 0); 48: for (q=www; q<www+MAXSIZ; q++) { 49: q->inp =0; q->out =0; q->nst =0; q->link =0; q->fail =0; 50: } 51: xargc = argc-1; 52: xargv = argv+1; 53: while (xargc>0 && xargv[0][0]=='-') 54: { 55: switch(xargv[0][1]) 56: { 57: case 'r': /* return value only */ 58: rflag++; 59: break; 60: case 'n': /* number of answers needed */ 61: need = (int) xargv[1]; 62: xargv++; xargc--; 63: break; 64: case 'i': 65: instr = xargv[1]; 66: inct = (int) xargv[2]+2; 67: # if D2 68: fprintf(stderr,"inct %d xargv.2. %o %d\n",inct, xargv[2],xargv[2]); 69: # endif 70: xargv += 2; xargc -= 2; 71: break; 72: } 73: xargv++; xargc--; 74: } 75: if (xargc<=0) 76: { 77: write (2, "bad fgrep call\n", 15); 78: exit(2); 79: } 80: # if D1 81: fprintf(stderr, "before cgoto\n"); 82: # endif 83: cgotofn(); 84: # if D1 85: fprintf(stderr, "before cfail\n"); 86: # endif 87: cfail(); 88: # if D1 89: fprintf(stderr, "before execute instr %.20s\n", instr? instr: ""); 90: fprintf(stderr, "end of string %d %c %c %c\n", inct, instr[inct-3], 91: instr[inct-2], instr[inct-1]); 92: # endif 93: execute(); 94: # if D1 95: fprintf(stderr, "returning nsucc %d\n", nsucc); 96: fprintf(stderr, "fgrep done www %o\n",www); 97: # endif 98: return(nsucc == 0); 99: } 100: 101: execute() 102: { 103: register char *p; 104: register struct words *c; 105: register ch; 106: register ccount; 107: int f; 108: char *nlp; 109: f=0; 110: ccount = instr ? inct : 0; 111: nfound=0; 112: p = instr ? instr : buf; 113: if (need == 0) need = numwords; 114: nlp = p; 115: c = www; 116: # if D2 117: fprintf(stderr, "in execute ccount %d inct %d\n",ccount, inct ); 118: # endif 119: for (;;) { 120: # if D3 121: fprintf(stderr, "down ccount\n"); 122: # endif 123: if (--ccount <= 0) { 124: # if D2 125: fprintf(stderr, "ex loop ccount %d instr %o\n",ccount, instr); 126: # endif 127: if (instr) break; 128: if (p == &buf[2*BUFSIZ]) p = buf; 129: if (p > &buf[BUFSIZ]) { 130: if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break; 131: } 132: else if ((ccount = read(f, p, BUFSIZ)) <= 0) break; 133: # if D2 134: fprintf(stderr, " normal read %d bytres\n", ccount); 135: {char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount); 136: fprintf(stderr, xx, p); 137: } 138: # endif 139: } 140: nstate: 141: ch = *p; 142: # if D2 143: fprintf(stderr, "roaming along in ex ch %c c %o\n",ch,c); 144: # endif 145: if (isupper(ch)) ch |= 040; 146: if (c->inp == ch) { 147: c = c->nst; 148: } 149: else if (c->link != 0) { 150: c = c->link; 151: goto nstate; 152: } 153: else { 154: c = c->fail; 155: if (c==0) { 156: c = www; 157: istate: 158: if (c->inp == ch) { 159: c = c->nst; 160: } 161: else if (c->link != 0) { 162: c = c->link; 163: goto istate; 164: } 165: } 166: else goto nstate; 167: } 168: if (c->out && new (c)) { 169: # if D2 170: fprintf(stderr, " found: nfound %d need %d\n",nfound,need); 171: # endif 172: if (++nfound >= need) 173: { 174: # if D1 175: fprintf(stderr, "found, p %o nlp %o ccount %d buf %o buf[2*BUFSIZ] %o\n",p,nlp,ccount,buf,buf+2*BUFSIZ); 176: # endif 177: if (instr==0) 178: while (*p++ != '\n') { 179: # if D3 180: fprintf(stderr, "down ccount2\n"); 181: # endif 182: if (--ccount <= 0) { 183: if (p == &buf[2*BUFSIZ]) p = buf; 184: if (p > &buf[BUFSIZ]) { 185: if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break; 186: } 187: else if ((ccount = read(f, p, BUFSIZ)) <= 0) break; 188: # if D2 189: fprintf(stderr, " read %d bytes\n",ccount); 190: { char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount); 191: fprintf(stderr, xx, p); 192: } 193: # endif 194: } 195: } 196: nsucc = 1; 197: if (rflag==0) 198: { 199: # if D2 200: fprintf(stderr, "p %o nlp %o buf %o\n",p,nlp,buf); 201: if (p>nlp) 202: {write (2, "XX\n", 3); write (2, nlp, p-nlp); write (2, "XX\n", 3);} 203: # endif 204: if (p > nlp) write(1, nlp, p-nlp); 205: else { 206: write(1, nlp, &buf[2*BUFSIZ] - nlp); 207: write(1, buf, p-&buf[0]); 208: } 209: if (p[-1]!= '\n') write (1, "\n", 1); 210: } 211: if (instr==0) 212: { 213: nlp = p; 214: c = www; 215: nfound=0; 216: } 217: } 218: else 219: ccount++; 220: continue; 221: } 222: # if D2 223: fprintf(stderr, "nr end loop p %o\n",p); 224: # endif 225: if (instr) 226: p++; 227: else 228: if (*p++ == '\n') 229: { 230: nlp = p; 231: c = www; 232: nfound=0; 233: } 234: } 235: if (instr==0) 236: close(f); 237: } 238: 239: cgotofn() { 240: register c; 241: register struct words *s; 242: s = smax = www; 243: nword: 244: for(;;) { 245: # if D1 246: fprintf(stderr, " in for loop c now %o %c\n",c, c>' ' ? c : ' '); 247: # endif 248: if ((c = gch())==0) return; 249: else if (c == '\n') { 250: s->out = 1; 251: s = www; 252: } 253: else { 254: loop: 255: if (s->inp == c) { 256: s = s->nst; 257: continue; 258: } 259: if (s->inp == 0) goto enter; 260: if (s->link == 0) { 261: if (smax >= &www[MAXSIZ - 1]) overflo(); 262: s->link = ++smax; 263: s = smax; 264: goto enter; 265: } 266: s = s->link; 267: goto loop; 268: } 269: } 270: 271: enter: 272: do { 273: s->inp = c; 274: if (smax >= &www[MAXSIZ - 1]) overflo(); 275: s->nst = ++smax; 276: s = smax; 277: } 278: while ((c = gch()) != '\n'); 279: smax->out = 1; 280: s = www; 281: numwords++; 282: goto nword; 283: 284: } 285: 286: gch() 287: { 288: static char *s; 289: if (flag==0) 290: { 291: flag=1; 292: s = *xargv++; 293: # if D1 294: fprintf(stderr, "next arg is %s xargc %d\n",s,xargc); 295: # endif 296: if (xargc-- <=0) return(0); 297: } 298: if (*s) return(*s++); 299: for(flag=0; flag<2*BUFSIZ; flag++) 300: buf[flag]=0; 301: flag=0; 302: return('\n'); 303: } 304: 305: overflo() { 306: write(2,"wordlist too large\n", 19); 307: exit(2); 308: } 309: cfail() { 310: struct words *queue[QSIZE]; 311: struct words **front, **rear; 312: struct words *state; 313: register char c; 314: register struct words *s; 315: s = www; 316: front = rear = queue; 317: init: 318: if ((s->inp) != 0) { 319: *rear++ = s->nst; 320: if (rear >= &queue[QSIZE - 1]) overflo(); 321: } 322: if ((s = s->link) != 0) { 323: goto init; 324: } 325: 326: while (rear!=front) { 327: s = *front; 328: if (front == &queue[QSIZE-1]) 329: front = queue; 330: else front++; 331: cloop: 332: if ((c = s->inp) != 0) { 333: *rear = (q = s->nst); 334: if (front < rear) 335: if (rear >= &queue[QSIZE-1]) 336: if (front == queue) overflo(); 337: else rear = queue; 338: else rear++; 339: else 340: if (++rear == front) overflo(); 341: state = s->fail; 342: floop: 343: if (state == 0) state = www; 344: if (state->inp == c) { 345: q->fail = state->nst; 346: if ((state->nst)->out == 1) q->out = 1; 347: continue; 348: } 349: else if ((state = state->link) != 0) 350: goto floop; 351: } 352: if ((s = s->link) != 0) 353: goto cloop; 354: } 355: } 356: 357: static int seen[50]; 358: new (x) 359: { 360: int i; 361: for(i=0; i<nfound; i++) 362: if (seen[i]==x) 363: return(0); 364: seen[i]=x; 365: return(1); 366: }