private static CharPtr scanformat(LuaState L, CharPtr strfrmt, CharPtr form) { var p = strfrmt; while (p[0] != '\0' && strchr(FLAGS, p[0]) != null) p = p.next(); /* skip flags */ if ((uint) (p - strfrmt) >= (FLAGS.Length + 1)) LuaLError(L, "invalid format (repeated flags)"); if (isdigit((byte) (p[0]))) p = p.next(); /* skip width */ if (isdigit((byte) (p[0]))) p = p.next(); /* (2 digits at most) */ if (p[0] == '.') { p = p.next(); if (isdigit((byte) (p[0]))) p = p.next(); /* skip precision */ if (isdigit((byte) (p[0]))) p = p.next(); /* (2 digits at most) */ } if (isdigit((byte) (p[0]))) LuaLError(L, "invalid format (width or precision too long)"); form[0] = '%'; form = form.next(); strncpy(form, strfrmt, p - strfrmt + 1); form += p - strfrmt + 1; form[0] = '\0'; return p; }
private static CharPtr match(MatchState ms, CharPtr s, CharPtr p) { s = new CharPtr(s); p = new CharPtr(p); if (ms.matchdepth-- == 0) LuaLError(ms.L, "pattern too complex"); init: /* using goto's to optimize tail recursion */ switch (p[0]) { case '(': { /* start capture */ if (p[1] == ')') /* position capture? */ return start_capture(ms, s, p + 2, CAP_POSITION); return start_capture(ms, s, p + 1, CAP_UNFINISHED); } case ')': { /* end capture */ return end_capture(ms, s, p + 1); } case L_ESC: { switch (p[1]) { case 'b': { /* balanced string? */ s = matchbalance(ms, s, p + 2); if (s == null) return null; p += 4; goto init; /* else return match(ms, s, p+4); */ } case 'f': { /* frontier? */ CharPtr ep; char previous; p += 2; if (p[0] != '[') LuaLError(ms.L, "missing " + LUA_QL("[") + " after " + LUA_QL("%f") + " in pattern"); ep = classend(ms, p); /* points to what is next */ previous = (s == ms.src_init) ? '\0' : s[-1]; if ((matchbracketclass((byte) (previous), p, ep - 1) != 0) || (matchbracketclass((byte) (s[0]), p, ep - 1) == 0)) return null; p = ep; goto init; /* else return match(ms, s, ep); */ } default: { if (isdigit(p[1])) { /* capture results (%0-%9)? */ s = match_capture(ms, s, (byte) (p[1])); if (s == null) return null; p += 2; goto init; /* else return match(ms, s, p+2) */ } //ismeretlen hiba miatt lett ide átmásolva { /* it is a pattern item */ var ep = classend(ms, p); /* points to what is next */ var m = (s < ms.src_end) && (singlematch((byte) (s[0]), p, ep) != 0) ? 1 : 0; switch (ep[0]) { case '?': { /* optional */ CharPtr res; if ((m != 0) && ((res = match(ms, s + 1, ep + 1)) != null)) return res; p = ep + 1; goto init; /* else return match(ms, s, ep+1); */ } case '*': { /* 0 or more repetitions */ return max_expand(ms, s, p, ep); } case '+': { /* 1 or more repetitions */ return ((m != 0) ? max_expand(ms, s + 1, p, ep) : null); } case '-': { /* 0 or more repetitions (minimum) */ return min_expand(ms, s, p, ep); } default: { if (m == 0) return null; s = s.next(); p = ep; goto init; /* else return match(ms, s+1, ep); */ } } } //goto dflt; /* case default */ } } } case '\0': { /* end of pattern */ return s; /* match succeeded */ } case '$': { if (p[1] == '\0') /* is the `$' the last char in pattern? */ return (s == ms.src_end) ? s : null; /* check end of string */ goto dflt; } default: dflt: { /* it is a pattern item */ var ep = classend(ms, p); /* points to what is next */ var m = (s < ms.src_end) && (singlematch((byte) (s[0]), p, ep) != 0) ? 1 : 0; switch (ep[0]) { case '?': { /* optional */ CharPtr res; if ((m != 0) && ((res = match(ms, s + 1, ep + 1)) != null)) return res; p = ep + 1; goto init; /* else return match(ms, s, ep+1); */ } case '*': { /* 0 or more repetitions */ return max_expand(ms, s, p, ep); } case '+': { /* 1 or more repetitions */ return ((m != 0) ? max_expand(ms, s + 1, p, ep) : null); } case '-': { /* 0 or more repetitions (minimum) */ return min_expand(ms, s, p, ep); } default: { if (m == 0) return null; s = s.next(); p = ep; goto init; /* else return match(ms, s+1, ep); */ } } } } }
private static CharPtr min_expand(MatchState ms, CharPtr s, CharPtr p, CharPtr ep) { for (;;) { var res = match(ms, s, ep + 1); if (res != null) return res; if ((s < ms.src_end) && (singlematch((byte) (s[0]), p, ep) != 0)) s = s.next(); /* try with one more repetition */ else return null; } }
private static CharPtr matchbalance(MatchState ms, CharPtr s, CharPtr p) { if ((p[0] == 0) || (p[1] == 0)) LuaLError(ms.L, "unbalanced pattern"); if (s[0] != p[0]) return null; int b = p[0]; int e = p[1]; var cont = 1; while ((s = s.next()) < ms.src_end) { if (s[0] == e) { if (--cont == 0) return s + 1; } else if (s[0] == b) cont++; } return null; /* string ends out of balance */ }
private static int matchbracketclass(int c, CharPtr p, CharPtr ec) { var sig = 1; if (p[1] == '^') { sig = 0; p = p.next(); /* skip the `^' */ } while ((p = p.next()) < ec) { if (p == L_ESC) { p = p.next(); if (match_class((char) c, p[0]) != 0) return sig; } else if ((p[1] == '-') && (p + 2 < ec)) { p += 2; if ((byte) ((p[-2])) <= c && (c <= (byte) p[0])) return sig; } else if ((byte) (p[0]) == c) return sig; } return (sig == 0) ? 1 : 0; }
private static CharPtr classend(MatchState ms, CharPtr p) { p = new CharPtr(p); var c = p[0]; p = p.next(); switch (c) { case L_ESC: { if (p[0] == '\0') LuaLError(ms.L, "malformed pattern (ends with " + LUA_QL("%") + ")"); return p + 1; } case '[': { if (p[0] == '^') p = p.next(); do { /* look for a `]' */ if (p[0] == '\0') LuaLError(ms.L, "malformed pattern (missing " + LUA_QL("]") + ")"); c = p[0]; p = p.next(); if (c == L_ESC && p[0] != '\0') p = p.next(); /* skip escapes (e.g. `%]') */ } while (p[0] != ']'); return p + 1; } default: { return p; } } }