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