1 #ifndef lint 2 static char *sccsid = "@(#)glue5.c 4.2 (Berkeley) 01/09/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 } 367