#define EXTERN #include "grep.h" char *validflags = "bchiLlnsv"; void usage(void) { fprint(2, "usage: grep [-%s] [-e pattern] [-f patternfile] [file ...]\n", validflags); exits("usage"); } void main(int argc, char *argv[]) { int i, status; ARGBEGIN { default: if(utfrune(validflags, ARGC()) == nil) usage(); flags[ARGC()]++; break; case 'e': flags['e']++; lineno = 0; str2top(EARGF(usage())); break; case 'f': flags['f']++; filename = EARGF(usage()); rein = Bopen(filename, OREAD); if(rein == 0) { fprint(2, "grep: can't open %s: %r\n", filename); exits("open"); } lineno = 1; str2top(filename); break; } ARGEND if(flags['f'] == 0 && flags['e'] == 0) { if(argc <= 0) usage(); str2top(argv[0]); argc--; argv++; } follow = mal(maxfollow*sizeof(*follow)); state0 = initstate(topre.beg); Binit(&bout, 1, OWRITE); switch(argc) { case 0: status = search(0, 0); break; case 1: status = search(argv[0], 0); break; default: status = 0; for(i=0; i sizeof(u.pre)) n = sizeof(u.pre); memmove(u.buf-n, bol, n); bol = u.buf-n; n = read(fid, u.buf, sizeof(u.buf)); /* if file has no final newline, simulate one to emit matches to last line */ if(n > 0) { empty = 0; nl = u.buf[n-1]=='\n'; } else { if(n < 0){ fprint(2, "grep: read error on %s: %r\n", file); return count != 0; } if(!eof && !nl && !empty) { u.buf[0] = '\n'; n = 1; eof = 1; } } if(n <= 0) { close(fid); if(flag & Cflag) { if(flag & Hflag) Bprint(&bout, "%s:", file); Bprint(&bout, "%ld\n", count); } if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0)) Bprint(&bout, "%s\n", file); Bflush(&bout); return count != 0; } lp = u.buf; elp = lp+n; if(flag & Iflag) goto loopi; /* * normal character loop */ loop: c = *lp; ns = s->next[c]; if(ns == 0) { increment(s, c); goto loop; } // if(flags['2']) // if(s->match) // print("%d: %.2x**\n", s, c); // else // print("%d: %.2x\n", s, c); lp++; s = ns; if(c == '\n') { lineno++; if(!!s->match == !(flag&Vflag)) { count++; if(flag & (Cflag|Sflag|Llflag|LLflag)) goto cont; if(flag & Hflag) Bprint(&bout, "%s:", file); if(flag & Nflag) Bprint(&bout, "%ld: ", lineno); /* suppress extra newline at EOF unless we are labeling matches with file name */ Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag))); if(flag & Bflag) Bflush(&bout); } if((lineno & Flshcnt) == 0) Bflush(&bout); cont: bol = lp; } if(lp != elp) goto loop; goto loop0; /* * character loop for -i flag * for speed */ loopi: c = *lp; if(c >= 'A' && c <= 'Z') c += 'a'-'A'; ns = s->next[c]; if(ns == 0) { increment(s, c); goto loopi; } lp++; s = ns; if(c == '\n') { lineno++; if(!!s->match == !(flag&Vflag)) { count++; if(flag & (Cflag|Sflag|Llflag|LLflag)) goto conti; if(flag & Hflag) Bprint(&bout, "%s:", file); if(flag & Nflag) Bprint(&bout, "%ld: ", lineno); /* suppress extra newline at EOF unless we are labeling matches with file name */ Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag))); if(flag & Bflag) Bflush(&bout); } if((lineno & Flshcnt) == 0) Bflush(&bout); conti: bol = lp; } if(lp != elp) goto loopi; goto loop0; } State* initstate(Re *r) { State *s; int i; addcase(r); if(flags['1']) reprint("r", r); nfollow = 0; gen++; fol1(r, Cbegin); follow[nfollow++] = r; qsort(follow, nfollow, sizeof(*follow), fcmp); s = sal(nfollow); for(i=0; ire[i] = follow[i]; return s; }