Bell 32V release
[unix-history] / usr / src / cmd / sdb / re.c
CommitLineData
c9e00be6
TL
1#include "head.h"
2#define CBRA 1
3#define CCHR 2
4#define CDOT 4
5#define CCL 6
6#define NCCL 8
7#define CDOL 10
8#define CEOF 11
9#define CKET 12
10#define CBACK 18
11
12#define CSTAR 01
13
14#define LBSIZE 512
15#define ESIZE 256
16#define NBRA 9
17
18char expbuf[ESIZE];
19int circf;
20char *braslist[NBRA];
21char *braelist[NBRA];
22char bittab[] = {
23 1,
24 2,
25 4,
26 8,
27 16,
28 32,
29 64,
30 128
31};
32
33dore() {
34 register int line;
35 register char *p;
36
37 line = fline;
38 compile(re);
39 do {
40 if (redir) fnext();
41 else fprev();
42 p = fbuf;
43 while(*p++ != '\n')
44 ;
45 *--p = '\0';
46 if (match(fbuf)) goto l1;
47 } while (fline != line);
48 error("No match");
49l1: *p = '\n';
50 fprint();
51}
52
53
54compile(astr)
55char *astr;
56{
57 register c;
58 register char *ep, *sp;
59 char *cstart;
60 char *lastep;
61 int cclcnt;
62 char bracket[NBRA], *bracketp;
63 int closed;
64 char numbra;
65 char neg;
66
67 ep = expbuf;
68 sp = astr;
69 lastep = 0;
70 bracketp = bracket;
71 closed = numbra = 0;
72 if (*sp == '^') {
73 circf++;
74 sp++;
75 }
76 for (;;) {
77 if (ep >= &expbuf[ESIZE])
78 goto cerror;
79 if ((c = *sp++) != '*')
80 lastep = ep;
81 switch (c) {
82
83 case '\0':
84 *ep++ = CEOF;
85 return;
86
87 case '.':
88 *ep++ = CDOT;
89 continue;
90
91 case '*':
92 if (lastep==0 || *lastep==CBRA || *lastep==CKET)
93 goto defchar;
94 *lastep |= CSTAR;
95 continue;
96
97 case '$':
98 if (*sp != '\0')
99 goto defchar;
100 *ep++ = CDOL;
101 continue;
102
103 case '[':
104 if(&ep[17] >= &expbuf[ESIZE])
105 goto cerror;
106 *ep++ = CCL;
107 neg = 0;
108 if((c = *sp++) == '^') {
109 neg = 1;
110 c = *sp++;
111 }
112 cstart = sp;
113 do {
114 if (c=='\0')
115 goto cerror;
116 if (c=='-' && sp>cstart && *sp!=']') {
117 for (c = sp[-2]; c<*sp; c++)
118 ep[c>>3] |= bittab[c&07];
119 sp++;
120 }
121 ep[c>>3] |= bittab[c&07];
122 } while((c = *sp++) != ']');
123 if(neg) {
124 for(cclcnt = 0; cclcnt < 16; cclcnt++)
125 ep[cclcnt] ^= -1;
126 ep[0] &= 0376;
127 }
128
129 ep += 16;
130
131 continue;
132
133 case '\\':
134 if((c = *sp++) == '(') {
135 if(numbra >= NBRA) {
136 goto cerror;
137 }
138 *bracketp++ = numbra;
139 *ep++ = CBRA;
140 *ep++ = numbra++;
141 continue;
142 }
143 if(c == ')') {
144 if(bracketp <= bracket) {
145 goto cerror;
146 }
147 *ep++ = CKET;
148 *ep++ = *--bracketp;
149 closed++;
150 continue;
151 }
152
153 if(c >= '1' && c <= '9') {
154 if((c -= '1') >= closed)
155 goto cerror;
156 *ep++ = CBACK;
157 *ep++ = c;
158 continue;
159 }
160
161 defchar:
162 default:
163 *ep++ = CCHR;
164 *ep++ = c;
165 }
166 }
167 cerror:
168 errexit("RE error\n", (char *)NULL);
169}
170
171match(p1)
172register char *p1; {
173 register char *p2;
174 register c;
175 p2 = expbuf;
176 if (circf) {
177 if (advance(p1, p2))
178 goto found;
179 goto nfound;
180 }
181 /* fast check for first character */
182 if (*p2==CCHR) {
183 c = p2[1];
184 do {
185 if (*p1!=c)
186 continue;
187 if (advance(p1, p2))
188 goto found;
189 } while (*p1++);
190 goto nfound;
191 }
192 /* regular algorithm */
193 do {
194 if (advance(p1, p2))
195 goto found;
196 } while (*p1++);
197 nfound:
198 return(0);
199 found:
200 return(1);
201}
202
203advance(lp, ep)
204register char *lp, *ep;
205{
206 register char *curlp;
207 char c;
208 char *bbeg;
209 int ct;
210
211 for (;;) switch (*ep++) {
212
213 case CCHR:
214 if (*ep++ == *lp++)
215 continue;
216 return(0);
217
218 case CDOT:
219 if (*lp++)
220 continue;
221 return(0);
222
223 case CDOL:
224 if (*lp=='\0')
225 continue;
226 return(0);
227
228 case CEOF:
229 return(1);
230
231 case CCL:
232 c = *lp++ & 0177;
233 if(ep[c>>3] & bittab[c & 07]) {
234 ep += 16;
235 continue;
236 }
237 return(0);
238 case CBRA:
239 braslist[*ep++] = lp;
240 continue;
241
242 case CKET:
243 braelist[*ep++] = lp;
244 continue;
245
246 case CBACK:
247 bbeg = braslist[*ep];
248 if (braelist[*ep]==0)
249 return(0);
250 ct = braelist[*ep++] - bbeg;
251 if(ecmp(bbeg, lp, ct)) {
252 lp += ct;
253 continue;
254 }
255 return(0);
256
257 case CBACK|CSTAR:
258 bbeg = braslist[*ep];
259 if (braelist[*ep]==0)
260 return(0);
261 ct = braelist[*ep++] - bbeg;
262 curlp = lp;
263 while(ecmp(bbeg, lp, ct))
264 lp += ct;
265 while(lp >= curlp) {
266 if(advance(lp, ep)) return(1);
267 lp -= ct;
268 }
269 return(0);
270
271
272 case CDOT|CSTAR:
273 curlp = lp;
274 while (*lp++);
275 goto star;
276
277 case CCHR|CSTAR:
278 curlp = lp;
279 while (*lp++ == *ep);
280 ep++;
281 goto star;
282
283 case CCL|CSTAR:
284 curlp = lp;
285 do {
286 c = *lp++ & 0177;
287 } while(ep[c>>3] & bittab[c & 07]);
288 ep += 16;
289 goto star;
290
291 star:
292 if(--lp == curlp) {
293 continue;
294 }
295
296 if(*ep == CCHR) {
297 c = ep[1];
298 do {
299 if(*lp != c)
300 continue;
301 if(advance(lp, ep))
302 return(1);
303 } while(lp-- > curlp);
304 return(0);
305 }
306
307 do {
308 if (advance(lp, ep))
309 return(1);
310 } while (lp-- > curlp);
311 return(0);
312
313 default:
314 errexit("RE botch\n", (char *)NULL);
315 }
316}
317ecmp(a, b, count)
318char *a, *b;
319{
320 register cc = count;
321 while(cc--)
322 if(*a++ != *b++) return(0);
323 return(1);
324}
325
326
327errexit(s)
328char *s; {
329 error(s);
330 return;
331}