📄 glue5.c
字号:
#ifndef lintstatic char *sccsid = "@(#)glue5.c 4.1 ULTRIX 7/17/90";/* Original Id: "@(#)glue5.c 4.2 (Berkeley) 1/9/85" */#endif#include <stdio.h>#include <ctype.h>/* * fgrep -- print all lines containing any of a set of keywords * * status returns: * 0 - ok, and some matches * 1 - ok, but no matches * 2 - some error */#define MAXSIZ 700#define QSIZE 400struct words { char inp; char out; struct words *nst; struct words *link; struct words *fail;} *www, *smax, *q;char buf[2*BUFSIZ];int nsucc;int need;char *instr;int inct;int rflag;int xargc;char **xargv;int numwords;int nfound;static int flag = 0;fgrep(argc, argv)char **argv;{ nsucc = need = inct = rflag = numwords = nfound = 0; instr = 0; flag = 0; if (www==0) www = (struct words *) zalloc(MAXSIZ, sizeof (*www)); if (www==NULL) err("Can't get space for machines", 0); for (q=www; q<www+MAXSIZ; q++) { q->inp =0; q->out =0; q->nst =0; q->link =0; q->fail =0; } xargc = argc-1; xargv = argv+1; while (xargc>0 && xargv[0][0]=='-') { switch(xargv[0][1]) { case 'r': /* return value only */ rflag++; break; case 'n': /* number of answers needed */ need = (int) xargv[1]; xargv++; xargc--; break; case 'i': instr = xargv[1]; inct = (int) xargv[2]+2;# if D2fprintf(stderr,"inct %d xargv.2. %o %d\n",inct, xargv[2],xargv[2]);# endif xargv += 2; xargc -= 2; break; } xargv++; xargc--; } if (xargc<=0) { write (2, "bad fgrep call\n", 15); exit(2); }# if D1 fprintf(stderr, "before cgoto\n");# endif cgotofn();# if D1 fprintf(stderr, "before cfail\n");# endif cfail();# if D1 fprintf(stderr, "before execute instr %.20s\n", instr? instr: ""); fprintf(stderr, "end of string %d %c %c %c\n", inct, instr[inct-3], instr[inct-2], instr[inct-1]);# endif execute();# if D1 fprintf(stderr, "returning nsucc %d\n", nsucc); fprintf(stderr, "fgrep done www %o\n",www);# endif return(nsucc == 0);}execute(){ register char *p; register struct words *c; register ch; register ccount; int f; char *nlp; f=0; ccount = instr ? inct : 0; nfound=0; p = instr ? instr : buf; if (need == 0) need = numwords; nlp = p; c = www;# if D2fprintf(stderr, "in execute ccount %d inct %d\n",ccount, inct );# endif for (;;) {# if D3fprintf(stderr, "down ccount\n");# endif if (--ccount <= 0) {# if D2fprintf(stderr, "ex loop ccount %d instr %o\n",ccount, instr);# endif if (instr) break; if (p == &buf[2*BUFSIZ]) p = buf; if (p > &buf[BUFSIZ]) { if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break; } else if ((ccount = read(f, p, BUFSIZ)) <= 0) break;# if D2fprintf(stderr, " normal read %d bytres\n", ccount);{char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount);fprintf(stderr, xx, p);}# endif }nstate: ch = *p;# if D2fprintf(stderr, "roaming along in ex ch %c c %o\n",ch,c);# endif if (isupper(ch)) ch |= 040; if (c->inp == ch) { c = c->nst; } else if (c->link != 0) { c = c->link; goto nstate; } else { c = c->fail; if (c==0) { c = www;istate: if (c->inp == ch) { c = c->nst; } else if (c->link != 0) { c = c->link; goto istate; } } else goto nstate; } if (c->out && new (c)) {# if D2fprintf(stderr, " found: nfound %d need %d\n",nfound,need);# endif if (++nfound >= need) {# if D1fprintf(stderr, "found, p %o nlp %o ccount %d buf %o buf[2*BUFSIZ] %o\n",p,nlp,ccount,buf,buf+2*BUFSIZ);# endif if (instr==0) while (*p++ != '\n') {# if D3fprintf(stderr, "down ccount2\n");# endif if (--ccount <= 0) { if (p == &buf[2*BUFSIZ]) p = buf; if (p > &buf[BUFSIZ]) { if ((ccount = read(f, p, &buf[2*BUFSIZ] - p)) <= 0) break; } else if ((ccount = read(f, p, BUFSIZ)) <= 0) break;# if D2fprintf(stderr, " read %d bytes\n",ccount);{ char xx[20]; sprintf(xx, "they are %%.%ds\n", ccount);fprintf(stderr, xx, p);}# endif } } nsucc = 1; if (rflag==0) {# if D2fprintf(stderr, "p %o nlp %o buf %o\n",p,nlp,buf);if (p>nlp){write (2, "XX\n", 3); write (2, nlp, p-nlp); write (2, "XX\n", 3);}# endif if (p > nlp) write(1, nlp, p-nlp); else { write(1, nlp, &buf[2*BUFSIZ] - nlp); write(1, buf, p-&buf[0]); } if (p[-1]!= '\n') write (1, "\n", 1); } if (instr==0) { nlp = p; c = www; nfound=0; } } else ccount++; continue; }# if D2fprintf(stderr, "nr end loop p %o\n",p);# endif if (instr) p++; else if (*p++ == '\n') { nlp = p; c = www; nfound=0; } } if (instr==0) close(f);}cgotofn() { register c; register struct words *s; s = smax = www;nword: for(;;) {# if D1 fprintf(stderr, " in for loop c now %o %c\n",c, c>' ' ? c : ' ');# endif if ((c = gch())==0) return; else if (c == '\n') { s->out = 1; s = www; } else {loop: if (s->inp == c) { s = s->nst; continue; } if (s->inp == 0) goto enter; if (s->link == 0) { if (smax >= &www[MAXSIZ - 1]) overflo(); s->link = ++smax; s = smax; goto enter; } s = s->link; goto loop; } }enter: do { s->inp = c; if (smax >= &www[MAXSIZ - 1]) overflo(); s->nst = ++smax; s = smax; } while ((c = gch()) != '\n'); smax->out = 1; s = www; numwords++; goto nword;}gch(){ static char *s; if (flag==0) { flag=1; s = *xargv++;# if D1 fprintf(stderr, "next arg is %s xargc %d\n",s,xargc);# endif if (xargc-- <=0) return(0); } if (*s) return(*s++); for(flag=0; flag<2*BUFSIZ; flag++) buf[flag]=0; flag=0; return('\n');}overflo() { write(2,"wordlist too large\n", 19); exit(2);}cfail() { struct words *queue[QSIZE]; struct words **front, **rear; struct words *state; register char c; register struct words *s; s = www; front = rear = queue;init: if ((s->inp) != 0) { *rear++ = s->nst; if (rear >= &queue[QSIZE - 1]) overflo(); } if ((s = s->link) != 0) { goto init; } while (rear!=front) { s = *front; if (front == &queue[QSIZE-1]) front = queue; else front++;cloop: if ((c = s->inp) != 0) { *rear = (q = s->nst); if (front < rear) if (rear >= &queue[QSIZE-1]) if (front == queue) overflo(); else rear = queue; else rear++; else if (++rear == front) overflo(); state = s->fail;floop: if (state == 0) state = www; if (state->inp == c) { q->fail = state->nst; if ((state->nst)->out == 1) q->out = 1; continue; } else if ((state = state->link) != 0) goto floop; } if ((s = s->link) != 0) goto cloop; }}static int seen[50];new (x){ int i; for(i=0; i<nfound; i++) if (seen[i]==x) return(0); seen[i]=x; return(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -