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); }
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; } }