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