/* pp_hot.c
*
- * Copyright (c) 1991-1997, Larry Wall
+ * Copyright (c) 1991-1999, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
{
tryAMAGICunTARGET(iter, 0);
PL_last_in_gv = (GV*)(*PL_stack_sp--);
- if (PL_op->op_flags & OPf_SPECIAL) { /* Are called as <$var> */
- if (SvROK(PL_last_in_gv)) {
- if (SvTYPE(SvRV(PL_last_in_gv)) != SVt_PVGV)
- goto hard_way;
+ if (SvTYPE(PL_last_in_gv) != SVt_PVGV) {
+ if (SvROK(PL_last_in_gv) && SvTYPE(SvRV(PL_last_in_gv)) == SVt_PVGV)
PL_last_in_gv = (GV*)SvRV(PL_last_in_gv);
- } else if (SvTYPE(PL_last_in_gv) != SVt_PVGV) {
- hard_way: {
+ else {
dSP;
XPUSHs((SV*)PL_last_in_gv);
PUTBACK;
pp_rv2gv(ARGS);
PL_last_in_gv = (GV*)(*PL_stack_sp--);
- }
}
}
return do_readline();
djSP;
if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
croak(PL_no_modify);
- if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
+ if (SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MAX)
{
++SvIVX(TOPs);
RETSETUNDEF;
}
sym = SvPV(sv,n_a);
- if (PL_op->op_private & HINT_STRICT_REFS)
- DIE(PL_no_symref, sym, "an ARRAY");
- gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV);
- } else {
+ if ((PL_op->op_flags & OPf_SPECIAL) &&
+ !(PL_op->op_flags & OPf_MOD))
+ {
+ gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PVAV);
+ if (!gv)
+ RETSETUNDEF;
+ }
+ else {
+ if (PL_op->op_private & HINT_STRICT_REFS)
+ DIE(PL_no_symref, sym, "an ARRAY");
+ gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV);
+ }
+ }
+ else {
gv = (GV*)sv;
}
av = GvAVn(gv);
RETSETUNDEF;
}
sym = SvPV(sv,n_a);
- if (PL_op->op_private & HINT_STRICT_REFS)
- DIE(PL_no_symref, sym, "a HASH");
- gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV);
- } else {
+ if ((PL_op->op_flags & OPf_SPECIAL) &&
+ !(PL_op->op_flags & OPf_MOD))
+ {
+ gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PVHV);
+ if (!gv)
+ RETSETUNDEF;
+ }
+ else {
+ if (PL_op->op_private & HINT_STRICT_REFS)
+ DIE(PL_no_symref, sym, "a HASH");
+ gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV);
+ }
+ }
+ else {
gv = (GV*)sv;
}
hv = GvHVn(gv);
if (SvSMAGICAL(sv))
mg_set(sv);
if (!didstore)
- SvREFCNT_dec(sv);
+ sv_2mortal(sv);
}
TAINT_NOT;
}
if (SvSMAGICAL(tmpstr))
mg_set(tmpstr);
if (!didstore)
- SvREFCNT_dec(tmpstr);
+ sv_2mortal(tmpstr);
}
TAINT_NOT;
}
if (SvSMAGICAL(tmpstr))
mg_set(tmpstr);
if (!didstore)
- SvREFCNT_dec(tmpstr);
+ sv_2mortal(tmpstr);
}
TAINT_NOT;
}
}
break;
default:
- if (SvTHINKFIRST(sv)) {
- if (SvREADONLY(sv) && PL_curcop != &PL_compiling) {
- if (!SvIMMORTAL(sv))
- DIE(PL_no_modify);
- if (relem <= lastrelem)
- relem++;
- break;
- }
- if (SvROK(sv))
- sv_unref(sv);
+ if (SvIMMORTAL(sv)) {
+ if (relem <= lastrelem)
+ relem++;
+ break;
}
if (relem <= lastrelem) {
sv_setsv(sv, *relem);
register char *s;
char *strend;
I32 global;
- I32 r_flags;
+ I32 r_flags = 0;
char *truebase;
register REGEXP *rx = pm->op_pmregexp;
bool rxtainted;
I32 minmatch = 0;
I32 oldsave = PL_savestack_ix;
I32 update_minmatch = 1;
+ I32 had_zerolen = 0;
if (PL_op->op_flags & OPf_STACKED)
TARG = POPs;
if (rx->minlen > len) goto failure;
truebase = t = s;
+
+ /* XXXX What part of this is needed with true \G-support? */
if (global = pm->op_pmflags & PMf_GLOBAL) {
rx->startp[0] = 0;
if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
MAGIC* mg = mg_find(TARG, 'g');
if (mg && mg->mg_len >= 0) {
- rx->endp[0] = rx->startp[0] = s + mg->mg_len;
+ if (!(rx->reganch & ROPT_GPOS_SEEN))
+ rx->endp[0] = rx->startp[0] = s + mg->mg_len;
+ else if (rx->reganch & ROPT_ANCH_GPOS) {
+ r_flags |= REXEC_IGNOREPOS;
+ rx->endp[0] = rx->startp[0] = s + mg->mg_len;
+ }
minmatch = (mg->mg_flags & MGf_MINMATCH);
update_minmatch = 0;
}
}
}
- r_flags = ((gimme != G_ARRAY && !global && rx->nparens)
- || SvTEMP(TARG) || PL_sawampersand)
- ? REXEC_COPY_STR : 0;
+ if ((gimme != G_ARRAY && !global && rx->nparens)
+ || SvTEMP(TARG) || PL_sawampersand)
+ r_flags |= REXEC_COPY_STR;
if (SvSCREAM(TARG) && rx->check_substr
&& SvTYPE(rx->check_substr) == SVt_PVBM
&& SvVALID(rx->check_substr))
if ((s + rx->minlen) > strend)
goto nope;
if (update_minmatch++)
- minmatch = (s == rx->startp[0]);
+ minmatch = had_zerolen;
}
if (rx->check_substr) {
if (!(rx->reganch & ROPT_NOSCAN)) { /* Floating checkstring. */
if (global) {
truebase = rx->subbeg;
strend = rx->subend;
- if (rx->startp[0] && rx->startp[0] == rx->endp[0])
- ++rx->endp[0];
+ had_zerolen = (rx->startp[0] && rx->startp[0] == rx->endp[0]);
PUTBACK; /* EVAL blocks may use stack */
+ r_flags |= REXEC_IGNOREPOS;
goto play_it_again;
}
else if (!iters)
sv_setpv(tmpcmd, "/dev/dosglob/"); /* File System Extension */
sv_catsv(tmpcmd, tmpglob);
#else
+#ifdef CYGWIN32
+ sv_setpv(tmpcmd, "for a in ");
+ sv_catsv(tmpcmd, tmpglob);
+ sv_catpv(tmpcmd, "; do echo -e \"$a\\0\\c\"; done |");
+#else
sv_setpv(tmpcmd, "perlglob ");
sv_catsv(tmpcmd, tmpglob);
sv_catpv(tmpcmd, " |");
+#endif /* !CYGWIN */
#endif /* !DJGPP */
#endif /* !OS2 */
#else /* !DOSISH */
SP--;
}
if (!fp) {
- if (ckWARN(WARN_CLOSED) && io && !(IoFLAGS(io) & IOf_START))
- warner(WARN_CLOSED,
- "Read on closed filehandle <%s>", GvENAME(PL_last_in_gv));
+ if (ckWARN(WARN_CLOSED) && io && !(IoFLAGS(io) & IOf_START)) {
+ if (type == OP_GLOB)
+ warner(WARN_CLOSED, "glob failed (can't start child: %s)",
+ Strerror(errno));
+ else
+ warner(WARN_CLOSED, "Read on closed filehandle <%s>",
+ GvENAME(PL_last_in_gv));
+ }
if (gimme == G_SCALAR) {
(void)SvOK_off(TARG);
PUSHTARG;
sv = sv_2mortal(NEWSV(57, 80));
offset = 0;
}
+
+/* flip-flop EOF state for a snarfed empty file */
+#define SNARF_EOF(gimme,rs,io,sv) \
+ ((gimme != G_SCALAR || SvCUR(sv) \
+ || (IoFLAGS(io) & IOf_NOLINE) || IoLINES(io) || !RsSNARF(rs)) \
+ ? ((IoFLAGS(io) &= ~IOf_NOLINE), TRUE) \
+ : ((IoFLAGS(io) |= IOf_NOLINE), FALSE))
+
for (;;) {
- if (!sv_gets(sv, fp, offset)) {
+ if (!sv_gets(sv, fp, offset)
+ && (type == OP_GLOB || SNARF_EOF(gimme, PL_rs, io, sv)))
+ {
PerlIO_clearerr(fp);
if (IoFLAGS(io) & IOf_ARGV) {
fp = nextargv(PL_last_in_gv);
PUSHSUBST(cx);
RETURNOP(cPMOP->op_pmreplroot);
}
+ r_flags |= REXEC_IGNOREPOS;
do {
if (iters++ > maxiters)
DIE("Substitution loop");
sv_catpvn(dstr, c, clen);
if (once)
break;
- } while (CALLREGEXEC(rx, s, strend, orig, s == m, Nullsv, NULL, r_flags));
+ } while (CALLREGEXEC(rx, s, strend, orig, s == m, TARG, NULL, r_flags));
sv_catpvn(dstr, s, strend - s);
(void)SvOOK_off(TARG);
break;
case SVt_PVGV:
if (!(cv = GvCVu((GV*)sv)))
- cv = sv_2cv(sv, &stash, &gv, TRUE);
+ cv = sv_2cv(sv, &stash, &gv, FALSE);
+ if (!cv) {
+ ENTER;
+ SAVETMPS;
+ goto try_autoload;
+ }
break;
}
SAVETMPS;
retry:
- if (!cv)
- DIE("Not a CODE reference");
-
if (!CvROOT(cv) && !CvXSUB(cv)) {
GV* autogv;
SV* sub_name;
/* anonymous or undef'd function leaves us no recourse */
if (CvANON(cv) || !(gv = CvGV(cv)))
DIE("Undefined subroutine called");
+
/* autoloaded stub? */
if (cv != GvCV(gv)) {
cv = GvCV(gv);
- goto retry;
}
/* should call AUTOLOAD now? */
- if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
+ else {
+try_autoload:
+ if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv),
FALSE)))
- {
- cv = GvCV(autogv);
- goto retry;
+ {
+ cv = GvCV(autogv);
+ }
+ /* sorry */
+ else {
+ sub_name = sv_newmortal();
+ gv_efullname3(sub_name, gv, Nullch);
+ DIE("Undefined subroutine &%s called", SvPVX(sub_name));
+ }
}
- /* sorry */
- sub_name = sv_newmortal();
- gv_efullname3(sub_name, gv, Nullch);
- DIE("Undefined subroutine &%s called", SvPVX(sub_name));
+ if (!cv)
+ DIE("Not a CODE reference");
+ goto retry;
}
gimme = GIMME_V;
- if ((PL_op->op_private & OPpENTERSUB_DB) && GvCV(PL_DBsub) && !CvNODEBUG(cv))
+ if ((PL_op->op_private & OPpENTERSUB_DB) && GvCV(PL_DBsub) && !CvNODEBUG(cv)) {
cv = get_db_sub(&sv, cv);
- if (!cv)
- DIE("No DBsub routine");
+ if (!cv)
+ DIE("No DBsub routine");
+ }
#ifdef USE_THREADS
/*
if (SP > PL_stack_base + TOPMARK)
sv = *(PL_stack_base + TOPMARK + 1);
else {
- MUTEX_UNLOCK(CvMUTEXP(cv));
- croak("no argument for locked method call");
+ AV *av = (AV*)PL_curpad[0];
+ if (hasargs || !av || AvFILLp(av) < 0
+ || !(sv = AvARRAY(av)[0]))
+ {
+ MUTEX_UNLOCK(CvMUTEXP(cv));
+ croak("no argument for locked method call");
+ }
}
if (SvROK(sv))
sv = SvRV(sv);
#endif /* USE_THREADS */
if (CvXSUB(cv)) {
+#ifdef PERL_XSUB_OLDSTYLE
if (CvOLDSTYLE(cv)) {
I32 (*fp3)_((int,int,int));
dMARK;
items);
PL_stack_sp = PL_stack_base + items;
}
- else {
+ else
+#endif /* PERL_XSUB_OLDSTYLE */
+ {
I32 markix = TOPMARK;
PUTBACK;
PUTBACK ;
}
}
- if (PL_curcopdb) { /* We assume that the first
- XSUB in &DB::sub is the
- called one. */
+ /* We assume first XSUB in &DB::sub is the called one. */
+ if (PL_curcopdb) {
SAVESPTR(PL_curcop);
PL_curcop = PL_curcopdb;
PL_curcopdb = NULL;