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