DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
} \
\
+ set_regs_matched_done = 0; \
DEBUG_STATEMENT (nfailure_points_popped++); \
} /* POP_FAILURE_POINT */
/* Call this when have matched a real character; it sets `matched' flags
for the subexpressions which we are currently inside. Also records
that those subexprs have matched. */
-#define SET_REGS_MATCHED() \
- do \
- { \
- unsigned r; \
- for (r = lowest_active_reg; r <= highest_active_reg; r++) \
- { \
- MATCHED_SOMETHING (reg_info[r]) \
- = EVER_MATCHED_SOMETHING (reg_info[r]) \
- = 1; \
- } \
- } \
- while (0)
+#define SET_REGS_MATCHED() \
+ if (!set_regs_matched_done) \
+ { \
+ unsigned r; \
+ set_regs_matched_done = 1; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ else
/* Registers are set to a sentinel when they haven't yet matched. */
and need to test it, it's not garbage. */
const char *match_end = NULL;
+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
+ int set_regs_matched_done = 0;
+
/* Used when we pop values we don't care about. */
#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
const char **reg_dummy;
IS_ACTIVE (reg_info[*p]) = 1;
MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
/* This is the new highest active register. */
highest_active_reg = *p;
/* Move past the register number and inner group count. */
p += 2;
just_past_start_mem = p;
+
break;
/* This register isn't active anymore. */
IS_ACTIVE (reg_info[*p]) = 0;
-
+
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
+
/* If this was the only register active, nothing is active
anymore. */
if (lowest_active_reg == highest_active_reg)
: bcmp (d, d2, mcnt))
goto fail;
d += mcnt, d2 += mcnt;
+
+ /* Do this because we've match some characters. */
+ SET_REGS_MATCHED ();
}
}
break;