/* * grep. */ #include #define LMAX 128 #define PMAX 128 #define END 0 #define CHAR 1 #define BOL 2 #define EOL 3 #define ANY 4 #define CLASS 5 #define NCLASS 6 #define CLOSURE 7 int cflag; int fflag; int nflag; int vflag; char *pp; char lbuf[LMAX]; char pbuf[PMAX]; main(argc, argv) char *argv[]; { register char *p; register int c, i; int nf, gp; FILE *f; nf = argc-1; gp = 0; for(i=1; i lp) *pp = pp[-1]; *pp = CLOSURE; pp = spp; continue; } /* * All the rest. */ lp = pp; switch(c) { case '^': store(BOL); break; case '$': store(EOL); break; case '.': store(ANY); break; case '[': s = cclass(s); break; case '\\': if(*s) c = *s++; default: store(CHAR); store(lower(c)); } } store(END); } char * cclass(s) register char *s; { register char *cp; register int c; int o; o = CLASS; if(*s == '^') { ++s; o = NCLASS; } store(o); cp = pp; store(0); /* Byte count */ while((c=*s++) && c!=']') { if(c == '\\') if((c=*s++) == '\0') badpat(); store(lower(c)); if(++*cp == 0) error("Class too complex\n"); } if(c != ']') badpat(); return(s); } store(op) { if(pp >= &pbuf[PMAX]) error("Pattern too complex\n"); *pp++ = op; } match() { register char *l; char *pmatch(); l = lbuf; while(*l) { if(pmatch(l, pbuf)) return(1); ++l; } return(0); } char * pmatch(l, p) register char *l, *p; { register char *e; int op, c, n; char *are; while((op=*p++) != END) switch(op) { case CHAR: if(lower(*l++) != *p++) return(0); break; case BOL: if(l != lbuf) return(0); break; case EOL: if(*l != '\0') return(0); break; case ANY: if(*l++ == '\0') return(0); break; case CLASS: c = lower(*l++); if((n=*p++&0377) == 0) return(0); do { if(c == *p++) break; } while(--n); if(n == 0) return(0); p += n-1; break; case NCLASS: c = lower(*l++); if((n=*p++&0377) == 0) break; do { if(c == *p++) break; } while(--n); if(n) return(0); break; case CLOSURE: are = l; while(e = pmatch(l, p)) l = e; while(*p++ != END) ; while(l >= are) { if(e = pmatch(l, p)) return(e); --l; } return(0); default: error("Cannot happen -- match\n"); } return(l); } lower(c) register int c; { if(c>='A' && c<='Z') c += 'a'-'A'; return(c); } badpat() { error("Bad pattern\n"); } file(s) char *s; { printf("File %s:\n", s); } cant(s) char *s; { fprintf(stderr, "%s: cannot open\n", s); } usage() { error("Usage: grep [-cfnv] pattern [file ...]\n"); }