Exemplo n.º 1
0
static int wsinglematch (lua_WChar c, const lua_WChar *p, const lua_WChar *ep) {
  switch (*p) {
    case '.': return 1;  /* matches any char */
    case WL_ESC: return wmatch_class(c, *(p+1));
    case '[': return wmatchbracketclass(c, p, ep-1);
    default:  return (*p == c);
  }
}
Exemplo n.º 2
0
static const lua_WChar *wmatch (WMatchState *ms, const lua_WChar *s, const lua_WChar *p) {
init: /* using goto's to optimize tail recursion */
    switch (*p) {
    case '(': {  /* start capture */
        if (*(p+1) == ')')  /* position capture? */
            return wstart_capture(ms, s, p+2, CAP_POSITION);
        else
            return wstart_capture(ms, s, p+1, CAP_UNFINISHED);
    }
    case ')': {  /* end capture */
        return wend_capture(ms, s, p+1);
    }
    case WL_ESC: {
        switch (*(p+1)) {
        case 'b': {  /* balanced string? */
            s = wmatchbalance(ms, s, p+2);
            if (s == NULL) return NULL;
            p+=4;
            goto init;  /* else return wmatch(ms, s, p+4); */
        }
        case 'f': {  /* frontier? */
            const lua_WChar *ep;
            lua_WChar previous;
            p += 2;
            if (*p != '[')
                luaL_error(ms->L, "missing " LUA_QL("[") " after "
                           LUA_QL("%%f") " in pattern");
            ep = wclassend(ms, p);  /* points to what is next */
            previous = (s == ms->src_init) ? '\0' : *(s-1);
            if (wmatchbracketclass(previous, p, ep-1) ||
                    !wmatchbracketclass(*s, p, ep-1)) return NULL;
            p=ep;
            goto init;  /* else return wmatch(ms, s, ep); */
        }
        default: {
            if (iswdigit(*(p+1))) {  /* capture results (%0-%9)? */
                s = wmatch_capture(ms, s, *(p+1));
                if (s == NULL) return NULL;
                p+=2;
                goto init;  /* else return wmatch(ms, s, p+2) */
            }
            goto dflt;  /* case default */
        }
        }
    }
    case '\0': {  /* end of pattern */
        return s;  /* wmatch succeeded */
    }
    case '$': {
        if (*(p+1) == '\0')  /* is the `$' the last char in pattern? */
            return (s == ms->src_end) ? s : NULL;  /* check end of string */
        else goto dflt;
    }
    default:
dflt: {  /* it is a pattern item */
            const lua_WChar *ep = wclassend(ms, p);  /* points to what is next */
            int m = s<ms->src_end && wsinglematch(*s, p, ep);
            switch (*ep) {
            case '?': {  /* optional */
                const lua_WChar *res;
                if (m && ((res=wmatch(ms, s+1, ep+1)) != NULL))
                    return res;
                p=ep+1;
                goto init;  /* else return wmatch(ms, s, ep+1); */
            }
            case '*': {  /* 0 or more repetitions */
                return wmax_expand(ms, s, p, ep);
            }
            case '+': {  /* 1 or more repetitions */
                return (m ? wmax_expand(ms, s+1, p, ep) : NULL);
            }
            case '-': {  /* 0 or more repetitions (minimum) */
                return wmin_expand(ms, s, p, ep);
            }
            default: {
                if (!m) return NULL;
                s++;
                p=ep;
                goto init;  /* else return wmatch(ms, s+1, ep); */
            }
            }
        }
    }
}