Blame


1 8ad51794 2004-03-25 devnull #define EXTERN
2 8ad51794 2004-03-25 devnull #include "grep.h"
3 8ad51794 2004-03-25 devnull
4 2305af1c 2007-05-03 devnull char *validflags = "bchiLlnsv";
5 8ad51794 2004-03-25 devnull void
6 8ad51794 2004-03-25 devnull usage(void)
7 8ad51794 2004-03-25 devnull {
8 93c75d2b 2018-10-01 0intro fprint(2, "usage: grep [-%s] [-e pattern] [-f patternfile] [file ...]\n", validflags);
9 8ad51794 2004-03-25 devnull exits("usage");
10 8ad51794 2004-03-25 devnull }
11 8ad51794 2004-03-25 devnull
12 8ad51794 2004-03-25 devnull void
13 8ad51794 2004-03-25 devnull main(int argc, char *argv[])
14 8ad51794 2004-03-25 devnull {
15 8ad51794 2004-03-25 devnull int i, status;
16 8ad51794 2004-03-25 devnull
17 8ad51794 2004-03-25 devnull ARGBEGIN {
18 8ad51794 2004-03-25 devnull default:
19 8ad51794 2004-03-25 devnull if(utfrune(validflags, ARGC()) == nil)
20 8ad51794 2004-03-25 devnull usage();
21 8ad51794 2004-03-25 devnull flags[ARGC()]++;
22 29cfa385 2007-05-03 devnull break;
23 29cfa385 2007-05-03 devnull
24 29cfa385 2007-05-03 devnull case 'q': /* gnu grep -q means plan 9 grep -s */
25 29cfa385 2007-05-03 devnull flags['s']++;
26 8ad51794 2004-03-25 devnull break;
27 8ad51794 2004-03-25 devnull
28 c8b6342d 2005-01-13 devnull case 'E': /* ignore, turns gnu grep into egrep */
29 c8b6342d 2005-01-13 devnull break;
30 c8b6342d 2005-01-13 devnull
31 8ad51794 2004-03-25 devnull case 'e':
32 8ad51794 2004-03-25 devnull flags['e']++;
33 8ad51794 2004-03-25 devnull lineno = 0;
34 93c75d2b 2018-10-01 0intro str2top(EARGF(usage()));
35 8ad51794 2004-03-25 devnull break;
36 8ad51794 2004-03-25 devnull
37 8ad51794 2004-03-25 devnull case 'f':
38 8ad51794 2004-03-25 devnull flags['f']++;
39 93c75d2b 2018-10-01 0intro filename = EARGF(usage());
40 8ad51794 2004-03-25 devnull rein = Bopen(filename, OREAD);
41 8ad51794 2004-03-25 devnull if(rein == 0) {
42 8ad51794 2004-03-25 devnull fprint(2, "grep: can't open %s: %r\n", filename);
43 8ad51794 2004-03-25 devnull exits("open");
44 8ad51794 2004-03-25 devnull }
45 8ad51794 2004-03-25 devnull lineno = 1;
46 8ad51794 2004-03-25 devnull str2top(filename);
47 8ad51794 2004-03-25 devnull break;
48 8ad51794 2004-03-25 devnull } ARGEND
49 8ad51794 2004-03-25 devnull
50 8ad51794 2004-03-25 devnull if(flags['f'] == 0 && flags['e'] == 0) {
51 8ad51794 2004-03-25 devnull if(argc <= 0)
52 8ad51794 2004-03-25 devnull usage();
53 8ad51794 2004-03-25 devnull str2top(argv[0]);
54 8ad51794 2004-03-25 devnull argc--;
55 8ad51794 2004-03-25 devnull argv++;
56 8ad51794 2004-03-25 devnull }
57 8ad51794 2004-03-25 devnull
58 8ad51794 2004-03-25 devnull follow = mal(maxfollow*sizeof(*follow));
59 8ad51794 2004-03-25 devnull state0 = initstate(topre.beg);
60 8ad51794 2004-03-25 devnull
61 8ad51794 2004-03-25 devnull Binit(&bout, 1, OWRITE);
62 8ad51794 2004-03-25 devnull switch(argc) {
63 8ad51794 2004-03-25 devnull case 0:
64 8ad51794 2004-03-25 devnull status = search(0, 0);
65 8ad51794 2004-03-25 devnull break;
66 8ad51794 2004-03-25 devnull case 1:
67 8ad51794 2004-03-25 devnull status = search(argv[0], 0);
68 8ad51794 2004-03-25 devnull break;
69 8ad51794 2004-03-25 devnull default:
70 8ad51794 2004-03-25 devnull status = 0;
71 8ad51794 2004-03-25 devnull for(i=0; i<argc; i++)
72 8ad51794 2004-03-25 devnull status |= search(argv[i], Hflag);
73 8ad51794 2004-03-25 devnull break;
74 8ad51794 2004-03-25 devnull }
75 8ad51794 2004-03-25 devnull if(status)
76 8ad51794 2004-03-25 devnull exits(0);
77 8ad51794 2004-03-25 devnull exits("no matches");
78 8ad51794 2004-03-25 devnull }
79 8ad51794 2004-03-25 devnull
80 8ad51794 2004-03-25 devnull int
81 8ad51794 2004-03-25 devnull search(char *file, int flag)
82 8ad51794 2004-03-25 devnull {
83 8ad51794 2004-03-25 devnull State *s, *ns;
84 8ad51794 2004-03-25 devnull int c, fid, eof, nl, empty;
85 8ad51794 2004-03-25 devnull long count, lineno, n;
86 8ad51794 2004-03-25 devnull uchar *elp, *lp, *bol;
87 8ad51794 2004-03-25 devnull
88 8ad51794 2004-03-25 devnull if(file == 0) {
89 8ad51794 2004-03-25 devnull file = "stdin";
90 8ad51794 2004-03-25 devnull fid = 0;
91 8ad51794 2004-03-25 devnull flag |= Bflag;
92 8ad51794 2004-03-25 devnull } else
93 8ad51794 2004-03-25 devnull fid = open(file, OREAD);
94 8ad51794 2004-03-25 devnull
95 8ad51794 2004-03-25 devnull if(fid < 0) {
96 8ad51794 2004-03-25 devnull fprint(2, "grep: can't open %s: %r\n", file);
97 8ad51794 2004-03-25 devnull return 0;
98 8ad51794 2004-03-25 devnull }
99 8ad51794 2004-03-25 devnull
100 8ad51794 2004-03-25 devnull if(flags['b'])
101 8ad51794 2004-03-25 devnull flag ^= Bflag; /* dont buffer output */
102 8ad51794 2004-03-25 devnull if(flags['c'])
103 8ad51794 2004-03-25 devnull flag |= Cflag; /* count */
104 8ad51794 2004-03-25 devnull if(flags['h'])
105 8ad51794 2004-03-25 devnull flag &= ~Hflag; /* do not print file name in output */
106 8ad51794 2004-03-25 devnull if(flags['i'])
107 8ad51794 2004-03-25 devnull flag |= Iflag; /* fold upper-lower */
108 8ad51794 2004-03-25 devnull if(flags['l'])
109 8ad51794 2004-03-25 devnull flag |= Llflag; /* print only name of file if any match */
110 8ad51794 2004-03-25 devnull if(flags['L'])
111 8ad51794 2004-03-25 devnull flag |= LLflag; /* print only name of file if any non match */
112 8ad51794 2004-03-25 devnull if(flags['n'])
113 8ad51794 2004-03-25 devnull flag |= Nflag; /* count only */
114 8ad51794 2004-03-25 devnull if(flags['s'])
115 8ad51794 2004-03-25 devnull flag |= Sflag; /* status only */
116 8ad51794 2004-03-25 devnull if(flags['v'])
117 8ad51794 2004-03-25 devnull flag |= Vflag; /* inverse match */
118 8ad51794 2004-03-25 devnull
119 8ad51794 2004-03-25 devnull s = state0;
120 8ad51794 2004-03-25 devnull lineno = 0;
121 8ad51794 2004-03-25 devnull count = 0;
122 8ad51794 2004-03-25 devnull eof = 0;
123 8ad51794 2004-03-25 devnull empty = 1;
124 8ad51794 2004-03-25 devnull nl = 0;
125 1a84af59 2004-03-25 devnull lp = u.u.buf;
126 8ad51794 2004-03-25 devnull bol = lp;
127 8ad51794 2004-03-25 devnull
128 8ad51794 2004-03-25 devnull loop0:
129 8ad51794 2004-03-25 devnull n = lp-bol;
130 1a84af59 2004-03-25 devnull if(n > sizeof(u.u.pre))
131 1a84af59 2004-03-25 devnull n = sizeof(u.u.pre);
132 1a84af59 2004-03-25 devnull memmove(u.u.buf-n, bol, n);
133 1a84af59 2004-03-25 devnull bol = u.u.buf-n;
134 1a84af59 2004-03-25 devnull n = read(fid, u.u.buf, sizeof(u.u.buf));
135 8ad51794 2004-03-25 devnull /* if file has no final newline, simulate one to emit matches to last line */
136 8ad51794 2004-03-25 devnull if(n > 0) {
137 8ad51794 2004-03-25 devnull empty = 0;
138 1a84af59 2004-03-25 devnull nl = u.u.buf[n-1]=='\n';
139 8ad51794 2004-03-25 devnull } else {
140 8ad51794 2004-03-25 devnull if(n < 0){
141 8ad51794 2004-03-25 devnull fprint(2, "grep: read error on %s: %r\n", file);
142 8ad51794 2004-03-25 devnull return count != 0;
143 8ad51794 2004-03-25 devnull }
144 8ad51794 2004-03-25 devnull if(!eof && !nl && !empty) {
145 1a84af59 2004-03-25 devnull u.u.buf[0] = '\n';
146 8ad51794 2004-03-25 devnull n = 1;
147 8ad51794 2004-03-25 devnull eof = 1;
148 8ad51794 2004-03-25 devnull }
149 8ad51794 2004-03-25 devnull }
150 8ad51794 2004-03-25 devnull if(n <= 0) {
151 8ad51794 2004-03-25 devnull close(fid);
152 8ad51794 2004-03-25 devnull if(flag & Cflag) {
153 8ad51794 2004-03-25 devnull if(flag & Hflag)
154 8ad51794 2004-03-25 devnull Bprint(&bout, "%s:", file);
155 8ad51794 2004-03-25 devnull Bprint(&bout, "%ld\n", count);
156 8ad51794 2004-03-25 devnull }
157 8ad51794 2004-03-25 devnull if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))
158 8ad51794 2004-03-25 devnull Bprint(&bout, "%s\n", file);
159 8ad51794 2004-03-25 devnull Bflush(&bout);
160 8ad51794 2004-03-25 devnull return count != 0;
161 8ad51794 2004-03-25 devnull }
162 1a84af59 2004-03-25 devnull lp = u.u.buf;
163 8ad51794 2004-03-25 devnull elp = lp+n;
164 8ad51794 2004-03-25 devnull if(flag & Iflag)
165 8ad51794 2004-03-25 devnull goto loopi;
166 8ad51794 2004-03-25 devnull
167 8ad51794 2004-03-25 devnull /*
168 8ad51794 2004-03-25 devnull * normal character loop
169 8ad51794 2004-03-25 devnull */
170 8ad51794 2004-03-25 devnull loop:
171 8ad51794 2004-03-25 devnull c = *lp;
172 8ad51794 2004-03-25 devnull ns = s->next[c];
173 8ad51794 2004-03-25 devnull if(ns == 0) {
174 8ad51794 2004-03-25 devnull increment(s, c);
175 8ad51794 2004-03-25 devnull goto loop;
176 8ad51794 2004-03-25 devnull }
177 cbeb0b26 2006-04-01 devnull /* if(flags['2']) */
178 cbeb0b26 2006-04-01 devnull /* if(s->match) */
179 cbeb0b26 2006-04-01 devnull /* print("%d: %.2x**\n", s, c); */
180 cbeb0b26 2006-04-01 devnull /* else */
181 cbeb0b26 2006-04-01 devnull /* print("%d: %.2x\n", s, c); */
182 8ad51794 2004-03-25 devnull lp++;
183 8ad51794 2004-03-25 devnull s = ns;
184 8ad51794 2004-03-25 devnull if(c == '\n') {
185 8ad51794 2004-03-25 devnull lineno++;
186 8ad51794 2004-03-25 devnull if(!!s->match == !(flag&Vflag)) {
187 8ad51794 2004-03-25 devnull count++;
188 8ad51794 2004-03-25 devnull if(flag & (Cflag|Sflag|Llflag|LLflag))
189 8ad51794 2004-03-25 devnull goto cont;
190 8ad51794 2004-03-25 devnull if(flag & Hflag)
191 8ad51794 2004-03-25 devnull Bprint(&bout, "%s:", file);
192 8ad51794 2004-03-25 devnull if(flag & Nflag)
193 8ad51794 2004-03-25 devnull Bprint(&bout, "%ld: ", lineno);
194 8ad51794 2004-03-25 devnull /* suppress extra newline at EOF unless we are labeling matches with file name */
195 8ad51794 2004-03-25 devnull Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
196 8ad51794 2004-03-25 devnull if(flag & Bflag)
197 8ad51794 2004-03-25 devnull Bflush(&bout);
198 8ad51794 2004-03-25 devnull }
199 8ad51794 2004-03-25 devnull if((lineno & Flshcnt) == 0)
200 8ad51794 2004-03-25 devnull Bflush(&bout);
201 8ad51794 2004-03-25 devnull cont:
202 8ad51794 2004-03-25 devnull bol = lp;
203 8ad51794 2004-03-25 devnull }
204 8ad51794 2004-03-25 devnull if(lp != elp)
205 8ad51794 2004-03-25 devnull goto loop;
206 8ad51794 2004-03-25 devnull goto loop0;
207 8ad51794 2004-03-25 devnull
208 8ad51794 2004-03-25 devnull /*
209 8ad51794 2004-03-25 devnull * character loop for -i flag
210 8ad51794 2004-03-25 devnull * for speed
211 8ad51794 2004-03-25 devnull */
212 8ad51794 2004-03-25 devnull loopi:
213 8ad51794 2004-03-25 devnull c = *lp;
214 8ad51794 2004-03-25 devnull if(c >= 'A' && c <= 'Z')
215 8ad51794 2004-03-25 devnull c += 'a'-'A';
216 8ad51794 2004-03-25 devnull ns = s->next[c];
217 8ad51794 2004-03-25 devnull if(ns == 0) {
218 8ad51794 2004-03-25 devnull increment(s, c);
219 8ad51794 2004-03-25 devnull goto loopi;
220 8ad51794 2004-03-25 devnull }
221 8ad51794 2004-03-25 devnull lp++;
222 8ad51794 2004-03-25 devnull s = ns;
223 8ad51794 2004-03-25 devnull if(c == '\n') {
224 8ad51794 2004-03-25 devnull lineno++;
225 8ad51794 2004-03-25 devnull if(!!s->match == !(flag&Vflag)) {
226 8ad51794 2004-03-25 devnull count++;
227 8ad51794 2004-03-25 devnull if(flag & (Cflag|Sflag|Llflag|LLflag))
228 8ad51794 2004-03-25 devnull goto conti;
229 8ad51794 2004-03-25 devnull if(flag & Hflag)
230 8ad51794 2004-03-25 devnull Bprint(&bout, "%s:", file);
231 8ad51794 2004-03-25 devnull if(flag & Nflag)
232 8ad51794 2004-03-25 devnull Bprint(&bout, "%ld: ", lineno);
233 8ad51794 2004-03-25 devnull /* suppress extra newline at EOF unless we are labeling matches with file name */
234 8ad51794 2004-03-25 devnull Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
235 8ad51794 2004-03-25 devnull if(flag & Bflag)
236 8ad51794 2004-03-25 devnull Bflush(&bout);
237 8ad51794 2004-03-25 devnull }
238 8ad51794 2004-03-25 devnull if((lineno & Flshcnt) == 0)
239 8ad51794 2004-03-25 devnull Bflush(&bout);
240 8ad51794 2004-03-25 devnull conti:
241 8ad51794 2004-03-25 devnull bol = lp;
242 8ad51794 2004-03-25 devnull }
243 8ad51794 2004-03-25 devnull if(lp != elp)
244 8ad51794 2004-03-25 devnull goto loopi;
245 8ad51794 2004-03-25 devnull goto loop0;
246 8ad51794 2004-03-25 devnull }
247 8ad51794 2004-03-25 devnull
248 8ad51794 2004-03-25 devnull State*
249 8ad51794 2004-03-25 devnull initstate(Re *r)
250 8ad51794 2004-03-25 devnull {
251 8ad51794 2004-03-25 devnull State *s;
252 8ad51794 2004-03-25 devnull int i;
253 8ad51794 2004-03-25 devnull
254 8ad51794 2004-03-25 devnull addcase(r);
255 8ad51794 2004-03-25 devnull if(flags['1'])
256 8ad51794 2004-03-25 devnull reprint("r", r);
257 8ad51794 2004-03-25 devnull nfollow = 0;
258 8ad51794 2004-03-25 devnull gen++;
259 8ad51794 2004-03-25 devnull fol1(r, Cbegin);
260 8ad51794 2004-03-25 devnull follow[nfollow++] = r;
261 8ad51794 2004-03-25 devnull qsort(follow, nfollow, sizeof(*follow), fcmp);
262 8ad51794 2004-03-25 devnull
263 8ad51794 2004-03-25 devnull s = sal(nfollow);
264 8ad51794 2004-03-25 devnull for(i=0; i<nfollow; i++)
265 8ad51794 2004-03-25 devnull s->re[i] = follow[i];
266 8ad51794 2004-03-25 devnull return s;
267 8ad51794 2004-03-25 devnull }