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