Introduction
Introduction Statistics Contact Development Disclaimer Help
sub.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
sub.c (4041B)
---
1 #include "grep.h"
2
3 void*
4 mal(int n)
5 {
6 static char *s = NULL;
7 static int m = 0;
8 void *v = NULL;
9
10 n = (n+3) & ~3;
11 if(m < n) {
12 if(n > Nhunk) {
13 v = malloc(n);
14 if(v != NULL)
15 memset(v, 0, n);
16 return v;
17 }
18 s = malloc(Nhunk);
19 m = Nhunk;
20 }
21 v = s;
22 if(s != NULL)
23 s += n;
24 m -= n;
25 if(v != NULL)
26 memset(v, 0, n);
27 return v;
28 }
29
30 State*
31 sal(int n)
32 {
33 State *s;
34
35 s = mal(sizeof(*s));
36 /* s->next = mal(256*sizeof(*s->next)); */
37 s->count = n;
38 s->re = mal(n*sizeof(*state0->re));
39 return s;
40 }
41
42 Re*
43 ral(int type)
44 {
45 Re *r;
46
47 r = mal(sizeof(*r));
48 r->type = type;
49 maxfollow++;
50 return r;
51 }
52
53 void
54 error(char *s)
55 {
56 fprint(2, "grep: internal error: %s\n", s);
57 exits(s);
58 }
59
60 int
61 countor(Re *r)
62 {
63 int n;
64
65 n = 0;
66 loop:
67 switch(r->type) {
68 case Tor:
69 n += countor(r->u.alt);
70 r = r->next;
71 goto loop;
72 case Tclass:
73 return n + r->u.x.hi - r->u.x.lo + 1;
74 }
75 return n;
76 }
77
78 Re*
79 oralloc(int t, Re *r, Re *b)
80 {
81 Re *a;
82
83 if(b == 0)
84 return r;
85 a = ral(t);
86 a->u.alt = r;
87 a->next = b;
88 return a;
89 }
90
91 void
92 case1(Re *c, Re *r)
93 {
94 int n;
95
96 loop:
97 switch(r->type) {
98 case Tor:
99 case1(c, r->u.alt);
100 r = r->next;
101 goto loop;
102
103 case Tclass: /* add to character */
104 for(n=r->u.x.lo; n<=r->u.x.hi; n++)
105 c->u.cases[n] = oralloc(Tor, r->next, c->u.cases…
106 break;
107
108 default: /* add everything unknown to next */
109 c->next = oralloc(Talt, r, c->next);
110 break;
111 }
112 }
113
114 Re*
115 addcase(Re *r)
116 {
117 int i, n;
118 Re *a;
119
120 if(r->gen == gen)
121 return r;
122 r->gen = gen;
123 switch(r->type) {
124 default:
125 error("addcase");
126
127 case Tor:
128 n = countor(r);
129 if(n >= Caselim) {
130 a = ral(Tcase);
131 a->u.cases = mal(256*sizeof(*a->u.cases));
132 case1(a, r);
133 for(i=0; i<256; i++)
134 if(a->u.cases[i]) {
135 r = a->u.cases[i];
136 if(countor(r) < n)
137 a->u.cases[i] = addcase(…
138 }
139 return a;
140 }
141 return r;
142
143 case Talt:
144 r->next = addcase(r->next);
145 r->u.alt = addcase(r->u.alt);
146 return r;
147
148 case Tbegin:
149 case Tend:
150 case Tclass:
151 return r;
152 }
153 }
154
155 void
156 str2top(char *p)
157 {
158 Re2 oldtop;
159
160 oldtop = topre;
161 input = p;
162 topre.beg = 0;
163 topre.end = 0;
164 yyparse();
165 gen++;
166 if(topre.beg == 0)
167 yyerror("syntax");
168 if(oldtop.beg)
169 topre = re2or(oldtop, topre);
170 }
171
172 void
173 appendnext(Re *a, Re *b)
174 {
175 Re *n;
176
177 while(n = a->next)
178 a = n;
179 a->next = b;
180 }
181
182 void
183 patchnext(Re *a, Re *b)
184 {
185 Re *n;
186
187 while(a) {
188 n = a->next;
189 a->next = b;
190 a = n;
191 }
192 }
193
194 int
195 getrec(void)
196 {
197 int c;
198
199 if(flags['f']) {
200 c = Bgetc(rein);
201 if(c <= 0)
202 return 0;
203 } else
204 c = *input++ & 0xff;
205 if(flags['i'] && c >= 'A' && c <= 'Z')
206 c += 'a'-'A';
207 if(c == '\n')
208 lineno++;
209 return c;
210 }
211
212 Re2
213 re2cat(Re2 a, Re2 b)
214 {
215 Re2 c;
216
217 c.beg = a.beg;
218 c.end = b.end;
219 patchnext(a.end, b.beg);
220 return c;
221 }
222
223 Re2
224 re2star(Re2 a)
225 {
226 Re2 c;
227
228 c.beg = ral(Talt);
229 c.beg->u.alt = a.beg;
230 patchnext(a.end, c.beg);
231 c.end = c.beg;
232 return c;
233 }
234
235 Re2
236 re2or(Re2 a, Re2 b)
237 {
238 Re2 c;
239
240 c.beg = ral(Tor);
241 c.beg->u.alt = b.beg;
242 c.beg->next = a.beg;
243 c.end = b.end;
244 appendnext(c.end, a.end);
245 return c;
246 }
247
248 Re2
249 re2char(int c0, int c1)
250 {
251 Re2 c;
252
253 c.beg = ral(Tclass);
254 c.beg->u.x.lo = c0 & 0xff;
255 c.beg->u.x.hi = c1 & 0xff;
256 c.end = c.beg;
257 return c;
258 }
259
260 void
261 reprint1(Re *a)
262 {
263 int i, j;
264
265 loop:
266 if(a == 0)
267 return;
268 if(a->gen == gen)
269 return;
270 a->gen = gen;
271 print("%p: ", a);
272 switch(a->type) {
273 default:
274 print("type %d\n", a->type);
275 error("print1 type");
276
277 case Tcase:
278 print("case ->%p\n", a->next);
279 for(i=0; i<256; i++)
280 if(a->u.cases[i]) {
281 for(j=i+1; j<256; j++)
282 if(a->u.cases[i] != a->u.cases[j…
283 break;
284 print(" [%.2x-%.2x] ->%p\n", i, j…
285 i = j-1;
286 }
287 for(i=0; i<256; i++)
288 reprint1(a->u.cases[i]);
289 break;
290
291 case Tbegin:
292 print("^ ->%p\n", a->next);
293 break;
294
295 case Tend:
296 print("$ ->%p\n", a->next);
297 break;
298
299 case Tclass:
300 print("[%.2x-%.2x] ->%p\n", a->u.x.lo, a->u.x.hi, a->nex…
301 break;
302
303 case Tor:
304 case Talt:
305 print("| %p ->%p\n", a->u.alt, a->next);
306 reprint1(a->u.alt);
307 break;
308 }
309 a = a->next;
310 goto loop;
311 }
312
313 void
314 reprint(char *s, Re *r)
315 {
316 print("%s:\n", s);
317 gen++;
318 reprint1(r);
319 print("\n\n");
320 }
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.