123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #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<argc; i++)
- status |= search(argv[i], Hflag);
- break;
- }
- if(status)
- exits(0);
- exits("no matches");
- }
- int
- search(char *file, int flag)
- {
- State *s, *ns;
- int c, fid, eof, nl, empty;
- long count, lineno, n;
- uchar *elp, *lp, *bol;
- if(file == 0) {
- file = "stdin";
- fid = 0;
- flag |= Bflag;
- } else
- fid = open(file, OREAD);
- if(fid < 0) {
- fprint(2, "grep: can't open %s: %r\n", file);
- return 0;
- }
- if(flags['b'])
- flag ^= Bflag; /* dont buffer output */
- if(flags['c'])
- flag |= Cflag; /* count */
- if(flags['h'])
- flag &= ~Hflag; /* do not print file name in output */
- if(flags['i'])
- flag |= Iflag; /* fold upper-lower */
- if(flags['l'])
- flag |= Llflag; /* print only name of file if any match */
- if(flags['L'])
- flag |= LLflag; /* print only name of file if any non match */
- if(flags['n'])
- flag |= Nflag; /* count only */
- if(flags['s'])
- flag |= Sflag; /* status only */
- if(flags['v'])
- flag |= Vflag; /* inverse match */
- s = state0;
- lineno = 0;
- count = 0;
- eof = 0;
- empty = 1;
- nl = 0;
- lp = u.buf;
- bol = lp;
- loop0:
- n = lp-bol;
- if(n > 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; i<nfollow; i++)
- s->re[i] = follow[i];
- return s;
- }
|