示例#1
0
static int
_advance(char *lp, char *ep)
{
    char 	*rp;
    char 	*curlp;
    wchar_t	c, d;
    int 	n;
    wchar_t cl;
    int 	neg;
    char 	*bbeg;
    int 	ct;

    for (;;) {
        neg = 0;
        switch (*ep++) {

        case CCHR:
            if (*ep++ == *lp++)
                continue;
            return (0);

        case MCCHR:
            ep += Popwchar(ep, cl);
            c = cl;
            if ((n = Popwchar(lp, cl)) <= 0 || c !=  cl)
                return (0);
            lp += n;
            continue;

        case CDOT:
            /*
             * match any characters except NULL
             */
            if ((n = Popwchar(lp, cl)) > 0) {
                lp += n;
                continue;
            } else if (n < 0) {
                lp++;
                continue;
            } else {
                return (0);
            }
        case CDOL:
            if (*lp == 0)
                continue;
            return (0);

        case CCEOF:
            loc2 = lp;
            return (1);

        case CCL:
            c = (unsigned char)*lp++;
            if (ISTHERE(c)) {
                ep += 32;
                continue;
            }
            return (0);

        case NMCCL:
            neg = 1;
        /* FALLTHRU */

        case MCCL:
            rp = lp;
            if (cclass(ep, &rp, neg) != 1)
                return (0);
            ep += *(ep + 32) + 32;
            lp = rp;
            continue;

        case CBRA:
            braslist[*ep++] = lp;
            continue;

        case CKET:
            braelist[*ep++] = lp;
            continue;

        case MCCHR | RNGE:
            ep += Popwchar(ep, cl);
            c = cl;
            getrnge(ep);
            while (low--) {
                if ((n = Popwchar(lp, cl)) <= 0 || cl != c)
                    return (0);
                lp += n;
            }
            curlp = lp;
            while (size--) {
                if ((n = Popwchar(lp, cl)) <= 0 || cl != c)
                    break;
                lp += n;
            }
            if (size < 0)
                n = Popwchar(lp, cl);
            if (n == -1)
                return (0);
            lp += (n ? n : 1);
            ep += 2;
            goto mstar;

        case CCHR | RNGE:
            c = *ep++;
            getrnge(ep);
            while (low--)
                if (*lp++ != c)
                    return (0);
            curlp = lp;
            while (size--)
                if (*lp++ != c)
                    break;
            if (size < 0)
                lp++;
            ep += 2;
            goto star;

        case CDOT | RNGE:
            getrnge(ep);
            while (low--) {
                if ((n = Popwchar(lp, cl)) > 0) {
                    lp += n;
                } else if (n < 0) {
                    lp++;
                } else {
                    return (0);
                }
            }
            curlp = lp;
            while (size--) {
                if ((n = Popwchar(lp, cl)) > 0) {
                    lp += n;
                } else if (n < 0) {
                    lp++;
                } else {
                    break;
                }
            }
            if (size < 0)
                n = Popwchar(lp, cl);
            if (n > 0) {
                lp += n;
            } else {
                lp++;
            }
            ep += 2;
            goto mstar;

        case NMCCL | RNGE:
            neg = 1;
        /* FALLTHRU */

        case MCCL | RNGE:
            getrnge(ep + *(ep + 32) + 32);
            rp = lp;
            while (low--) {
                if (cclass(ep, &rp, neg) != 1)
                    return (0);
            }
            curlp = rp;
            while (size-- && (c = (cclass(ep, &rp, neg))) == 1)
                ;
            if (c == -1)
                return (0);
            lp = rp;
            if (size < 0) {
                if ((n = Popwchar(lp, cl)) == -1)
                    return (0);
                lp += (n ? n : 1);
            }
            ep += *(ep + 32) + 34;
            goto mstar;

        case CCL | RNGE:
            getrnge(ep + 32);
            while (low--) {
                c = (unsigned char)*lp++;
                if (!ISTHERE(c))
                    return (0);
            }
            curlp = lp;
            while (size--) {
                c = (unsigned char)*lp++;
                if (!ISTHERE(c))
                    break;
            }
            if (size < 0)
                lp++;
            ep += 34;		/* 32 + 2 */
            goto star;

        case CBACK:
            bbeg = braslist[*ep];
            ct = (int)(braelist[*ep++] - bbeg);

            if (ecmp(bbeg, lp, ct)) {
                lp += ct;
                continue;
            }
            return (0);

        case CBACK | STAR:
            bbeg = braslist[*ep];
            ct = (int)(braelist[*ep++] - bbeg);
            curlp = lp;
            while (ecmp(bbeg, lp, ct))
                lp += ct;

            while (lp >= curlp) {
                if (_advance(lp, ep))
                    return (1);
                lp -= ct;
            }
            return (0);

        case CDOT | STAR:
            curlp = lp;
            if (!multibyte)
                while (*lp++)
                    ;
            else {
                for (;;) {
                    n = Popwchar(lp, cl);
                    if (n > 0) {
                        lp += n;
                    } else if (n < 0) {
                        lp++;
                    } else {
                        lp++;
                        break;
                    }
                }
            }
            goto mstar;

        case CCHR | STAR:
            curlp = lp;
            while (*lp++ == *ep)
                ;
            ep++;
            goto star;

        case MCCHR | STAR:
            curlp = lp;
            ep += Popwchar(ep, cl);
            c = cl;
            while ((n = Popwchar(lp, cl))  > 0 && cl == c)
                lp += n;
            if (n == -1)
                return (0);
            lp += (n ? n : 1);
            goto mstar;

        case NMCCL | STAR:
            neg = 1;
        /* FALLTHRU */

        case MCCL | STAR:
            curlp = rp = lp;
            while ((d = cclass(ep, &rp, neg)) == 1)
                ;
            if (d == -1)
                return (0);
            lp = rp;
            ep += *(ep + 32) + 32;
            goto mstar;

        case CCL | STAR:
            curlp = lp;
            do {
                c = (unsigned char)*lp++;
            } while (ISTHERE(c));
            ep += 32;
            goto star;

        case CBRC:
            if (lp == start && locs == (char *)0)
                continue;
            c = (unsigned char)*lp;
            d = (unsigned char)*(lp-1);
            if ((isdigit((int)c) || uletter((int)c) || c >= 0200 &&
                    MB_CUR_MAX > 1) && !isdigit((int)d) &&
                    !uletter((int)d) &&
                    (d < 0200 || MB_CUR_MAX == 1))
                continue;
            return (0);

        case CLET:
            d = (unsigned char)*lp;
            if (!isdigit((int)d) && !uletter((int)d) && (d < 0200 ||
                    MB_CUR_MAX == 1))
                continue;
            return (0);

        default:
            return (0);
        }
    }

mstar:
    if (multibyte) {
        /* MB_CUR_MAX > 1 */
        if ((eucw1 != 0) || (eucw2 != 0) || (eucw3 != 0)) {
            /* EUC locale */
            do {
                char *p1, *p2;
                lp--;
                p1 = lp - eucw2;
                p2 = lp - eucw3;
                /* check if previous character is from    */
                /* supplementary code sets 1, 2, or 3 and */
                /* back up appropriate number of bytes    */
                if ((unsigned char)*lp >= 0200) {
                    if (p1 >= curlp &&
                            (unsigned char)*p1 == SS2)
                        lp = p1;
                    else if (p2 >= curlp &&
                             (unsigned char)*p2 == SS3)
                        lp = p2;
                    else
                        lp = lp - eucw1 + 1;
                }
                if (lp == locs)
                    break;
                if (_advance(lp, ep))
                    return (1);
            } while (lp > curlp);
            return (0);
        } else {
            /* Anything else */
            do {
                int	len;
                char	*p1, *p2;

                p2 = curlp;
                do {
                    p1 = p2;
                    if (isascii(*p1)) {
                        p2 = p1 + 1;
                    } else {
                        len = mblen(p1, MB_CUR_MAX);
                        if (len == -1) {
                            len = 1;
                        }
                        p2 = p1 + len;
                    }
                    if (p2 > lp) {
                        /* something is wrong */
                        return (0);
                    }
                } while (p2 != lp);
                lp = p1;
                if (lp == locs)
                    break;
                if (_advance(lp, ep))
                    return (1);
            } while (lp > curlp);
            return (0);
        }
    }
star:
    do {
        if (--lp == locs)
            break;
        if (_advance(lp, ep))
            return (1);
    } while (lp > curlp);
    return (0);
}
示例#2
0
文件: ex_re.c 项目: n-t-roff/ex-2.2
static int
advance(char *lp, char *ep)
{
	register char *curlp;

	for (;;) switch (*ep++) {

	case CCHR:
/* useless
		if (*ep & RE_QUOTE) {
			c = *ep++ & TRIM;
			sp = braslist[c];
			sp1 = braelist[c];
			while (sp < sp1) {
				if (!same(*sp, *lp))
					return (0);
				sp++, lp++;
			}
			continue;
		}
*/
		if (!same(*ep, *lp))
			return (0);
		ep++, lp++;
		continue;

	case CDOT:
		if (*lp++)
			continue;
		return (0);

	case CDOL:
		if (*lp == 0)
			continue;
		return (0);

	case EX_CEOF:
		loc2 = lp;
		return (1);

	case CCL:
		if (cclass(ep, *lp++, 1)) {
			ep += *ep;
			continue;
		}
		return (0);

	case NCCL:
		if (cclass(ep, *lp++, 0)) {
			ep += *ep;
			continue;
		}
		return (0);

	case CBRA:
		braslist[(int)*ep++] = lp;
		continue;

	case CKET:
		braelist[(int)*ep++] = lp;
		continue;

	case CDOT|STAR:
		curlp = lp;
		while (*lp++)
			continue;
		goto star;

	case CCHR|STAR:
		curlp = lp;
		while (same(*lp, *ep))
			lp++;
		lp++;
		ep++;
		goto star;

	case CCL|STAR:
	case NCCL|STAR:
		curlp = lp;
		while (cclass(ep, *lp++, ep[-1] == (CCL|STAR)))
			continue;
		ep += *ep;
		goto star;
star:
		do {
			lp--;
			if (lp == locs)
				break;
			if (advance(lp, ep))
				return (1);
		} while (lp > curlp);
		return (0);

	case CBRC:
		if (lp == expbuf)
			continue;
		if ((isdigit((int)*lp) || uletter((int)*lp)) && !uletter((int)lp[-1]) && !isdigit((int)lp[-1]))
			continue;
		return (0);

	case CLET:
		if (!uletter((int)*lp) && !isdigit((int)*lp))
			continue;
		return (0);

	default:
		error("Re internal error");
		return 0;
	}
}