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