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