S_regcppush(pTHX_ I32 parenfloor)
{
int retval = PL_savestack_ix;
- int i = (PL_regsize - parenfloor) * 4;
+#define REGCP_PAREN_ELEMS 4
+ int paren_elems_to_push = (PL_regsize - parenfloor) * REGCP_PAREN_ELEMS;
int p;
- SSCHECK(i + 5);
+#define REGCP_OTHER_ELEMS 5
+ SSCHECK(paren_elems_to_push + REGCP_OTHER_ELEMS);
for (p = PL_regsize; p > parenfloor; p--) {
+/* REGCP_PARENS_ELEMS are pushed per pairs of parentheses. */
SSPUSHINT(PL_regendp[p]);
SSPUSHINT(PL_regstartp[p]);
SSPUSHPTR(PL_reg_start_tmp[p]);
SSPUSHINT(p);
}
+/* REGCP_OTHER_ELEMS are pushed in any case, parentheses or no. */
SSPUSHINT(PL_regsize);
SSPUSHINT(*PL_reglastparen);
SSPUSHPTR(PL_reginput);
- SSPUSHINT(i + 3);
- SSPUSHINT(SAVEt_REGCONTEXT);
+#define REGCP_FRAME_ELEMS 2
+/* REGCP_FRAME_ELEMS are part of the REGCP_OTHER_ELEMS and
+ * are needed for the regexp context stack bookkeeping. */
+ SSPUSHINT(paren_elems_to_push + REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS);
+ SSPUSHINT(SAVEt_REGCONTEXT); /* Magic cookie. */
+
return retval;
}
STATIC char *
S_regcppop(pTHX)
{
- I32 i = SSPOPINT;
+ I32 i;
U32 paren = 0;
char *input;
I32 tmps;
- assert(i == SAVEt_REGCONTEXT);
+
+ /* Pop REGCP_OTHER_ELEMS before the parentheses loop starts. */
i = SSPOPINT;
+ assert(i == SAVEt_REGCONTEXT); /* Check that the magic cookie is there. */
+ i = SSPOPINT; /* Parentheses elements to pop. */
input = (char *) SSPOPPTR;
*PL_reglastparen = SSPOPINT;
PL_regsize = SSPOPINT;
- for (i -= 3; i > 0; i -= 4) {
+
+ /* Now restore the parentheses context. */
+ for (i -= (REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS);
+ i > 0; i -= REGCP_PAREN_ELEMS) {
paren = (U32)SSPOPINT;
PL_reg_start_tmp[paren] = (char *) SSPOPPTR;
PL_regstartp[paren] = SSPOPINT;
DEBUG_r(PerlIO_printf(Perl_debug_log, "Not at start...\n"));
goto fail;
}
- if (prog->check_offset_min == prog->check_offset_max) {
+ if (prog->check_offset_min == prog->check_offset_max &&
+ !(prog->reganch & ROPT_SANY_SEEN)) {
/* Substring at constant offset from beg-of-str... */
I32 slen;
#endif
restart:
- other_last = Nullch;
-
/* Find a possible match in the region s..strend by looking for
the "check" substring in the region corrected by start/end_shift. */
if (flags & REXEC_SCREAM) {
if (data)
*data->scream_olds = s;
}
+ else if (prog->reganch & ROPT_SANY_SEEN)
+ s = fbm_instr((U8*)(s + start_shift),
+ (U8*)(strend - end_shift),
+ check, PL_multiline ? FBMrf_MULTILINE : 0);
else
s = fbm_instr(HOP3(s, start_shift, strend),
HOP3(strend, -end_shift, strbeg),
DEBUG_r(PerlIO_printf(Perl_debug_log,
", trying anchored starting at offset %ld...\n",
(long)(s1 + 1 - i_strpos)));
- other_last = last + 1;
+ other_last = last;
s = HOP3c(t, 1, strend);
goto restart;
}
else {
DEBUG_r(PerlIO_printf(Perl_debug_log, " at offset %ld...\n",
(long)(s - i_strpos)));
- other_last = s + 1;
+ other_last = s; /* Fix this later. --Hugo */
s = s1;
if (t == strpos)
goto try_at_start;
minlen = prog->minlen;
if (do_utf8) {
- if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey;
+ if (!(prog->reganch & ROPT_SANY_SEEN))
+ if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey;
}
else {
if (strend - startpos < minlen) goto phooey;
PL_reg_ganch = strbeg;
}
- if (!(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
+ if (do_utf8 == (UTF!=0) &&
+ !(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
re_scream_pos_data d;
d.scream_olds = &scream_olds;
sayNO;
break;
case SANY:
- if (do_utf8) {
- locinput += PL_utf8skip[nextchr];
- if (locinput > PL_regeol)
- sayNO;
- nextchr = UCHARAT(locinput);
- break;
- }
if (!nextchr && locinput >= PL_regeol)
sayNO;
nextchr = UCHARAT(++locinput);
}
break;
case SANY:
- if (do_utf8) {
- loceol = PL_regeol;
- while (hardcount < max && scan < loceol) {
- scan += UTF8SKIP(scan);
- hardcount++;
- }
- } else {
- scan = loceol;
- }
+ scan = loceol;
break;
case EXACT: /* length of string is 1 */
c = (U8)*STRING(p);