#define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uscan, len, \
uvc, charid, foldlen, foldbuf, uniflags) STMT_START { \
+ UV uvc_unfolded = 0; \
switch (trie_type) { \
case trie_utf8_fold: \
if ( foldlen>0 ) { \
- uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags ); \
+ uvc_unfolded = uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags ); \
foldlen -= len; \
uscan += len; \
len=0; \
} else { \
- uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags ); \
+ uvc_unfolded = uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags ); \
uvc = to_uni_fold( uvc, foldbuf, &foldlen ); \
foldlen -= UNISKIP( uvc ); \
uscan = foldbuf + UNISKIP( uvc ); \
charid = (U16)SvIV(*svpp); \
} \
} \
+ if (!charid && trie_type == trie_utf8_fold && !UTF) { \
+ charid = trie->charmap[uvc_unfolded]; \
+ } \
} STMT_END
#define REXEC_FBC_EXACTISH_CHECK(CoNd) \
state_num = OP(scan);
reenter_switch:
+
+ assert(PL_reglastparen == &rex->lastparen);
+ assert(PL_reglastcloseparen == &rex->lastcloseparen);
+ assert(PL_regoffs == rex->offs);
+
switch (state_num) {
case BOL:
if (locinput == PL_bostr)
if ( got_wordnum ) {
if ( ! ST.accepted ) {
ENTER;
- /* SAVETMPS; */ /* XXX is this necessary? dmq */
+ SAVETMPS; /* XXX is this necessary? dmq */
bufflen = TRIE_INITAL_ACCEPT_BUFFLEN;
sv_accept_buff=newSV(bufflen *
sizeof(reg_trie_accepted) - 1);
}
/* NOTREACHED */
case TRIE_next:
+ /* we dont want to throw this away, see bug 57042*/
+ if (oreplsv != GvSV(PL_replgv))
+ sv_setsv(oreplsv, GvSV(PL_replgv));
FREETMPS;
LEAVE;
sayYES;
regcpblow(ST.cp);
cur_eval = ST.prev_eval;
cur_curlyx = ST.prev_curlyx;
-
+
+ /* rex was changed so update the pointer in PL_reglastparen and PL_reglastcloseparen */
PL_reglastparen = &rex->lastparen;
PL_reglastcloseparen = &rex->lastcloseparen;
+ /* also update PL_regoffs */
+ PL_regoffs = rex->offs;
/* XXXX This is too dramatic a measure... */
PL_reg_maxiter = 0;
SETREX(rex_sv,ST.prev_rex);
rex = (struct regexp *)SvANY(rex_sv);
rexi = RXi_GET(rex);
+ /* rex was changed so update the pointer in PL_reglastparen and PL_reglastcloseparen */
PL_reglastparen = &rex->lastparen;
PL_reglastcloseparen = &rex->lastcloseparen;
cur_eval->u.eval.close_paren == (U32)ST.me->flags)
goto fake_end;
- if ( ST.count < (ST.minmod ? ARG1(ST.me) : ARG2(ST.me)) )
- goto curlym_do_A; /* try to match another A */
+ {
+ I32 max = (ST.minmod ? ARG1(ST.me) : ARG2(ST.me));
+ if ( max == REG_INFTY || ST.count < max )
+ goto curlym_do_A; /* try to match another A */
+ }
goto curlym_do_B; /* try to match B */
case CURLYM_A_fail: /* just failed to match an A */
cur_curlyx = cur_eval->u.eval.prev_curlyx;
ReREFCNT_inc(rex_sv);
st->u.eval.cp = regcppush(0); /* Save *all* the positions. */
+
+ /* rex was changed so update the pointer in PL_reglastparen and PL_reglastcloseparen */
+ PL_reglastparen = &rex->lastparen;
+ PL_reglastcloseparen = &rex->lastcloseparen;
+
REGCP_SET(st->u.eval.lastcp);
PL_reginput = locinput;
SV * const sw = regclass_swash(prog, n, TRUE, 0, (SV**)&av);
if (sw) {
- if (swash_fetch(sw, p, do_utf8))
+ U8 * utf8_p;
+ if (do_utf8) {
+ utf8_p = (U8 *) p;
+ } else {
+ STRLEN len = 1;
+ utf8_p = bytes_to_utf8(p, &len);
+ }
+ if (swash_fetch(sw, utf8_p, 1))
match = TRUE;
else if (flags & ANYOF_FOLD) {
if (!match && lenp && av) {
SV* const sv = *av_fetch(av, i, FALSE);
STRLEN len;
const char * const s = SvPV_const(sv, len);
-
- if (len <= plen && memEQ(s, (char*)p, len)) {
+ if (len <= plen && memEQ(s, (char*)utf8_p, len)) {
*lenp = len;
match = TRUE;
break;
}
if (!match) {
U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
- STRLEN tmplen;
- to_utf8_fold(p, tmpbuf, &tmplen);
- if (swash_fetch(sw, tmpbuf, do_utf8))
+ STRLEN tmplen;
+ to_utf8_fold(utf8_p, tmpbuf, &tmplen);
+ if (swash_fetch(sw, tmpbuf, 1))
match = TRUE;
}
}
+
+ /* If we allocated a string above, free it */
+ if (! do_utf8) Safefree(utf8_p);
}
}
if (match && lenp && *lenp == 0)