{
djSP;
AV *av = GvAV((GV*)cSVOP->op_sv);
- SV** svp = av_fetch(av, op->op_private, op->op_flags & OPf_MOD);
+ U32 lval = op->op_flags & OPf_MOD;
+ SV** svp = av_fetch(av, op->op_private, lval);
+ SV *sv = (svp ? *svp : &sv_undef);
EXTEND(SP, 1);
- PUSHs(svp ? *svp : &sv_undef);
+ if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
+ sv = sv_mortalcopy(sv);
+ PUSHs(sv);
RETURN;
}
}
else {
dTARGET;
- /* This bit is OK even when hv is really an AV */
+ if (SvTYPE(hv) == SVt_PVAV)
+ hv = avhv_keys((AV*)hv);
if (HvFILL(hv))
sv_setpvf(TARG, "%ld/%ld",
(long)HvFILL(hv), (long)HvMAX(hv) + 1);
hv_clear(hash);
while (relem < lastrelem) { /* gobble up all the rest */
- STRLEN len;
HE *didstore;
if (*relem)
sv = *(relem++);
}
TAINT_NOT;
}
- if (relem == lastrelem && dowarn) {
- if (relem == firstrelem &&
- SvROK(*relem) &&
- ( SvTYPE(SvRV(*relem)) == SVt_PVAV ||
- SvTYPE(SvRV(*relem)) == SVt_PVHV ) )
- warn("Reference found where even-sized list expected");
- else
- warn("Odd number of elements in hash assignment");
+ if (relem == lastrelem) {
+ if (*relem) {
+ HE *didstore;
+ if (dowarn) {
+ if (relem == firstrelem &&
+ SvROK(*relem) &&
+ ( SvTYPE(SvRV(*relem)) == SVt_PVAV ||
+ SvTYPE(SvRV(*relem)) == SVt_PVHV ) )
+ warn("Reference found where even-sized list expected");
+ else
+ warn("Odd number of elements in hash assignment");
+ }
+ tmpstr = NEWSV(29,0);
+ didstore = hv_store_ent(hash,*relem,tmpstr,0);
+ if (magic) {
+ if (SvSMAGICAL(tmpstr))
+ mg_set(tmpstr);
+ if (!didstore)
+ SvREFCNT_dec(tmpstr);
+ }
+ TAINT_NOT;
+ }
+ relem++;
}
}
break;
default:
if (SvTHINKFIRST(sv)) {
if (SvREADONLY(sv) && curcop != &compiling) {
- if (sv != &sv_undef && sv != &sv_yes && sv != &sv_no)
+ if (!SvIMMORTAL(sv))
DIE(no_modify);
if (relem <= lastrelem)
relem++;
RETURN;
}
+PP(pp_qr)
+{
+ djSP;
+ register PMOP *pm = cPMOP;
+ SV *rv = sv_newmortal();
+ SV *sv = newSVrv(rv, "Regexp");
+ sv_magic(sv,(SV*)ReREFCNT_inc(pm->op_pmregexp),'r',0,0);
+ RETURNX(PUSHs(rv));
+}
+
PP(pp_match)
{
djSP; dTARG;
I32 safebase;
char *truebase;
register REGEXP *rx = pm->op_pmregexp;
+ bool rxtainted;
I32 gimme = GIMME;
STRLEN len;
I32 minmatch = 0;
strend = s + len;
if (!s)
DIE("panic: do_match");
+ rxtainted = ((pm->op_pmdynflags & PMdf_TAINTED) ||
+ (tainted && (pm->op_pmflags & PMf_RETAINT)));
TAINT_NOT;
if (pm->op_pmdynflags & PMdf_USED) {
}
else if (!(s = fbm_instr((unsigned char*)s + rx->check_offset_min,
(unsigned char*)strend,
- rx->check_substr)))
+ rx->check_substr, 0)))
goto nope;
else if ((rx->reganch & ROPT_CHECK_ALL) && !sawampersand)
goto yup;
- if (s && rx->check_offset_max < t - s) {
+ if (s && rx->check_offset_max < s - t) {
++BmUSEFUL(rx->check_substr);
s -= rx->check_offset_max;
}
rx->float_substr = Nullsv;
}
}
- if (regexec_flags(rx, s, strend, truebase, minmatch,
+ if (CALLREGEXEC(rx, s, strend, truebase, minmatch,
screamer, NULL, safebase))
{
curpm = pm;
/*NOTREACHED*/
gotcha:
+ if (rxtainted)
+ RX_MATCH_TAINTED_on(rx);
TAINT_IF(RX_MATCH_TAINTED(rx));
if (gimme == G_ARRAY) {
I32 iters, i, len;
}
yup: /* Confirmed by check_substr */
+ if (rxtainted)
+ RX_MATCH_TAINTED_on(rx);
TAINT_IF(RX_MATCH_TAINTED(rx));
++BmUSEFUL(rx->check_substr);
curpm = pm;
IoFLAGS(io) &= ~IOf_START;
IoLINES(io) = 0;
if (av_len(GvAVn(last_in_gv)) < 0) {
- SV *tmpstr = newSVpv("-", 1); /* assume stdin */
- av_push(GvAVn(last_in_gv), tmpstr);
+ do_open(last_in_gv,"-",1,FALSE,0,0,Nullfp);
+ sv_setpvn(GvSV(last_in_gv), "-", 1);
+ SvSETMAGIC(GvSV(last_in_gv));
+ fp = IoIFP(io);
+ goto have_fp;
}
}
fp = nextargv(last_in_gv);
}
RETURN;
}
+ have_fp:
if (gimme == G_SCALAR) {
sv = TARG;
if (SvROK(sv))
HV *hv = (HV*)POPs;
U32 lval = op->op_flags & OPf_MOD;
U32 defer = op->op_private & OPpLVAL_DEFER;
+ SV *sv;
if (SvTYPE(hv) == SVt_PVHV) {
he = hv_fetch_ent(hv, keysv, lval && !defer, 0);
else if (op->op_private & OPpDEREF)
vivify_ref(*svp, op->op_private & OPpDEREF);
}
- PUSHs(svp ? *svp : &sv_undef);
+ sv = (svp ? *svp : &sv_undef);
+ /* This makes C<local $tied{foo} = $tied{foo}> possible.
+ * Pushing the magical RHS on to the stack is useless, since
+ * that magic is soon destined to be misled by the local(),
+ * and thus the later pp_sassign() will fail to mg_get() the
+ * old value. This should also cure problems with delayed
+ * mg_get()s. GSAR 98-07-03 */
+ if (!lval && SvGMAGICAL(sv))
+ sv = sv_mortalcopy(sv);
+ PUSHs(sv);
RETURN;
}
DIE("panic: pp_iter");
av = cx->blk_loop.iterary;
+ if (SvTYPE(av) != SVt_PVAV) {
+ /* iterate ($min .. $max) */
+ if (cx->blk_loop.iterlval) {
+ /* string increment */
+ register SV* cur = cx->blk_loop.iterlval;
+ STRLEN maxlen;
+ char *max = SvPV((SV*)av, maxlen);
+ if (!SvNIOK(cur) && SvCUR(cur) <= maxlen) {
+ /* we need a fresh SV every time so that loop body sees a
+ * completely new SV for closures/references to work as they
+ * used to */
+ SvREFCNT_dec(*cx->blk_loop.itervar);
+ *cx->blk_loop.itervar = newSVsv(cur);
+ if (strEQ(SvPVX(cur), max))
+ sv_setiv(cur, 0); /* terminate next time */
+ else
+ sv_inc(cur);
+ RETPUSHYES;
+ }
+ RETPUSHNO;
+ }
+ /* integer increment */
+ if (cx->blk_loop.iterix > cx->blk_loop.itermax)
+ RETPUSHNO;
+
+ /* we need a fresh SV every time so that loop body sees a
+ * completely new SV for closures/references to work as they
+ * used to */
+ SvREFCNT_dec(*cx->blk_loop.itervar);
+ *cx->blk_loop.itervar = newSViv(cx->blk_loop.iterix++);
+ RETPUSHYES;
+ }
+
+ /* iterate array */
if (cx->blk_loop.iterix >= (av == curstack ? cx->blk_oldsp : AvFILL(av)))
RETPUSHNO;
s = SvPV(TARG, len);
if (!SvPOKp(TARG) || SvTYPE(TARG) == SVt_PVGV)
force_on_match = 1;
- rxtainted = tainted << 1;
+ rxtainted = ((pm->op_pmdynflags & PMdf_TAINTED) ||
+ (tainted && (pm->op_pmflags & PMf_RETAINT)));
+ if (tainted)
+ rxtainted |= 2;
TAINT_NOT;
force_it:
}
else if (!(s = fbm_instr((unsigned char*)s + rx->check_offset_min,
(unsigned char*)strend,
- rx->check_substr)))
+ rx->check_substr, 0)))
goto nope;
if (s && rx->check_offset_max < s - m) {
++BmUSEFUL(rx->check_substr);
/* can do inplace substitution? */
if (c && clen <= rx->minlen && (once || !(safebase & REXEC_COPY_STR))
&& !(rx->reganch & ROPT_LOOKBEHIND_SEEN)) {
- if (!regexec_flags(rx, s, strend, orig, 0, screamer, NULL, safebase)) {
+ if (!CALLREGEXEC(rx, s, strend, orig, 0, screamer, NULL, safebase)) {
SPAGAIN;
PUSHs(&sv_no);
LEAVE_SCOPE(oldsave);
d += clen;
}
s = rx->endp[0];
- } while (regexec_flags(rx, s, strend, orig, s == m,
+ } while (CALLREGEXEC(rx, s, strend, orig, s == m,
Nullsv, NULL, 0)); /* don't match same null twice */
if (s != d) {
i = strend - s;
RETURN;
}
- if (regexec_flags(rx, s, strend, orig, 0, screamer, NULL, safebase)) {
+ if (CALLREGEXEC(rx, s, strend, orig, 0, screamer, NULL, safebase)) {
if (force_on_match) {
force_on_match = 0;
s = SvPV_force(TARG, len);
sv_catpvn(dstr, c, clen);
if (once)
break;
- } while (regexec_flags(rx, s, strend, orig, s == m, Nullsv, NULL, safebase));
+ } while (CALLREGEXEC(rx, s, strend, orig, s == m, Nullsv, NULL, safebase));
sv_catpvn(dstr, s, strend - s);
(void)SvOOK_off(TARG);
TAINT_NOT;
if (gimme == G_SCALAR) {
MARK = newsp + 1;
- if (MARK <= SP)
- *MARK = SvTEMP(TOPs) ? TOPs : sv_mortalcopy(TOPs);
- else {
+ if (MARK <= SP) {
+ if (cxsub.cv && CvDEPTH(cxsub.cv) > 1) {
+ if (SvTEMP(TOPs)) {
+ *MARK = SvREFCNT_inc(TOPs);
+ FREETMPS;
+ sv_2mortal(*MARK);
+ } else {
+ FREETMPS;
+ *MARK = sv_mortalcopy(TOPs);
+ }
+ } else
+ *MARK = SvTEMP(TOPs) ? TOPs : sv_mortalcopy(TOPs);
+ } else {
MEXTEND(MARK, 0);
*MARK = &sv_undef;
}
curcopdb = NULL;
}
/* Do we need to open block here? XXXX */
- (void)(*CvXSUB(cv))(cv _THIS);
+ (void)(*CvXSUB(cv))(cv _PERL_OBJECT_THIS);
/* Enforce some sanity in scalar context. */
if (gimme == G_SCALAR && ++markix != stack_sp - stack_base ) {
AV* av = (AV*)POPs;
U32 lval = op->op_flags & OPf_MOD;
U32 defer = (op->op_private & OPpLVAL_DEFER) && (elem > AvFILL(av));
+ SV *sv;
if (elem > 0)
elem -= curcop->cop_arybase;
else if (op->op_private & OPpDEREF)
vivify_ref(*svp, op->op_private & OPpDEREF);
}
- PUSHs(svp ? *svp : &sv_undef);
+ sv = (svp ? *svp : &sv_undef);
+ if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
+ sv = sv_mortalcopy(sv);
+ PUSHs(sv);
RETURN;
}
!(ob=(SV*)GvIO(iogv)))
{
if (!packname || !isIDFIRST(*packname))
- DIE("Can't call method \"%s\" without a package or object reference", name);
+ DIE("Can't call method \"%s\" %s", name,
+ SvOK(sv)? "without a package or object reference"
+ : "on an undefined value");
stash = gv_stashpvn(packname, packlen, TRUE);
goto fetch;
}