Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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 *
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
 
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
 
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
 
396
getrnge(str)
397
register char *str;
398
{
399
	low = *str++ & 0377;
400
	size = *str == 255 ? 20000 : (*str &0377) - low;
401
}
402
 
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
}