EXTEND(SP, maxarg);
if (SvRMAGICAL(av)) {
U32 i;
- for (i=0; i < maxarg; i++) {
+ for (i=0; i < (U32)maxarg; i++) {
SV **svp = av_fetch(av, i, FALSE);
SP[i+1] = (svp) ? *svp : &PL_sv_undef;
}
{
dSP; dTARG;
register PMOP *pm = cPMOP;
+ PMOP *dynpm = pm;
register char *t;
register char *s;
char *strend;
PL_reg_match_utf8 = DO_UTF8(TARG);
+ /* PMdf_USED is set after a ?? matches once */
if (pm->op_pmdynflags & PMdf_USED) {
failure:
if (gimme == G_ARRAY)
RETPUSHNO;
}
+ /* empty pattern special-cased to use last successful pattern if possible */
if (!rx->prelen && PL_curpm) {
pm = PL_curpm;
rx = PM_GETRE(pm);
}
- if (rx->minlen > len)
- goto failure;
+
+ if (rx->minlen > (I32)len)
+ goto failure;
truebase = t = s;
/* XXXX What part of this is needed with true \G-support? */
- if ((global = pm->op_pmflags & PMf_GLOBAL)) {
+ if ((global = dynpm->op_pmflags & PMf_GLOBAL)) {
rx->startp[0] = -1;
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
MAGIC* mg = mg_find(TARG, PERL_MAGIC_regex_global);
if (CALLREGEXEC(aTHX_ rx, s, strend, truebase, minmatch, TARG, NULL, r_flags))
{
PL_curpm = pm;
- if (pm->op_pmflags & PMf_ONCE)
- pm->op_pmdynflags |= PMdf_USED;
+ if (dynpm->op_pmflags & PMf_ONCE)
+ dynpm->op_pmdynflags |= PMdf_USED;
goto gotcha;
}
else
}
}
if (global) {
- if (pm->op_pmflags & PMf_CONTINUE) {
+ if (dynpm->op_pmflags & PMf_CONTINUE) {
MAGIC* mg = 0;
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG))
mg = mg_find(TARG, PERL_MAGIC_regex_global);
RX_MATCH_TAINTED_on(rx);
TAINT_IF(RX_MATCH_TAINTED(rx));
PL_curpm = pm;
- if (pm->op_pmflags & PMf_ONCE)
- pm->op_pmdynflags |= PMdf_USED;
+ if (dynpm->op_pmflags & PMf_ONCE)
+ dynpm->op_pmdynflags |= PMdf_USED;
if (RX_MATCH_COPIED(rx))
Safefree(rx->subbeg);
RX_MATCH_COPIED_off(rx);
nope:
ret_no:
- if (global && !(pm->op_pmflags & PMf_CONTINUE)) {
+ if (global && !(dynpm->op_pmflags & PMf_CONTINUE)) {
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
MAGIC* mg = mg_find(TARG, PERL_MAGIC_regex_global);
if (mg)
STRLEN keylen;
char *key = SvPV(keysv, keylen);
SAVEDELETE(hv, savepvn(key,keylen), keylen);
- } else
+ } else {
+ SV *sv;
save_helem(hv, keysv, svp);
+ sv = *svp;
+ /* If we're localizing a tied hash element, this new
+ * sv won't actually be stored in the hash - so it
+ * won't get reaped when the localize ends. Ensure it
+ * gets reaped by mortifying it instead. DAPM */
+ if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
+ sv_2mortal(sv);
+ }
}
}
else if (PL_op->op_private & OPpDEREF)
int force_on_match = 0;
I32 oldsave = PL_savestack_ix;
STRLEN slen;
+ bool doutf8 = FALSE;
/* known replacement string? */
dstr = (pm->op_pmflags & PMf_CONST) ? POPs : Nullsv;
once = !(rpm->op_pmflags & PMf_GLOBAL);
/* known replacement string? */
- c = dstr ? SvPV(dstr, clen) : Nullch;
-
+ if (dstr) {
+ c = SvPV(dstr, clen);
+ doutf8 = DO_UTF8(dstr);
+ }
+ else {
+ c = Nullch;
+ doutf8 = FALSE;
+ }
+
/* can do inplace substitution? */
- if (c && clen <= rx->minlen && (once || !(r_flags & REXEC_COPY_STR))
+ if (c && (I32)clen <= rx->minlen && (once || !(r_flags & REXEC_COPY_STR))
&& !(rx->reganch & ROPT_LOOKBEHIND_SEEN)) {
if (!CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL,
r_flags | REXEC_CHECKED))
if (CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL,
r_flags | REXEC_CHECKED))
{
- bool isutf8;
-
if (force_on_match) {
force_on_match = 0;
s = SvPV_force(TARG, len);
break;
} while (CALLREGEXEC(aTHX_ rx, s, strend, orig, s == m,
TARG, NULL, r_flags));
- sv_catpvn(dstr, s, strend - s);
+ if (doutf8 && !DO_UTF8(dstr)) {
+ SV* nsv = sv_2mortal(newSVpvn(s, strend - s));
+
+ sv_utf8_upgrade(nsv);
+ sv_catpvn(dstr, SvPVX(nsv), SvCUR(nsv));
+ }
+ else
+ sv_catpvn(dstr, s, strend - s);
(void)SvOOK_off(TARG);
Safefree(SvPVX(TARG));
SvPVX(TARG) = SvPVX(dstr);
SvCUR_set(TARG, SvCUR(dstr));
SvLEN_set(TARG, SvLEN(dstr));
- isutf8 = DO_UTF8(dstr);
+ doutf8 |= DO_UTF8(dstr);
SvPVX(dstr) = 0;
sv_free(dstr);
PUSHs(sv_2mortal(newSViv((I32)iters)));
(void)SvPOK_only(TARG);
- if (isutf8)
+ if (doutf8)
SvUTF8_on(TARG);
TAINT_IF(rxtainted);
SvSETMAGIC(TARG);
PUSHs(lv);
RETURN;
}
- if (PL_op->op_private & OPpLVAL_INTRO)
+ if (PL_op->op_private & OPpLVAL_INTRO) {
+ SV *sv;
save_aelem(av, elem, svp);
+ sv = *svp;
+ /* If we're localizing a tied array element, this new sv
+ * won't actually be stored in the array - so it won't get
+ * reaped when the localize ends. Ensure it gets reaped by
+ * mortifying it instead. DAPM */
+ if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
+ sv_2mortal(sv);
+ }
else if (PL_op->op_private & OPpDEREF)
vivify_ref(*svp, PL_op->op_private & OPpDEREF);
}