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