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