int step(char *p1, char *p2) { int c; wchar_t cl; int n; int ret; /* check if match is restricted to beginning of string */ (void) mutex_lock(&lock); start = p1; if (*p2++) { loc1 = p1; ret = _advance(p1, p2); (void) mutex_unlock(&lock); return (ret); } if (*p2 == CCHR) { /* fast check for first character */ c = p2[1]; do { if (*p1 != c) continue; if (_advance(p1, p2)) { loc1 = p1; (void) mutex_unlock(&lock); return (1); } } while (*p1++); } else if (multibyte) do { if (_advance(p1, p2)) { loc1 = p1; (void) mutex_unlock(&lock); return (1); } n = Popwchar(p1, cl); if (n < 0) /* skip past illegal multibyte characters */ p1++; else p1 += n; } while (n); else /* regular algorithm */ do { if (_advance(p1, p2)) { loc1 = p1; (void) mutex_unlock(&lock); return (1); } } while (*p1++); (void) mutex_unlock(&lock); return (0); }
static int cclass(char *ep, char **rp, int neg) { char *lp; wchar_t c, d, f = 0; int n; wchar_t cl; char *endep; lp = *rp; if ((n = Popwchar(lp, cl)) == -1) return (-1); *rp = lp + (n ? n : 1); c = cl; /* look for eight bit characters in bitmap */ if (c <= 0177 || c <= 0377 && iscntrl((int)c)) return (ISTHERE(c) && !neg || !ISTHERE(c) && neg); else { /* look past bitmap for multibyte characters */ endep = *(ep + 32) + ep + 32; ep += 33; for (;;) { if (ep >= endep) return (neg); ep += Popwchar(ep, cl); d = cl; if (d == '-') { ep += Popwchar(ep, cl); d = cl; if (f <= c && c <= d) return (!neg); } if (d == c) return (!neg); f = d; } } /*NOTREACHED*/ }
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); }
int gmatch(const char *s, const char *p) { const char *olds; wchar_t scc, c; int n; wchar_t cl; olds = s; n = mbtowc(&cl, s, MB_LEN_MAX); if (n <= 0) { s++; scc = n; } else { scc = cl; s += n; } n = mbtowc(&cl, p, MB_LEN_MAX); if (n < 0) return (0); if (n == 0) return (scc == 0); p += n; c = cl; switch (c) { case '[': if (scc <= 0) return (0); { int ok; wchar_t lc = 0; int notflag = 0; ok = 0; if (*p == '!') { notflag = 1; p++; } Popwchar(p, c); do { if (c == '-' && lc && *p != ']') { Popwchar(p, c); if (c == '\\') { Popwchar(p, c); } if (notflag) { if (!multibyte || valid_range(lc, c)) { if (scc < lc || scc > c) ok++; else return (0); } } else { if (!multibyte || valid_range(lc, c)) if (lc <= scc && scc <= c) ok++; } } else if (c == '\\') { /* skip to quoted character */ Popwchar(p, c); } lc = c; if (notflag) { if (scc != lc) ok++; else return (0); } else { if (scc == lc) ok++; } Popwchar(p, c); } while (c != ']'); return (ok ? gmatch(s, p) : 0); } case '\\': /* skip to quoted character and see if it matches */ Popwchar(p, c); default: if (c != scc) return (0); /*FALLTHRU*/ case '?': return (scc > 0 ? gmatch(s, p) : 0); case '*': while (*p == '*') p++; if (*p == 0) return (1); s = olds; while (*s) { if (gmatch(s, p)) return (1); n = mbtowc(&cl, s, MB_LEN_MAX); if (n < 0) /* skip past illegal byte sequence */ s++; else s += n; } return (0); } }