4 char *validflags = "bchiLlnsv";
8 fprint(2, "usage: grep [-%s] [-e pattern] [-f patternfile] [file ...]\n", validflags);
13 main(int argc, char *argv[])
19 if(utfrune(validflags, ARGC()) == nil)
24 case 'q': /* gnu grep -q means plan 9 grep -s */
28 case 'E': /* ignore, turns gnu grep into egrep */
34 str2top(EARGF(usage()));
39 filename = EARGF(usage());
40 rein = Bopen(filename, OREAD);
42 fprint(2, "grep: can't open %s: %r\n", filename);
50 if(flags['f'] == 0 && flags['e'] == 0) {
58 follow = mal(maxfollow*sizeof(*follow));
59 state0 = initstate(topre.beg);
61 Binit(&bout, 1, OWRITE);
64 status = search(0, 0);
67 status = search(argv[0], 0);
72 status |= search(argv[i], Hflag);
81 search(char *file, int flag)
84 int c, fid, eof, nl, empty;
85 long count, lineno, n;
86 uchar *elp, *lp, *bol;
93 fid = open(file, OREAD);
96 fprint(2, "grep: can't open %s: %r\n", file);
101 flag ^= Bflag; /* dont buffer output */
103 flag |= Cflag; /* count */
105 flag &= ~Hflag; /* do not print file name in output */
107 flag |= Iflag; /* fold upper-lower */
109 flag |= Llflag; /* print only name of file if any match */
111 flag |= LLflag; /* print only name of file if any non match */
113 flag |= Nflag; /* count only */
115 flag |= Sflag; /* status only */
117 flag |= Vflag; /* inverse match */
130 if(n > sizeof(u.u.pre))
132 memmove(u.u.buf-n, bol, n);
134 n = read(fid, u.u.buf, sizeof(u.u.buf));
135 /* if file has no final newline, simulate one to emit matches to last line */
138 nl = u.u.buf[n-1]=='\n';
141 fprint(2, "grep: read error on %s: %r\n", file);
144 if(!eof && !nl && !empty) {
154 Bprint(&bout, "%s:", file);
155 Bprint(&bout, "%ld\n", count);
157 if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))
158 Bprint(&bout, "%s\n", file);
168 * normal character loop
179 /* print("%d: %.2x**\n", s, c); */
181 /* print("%d: %.2x\n", s, c); */
186 if(!!s->match == !(flag&Vflag)) {
188 if(flag & (Cflag|Sflag|Llflag|LLflag))
191 Bprint(&bout, "%s:", file);
193 Bprint(&bout, "%ld: ", lineno);
194 /* suppress extra newline at EOF unless we are labeling matches with file name */
195 Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
199 if((lineno & Flshcnt) == 0)
209 * character loop for -i flag
214 if(c >= 'A' && c <= 'Z')
225 if(!!s->match == !(flag&Vflag)) {
227 if(flag & (Cflag|Sflag|Llflag|LLflag))
230 Bprint(&bout, "%s:", file);
232 Bprint(&bout, "%ld: ", lineno);
233 /* suppress extra newline at EOF unless we are labeling matches with file name */
234 Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
238 if((lineno & Flshcnt) == 0)
260 follow[nfollow++] = r;
261 qsort(follow, nfollow, sizeof(*follow), fcmp);
264 for(i=0; i<nfollow; i++)
265 s->re[i] = follow[i];