diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-07-09 13:08:39 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-07-09 13:15:27 +0100 |
commit | 175d7ac25a9d638e859d677d662ced1cc746c6ce (patch) | |
tree | 997e9e89e20cb0432d2a105aceb8d8d261fd346b /contrib/lua-lpeg/lpcode.c | |
parent | 4eba0ef16211ae27f13e826fb1957858439666ec (diff) | |
download | rspamd-175d7ac25a9d638e859d677d662ced1cc746c6ce.tar.gz rspamd-175d7ac25a9d638e859d677d662ced1cc746c6ce.zip |
[Minor] Update lpeg to the upstream
Diffstat (limited to 'contrib/lua-lpeg/lpcode.c')
-rw-r--r-- | contrib/lua-lpeg/lpcode.c | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/contrib/lua-lpeg/lpcode.c b/contrib/lua-lpeg/lpcode.c index 6feefeb43..392345972 100644 --- a/contrib/lua-lpeg/lpcode.c +++ b/contrib/lua-lpeg/lpcode.c @@ -1,5 +1,5 @@ /* -** $Id: lpcode.c,v 1.23 2015/06/12 18:36:47 roberto Exp $ +** $Id: lpcode.c $ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ @@ -126,6 +126,27 @@ int tocharset (TTree *tree, Charset *cs) { /* +** Visit a TCall node taking care to stop recursion. If node not yet +** visited, return 'f(sib2(tree))', otherwise return 'def' (default +** value) +*/ +static int callrecursive (TTree *tree, int f (TTree *t), int def) { + int key = tree->key; + assert(tree->tag == TCall); + assert(sib2(tree)->tag == TRule); + if (key == 0) /* node already visited? */ + return def; /* return default value */ + else { /* first visit */ + int result; + tree->key = 0; /* mark call as already visited */ + result = f(sib2(tree)); /* go to called rule */ + tree->key = key; /* restore tree */ + return result; + } +} + + +/* ** Check whether a pattern tree has captures */ int hascaptures (TTree *tree) { @@ -134,14 +155,17 @@ int hascaptures (TTree *tree) { case TCapture: case TRunTime: return 1; case TCall: - tree = sib2(tree); goto tailcall; /* return hascaptures(sib2(tree)); */ + return callrecursive(tree, hascaptures, 0); + case TRule: /* do not follow siblings */ + tree = sib1(tree); goto tailcall; case TOpenCall: assert(0); default: { switch (numsiblings[tree->tag]) { case 1: /* return hascaptures(sib1(tree)); */ tree = sib1(tree); goto tailcall; case 2: - if (hascaptures(sib1(tree))) return 1; + if (hascaptures(sib1(tree))) + return 1; /* else return hascaptures(sib2(tree)); */ tree = sib2(tree); goto tailcall; default: assert(numsiblings[tree->tag] == 0); return 0; @@ -208,9 +232,9 @@ int checkaux (TTree *tree, int pred) { /* ** number of characters to match a pattern (or -1 if variable) -** ('count' avoids infinite loops for grammars) */ -int fixedlenx (TTree *tree, int count, int len) { +int fixedlen (TTree *tree) { + int len = 0; /* to accumulate in tail calls */ tailcall: switch (tree->tag) { case TChar: case TSet: case TAny: @@ -220,26 +244,29 @@ int fixedlenx (TTree *tree, int count, int len) { case TRep: case TRunTime: case TOpenCall: return -1; case TCapture: case TRule: case TGrammar: - /* return fixedlenx(sib1(tree), count); */ + /* return fixedlen(sib1(tree)); */ tree = sib1(tree); goto tailcall; - case TCall: - if (count++ >= MAXRULES) - return -1; /* may be a loop */ - /* else return fixedlenx(sib2(tree), count); */ - tree = sib2(tree); goto tailcall; + case TCall: { + int n1 = callrecursive(tree, fixedlen, -1); + if (n1 < 0) + return -1; + else + return len + n1; + } case TSeq: { - len = fixedlenx(sib1(tree), count, len); - if (len < 0) return -1; - /* else return fixedlenx(sib2(tree), count, len); */ - tree = sib2(tree); goto tailcall; + int n1 = fixedlen(sib1(tree)); + if (n1 < 0) + return -1; + /* else return fixedlen(sib2(tree)) + len; */ + len += n1; tree = sib2(tree); goto tailcall; } case TChoice: { - int n1, n2; - n1 = fixedlenx(sib1(tree), count, len); - if (n1 < 0) return -1; - n2 = fixedlenx(sib2(tree), count, len); - if (n1 == n2) return n1; - else return -1; + int n1 = fixedlen(sib1(tree)); + int n2 = fixedlen(sib2(tree)); + if (n1 != n2 || n1 < 0) + return -1; + else + return len + n1; } default: assert(0); return 0; }; @@ -248,7 +275,7 @@ int fixedlenx (TTree *tree, int count, int len) { /* ** Computes the 'first set' of a pattern. -** The result is a conservative approximation: +** The result is a conservative aproximation: ** match p ax -> x (for some x) ==> a belongs to first(p) ** or ** a not in first(p) ==> match p ax -> fail (for all x) @@ -710,9 +737,10 @@ static void codeand (CompileState *compst, TTree *tree, int tt) { /* -** Captures: if pattern has fixed (and not too big) length, use -** a single IFullCapture instruction after the match; otherwise, -** enclose the pattern with OpenCapture - CloseCapture. +** Captures: if pattern has fixed (and not too big) length, and it +** has no nested captures, use a single IFullCapture instruction +** after the match; otherwise, enclose the pattern with OpenCapture - +** CloseCapture. */ static void codecapture (CompileState *compst, TTree *tree, int tt, const Charset *fl) { @@ -737,13 +765,13 @@ static void coderuntime (CompileState *compst, TTree *tree, int tt) { /* -** Repetition; optimizations: +** Repetion; optimizations: ** When pattern is a charset, can use special instruction ISpan. ** When pattern is head fail, or if it starts with characters that ** are disjoint from what follows the repetions, a simple test ** is enough (a fail inside the repetition would backtrack to fail ** again in the following pattern, so there is no need for a choice). -** When 'opt' is true, the repetition can reuse the Choice already +** When 'opt' is true, the repetion can reuse the Choice already ** active in the stack. */ static void coderep (CompileState *compst, TTree *tree, int opt, @@ -884,7 +912,7 @@ static int codeseq1 (CompileState *compst, TTree *p1, TTree *p2, /* -** Main code-generation function: dispatch to auxiliary functions +** Main code-generation function: dispatch to auxiliar functions ** according to kind of tree. ('needfollow' should return true ** only for consructions that use 'fl'.) */ |