dSP;
register PMOP *pm = (PMOP*)cLOGOP->op_other;
SV *tmpstr;
- MAGIC *mg = Null(MAGIC*);
+ MAGIC *mg = NULL;
/* prevent recompiling under /o and ithreads. */
#if defined(USE_ITHREADS)
{
if (PM_GETRE(pm)) {
ReREFCNT_dec(PM_GETRE(pm));
- PM_SETRE(pm, Null(REGEXP*)); /* crucial if regcomp aborts */
+ PM_SETRE(pm, NULL); /* crucial if regcomp aborts */
}
if (PL_op->op_flags & OPf_SPECIAL)
PL_reginterp_cnt = I32_MAX; /* Mark as safe. */
if (SvTYPE(sv) < SVt_PVMG)
SvUPGRADE(sv, SVt_PVMG);
if (!(mg = mg_find(sv, PERL_MAGIC_regex_global))) {
- sv_magic(sv, NULL, PERL_MAGIC_regex_global, NULL, 0);
- mg = mg_find(sv, PERL_MAGIC_regex_global);
+#ifdef PERL_OLD_COPY_ON_WRITE
+ if (SvIsCOW(lsv))
+ sv_force_normal_flags(sv, 0);
+#endif
+ mg = sv_magicext(sv, NULL, PERL_MAGIC_regex_global, &PL_vtbl_mglob,
+ NULL, 0);
}
i = m - orig;
if (DO_UTF8(sv))
{
UV *p = (UV*)*rsp;
U32 i;
+ PERL_UNUSED_CONTEXT;
if (!p || p[1] < rx->nparens) {
#ifdef PERL_OLD_COPY_ON_WRITE
{
UV *p = (UV*)*rsp;
U32 i;
+ PERL_UNUSED_CONTEXT;
RX_MATCH_COPY_FREE(rx);
RX_MATCH_COPIED_set(rx, *p);
Perl_rxres_free(pTHX_ void **rsp)
{
UV * const p = (UV*)*rsp;
+ PERL_UNUSED_CONTEXT;
if (p) {
#ifdef PERL_POISON
void *tmp = INT2PTR(char*,*p);
Safefree(tmp);
if (*p)
- Poison(*p, 1, sizeof(*p));
+ PoisonFree(*p, 1, sizeof(*p));
#else
Safefree(INT2PTR(char*,*p));
#endif
}
#endif
Safefree(p);
- *rsp = Null(void*);
+ *rsp = NULL;
}
}
flip = SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv));
}
else {
- GV * const gv = gv_fetchpvs(".", GV_ADD, SVt_PV);
+ GV * const gv = gv_fetchpvs(".", GV_ADD|GV_NOTQUAL, SVt_PV);
if (gv && GvSV(gv))
flip = SvIV(sv) == SvIV(GvSV(gv));
}
flop = SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv));
}
else {
- GV * const gv = gv_fetchpvs(".", GV_ADD, SVt_PV);
+ GV * const gv = gv_fetchpvs(".", GV_ADD|GV_NOTQUAL, SVt_PV);
if (gv && GvSV(gv)) flop = SvIV(sv) == SvIV(GvSV(gv));
}
}
RETURN;
}
- EXTEND(SP, 10);
+ EXTEND(SP, 11);
if (!stashname)
PUSHs(&PL_sv_undef);
/* XXX only hints propagated via op_private are currently
* visible (others are not easily accessible, since they
* use the global PL_hints) */
- PUSHs(sv_2mortal(newSViv((I32)cx->blk_oldcop->op_private &
- HINT_PRIVATE_MASK)));
+ PUSHs(sv_2mortal(newSViv(CopHINTS_get(cx->blk_oldcop))));
{
SV * mask ;
- SV * const old_warnings = cx->blk_oldcop->cop_warnings ;
+ STRLEN * const old_warnings = cx->blk_oldcop->cop_warnings ;
if (old_warnings == pWARN_NONE ||
(old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0))
}
}
else
- mask = newSVsv(old_warnings);
+ mask = newSVpvn((char *) (old_warnings + 1), old_warnings[0]);
PUSHs(sv_2mortal(mask));
}
+
+ PUSHs(cx->blk_oldcop->cop_hints ?
+ sv_2mortal(newRV_noinc(
+ (SV*)Perl_refcounted_he_chain_2hv(aTHX_
+ cx->blk_oldcop->cop_hints)))
+ : &PL_sv_undef);
RETURN;
}
hasargs = 0;
SPAGAIN;
- if (CvXSUB(cv)) {
+ if (CvISXSUB(cv)) {
CvDEPTH(cv)++;
PUSHMARK(SP);
(void)(*CvXSUB(cv))(aTHX_ cv);
TAINT_NOT;
if (gimme == G_VOID)
- ; /* do nothing */
+ /*EMPTY*/; /* do nothing */
else if (gimme == G_SCALAR) {
if (mark < SP)
*++newsp = sv_mortalcopy(*SP);
}
/* First do some returnish stuff. */
- (void)SvREFCNT_inc(cv); /* avoid premature free during unwind */
+ SvREFCNT_inc_simple_void(cv); /* avoid premature free during unwind */
FREETMPS;
cxix = dopoptosub(cxstack_ix);
if (cxix < 0)
PAD_SVl(0) = (SV*)(cx->blk_sub.argarray = av);
}
}
- else if (CvXSUB(cv)) { /* put GvAV(defgv) back onto stack */
+ else if (CvISXSUB(cv)) { /* put GvAV(defgv) back onto stack */
AV* const av = GvAV(PL_defgv);
items = AvFILLp(av) + 1;
EXTEND(SP, items+1); /* @_ could have been extended. */
/* Now do some callish stuff. */
SAVETMPS;
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
- if (CvXSUB(cv)) {
- OP* retop = cx->blk_sub.retop;
+ if (CvISXSUB(cv)) {
+ OP* const retop = cx->blk_sub.retop;
+ SV **newsp;
+ I32 gimme;
if (reified) {
I32 index;
for (index=0; index<items; index++)
sv_2mortal(SP[-index]);
}
-#ifdef PERL_XSUB_OLDSTYLE
- if (CvOLDSTYLE(cv)) {
- I32 (*fp3)(int,int,int);
- while (SP > mark) {
- SP[1] = SP[0];
- SP--;
- }
- fp3 = (I32(*)(int,int,int))CvXSUB(cv);
- items = (*fp3)(CvXSUBANY(cv).any_i32,
- mark - PL_stack_base + 1,
- items);
- SP = PL_stack_base + items;
- }
- else
-#endif /* PERL_XSUB_OLDSTYLE */
- {
- SV **newsp;
- I32 gimme;
- /* XS subs don't have a CxSUB, so pop it */
- POPBLOCK(cx, PL_curpm);
- /* Push a mark for the start of arglist */
- PUSHMARK(mark);
- PUTBACK;
- (void)(*CvXSUB(cv))(aTHX_ cv);
- /* Put these at the bottom since the vars are set but not used */
- PERL_UNUSED_VAR(newsp);
- PERL_UNUSED_VAR(gimme);
- }
+ /* XS subs don't have a CxSUB, so pop it */
+ POPBLOCK(cx, PL_curpm);
+ /* Push a mark for the start of arglist */
+ PUSHMARK(mark);
+ PUTBACK;
+ (void)(*CvXSUB(cv))(aTHX_ cv);
LEAVE;
return retop;
}
else {
- AV* padlist = CvPADLIST(cv);
+ AV* const padlist = CvPADLIST(cv);
if (CxTYPE(cx) == CXt_EVAL) {
PL_in_eval = cx->blk_eval.old_in_eval;
PL_eval_root = cx->blk_eval.old_eval_root;
cx->blk_sub.hasargs = 0;
}
cx->blk_sub.cv = cv;
- cx->blk_sub.olddepth = (U16)CvDEPTH(cv);
+ cx->blk_sub.olddepth = CvDEPTH(cv);
CvDEPTH(cv)++;
if (CvDEPTH(cv) < 2)
- (void)SvREFCNT_inc(cv);
+ SvREFCNT_inc_void_NN(cv);
else {
if (CvDEPTH(cv) == 100 && ckWARN(WARN_RECURSION))
sub_crush_depth(cv);
PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
if (cx->blk_sub.hasargs)
{
- AV* av = (AV*)PAD_SVl(0);
- SV** ary;
+ AV* const av = (AV*)PAD_SVl(0);
cx->blk_sub.savearray = GvAV(PL_defgv);
- GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+ GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
CX_CURPAD_SAVE(cx->blk_sub);
cx->blk_sub.argarray = av;
if (items >= AvMAX(av) + 1) {
- ary = AvALLOC(av);
+ SV **ary = AvALLOC(av);
if (AvARRAY(av) != ary) {
AvMAX(av) += AvARRAY(av) - AvALLOC(av);
SvPV_set(av, (char*)ary);
* it's for informational purposes only.
*/
SV * const sv = GvSV(PL_DBsub);
- CV *gotocv;
-
save_item(sv);
if (PERLDB_SUB_NN) {
const int type = SvTYPE(sv);
} else {
gv_efullname3(sv, CvGV(cv), NULL);
}
- if ( PERLDB_GOTO
- && (gotocv = get_cv("DB::goto", FALSE)) ) {
- PUSHMARK( PL_stack_sp );
- call_sv((SV*)gotocv, G_SCALAR | G_NODEBUG);
- PL_stack_sp--;
+ if (PERLDB_GOTO) {
+ CV * const gotocv = get_cv("DB::goto", FALSE);
+ if (gotocv) {
+ PUSHMARK( PL_stack_sp );
+ call_sv((SV*)gotocv, G_SCALAR | G_NODEBUG);
+ PL_stack_sp--;
+ }
}
}
RETURNOP(CvSTART(cv));
/* find label */
- PL_lastgotoprobe = 0;
+ PL_lastgotoprobe = NULL;
*enterops = 0;
for (ix = cxstack_ix; ix >= 0; ix--) {
cx = &cxstack[ix];
#endif
}
PL_exit_flags |= PERL_EXIT_EXPECTED;
+#ifdef PERL_MAD
+ /* KLUDGE: disable exit 0 in BEGIN blocks when we're just compiling */
+ if (anum || !(PL_minus_c && PL_madskills))
+ my_exit(anum);
+#else
my_exit(anum);
+#endif
PUSHs(&PL_sv_undef);
RETURN;
}
}
JMPENV_POP;
PL_op = oldop;
- return Nullop;
+ return NULL;
}
OP *
char *tmpbuf = tbuf;
char *safestr;
int runtime;
- CV* runcv = Nullcv; /* initialise to avoid compiler warnings */
+ CV* runcv = NULL; /* initialise to avoid compiler warnings */
STRLEN len;
ENTER;
PL_op->op_type = OP_ENTEREVAL;
PL_op->op_flags = 0; /* Avoid uninit warning. */
PUSHBLOCK(cx, CXt_EVAL|(IN_PERL_COMPILETIME ? 0 : CXp_REAL), SP);
- PUSHEVAL(cx, 0, Nullgv);
+ PUSHEVAL(cx, 0, NULL);
if (runtime)
rop = doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
(*startop)->op_ppaddr = PL_ppaddr[OP_NULL];
lex_end();
/* XXX DAPM do this properly one year */
- *padp = (AV*)SvREFCNT_inc(PL_comppad);
+ *padp = (AV*)SvREFCNT_inc_simple(PL_comppad);
LEAVE;
if (IN_PERL_COMPILETIME)
- PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
+ CopHINTS_set(&PL_compiling, PL_hints);
#ifdef OP_IN_REGISTER
op = PL_opsave;
#endif
cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
CvOUTSIDE_SEQ(PL_compcv) = seq;
- CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(outside);
+ CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc_simple(outside);
/* set up a scratch pad */
CvPADLIST(PL_compcv) = pad_new(padnew_SAVE);
- SAVEMORTALIZESV(PL_compcv); /* must remain until end of current statement */
+ if (!PL_madskills)
+ SAVEMORTALIZESV(PL_compcv); /* must remain until end of current statement */
/* make sure we compile in the right package */
SAVEFREESV(PL_beginav);
SAVEI32(PL_error_count);
+#ifdef PERL_MAD
+ SAVEI32(PL_madskills);
+ PL_madskills = 0;
+#endif
+
/* try to compile it */
- PL_eval_root = Nullop;
+ PL_eval_root = NULL;
PL_error_count = 0;
PL_curcop = &PL_compiling;
- PL_curcop->cop_arybase = 0;
- if (saveop && saveop->op_type != OP_REQUIRE && saveop->op_flags & OPf_SPECIAL)
+ CopARYBASE_set(PL_curcop, 0);
+ if (saveop && (saveop->op_type != OP_REQUIRE) && (saveop->op_flags & OPf_SPECIAL))
PL_in_eval |= EVAL_KEEPERR;
else
sv_setpvn(ERRSV,"",0);
PL_op = saveop;
if (PL_eval_root) {
op_free(PL_eval_root);
- PL_eval_root = Nullop;
+ PL_eval_root = NULL;
}
SP = PL_stack_base + POPMARK; /* pop original mark */
if (!startop) {
{
Stat_t st;
const int st_rc = PerlLIO_stat(name, &st);
- if (st_rc < 0) {
- return Nullfp;
+ if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
+ return NULL;
}
- if(S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
- Perl_die(aTHX_ "%s %s not allowed in require",
- S_ISDIR(st.st_mode) ? "Directory" : "Block device", name);
- }
return PerlIO_open(name, mode);
}
fp = check_type_and_open(name, mode);
}
else {
- Stat_t pmstat;
- if (PerlLIO_stat(name, &pmstat) < 0 ||
- pmstat.st_mtime < pmcstat.st_mtime)
- {
- fp = check_type_and_open(pmc, mode);
- }
- else {
- fp = check_type_and_open(name, mode);
- }
+ fp = check_type_and_open(pmc, mode);
}
SvREFCNT_dec(pmcsv);
}
const I32 gimme = GIMME_V;
int filter_has_file = 0;
PerlIO *tryrsfp = NULL;
- GV *filter_child_proc = NULL;
SV *filter_state = NULL;
SV *filter_sub = NULL;
SV *hook_sv = NULL;
if (io) {
tryrsfp = IoIFP(io);
- if (IoTYPE(io) == IoTYPE_PIPE) {
- /* reading from a child process doesn't
- nest -- when returning from reading
- the inner module, the outer one is
- unreadable (closed?) I've tried to
- save the gv to manage the lifespan of
- the pipe, but this didn't help. XXX */
- filter_child_proc = (GV *)arg;
- (void)SvREFCNT_inc(filter_child_proc);
- }
- else {
- if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
- PerlIO_close(IoOFP(io));
- }
- IoIFP(io) = Nullfp;
- IoOFP(io) = Nullfp;
+ if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
+ PerlIO_close(IoOFP(io));
}
+ IoIFP(io) = NULL;
+ IoOFP(io) = NULL;
}
if (i < count) {
if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVCV) {
filter_sub = arg;
- (void)SvREFCNT_inc(filter_sub);
+ SvREFCNT_inc_void_NN(filter_sub);
if (i < count) {
filter_state = SP[i];
- (void)SvREFCNT_inc(filter_state);
+ SvREFCNT_inc_simple_void(filter_state);
}
if (!tryrsfp) {
- tryrsfp = PerlIO_open("/dev/null", PERL_SCRIPT_MODE);
+ tryrsfp = PerlIO_open(BIT_BUCKET,
+ PERL_SCRIPT_MODE);
}
}
SP--;
}
filter_has_file = 0;
- if (filter_child_proc) {
- SvREFCNT_dec(filter_child_proc);
- filter_child_proc = NULL;
- }
if (filter_state) {
SvREFCNT_dec(filter_state);
filter_state = NULL;
} else {
SV** const svp = hv_fetch(GvHVn(PL_incgv), name, len, 0);
if (!svp)
- (void)hv_store(GvHVn(PL_incgv), name, len, SvREFCNT_inc(hook_sv), 0 );
+ (void)hv_store(GvHVn(PL_incgv), name, len, SvREFCNT_inc_simple(hook_sv), 0 );
}
ENTER;
PL_rsfp = tryrsfp;
SAVEHINTS();
PL_hints = 0;
- SAVESPTR(PL_compiling.cop_warnings);
+ SAVECOMPILEWARNINGS();
if (PL_dowarn & G_WARN_ALL_ON)
PL_compiling.cop_warnings = pWARN_ALL ;
else if (PL_dowarn & G_WARN_ALL_OFF)
PL_compiling.cop_warnings = pWARN_NONE ;
- else if (PL_taint_warn)
- PL_compiling.cop_warnings = newSVpvn(WARN_TAINTstring, WARNsize);
+ else if (PL_taint_warn) {
+ PL_compiling.cop_warnings
+ = Perl_new_warnings_bitfield(aTHX_ NULL, WARN_TAINTstring, WARNsize);
+ }
else
PL_compiling.cop_warnings = pWARN_STD ;
SAVESPTR(PL_compiling.cop_io);
PL_compiling.cop_io = NULL;
- if (filter_sub || filter_child_proc) {
+ if (filter_sub) {
SV * const datasv = filter_add(S_run_user_filter, NULL);
IoLINES(datasv) = filter_has_file;
- IoFMT_GV(datasv) = (GV *)filter_child_proc;
IoTOP_GV(datasv) = (GV *)filter_state;
IoBOTTOM_GV(datasv) = (GV *)filter_sub;
}
/* switch to eval mode */
PUSHBLOCK(cx, CXt_EVAL, SP);
- PUSHEVAL(cx, name, Nullgv);
+ PUSHEVAL(cx, name, NULL);
cx->blk_eval.retop = PL_op->op_next;
SAVECOPLINE(&PL_compiling);
encoding = PL_encoding;
PL_encoding = NULL;
- op = DOCATCH(doeval(gimme, NULL, Nullcv, PL_curcop->cop_seq));
+ op = DOCATCH(doeval(gimme, NULL, NULL, PL_curcop->cop_seq));
/* Restore encoding. */
PL_encoding = encoding;
/* switch to eval mode */
if (PERLDB_NAMEEVAL && CopLINE(PL_curcop)) {
- SV * const sv = sv_newmortal();
- Perl_sv_setpvf(aTHX_ sv, "_<(eval %lu)[%s:%"IVdf"]",
+ SV * const temp_sv = sv_newmortal();
+ Perl_sv_setpvf(aTHX_ temp_sv, "_<(eval %lu)[%s:%"IVdf"]",
(unsigned long)++PL_evalseq,
CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
- tmpbuf = SvPVX(sv);
- len = SvCUR(sv);
+ tmpbuf = SvPVX(temp_sv);
+ len = SvCUR(temp_sv);
}
else
len = my_sprintf(tmpbuf, "_<(eval %lu)", (unsigned long)++PL_evalseq);
PL_hints = PL_op->op_targ;
if (saved_hh)
GvHV(PL_hintgv) = saved_hh;
- SAVESPTR(PL_compiling.cop_warnings);
- if (specialWARN(PL_curcop->cop_warnings))
- PL_compiling.cop_warnings = PL_curcop->cop_warnings;
- else {
- PL_compiling.cop_warnings = newSVsv(PL_curcop->cop_warnings);
- SAVEFREESV(PL_compiling.cop_warnings);
- }
+ SAVECOMPILEWARNINGS();
+ PL_compiling.cop_warnings = DUP_WARNINGS(PL_curcop->cop_warnings);
SAVESPTR(PL_compiling.cop_io);
if (specialCopIO(PL_curcop->cop_io))
PL_compiling.cop_io = PL_curcop->cop_io;
PL_compiling.cop_io = newSVsv(PL_curcop->cop_io);
SAVEFREESV(PL_compiling.cop_io);
}
+ if (PL_compiling.cop_hints) {
+ Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints);
+ }
+ PL_compiling.cop_hints = PL_curcop->cop_hints;
+ if (PL_compiling.cop_hints) {
+ HINTS_REFCNT_LOCK;
+ PL_compiling.cop_hints->refcounted_he_refcnt++;
+ HINTS_REFCNT_UNLOCK;
+ }
/* special case: an eval '' executed within the DB package gets lexically
* placed in the first non-DB CV rather than the current CV - this
* allows the debugger to execute code, find lexicals etc, in the
runcv = find_runcv(&seq);
PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
- PUSHEVAL(cx, 0, Nullgv);
+ PUSHEVAL(cx, 0, NULL);
cx->blk_eval.retop = PL_op->op_next;
/* prepare to compile string */
RETURNOP(retop);
}
-PP(pp_entertry)
+/* Common code for Perl_call_sv and Perl_fold_constants, put here to keep it
+ close to the related Perl_create_eval_scope. */
+void
+Perl_delete_eval_scope(pTHX)
{
- dVAR; dSP;
+ SV **newsp;
+ PMOP *newpm;
+ I32 gimme;
register PERL_CONTEXT *cx;
- const I32 gimme = GIMME_V;
+ I32 optype;
+
+ POPBLOCK(cx,newpm);
+ POPEVAL(cx);
+ PL_curpm = newpm;
+ LEAVE;
+ PERL_UNUSED_VAR(newsp);
+ PERL_UNUSED_VAR(gimme);
+ PERL_UNUSED_VAR(optype);
+}
+/* Common-ish code salvaged from Perl_call_sv and pp_entertry, because it was
+ also needed by Perl_fold_constants. */
+PERL_CONTEXT *
+Perl_create_eval_scope(pTHX_ U32 flags)
+{
+ PERL_CONTEXT *cx;
+ const I32 gimme = GIMME_V;
+
ENTER;
SAVETMPS;
- PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), SP);
+ PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
PUSHEVAL(cx, 0, 0);
- cx->blk_eval.retop = cLOGOP->op_other->op_next;
+ PL_eval_root = PL_op; /* Only needed so that goto works right. */
PL_in_eval = EVAL_INEVAL;
- sv_setpvn(ERRSV,"",0);
- PUTBACK;
+ if (flags & G_KEEPERR)
+ PL_in_eval |= EVAL_KEEPERR;
+ else
+ sv_setpvn(ERRSV,"",0);
+ if (flags & G_FAKINGEVAL) {
+ PL_eval_root = PL_op; /* Only needed so that goto works right. */
+ }
+ return cx;
+}
+
+PP(pp_entertry)
+{
+ dVAR;
+ PERL_CONTEXT *cx = create_eval_scope(0);
+ cx->blk_eval.retop = cLOGOP->op_other->op_next;
return DOCATCH(PL_op->op_next);
}
I32 gimme;
SV **newsp;
PMOP *newpm;
- SV **mark;
+ PERL_UNUSED_CONTEXT;
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_GIVEN);
- mark = newsp;
SP = newsp;
PUTBACK;
/* Do a smart match */
PP(pp_smartmatch)
{
- return do_smartmatch(Nullhv, Nullhv);
+ return do_smartmatch(NULL, NULL);
}
/* This version of do_smartmatch() implements the following
I32 i;
const I32 other_len = av_len(other_av);
- if (Nullhv == seen_this) {
+ if (NULL == seen_this) {
seen_this = newHV();
(void) sv_2mortal((SV *) seen_this);
}
- if (Nullhv == seen_other) {
+ if (NULL == seen_other) {
seen_this = newHV();
(void) sv_2mortal((SV *) seen_other);
}
PUSHs(other);
PUSHs(*svp);
PUTBACK;
- if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+ if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
(void) pp_i_eq();
else
(void) pp_eq();
/* Otherwise, numeric comparison */
PUSHs(d); PUSHs(e);
PUTBACK;
- if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+ if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
(void) pp_i_eq();
else
(void) pp_eq();
dVAR;
SV * const datasv = FILTER_DATA(idx);
const int filter_has_file = IoLINES(datasv);
- GV * const filter_child_proc = (GV *)IoFMT_GV(datasv);
SV * const filter_state = (SV *)IoTOP_GV(datasv);
SV * const filter_sub = (SV *)IoBOTTOM_GV(datasv);
int len = 0;
-
+ /* Filter API says that the filter appends to the contents of the buffer.
+ Usually the buffer is "", so the details don't matter. But if it's not,
+ then clearly what it contains is already filtered by this filter, so we
+ don't want to pass it in a second time.
+ I'm going to use a mortal in case the upstream filter croaks. */
+ SV *const upstream
+ = ((SvOK(buf_sv) && sv_len(buf_sv)) || SvGMAGICAL(buf_sv))
+ ? sv_newmortal() : buf_sv;
+
+ SvUPGRADE(upstream, SVt_PV);
/* I was having segfault trouble under Linux 2.2.5 after a
parse error occured. (Had to hack around it with a test
for PL_error_count == 0.) Solaris doesn't segfault --
not sure where the trouble is yet. XXX */
+ if (maxlen && IoFMT_GV(datasv)) {
+ SV *const cache = (SV *)IoFMT_GV(datasv);
+ if (SvOK(cache)) {
+ STRLEN cache_len;
+ const char *cache_p = SvPV(cache, cache_len);
+ /* Running in block mode and we have some cached data already. */
+ if (cache_len >= maxlen) {
+ /* In fact, so much data we don't even need to call
+ filter_read. */
+ sv_catpvn(buf_sv, cache_p, maxlen);
+ sv_chop(cache, cache_p + maxlen);
+ /* Definately not EOF */
+ return 1;
+ }
+ sv_catsv(buf_sv, cache);
+ maxlen -= cache_len;
+ SvOK_off(cache);
+ }
+ }
+
if (filter_has_file) {
- len = FILTER_READ(idx+1, buf_sv, maxlen);
+ len = FILTER_READ(idx+1, upstream, maxlen);
}
if (filter_sub && len >= 0) {
SAVETMPS;
EXTEND(SP, 2);
- DEFSV = buf_sv;
+ DEFSV = upstream;
PUSHMARK(SP);
PUSHs(sv_2mortal(newSViv(maxlen)));
if (filter_state) {
LEAVE;
}
+ if (maxlen) {
+ /* Running in block mode. */
+ STRLEN got_len;
+ const char *got_p = SvPV(upstream, got_len);
+
+ if (got_len > maxlen) {
+ /* Oh. Too long. Stuff some in our cache. */
+ SV *cache = (SV *)IoFMT_GV(datasv);
+
+ if (!cache) {
+ IoFMT_GV(datasv) = (GV*) (cache = newSV(got_len - maxlen));
+ } else if (SvOK(cache)) {
+ /* Cache should be empty. */
+ assert(!SvCUR(cache));
+ }
+
+ sv_setpvn(cache, got_p + maxlen, got_len - maxlen);
+ /* If you ask for block mode, you may well split UTF-8 characters.
+ "If it breaks, you get to keep both parts"
+ (Your code is broken if you don't put them back together again
+ before something notices.) */
+ if (SvUTF8(upstream)) {
+ SvUTF8_on(cache);
+ }
+ SvCUR_set(upstream, maxlen);
+ }
+ }
+
+ if (upstream != buf_sv) {
+ sv_catsv(buf_sv, upstream);
+ }
+
if (len <= 0) {
IoLINES(datasv) = 0;
- if (filter_child_proc) {
- SvREFCNT_dec(filter_child_proc);
- IoFMT_GV(datasv) = Nullgv;
- }
+ SvREFCNT_dec(IoFMT_GV(datasv));
if (filter_state) {
SvREFCNT_dec(filter_state);
- IoTOP_GV(datasv) = Nullgv;
+ IoTOP_GV(datasv) = NULL;
}
if (filter_sub) {
SvREFCNT_dec(filter_sub);
- IoBOTTOM_GV(datasv) = Nullgv;
+ IoBOTTOM_GV(datasv) = NULL;
}
filter_del(S_run_user_filter);
}
-
return len;
}
/* perhaps someone can come up with a better name for
this? it is not really "absolute", per se ... */
static bool
-S_path_is_absolute(pTHX_ const char *name)
+S_path_is_absolute(const char *name)
{
if (PERL_FILE_IS_ABSOLUTE(name)
#ifdef MACOS_TRADITIONAL