Introduction
Introduction Statistics Contact Development Disclaimer Help
main.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
main.c (4832B)
---
1 #define EXTERN
2 #include "grep.h"
3
4 char *validflags = "bchiLlnsv";
5 void
6 usage(void)
7 {
8 fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", …
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(ARGF());
35 break;
36
37 case 'f':
38 flags['f']++;
39 filename = ARGF();
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 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.