1*219b2ee8SDavid du Colombier #define CBRA 2
2*219b2ee8SDavid du Colombier #define CCHR 4
3*219b2ee8SDavid du Colombier #define CDOT 8
4*219b2ee8SDavid du Colombier #define CCL 12
5*219b2ee8SDavid du Colombier #define CDOL 20
6*219b2ee8SDavid du Colombier #define CEOF 22
7*219b2ee8SDavid du Colombier #define CKET 24
8*219b2ee8SDavid du Colombier #define CBACK 36
9*219b2ee8SDavid du Colombier
10*219b2ee8SDavid du Colombier #define STAR 01
11*219b2ee8SDavid du Colombier #define RNGE 03
12*219b2ee8SDavid du Colombier
13*219b2ee8SDavid du Colombier #define NBRA 9
14*219b2ee8SDavid du Colombier
15*219b2ee8SDavid du Colombier #define PLACE(c) ep[c >> 3] |= bittab[c & 07]
16*219b2ee8SDavid du Colombier #define ISTHERE(c) (ep[c >> 3] & bittab[c & 07])
17*219b2ee8SDavid du Colombier
18*219b2ee8SDavid du Colombier char *braslist[NBRA];
19*219b2ee8SDavid du Colombier char *braelist[NBRA];
20*219b2ee8SDavid du Colombier int nbra, ebra;
21*219b2ee8SDavid du Colombier char *loc1, *loc2, *locs;
22*219b2ee8SDavid du Colombier int sed;
23*219b2ee8SDavid du Colombier
24*219b2ee8SDavid du Colombier int circf;
25*219b2ee8SDavid du Colombier int low;
26*219b2ee8SDavid du Colombier int size;
27*219b2ee8SDavid du Colombier
28*219b2ee8SDavid du Colombier char bittab[] = {
29*219b2ee8SDavid du Colombier 1,
30*219b2ee8SDavid du Colombier 2,
31*219b2ee8SDavid du Colombier 4,
32*219b2ee8SDavid du Colombier 8,
33*219b2ee8SDavid du Colombier 16,
34*219b2ee8SDavid du Colombier 32,
35*219b2ee8SDavid du Colombier 64,
36*219b2ee8SDavid du Colombier 128
37*219b2ee8SDavid du Colombier };
38*219b2ee8SDavid du Colombier
39*219b2ee8SDavid du Colombier char *
compile(instring,ep,endbuf,seof)40*219b2ee8SDavid du Colombier compile(instring, ep, endbuf, seof)
41*219b2ee8SDavid du Colombier register char *ep;
42*219b2ee8SDavid du Colombier char *instring, *endbuf;
43*219b2ee8SDavid du Colombier {
44*219b2ee8SDavid du Colombier INIT /* Dependent declarations and initializations */
45*219b2ee8SDavid du Colombier register c;
46*219b2ee8SDavid du Colombier register eof = seof;
47*219b2ee8SDavid du Colombier char *lastep = instring;
48*219b2ee8SDavid du Colombier int cclcnt;
49*219b2ee8SDavid du Colombier char bracket[NBRA], *bracketp;
50*219b2ee8SDavid du Colombier int closed;
51*219b2ee8SDavid du Colombier char neg;
52*219b2ee8SDavid du Colombier int lc;
53*219b2ee8SDavid du Colombier int i, cflg;
54*219b2ee8SDavid du Colombier
55*219b2ee8SDavid du Colombier lastep = 0;
56*219b2ee8SDavid du Colombier if((c = GETC()) == eof) {
57*219b2ee8SDavid du Colombier if(*ep == 0 && !sed)
58*219b2ee8SDavid du Colombier ERROR(41);
59*219b2ee8SDavid du Colombier RETURN(ep);
60*219b2ee8SDavid du Colombier }
61*219b2ee8SDavid du Colombier bracketp = bracket;
62*219b2ee8SDavid du Colombier circf = closed = nbra = ebra = 0;
63*219b2ee8SDavid du Colombier if (c == '^')
64*219b2ee8SDavid du Colombier circf++;
65*219b2ee8SDavid du Colombier else
66*219b2ee8SDavid du Colombier UNGETC(c);
67*219b2ee8SDavid du Colombier for (;;) {
68*219b2ee8SDavid du Colombier if (ep >= endbuf)
69*219b2ee8SDavid du Colombier ERROR(50);
70*219b2ee8SDavid du Colombier if((c = GETC()) != '*' && ((c != '\\') || (PEEKC() != '{')))
71*219b2ee8SDavid du Colombier lastep = ep;
72*219b2ee8SDavid du Colombier if (c == eof) {
73*219b2ee8SDavid du Colombier *ep++ = CEOF;
74*219b2ee8SDavid du Colombier RETURN(ep);
75*219b2ee8SDavid du Colombier }
76*219b2ee8SDavid du Colombier switch (c) {
77*219b2ee8SDavid du Colombier
78*219b2ee8SDavid du Colombier case '.':
79*219b2ee8SDavid du Colombier *ep++ = CDOT;
80*219b2ee8SDavid du Colombier continue;
81*219b2ee8SDavid du Colombier
82*219b2ee8SDavid du Colombier case '\n':
83*219b2ee8SDavid du Colombier ERROR(36);
84*219b2ee8SDavid du Colombier case '*':
85*219b2ee8SDavid du Colombier if (lastep==0 || *lastep==CBRA || *lastep==CKET)
86*219b2ee8SDavid du Colombier goto defchar;
87*219b2ee8SDavid du Colombier *lastep |= STAR;
88*219b2ee8SDavid du Colombier continue;
89*219b2ee8SDavid du Colombier
90*219b2ee8SDavid du Colombier case '$':
91*219b2ee8SDavid du Colombier if(PEEKC() != eof)
92*219b2ee8SDavid du Colombier goto defchar;
93*219b2ee8SDavid du Colombier *ep++ = CDOL;
94*219b2ee8SDavid du Colombier continue;
95*219b2ee8SDavid du Colombier
96*219b2ee8SDavid du Colombier case '[':
97*219b2ee8SDavid du Colombier if(&ep[17] >= endbuf)
98*219b2ee8SDavid du Colombier ERROR(50);
99*219b2ee8SDavid du Colombier
100*219b2ee8SDavid du Colombier *ep++ = CCL;
101*219b2ee8SDavid du Colombier lc = 0;
102*219b2ee8SDavid du Colombier for(i = 0; i < 16; i++)
103*219b2ee8SDavid du Colombier ep[i] = 0;
104*219b2ee8SDavid du Colombier
105*219b2ee8SDavid du Colombier neg = 0;
106*219b2ee8SDavid du Colombier if((c = GETC()) == '^') {
107*219b2ee8SDavid du Colombier neg = 1;
108*219b2ee8SDavid du Colombier c = GETC();
109*219b2ee8SDavid du Colombier }
110*219b2ee8SDavid du Colombier
111*219b2ee8SDavid du Colombier do {
112*219b2ee8SDavid du Colombier if(c == '\0' || c == '\n')
113*219b2ee8SDavid du Colombier ERROR(49);
114*219b2ee8SDavid du Colombier if(c == '-' && lc != 0) {
115*219b2ee8SDavid du Colombier if ((c = GETC()) == ']') {
116*219b2ee8SDavid du Colombier PLACE('-');
117*219b2ee8SDavid du Colombier break;
118*219b2ee8SDavid du Colombier }
119*219b2ee8SDavid du Colombier while(lc < c) {
120*219b2ee8SDavid du Colombier PLACE(lc);
121*219b2ee8SDavid du Colombier lc++;
122*219b2ee8SDavid du Colombier }
123*219b2ee8SDavid du Colombier }
124*219b2ee8SDavid du Colombier lc = c;
125*219b2ee8SDavid du Colombier PLACE(c);
126*219b2ee8SDavid du Colombier } while((c = GETC()) != ']');
127*219b2ee8SDavid du Colombier if(neg) {
128*219b2ee8SDavid du Colombier for(cclcnt = 0; cclcnt < 16; cclcnt++)
129*219b2ee8SDavid du Colombier ep[cclcnt] ^= -1;
130*219b2ee8SDavid du Colombier ep[0] &= 0376;
131*219b2ee8SDavid du Colombier }
132*219b2ee8SDavid du Colombier
133*219b2ee8SDavid du Colombier ep += 16;
134*219b2ee8SDavid du Colombier
135*219b2ee8SDavid du Colombier continue;
136*219b2ee8SDavid du Colombier
137*219b2ee8SDavid du Colombier case '\\':
138*219b2ee8SDavid du Colombier switch(c = GETC()) {
139*219b2ee8SDavid du Colombier
140*219b2ee8SDavid du Colombier case '(':
141*219b2ee8SDavid du Colombier if(nbra >= NBRA)
142*219b2ee8SDavid du Colombier ERROR(43);
143*219b2ee8SDavid du Colombier *bracketp++ = nbra;
144*219b2ee8SDavid du Colombier *ep++ = CBRA;
145*219b2ee8SDavid du Colombier *ep++ = nbra++;
146*219b2ee8SDavid du Colombier continue;
147*219b2ee8SDavid du Colombier
148*219b2ee8SDavid du Colombier case ')':
149*219b2ee8SDavid du Colombier if(bracketp <= bracket || ++ebra != nbra)
150*219b2ee8SDavid du Colombier ERROR(42);
151*219b2ee8SDavid du Colombier *ep++ = CKET;
152*219b2ee8SDavid du Colombier *ep++ = *--bracketp;
153*219b2ee8SDavid du Colombier closed++;
154*219b2ee8SDavid du Colombier continue;
155*219b2ee8SDavid du Colombier
156*219b2ee8SDavid du Colombier case '{':
157*219b2ee8SDavid du Colombier if(lastep == (char *) (0))
158*219b2ee8SDavid du Colombier goto defchar;
159*219b2ee8SDavid du Colombier *lastep |= RNGE;
160*219b2ee8SDavid du Colombier cflg = 0;
161*219b2ee8SDavid du Colombier nlim:
162*219b2ee8SDavid du Colombier c = GETC();
163*219b2ee8SDavid du Colombier i = 0;
164*219b2ee8SDavid du Colombier do {
165*219b2ee8SDavid du Colombier if ('0' <= c && c <= '9')
166*219b2ee8SDavid du Colombier i = 10 * i + c - '0';
167*219b2ee8SDavid du Colombier else
168*219b2ee8SDavid du Colombier ERROR(16);
169*219b2ee8SDavid du Colombier } while(((c = GETC()) != '\\') && (c != ','));
170*219b2ee8SDavid du Colombier if (i > 255)
171*219b2ee8SDavid du Colombier ERROR(11);
172*219b2ee8SDavid du Colombier *ep++ = i;
173*219b2ee8SDavid du Colombier if (c == ',') {
174*219b2ee8SDavid du Colombier if(cflg++)
175*219b2ee8SDavid du Colombier ERROR(44);
176*219b2ee8SDavid du Colombier if((c = GETC()) == '\\')
177*219b2ee8SDavid du Colombier *ep++ = 255;
178*219b2ee8SDavid du Colombier else {
179*219b2ee8SDavid du Colombier UNGETC(c);
180*219b2ee8SDavid du Colombier goto nlim; /* get 2'nd number */
181*219b2ee8SDavid du Colombier }
182*219b2ee8SDavid du Colombier }
183*219b2ee8SDavid du Colombier if(GETC() != '}')
184*219b2ee8SDavid du Colombier ERROR(45);
185*219b2ee8SDavid du Colombier if(!cflg) /* one number */
186*219b2ee8SDavid du Colombier *ep++ = i;
187*219b2ee8SDavid du Colombier else if((ep[-1] & 0377) < (ep[-2] & 0377))
188*219b2ee8SDavid du Colombier ERROR(46);
189*219b2ee8SDavid du Colombier continue;
190*219b2ee8SDavid du Colombier
191*219b2ee8SDavid du Colombier case '\n':
192*219b2ee8SDavid du Colombier ERROR(36);
193*219b2ee8SDavid du Colombier
194*219b2ee8SDavid du Colombier case 'n':
195*219b2ee8SDavid du Colombier c = '\n';
196*219b2ee8SDavid du Colombier goto defchar;
197*219b2ee8SDavid du Colombier
198*219b2ee8SDavid du Colombier default:
199*219b2ee8SDavid du Colombier if(c >= '1' && c <= '9') {
200*219b2ee8SDavid du Colombier if((c -= '1') >= closed)
201*219b2ee8SDavid du Colombier ERROR(25);
202*219b2ee8SDavid du Colombier *ep++ = CBACK;
203*219b2ee8SDavid du Colombier *ep++ = c;
204*219b2ee8SDavid du Colombier continue;
205*219b2ee8SDavid du Colombier }
206*219b2ee8SDavid du Colombier }
207*219b2ee8SDavid du Colombier /* Drop through to default to use \ to turn off special chars */
208*219b2ee8SDavid du Colombier
209*219b2ee8SDavid du Colombier defchar:
210*219b2ee8SDavid du Colombier default:
211*219b2ee8SDavid du Colombier lastep = ep;
212*219b2ee8SDavid du Colombier *ep++ = CCHR;
213*219b2ee8SDavid du Colombier *ep++ = c;
214*219b2ee8SDavid du Colombier }
215*219b2ee8SDavid du Colombier }
216*219b2ee8SDavid du Colombier }
217*219b2ee8SDavid du Colombier
step(p1,p2)218*219b2ee8SDavid du Colombier step(p1, p2)
219*219b2ee8SDavid du Colombier register char *p1, *p2;
220*219b2ee8SDavid du Colombier {
221*219b2ee8SDavid du Colombier register c;
222*219b2ee8SDavid du Colombier
223*219b2ee8SDavid du Colombier if (circf) {
224*219b2ee8SDavid du Colombier loc1 = p1;
225*219b2ee8SDavid du Colombier return(advance(p1, p2));
226*219b2ee8SDavid du Colombier }
227*219b2ee8SDavid du Colombier /* fast check for first character */
228*219b2ee8SDavid du Colombier if (*p2==CCHR) {
229*219b2ee8SDavid du Colombier c = p2[1];
230*219b2ee8SDavid du Colombier do {
231*219b2ee8SDavid du Colombier if (*p1 != c)
232*219b2ee8SDavid du Colombier continue;
233*219b2ee8SDavid du Colombier if (advance(p1, p2)) {
234*219b2ee8SDavid du Colombier loc1 = p1;
235*219b2ee8SDavid du Colombier return(1);
236*219b2ee8SDavid du Colombier }
237*219b2ee8SDavid du Colombier } while (*p1++);
238*219b2ee8SDavid du Colombier return(0);
239*219b2ee8SDavid du Colombier }
240*219b2ee8SDavid du Colombier /* regular algorithm */
241*219b2ee8SDavid du Colombier do {
242*219b2ee8SDavid du Colombier if (advance(p1, p2)) {
243*219b2ee8SDavid du Colombier loc1 = p1;
244*219b2ee8SDavid du Colombier return(1);
245*219b2ee8SDavid du Colombier }
246*219b2ee8SDavid du Colombier } while (*p1++);
247*219b2ee8SDavid du Colombier return(0);
248*219b2ee8SDavid du Colombier }
249*219b2ee8SDavid du Colombier
advance(lp,ep)250*219b2ee8SDavid du Colombier advance(lp, ep)
251*219b2ee8SDavid du Colombier register char *lp, *ep;
252*219b2ee8SDavid du Colombier {
253*219b2ee8SDavid du Colombier register char *curlp;
254*219b2ee8SDavid du Colombier char c;
255*219b2ee8SDavid du Colombier char *bbeg;
256*219b2ee8SDavid du Colombier int ct;
257*219b2ee8SDavid du Colombier
258*219b2ee8SDavid du Colombier for (;;) switch (*ep++) {
259*219b2ee8SDavid du Colombier
260*219b2ee8SDavid du Colombier case CCHR:
261*219b2ee8SDavid du Colombier if (*ep++ == *lp++)
262*219b2ee8SDavid du Colombier continue;
263*219b2ee8SDavid du Colombier return(0);
264*219b2ee8SDavid du Colombier
265*219b2ee8SDavid du Colombier case CDOT:
266*219b2ee8SDavid du Colombier if (*lp++)
267*219b2ee8SDavid du Colombier continue;
268*219b2ee8SDavid du Colombier return(0);
269*219b2ee8SDavid du Colombier
270*219b2ee8SDavid du Colombier case CDOL:
271*219b2ee8SDavid du Colombier if (*lp==0)
272*219b2ee8SDavid du Colombier continue;
273*219b2ee8SDavid du Colombier return(0);
274*219b2ee8SDavid du Colombier
275*219b2ee8SDavid du Colombier case CEOF:
276*219b2ee8SDavid du Colombier loc2 = lp;
277*219b2ee8SDavid du Colombier return(1);
278*219b2ee8SDavid du Colombier
279*219b2ee8SDavid du Colombier case CCL:
280*219b2ee8SDavid du Colombier c = *lp++ & 0177;
281*219b2ee8SDavid du Colombier if(ISTHERE(c)) {
282*219b2ee8SDavid du Colombier ep += 16;
283*219b2ee8SDavid du Colombier continue;
284*219b2ee8SDavid du Colombier }
285*219b2ee8SDavid du Colombier return(0);
286*219b2ee8SDavid du Colombier case CBRA:
287*219b2ee8SDavid du Colombier braslist[*ep++] = lp;
288*219b2ee8SDavid du Colombier continue;
289*219b2ee8SDavid du Colombier
290*219b2ee8SDavid du Colombier case CKET:
291*219b2ee8SDavid du Colombier braelist[*ep++] = lp;
292*219b2ee8SDavid du Colombier continue;
293*219b2ee8SDavid du Colombier
294*219b2ee8SDavid du Colombier case CCHR|RNGE:
295*219b2ee8SDavid du Colombier c = *ep++;
296*219b2ee8SDavid du Colombier getrnge(ep);
297*219b2ee8SDavid du Colombier while(low--)
298*219b2ee8SDavid du Colombier if(*lp++ != c)
299*219b2ee8SDavid du Colombier return(0);
300*219b2ee8SDavid du Colombier curlp = lp;
301*219b2ee8SDavid du Colombier while(size--)
302*219b2ee8SDavid du Colombier if(*lp++ != c)
303*219b2ee8SDavid du Colombier break;
304*219b2ee8SDavid du Colombier if(size < 0)
305*219b2ee8SDavid du Colombier lp++;
306*219b2ee8SDavid du Colombier ep += 2;
307*219b2ee8SDavid du Colombier goto star;
308*219b2ee8SDavid du Colombier
309*219b2ee8SDavid du Colombier case CDOT|RNGE:
310*219b2ee8SDavid du Colombier getrnge(ep);
311*219b2ee8SDavid du Colombier while(low--)
312*219b2ee8SDavid du Colombier if(*lp++ == '\0')
313*219b2ee8SDavid du Colombier return(0);
314*219b2ee8SDavid du Colombier curlp = lp;
315*219b2ee8SDavid du Colombier while(size--)
316*219b2ee8SDavid du Colombier if(*lp++ == '\0')
317*219b2ee8SDavid du Colombier break;
318*219b2ee8SDavid du Colombier if(size < 0)
319*219b2ee8SDavid du Colombier lp++;
320*219b2ee8SDavid du Colombier ep += 2;
321*219b2ee8SDavid du Colombier goto star;
322*219b2ee8SDavid du Colombier
323*219b2ee8SDavid du Colombier case CCL|RNGE:
324*219b2ee8SDavid du Colombier getrnge(ep + 16);
325*219b2ee8SDavid du Colombier while(low--) {
326*219b2ee8SDavid du Colombier c = *lp++ & 0177;
327*219b2ee8SDavid du Colombier if(!ISTHERE(c))
328*219b2ee8SDavid du Colombier return(0);
329*219b2ee8SDavid du Colombier }
330*219b2ee8SDavid du Colombier curlp = lp;
331*219b2ee8SDavid du Colombier while(size--) {
332*219b2ee8SDavid du Colombier c = *lp++ & 0177;
333*219b2ee8SDavid du Colombier if(!ISTHERE(c))
334*219b2ee8SDavid du Colombier break;
335*219b2ee8SDavid du Colombier }
336*219b2ee8SDavid du Colombier if(size < 0)
337*219b2ee8SDavid du Colombier lp++;
338*219b2ee8SDavid du Colombier ep += 18; /* 16 + 2 */
339*219b2ee8SDavid du Colombier goto star;
340*219b2ee8SDavid du Colombier
341*219b2ee8SDavid du Colombier case CBACK:
342*219b2ee8SDavid du Colombier bbeg = braslist[*ep];
343*219b2ee8SDavid du Colombier ct = braelist[*ep++] - bbeg;
344*219b2ee8SDavid du Colombier
345*219b2ee8SDavid du Colombier if(ecmp(bbeg, lp, ct)) {
346*219b2ee8SDavid du Colombier lp += ct;
347*219b2ee8SDavid du Colombier continue;
348*219b2ee8SDavid du Colombier }
349*219b2ee8SDavid du Colombier return(0);
350*219b2ee8SDavid du Colombier
351*219b2ee8SDavid du Colombier case CBACK|STAR:
352*219b2ee8SDavid du Colombier bbeg = braslist[*ep];
353*219b2ee8SDavid du Colombier ct = braelist[*ep++] - bbeg;
354*219b2ee8SDavid du Colombier curlp = lp;
355*219b2ee8SDavid du Colombier while(ecmp(bbeg, lp, ct))
356*219b2ee8SDavid du Colombier lp += ct;
357*219b2ee8SDavid du Colombier
358*219b2ee8SDavid du Colombier while(lp >= curlp) {
359*219b2ee8SDavid du Colombier if(advance(lp, ep)) return(1);
360*219b2ee8SDavid du Colombier lp -= ct;
361*219b2ee8SDavid du Colombier }
362*219b2ee8SDavid du Colombier return(0);
363*219b2ee8SDavid du Colombier
364*219b2ee8SDavid du Colombier
365*219b2ee8SDavid du Colombier case CDOT|STAR:
366*219b2ee8SDavid du Colombier curlp = lp;
367*219b2ee8SDavid du Colombier while (*lp++);
368*219b2ee8SDavid du Colombier goto star;
369*219b2ee8SDavid du Colombier
370*219b2ee8SDavid du Colombier case CCHR|STAR:
371*219b2ee8SDavid du Colombier curlp = lp;
372*219b2ee8SDavid du Colombier while (*lp++ == *ep);
373*219b2ee8SDavid du Colombier ep++;
374*219b2ee8SDavid du Colombier goto star;
375*219b2ee8SDavid du Colombier
376*219b2ee8SDavid du Colombier case CCL|STAR:
377*219b2ee8SDavid du Colombier curlp = lp;
378*219b2ee8SDavid du Colombier do {
379*219b2ee8SDavid du Colombier c = *lp++ & 0177;
380*219b2ee8SDavid du Colombier } while(ISTHERE(c));
381*219b2ee8SDavid du Colombier ep += 16;
382*219b2ee8SDavid du Colombier goto star;
383*219b2ee8SDavid du Colombier
384*219b2ee8SDavid du Colombier star:
385*219b2ee8SDavid du Colombier do {
386*219b2ee8SDavid du Colombier if(--lp == locs)
387*219b2ee8SDavid du Colombier break;
388*219b2ee8SDavid du Colombier if (advance(lp, ep))
389*219b2ee8SDavid du Colombier return(1);
390*219b2ee8SDavid du Colombier } while (lp > curlp);
391*219b2ee8SDavid du Colombier return(0);
392*219b2ee8SDavid du Colombier
393*219b2ee8SDavid du Colombier }
394*219b2ee8SDavid du Colombier }
395*219b2ee8SDavid du Colombier
getrnge(str)396*219b2ee8SDavid du Colombier getrnge(str)
397*219b2ee8SDavid du Colombier register char *str;
398*219b2ee8SDavid du Colombier {
399*219b2ee8SDavid du Colombier low = *str++ & 0377;
400*219b2ee8SDavid du Colombier size = *str == 255 ? 20000 : (*str &0377) - low;
401*219b2ee8SDavid du Colombier }
402*219b2ee8SDavid du Colombier
ecmp(a,b,count)403*219b2ee8SDavid du Colombier ecmp(a, b, count)
404*219b2ee8SDavid du Colombier register char *a, *b;
405*219b2ee8SDavid du Colombier register count;
406*219b2ee8SDavid du Colombier {
407*219b2ee8SDavid du Colombier while(count--)
408*219b2ee8SDavid du Colombier if(*a++ != *b++) return(0);
409*219b2ee8SDavid du Colombier return(1);
410*219b2ee8SDavid du Colombier }
411