summaryrefslogtreecommitdiff
path: root/regexp.h
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2016-03-05 20:40:36 +0100
committerYves Orton <demerphq@gmail.com>2016-03-06 14:02:14 +0100
commit24be310237a0f8f19cfdb71de1b068b4ce9572a0 (patch)
tree39f3536dbc2c898f0535b3f3a34dc5cf926d7490 /regexp.h
parent4b63804857c9bd58e6f67f23b9a9d007fa7c1071 (diff)
downloadperl-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.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/regexp.h b/regexp.h
index 5dbab2e4ed..ff44df27e7 100644
--- a/regexp.h
+++ b/regexp.h
@@ -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. */