xref: /csrg-svn/old/sdb/re.c (revision 7776)
1*7776Srrh static	char sccsid[] = "@(#)re.c 4.2 08/17/82";
21348Sbill #include "head.h"
31348Sbill #define	CBRA	1
41348Sbill #define	CCHR	2
51348Sbill #define	CDOT	4
61348Sbill #define	CCL	6
71348Sbill #define	NCCL	8
81348Sbill #define	CDOL	10
91348Sbill #define	CEOF	11
101348Sbill #define	CKET	12
111348Sbill #define	CBACK	18
121348Sbill 
131348Sbill #define	CSTAR	01
141348Sbill 
151348Sbill #define	LBSIZE	512
161348Sbill #define	ESIZE	256
171348Sbill #define	NBRA	9
181348Sbill 
191348Sbill char	expbuf[ESIZE];
201348Sbill int	circf;
211348Sbill char	*braslist[NBRA];
221348Sbill char	*braelist[NBRA];
231348Sbill char	bittab[] = {
241348Sbill 	1,
251348Sbill 	2,
261348Sbill 	4,
271348Sbill 	8,
281348Sbill 	16,
291348Sbill 	32,
301348Sbill 	64,
311348Sbill 	128
321348Sbill };
331348Sbill 
dore()341348Sbill dore() {
351348Sbill 	register int line;
361348Sbill 	register char *p;
371348Sbill 
381348Sbill 	circf = 0;
391348Sbill 	line = fline;
401348Sbill 	compile(re);
411348Sbill 	do {
421348Sbill 		if (redir) fnext();
431348Sbill 		else fprev();
441348Sbill 		p = fbuf;
451348Sbill 		while(*p++ != '\n')
461348Sbill 			;
471348Sbill 		*--p = '\0';
481348Sbill 		if (match(fbuf)) goto l1;
491348Sbill 	} while (fline != line);
501348Sbill 	error("No match");
511348Sbill l1:	*p = '\n';
521348Sbill 	fprint();
531348Sbill }
541348Sbill 
551348Sbill 
compile(astr)561348Sbill compile(astr)
571348Sbill char *astr;
581348Sbill {
591348Sbill 	register c;
601348Sbill 	register char *ep, *sp;
611348Sbill 	char *cstart;
621348Sbill 	char *lastep;
631348Sbill 	int cclcnt;
641348Sbill 	char bracket[NBRA], *bracketp;
651348Sbill 	int closed;
661348Sbill 	char numbra;
671348Sbill 	char neg;
681348Sbill 
691348Sbill 	ep = expbuf;
701348Sbill 	sp = astr;
711348Sbill 	lastep = 0;
721348Sbill 	bracketp = bracket;
731348Sbill 	closed = numbra = 0;
741348Sbill 	if (*sp == '^') {
751348Sbill 		circf++;
761348Sbill 		sp++;
771348Sbill 	}
781348Sbill 	for (;;) {
791348Sbill 		if (ep >= &expbuf[ESIZE])
801348Sbill 			goto cerror;
811348Sbill 		if ((c = *sp++) != '*')
821348Sbill 			lastep = ep;
831348Sbill 		switch (c) {
841348Sbill 
851348Sbill 		case '\0':
861348Sbill 			*ep++ = CEOF;
871348Sbill 			return;
881348Sbill 
891348Sbill 		case '.':
901348Sbill 			*ep++ = CDOT;
911348Sbill 			continue;
921348Sbill 
931348Sbill 		case '*':
941348Sbill 			if (lastep==0 || *lastep==CBRA || *lastep==CKET)
951348Sbill 				goto defchar;
961348Sbill 			*lastep |= CSTAR;
971348Sbill 			continue;
981348Sbill 
991348Sbill 		case '$':
1001348Sbill 			if (*sp != '\0')
1011348Sbill 				goto defchar;
1021348Sbill 			*ep++ = CDOL;
1031348Sbill 			continue;
1041348Sbill 
1051348Sbill 		case '[':
1061348Sbill 			if(&ep[17] >= &expbuf[ESIZE])
1071348Sbill 				goto cerror;
1081348Sbill 			*ep++ = CCL;
1091348Sbill 			neg = 0;
1101348Sbill 			if((c = *sp++) == '^') {
1111348Sbill 				neg = 1;
1121348Sbill 				c = *sp++;
1131348Sbill 			}
1141348Sbill 			cstart = sp;
1151348Sbill 			do {
1161348Sbill 				if (c=='\0')
1171348Sbill 					goto cerror;
1181348Sbill 				if (c=='-' && sp>cstart && *sp!=']') {
1191348Sbill 					for (c = sp[-2]; c<*sp; c++)
1201348Sbill 						ep[c>>3] |= bittab[c&07];
1211348Sbill 					sp++;
1221348Sbill 				}
1231348Sbill 				ep[c>>3] |= bittab[c&07];
1241348Sbill 			} while((c = *sp++) != ']');
1251348Sbill 			if(neg) {
1261348Sbill 				for(cclcnt = 0; cclcnt < 16; cclcnt++)
1271348Sbill 					ep[cclcnt] ^= -1;
1281348Sbill 				ep[0] &= 0376;
1291348Sbill 			}
1301348Sbill 
1311348Sbill 			ep += 16;
1321348Sbill 
1331348Sbill 			continue;
1341348Sbill 
1351348Sbill 		case '\\':
1361348Sbill 			if((c = *sp++) == '(') {
1371348Sbill 				if(numbra >= NBRA) {
1381348Sbill 					goto cerror;
1391348Sbill 				}
1401348Sbill 				*bracketp++ = numbra;
1411348Sbill 				*ep++ = CBRA;
1421348Sbill 				*ep++ = numbra++;
1431348Sbill 				continue;
1441348Sbill 			}
1451348Sbill 			if(c == ')') {
1461348Sbill 				if(bracketp <= bracket) {
1471348Sbill 					goto cerror;
1481348Sbill 				}
1491348Sbill 				*ep++ = CKET;
1501348Sbill 				*ep++ = *--bracketp;
1511348Sbill 				closed++;
1521348Sbill 				continue;
1531348Sbill 			}
1541348Sbill 
1551348Sbill 			if(c >= '1' && c <= '9') {
1561348Sbill 				if((c -= '1') >= closed)
1571348Sbill 					goto cerror;
1581348Sbill 				*ep++ = CBACK;
1591348Sbill 				*ep++ = c;
1601348Sbill 				continue;
1611348Sbill 			}
1621348Sbill 
1631348Sbill 		defchar:
1641348Sbill 		default:
1651348Sbill 			*ep++ = CCHR;
1661348Sbill 			*ep++ = c;
1671348Sbill 		}
1681348Sbill 	}
1691348Sbill     cerror:
1701348Sbill 	errexit("RE error\n", (char *)NULL);
1711348Sbill }
1721348Sbill 
match(p1)1731348Sbill match(p1)
1741348Sbill register char *p1; {
1751348Sbill 	register char *p2;
1761348Sbill 	register c;
1771348Sbill 		p2 = expbuf;
1781348Sbill 		if (circf) {
1791348Sbill 			if (advance(p1, p2))
1801348Sbill 				goto found;
1811348Sbill 			goto nfound;
1821348Sbill 		}
1831348Sbill 		/* fast check for first character */
1841348Sbill 		if (*p2==CCHR) {
1851348Sbill 			c = p2[1];
1861348Sbill 			do {
1871348Sbill 				if (*p1!=c)
1881348Sbill 					continue;
1891348Sbill 				if (advance(p1, p2))
1901348Sbill 					goto found;
1911348Sbill 			} while (*p1++);
1921348Sbill 			goto nfound;
1931348Sbill 		}
1941348Sbill 		/* regular algorithm */
1951348Sbill 		do {
1961348Sbill 			if (advance(p1, p2))
1971348Sbill 				goto found;
1981348Sbill 		} while (*p1++);
1991348Sbill 	nfound:
2001348Sbill 		return(0);
2011348Sbill 	found:
2021348Sbill 		return(1);
2031348Sbill }
2041348Sbill 
advance(lp,ep)2051348Sbill advance(lp, ep)
2061348Sbill register char *lp, *ep;
2071348Sbill {
2081348Sbill 	register char *curlp;
2091348Sbill 	char c;
2101348Sbill 	char *bbeg;
2111348Sbill 	int ct;
2121348Sbill 
2131348Sbill 	for (;;) switch (*ep++) {
2141348Sbill 
2151348Sbill 	case CCHR:
2161348Sbill 		if (*ep++ == *lp++)
2171348Sbill 			continue;
2181348Sbill 		return(0);
2191348Sbill 
2201348Sbill 	case CDOT:
2211348Sbill 		if (*lp++)
2221348Sbill 			continue;
2231348Sbill 		return(0);
2241348Sbill 
2251348Sbill 	case CDOL:
2261348Sbill 		if (*lp=='\0')
2271348Sbill 			continue;
2281348Sbill 		return(0);
2291348Sbill 
2301348Sbill 	case CEOF:
2311348Sbill 		return(1);
2321348Sbill 
2331348Sbill 	case CCL:
2341348Sbill 		c = *lp++ & 0177;
2351348Sbill 		if(ep[c>>3] & bittab[c & 07]) {
2361348Sbill 			ep += 16;
2371348Sbill 			continue;
2381348Sbill 		}
2391348Sbill 		return(0);
2401348Sbill 	case CBRA:
2411348Sbill 		braslist[*ep++] = lp;
2421348Sbill 		continue;
2431348Sbill 
2441348Sbill 	case CKET:
2451348Sbill 		braelist[*ep++] = lp;
2461348Sbill 		continue;
2471348Sbill 
2481348Sbill 	case CBACK:
2491348Sbill 		bbeg = braslist[*ep];
2501348Sbill 		if (braelist[*ep]==0)
2511348Sbill 			return(0);
2521348Sbill 		ct = braelist[*ep++] - bbeg;
2531348Sbill 		if(ecmp(bbeg, lp, ct)) {
2541348Sbill 			lp += ct;
2551348Sbill 			continue;
2561348Sbill 		}
2571348Sbill 		return(0);
2581348Sbill 
2591348Sbill 	case CBACK|CSTAR:
2601348Sbill 		bbeg = braslist[*ep];
2611348Sbill 		if (braelist[*ep]==0)
2621348Sbill 			return(0);
2631348Sbill 		ct = braelist[*ep++] - bbeg;
2641348Sbill 		curlp = lp;
2651348Sbill 		while(ecmp(bbeg, lp, ct))
2661348Sbill 			lp += ct;
2671348Sbill 		while(lp >= curlp) {
2681348Sbill 			if(advance(lp, ep))	return(1);
2691348Sbill 			lp -= ct;
2701348Sbill 		}
2711348Sbill 		return(0);
2721348Sbill 
2731348Sbill 
2741348Sbill 	case CDOT|CSTAR:
2751348Sbill 		curlp = lp;
2761348Sbill 		while (*lp++);
2771348Sbill 		goto star;
2781348Sbill 
2791348Sbill 	case CCHR|CSTAR:
2801348Sbill 		curlp = lp;
2811348Sbill 		while (*lp++ == *ep);
2821348Sbill 		ep++;
2831348Sbill 		goto star;
2841348Sbill 
2851348Sbill 	case CCL|CSTAR:
2861348Sbill 		curlp = lp;
2871348Sbill 		do {
2881348Sbill 			c = *lp++ & 0177;
2891348Sbill 		} while(ep[c>>3] & bittab[c & 07]);
2901348Sbill 		ep += 16;
2911348Sbill 		goto star;
2921348Sbill 
2931348Sbill 	star:
2941348Sbill 		if(--lp == curlp) {
2951348Sbill 			continue;
2961348Sbill 		}
2971348Sbill 
2981348Sbill 		if(*ep == CCHR) {
2991348Sbill 			c = ep[1];
3001348Sbill 			do {
3011348Sbill 				if(*lp != c)
3021348Sbill 					continue;
3031348Sbill 				if(advance(lp, ep))
3041348Sbill 					return(1);
3051348Sbill 			} while(lp-- > curlp);
3061348Sbill 			return(0);
3071348Sbill 		}
3081348Sbill 
3091348Sbill 		do {
3101348Sbill 			if (advance(lp, ep))
3111348Sbill 				return(1);
3121348Sbill 		} while (lp-- > curlp);
3131348Sbill 		return(0);
3141348Sbill 
3151348Sbill 	default:
3161348Sbill 		errexit("RE botch\n", (char *)NULL);
3171348Sbill 	}
3181348Sbill }
ecmp(a,b,count)3191348Sbill ecmp(a, b, count)
3201348Sbill char	*a, *b;
3211348Sbill {
3221348Sbill 	register cc = count;
3231348Sbill 	while(cc--)
3241348Sbill 		if(*a++ != *b++)	return(0);
3251348Sbill 	return(1);
3261348Sbill }
3271348Sbill 
3281348Sbill 
errexit(s)3291348Sbill errexit(s)
3301348Sbill char *s; {
3311348Sbill 	error(s);
3321348Sbill 	return;
3331348Sbill }
334