diff options
author | Yves Orton <demerphq@gmail.com> | 2016-03-05 20:40:36 +0100 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2016-03-06 14:02:14 +0100 |
commit | 24be310237a0f8f19cfdb71de1b068b4ce9572a0 (patch) | |
tree | 39f3536dbc2c898f0535b3f3a34dc5cf926d7490 /regexp.h | |
parent | 4b63804857c9bd58e6f67f23b9a9d007fa7c1071 (diff) | |
download | perl-24be310237a0f8f19cfdb71de1b068b4ce9572a0.tar.gz |
first step cleaning up regexp recursion "return" logic
When we do a GOSUB/GOSTART we need to know where the recursion
"returns" to the previous position in the pattern. Currently
this is done by comparing cur_eval->u.eval.close_paren to the
the argument of CLOSE parens, and within END blocks (for GOSTART).
However, there is a problem. The state machinery for GOSUB/GOSTART
is shared with EVAL ( implementing /(??{ ... })/ ), which also sets
cur_eval->u.eval.close_paren to 0. This for instance breaks /(?(R)YES|NO)/
by making it return true within a /(??{ ... })/ when arguably it
shouldn't. It also is confusing.
So we change the meaning of close_paren so that 0 means "from EVAL",
and that otherwise the value is "+1", so 1 means GOSTART (trigger for
END), and 2 means "CLOSE1", etc. In order to make this transparent
this patch adds the EVAL_CLOSE_PAREN_IS( cur_eval, EXPR ) macro which
does the right thing:
( cur_eval && cur_eval->u.eval.close_paren &&
( ( cur_eval->u.eval.close_paren - 1 ) == EXPR ) )
Diffstat (limited to 'regexp.h')
-rw-r--r-- | regexp.h | 9 |
1 files changed, 8 insertions, 1 deletions
@@ -747,7 +747,7 @@ typedef struct regmatch_state { REGEXP *prev_rex; CHECKPOINT cp; /* remember current savestack indexes */ CHECKPOINT lastcp; - U32 close_paren; /* which close bracket is our end */ + U32 close_paren; /* which close bracket is our end (+1) */ regnode *B; /* the node following us */ } eval; @@ -833,6 +833,13 @@ typedef struct regmatch_state { } u; } regmatch_state; +#define EVAL_CLOSE_PAREN_IS(cur_eval,expr) \ +(\ + ( ( cur_eval ) ) && \ + ( ( cur_eval )->u.eval.close_paren ) && \ + ( ( ( cur_eval )->u.eval.close_paren - 1 ) == ( expr ) ) \ +) + /* how many regmatch_state structs to allocate as a single slab. * We do it in 4K blocks for efficiency. The "3" is 2 for the next/prev * pointers, plus 1 for any mythical malloc overhead. */ |