| 1975 |
} |
} |
| 1976 |
|
|
| 1977 |
/* For a recursion/subroutine call, if its end has been reached, which |
/* For a recursion/subroutine call, if its end has been reached, which |
| 1978 |
implies a subroutine call, we can scan it. */ |
implies a backward reference subroutine call, we can scan it. If it's a |
| 1979 |
|
forward reference subroutine call, we can't. To detect forward reference |
| 1980 |
|
we have to scan up the list that is kept in the workspace. This function is |
| 1981 |
|
called only when doing the real compile, not during the pre-compile that |
| 1982 |
|
measures the size of the compiled pattern. */ |
| 1983 |
|
|
| 1984 |
if (c == OP_RECURSE) |
if (c == OP_RECURSE) |
| 1985 |
{ |
{ |
| 1986 |
BOOL empty_branch = FALSE; |
const uschar *scode; |
| 1987 |
const uschar *scode = cd->start_code + GET(code, 1); |
BOOL empty_branch; |
| 1988 |
|
|
| 1989 |
|
/* Test for forward reference */ |
| 1990 |
|
|
| 1991 |
|
for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) |
| 1992 |
|
if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE; |
| 1993 |
|
|
| 1994 |
|
/* Not a forward reference, test for completed backward reference */ |
| 1995 |
|
|
| 1996 |
|
empty_branch = FALSE; |
| 1997 |
|
scode = cd->start_code + GET(code, 1); |
| 1998 |
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ |
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ |
| 1999 |
|
|
| 2000 |
|
/* Completed backwards reference */ |
| 2001 |
|
|
| 2002 |
do |
do |
| 2003 |
{ |
{ |
| 2004 |
if (could_be_empty_branch(scode, endcode, utf8, cd)) |
if (could_be_empty_branch(scode, endcode, utf8, cd)) |
| 2009 |
scode += GET(scode, 1); |
scode += GET(scode, 1); |
| 2010 |
} |
} |
| 2011 |
while (*scode == OP_ALT); |
while (*scode == OP_ALT); |
| 2012 |
|
|
| 2013 |
if (!empty_branch) return FALSE; /* All branches are non-empty */ |
if (!empty_branch) return FALSE; /* All branches are non-empty */ |
| 2014 |
continue; |
continue; |
| 2015 |
} |
} |
| 2235 |
the current branch of the current pattern to see if it could match the empty |
the current branch of the current pattern to see if it could match the empty |
| 2236 |
string. If it could, we must look outwards for branches at other levels, |
string. If it could, we must look outwards for branches at other levels, |
| 2237 |
stopping when we pass beyond the bracket which is the subject of the recursion. |
stopping when we pass beyond the bracket which is the subject of the recursion. |
| 2238 |
|
This function is called only during the real compile, not during the |
| 2239 |
|
pre-compile. |
| 2240 |
|
|
| 2241 |
Arguments: |
Arguments: |
| 2242 |
code points to start of the recursion |
code points to start of the recursion |