aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/lua-lpeg/lpcode.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2020-07-09 13:08:39 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2020-07-09 13:15:27 +0100
commit175d7ac25a9d638e859d677d662ced1cc746c6ce (patch)
tree997e9e89e20cb0432d2a105aceb8d8d261fd346b /contrib/lua-lpeg/lpcode.c
parent4eba0ef16211ae27f13e826fb1957858439666ec (diff)
downloadrspamd-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.c84
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'.)
*/