}
LvTYPE(TARG) = '.';
- LvTARG(TARG) = sv;
+ if (LvTARG(TARG) != sv) {
+ if (LvTARG(TARG))
+ SvREFCNT_dec(LvTARG(TARG));
+ LvTARG(TARG) = SvREFCNT_inc(sv);
+ }
PUSHs(TARG); /* no SvSETMAGIC */
RETURN;
}
if (MAXARG == 1)
stash = curcop->cop_stash;
- else
- stash = gv_stashsv(POPs, TRUE);
+ else {
+ SV *ssv = POPs;
+ STRLEN len;
+ char *ptr = SvPV(ssv,len);
+ if (dowarn && len == 0)
+ warn("Explicit blessing to '' (assuming package main)");
+ stash = gv_stashpvn(ptr, len, TRUE);
+ }
(void)sv_bless(TOPs, stash);
RETURN;
djSP; dTARGET;
SV *sv;
I32 len;
+ I32 len_ok = 0;
STRLEN curlen;
I32 pos;
I32 rem;
I32 lvalue = op->op_flags & OPf_MOD;
char *tmps;
I32 arybase = curcop->cop_arybase;
+ char *repl = 0;
+ STRLEN repl_len;
SvTAINTED_off(TARG); /* decontaminate */
- if (MAXARG > 2)
+ if (MAXARG > 3) {
+ /* pop off replacement string */
+ sv = POPs;
+ repl = SvPV(sv, repl_len);
+ /* pop off length */
+ sv = POPs;
+ if (SvOK(sv)) {
+ len = SvIV(sv);
+ len_ok++;
+ }
+ } else if (MAXARG == 3) {
len = POPi;
+ len_ok++;
+ }
+
pos = POPi;
sv = POPs;
PUTBACK;
pos -= arybase;
rem = curlen-pos;
fail = rem;
- if (MAXARG > 2) {
+ if (len_ok) {
if (len < 0) {
rem += len;
if (rem < 0)
}
else {
pos += curlen;
- if (MAXARG < 3)
+ if (!len_ok)
rem = curlen;
else if (len >= 0) {
rem = pos+len;
rem -= pos;
}
if (fail < 0) {
- if (dowarn || lvalue)
+ if (dowarn || lvalue || repl)
warn("substr outside of string");
RETPUSHUNDEF;
}
}
LvTYPE(TARG) = 'x';
- LvTARG(TARG) = sv;
+ if (LvTARG(TARG) != sv) {
+ if (LvTARG(TARG))
+ SvREFCNT_dec(LvTARG(TARG));
+ LvTARG(TARG) = SvREFCNT_inc(sv);
+ }
LvTARGOFF(TARG) = pos;
LvTARGLEN(TARG) = rem;
}
+ else if (repl)
+ sv_insert(sv, pos, rem, repl, repl_len);
}
SPAGAIN;
PUSHs(TARG); /* avoid SvSETMAGIC here */
}
LvTYPE(TARG) = 'v';
- LvTARG(TARG) = src;
+ if (LvTARG(TARG) != src) {
+ if (LvTARG(TARG))
+ SvREFCNT_dec(LvTARG(TARG));
+ LvTARG(TARG) = SvREFCNT_inc(src);
+ }
LvTARGOFF(TARG) = offset;
LvTARGLEN(TARG) = size;
}