X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/9b2db8e94a2dd349aad72259cdcdd425bf501466..db8ab41e9b86ed452fc0ed716a2fc9d034b1ed8a:/pp_ctl.c diff --git a/pp_ctl.c b/pp_ctl.c index 9204879..7d777f5 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1,6 +1,6 @@ /* pp_ctl.c * - * Copyright (c) 1991-2000, Larry Wall + * Copyright (c) 1991-2001, 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. @@ -26,28 +26,11 @@ #define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o)) -static I32 sortcv(pTHXo_ SV *a, SV *b); -static I32 sortcv_stacked(pTHXo_ SV *a, SV *b); -static I32 sortcv_xsub(pTHXo_ SV *a, SV *b); -static I32 sv_ncmp(pTHXo_ SV *a, SV *b); -static I32 sv_i_ncmp(pTHXo_ SV *a, SV *b); -static I32 amagic_ncmp(pTHXo_ SV *a, SV *b); -static I32 amagic_i_ncmp(pTHXo_ SV *a, SV *b); -static I32 amagic_cmp(pTHXo_ SV *a, SV *b); -static I32 amagic_cmp_locale(pTHXo_ SV *a, SV *b); -static I32 run_user_filter(pTHXo_ int idx, SV *buf_sv, int maxlen); - -#ifdef PERL_OBJECT -static I32 sv_cmp_static(pTHXo_ SV *a, SV *b); -static I32 sv_cmp_locale_static(pTHXo_ SV *a, SV *b); -#else -#define sv_cmp_static Perl_sv_cmp -#define sv_cmp_locale_static Perl_sv_cmp_locale -#endif +static I32 run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen); PP(pp_wantarray) { - djSP; + dSP; I32 cxix; EXTEND(SP, 1); @@ -80,44 +63,58 @@ PP(pp_regcreset) PP(pp_regcomp) { - djSP; + dSP; register PMOP *pm = (PMOP*)cLOGOP->op_other; register char *t; SV *tmpstr; STRLEN len; MAGIC *mg = Null(MAGIC*); - + tmpstr = POPs; + + /* prevent recompiling under /o and ithreads. */ +#if defined(USE_ITHREADS) || defined(USE_5005THREADS) + if (pm->op_pmflags & PMf_KEEP && PM_GETRE(pm)) + RETURN; +#endif + if (SvROK(tmpstr)) { SV *sv = SvRV(tmpstr); if(SvMAGICAL(sv)) - mg = mg_find(sv, 'r'); + mg = mg_find(sv, PERL_MAGIC_qr); } if (mg) { regexp *re = (regexp *)mg->mg_obj; - ReREFCNT_dec(pm->op_pmregexp); - pm->op_pmregexp = ReREFCNT_inc(re); + ReREFCNT_dec(PM_GETRE(pm)); + PM_SETRE(pm, ReREFCNT_inc(re)); } else { t = SvPV(tmpstr, len); /* Check against the last compiled regexp. */ - if (!pm->op_pmregexp || !pm->op_pmregexp->precomp || - pm->op_pmregexp->prelen != len || - memNE(pm->op_pmregexp->precomp, t, len)) + if (!PM_GETRE(pm) || !PM_GETRE(pm)->precomp || + PM_GETRE(pm)->prelen != len || + memNE(PM_GETRE(pm)->precomp, t, len)) { - if (pm->op_pmregexp) { - ReREFCNT_dec(pm->op_pmregexp); - pm->op_pmregexp = Null(REGEXP*); /* crucial if regcomp aborts */ + if (PM_GETRE(pm)) { + ReREFCNT_dec(PM_GETRE(pm)); + PM_SETRE(pm, Null(REGEXP*)); /* crucial if regcomp aborts */ } if (PL_op->op_flags & OPf_SPECIAL) PL_reginterp_cnt = I32_MAX; /* Mark as safe. */ pm->op_pmflags = pm->op_pmpermflags; /* reset case sensitivity */ if (DO_UTF8(tmpstr)) - pm->op_pmdynflags |= PMdf_UTF8; - pm->op_pmregexp = CALLREGCOMP(aTHX_ t, t + len, pm); - PL_reginterp_cnt = 0; /* XXXX Be extra paranoid - needed + pm->op_pmdynflags |= PMdf_DYN_UTF8; + else { + pm->op_pmdynflags &= ~PMdf_DYN_UTF8; + if (pm->op_pmdynflags & PMdf_UTF8) + t = (char*)bytes_to_utf8((U8*)t, &len); + } + PM_SETRE(pm, CALLREGCOMP(aTHX_ t, t + len, pm)); + if (!DO_UTF8(tmpstr) && (pm->op_pmdynflags & PMdf_UTF8)) + Safefree(t); + PL_reginterp_cnt = 0; /* XXXX Be extra paranoid - needed inside tie/overload accessors. */ } } @@ -131,15 +128,17 @@ PP(pp_regcomp) } #endif - if (!pm->op_pmregexp->prelen && PL_curpm) + if (!PM_GETRE(pm)->prelen && PL_curpm) pm = PL_curpm; - else if (strEQ("\\s+", pm->op_pmregexp->precomp)) + else if (strEQ("\\s+", PM_GETRE(pm)->precomp)) pm->op_pmflags |= PMf_WHITE; + else + pm->op_pmflags &= ~PMf_WHITE; /* XXX runtime compiled output needs to move to the pad */ if (pm->op_pmflags & PMf_KEEP) { pm->op_private &= ~OPpRUNTIME; /* no point compiling again */ -#if !defined(USE_ITHREADS) && !defined(USE_THREADS) +#if !defined(USE_ITHREADS) && !defined(USE_5005THREADS) /* XXX can't change the optree at runtime either */ cLOGOP->op_first->op_next = PL_op->op_next; #endif @@ -149,7 +148,7 @@ PP(pp_regcomp) PP(pp_substcont) { - djSP; + dSP; register PMOP *pm = (PMOP*) cLOGOP->op_other; register PERL_CONTEXT *cx = &cxstack[cxstack_ix]; register SV *dstr = cx->sb_dstr; @@ -161,6 +160,7 @@ PP(pp_substcont) rxres_restore(&cx->sb_rxres, rx); if (cx->sb_iters++) { + I32 saviters = cx->sb_iters; if (cx->sb_iters > cx->sb_maxiters) DIE(aTHX_ "Substitution loop"); @@ -176,8 +176,8 @@ PP(pp_substcont) : (REXEC_COPY_STR|REXEC_IGNOREPOS|REXEC_NOT_FIRST)))) { SV *targ = cx->sb_targ; - sv_catpvn(dstr, s, cx->sb_strend - s); + sv_catpvn(dstr, s, cx->sb_strend - s); cx->sb_rxtainted |= RX_MATCH_TAINTED(rx); (void)SvOOK_off(targ); @@ -185,13 +185,15 @@ PP(pp_substcont) SvPVX(targ) = SvPVX(dstr); SvCUR_set(targ, SvCUR(dstr)); SvLEN_set(targ, SvLEN(dstr)); + if (DO_UTF8(dstr)) + SvUTF8_on(targ); SvPVX(dstr) = 0; sv_free(dstr); TAINT_IF(cx->sb_rxtainted & 1); PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1))); - (void)SvPOK_only(targ); + (void)SvPOK_only_UTF8(targ); TAINT_IF(cx->sb_rxtainted); SvSETMAGIC(targ); SvTAINT(targ); @@ -200,6 +202,7 @@ PP(pp_substcont) POPSUBST(cx); RETURNOP(pm->op_next); } + cx->sb_iters = saviters; } if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) { m = s; @@ -209,8 +212,24 @@ PP(pp_substcont) cx->sb_strend = s + (cx->sb_strend - m); } cx->sb_m = m = rx->startp[0] + orig; - sv_catpvn(dstr, s, m-s); + if (m > s) + sv_catpvn(dstr, s, m-s); cx->sb_s = rx->endp[0] + orig; + { /* Update the pos() information. */ + SV *sv = cx->sb_targ; + MAGIC *mg; + I32 i; + if (SvTYPE(sv) < SVt_PVMG) + (void)SvUPGRADE(sv, SVt_PVMG); + if (!(mg = mg_find(sv, PERL_MAGIC_regex_global))) { + sv_magic(sv, Nullsv, PERL_MAGIC_regex_global, Nullch, 0); + mg = mg_find(sv, PERL_MAGIC_regex_global); + } + i = m - orig; + if (DO_UTF8(sv)) + sv_pos_b2u(sv, &i); + mg->mg_len = i; + } cx->sb_rxtainted |= RX_MATCH_TAINTED(rx); rxres_save(&cx->sb_rxres, rx); RETURNOP(pm->op_pmreplstart); @@ -279,7 +298,7 @@ Perl_rxres_free(pTHX_ void **rsp) PP(pp_formline) { - djSP; dMARK; dORIGMARK; + dSP; dMARK; dORIGMARK; register SV *tmpForm = *++MARK; register U16 *fpc; register char *t; @@ -287,18 +306,18 @@ PP(pp_formline) register char *s; register char *send; register I32 arg; - register SV *sv; - char *item; - I32 itemsize; - I32 fieldsize; + register SV *sv = Nullsv; + char *item = Nullch; + I32 itemsize = 0; + I32 fieldsize = 0; I32 lines = 0; bool chopspace = (strchr(PL_chopset, ' ') != Nullch); - char *chophere; - char *linemark; + char *chophere = Nullch; + char *linemark = Nullch; NV value; - bool gotsome; + bool gotsome = FALSE; STRLEN len; - STRLEN fudge = SvCUR(tmpForm) * (IN_BYTE ? 1 : 3) + 1; + STRLEN fudge = SvCUR(tmpForm) * (IN_BYTES ? 1 : 3) + 1; bool item_is_utf = FALSE; if (!SvMAGICAL(tmpForm) || !SvCOMPILED(tmpForm)) { @@ -342,12 +361,13 @@ PP(pp_formline) case FF_MORE: name = "MORE"; break; case FF_LINEMARK: name = "LINEMARK"; break; case FF_END: name = "END"; break; + case FF_0DECIMAL: name = "0DECIMAL"; break; } if (arg >= 0) PerlIO_printf(Perl_debug_log, "%-16s%ld\n", name, (long) arg); else PerlIO_printf(Perl_debug_log, "%-16s\n", name); - } ) + } ); switch (*fpc++) { case FF_LINEMARK: linemark = t; @@ -524,8 +544,14 @@ PP(pp_formline) s = item; if (item_is_utf) { while (arg--) { - if (*s & 0x80) { - switch (UTF8SKIP(s)) { + if (UTF8_IS_CONTINUED(*s)) { + STRLEN skip = UTF8SKIP(s); + switch (skip) { + default: + Move(s,t,skip,char); + s += skip; + t += skip; + break; case 7: *t++ = *s++; case 6: *t++ = *s++; case 5: *t++ = *s++; @@ -620,6 +646,43 @@ PP(pp_formline) t += fieldsize; break; + case FF_0DECIMAL: + /* If the field is marked with ^ and the value is undefined, + blank it out. */ + arg = *fpc++; + if ((arg & 512) && !SvOK(sv)) { + arg = fieldsize; + while (arg--) + *t++ = ' '; + break; + } + gotsome = TRUE; + value = SvNV(sv); + /* Formats aren't yet marked for locales, so assume "yes". */ + { + STORE_NUMERIC_STANDARD_SET_LOCAL(); +#if defined(USE_LONG_DOUBLE) + if (arg & 256) { + sprintf(t, "%#0*.*" PERL_PRIfldbl, + (int) fieldsize, (int) arg & 255, value); +/* is this legal? I don't have long doubles */ + } else { + sprintf(t, "%0*.0" PERL_PRIfldbl, (int) fieldsize, value); + } +#else + if (arg & 256) { + sprintf(t, "%#0*.*f", + (int) fieldsize, (int) arg & 255, value); + } else { + sprintf(t, "%0*.0f", + (int) fieldsize, value); + } +#endif + RESTORE_NUMERIC_STANDARD(); + } + t += fieldsize; + break; + case FF_NEWLINE: f++; while (t-- > linemark && *t == ' ') ; @@ -687,7 +750,7 @@ PP(pp_formline) PP(pp_grepstart) { - djSP; + dSP; SV *src; if (PL_stack_base + *PL_markstack_ptr == SP) { @@ -702,7 +765,7 @@ PP(pp_grepstart) ENTER; /* enter outer scope */ SAVETMPS; - /* SAVE_DEFSV does *not* suffice here for USE_THREADS */ + /* SAVE_DEFSV does *not* suffice here for USE_5005THREADS */ SAVESPTR(DEFSV); ENTER; /* enter inner scope */ SAVEVPTR(PL_curpm); @@ -724,12 +787,12 @@ PP(pp_mapstart) PP(pp_mapwhile) { - djSP; + dSP; I32 items = (SP - PL_stack_base) - *PL_markstack_ptr; /* how many new items */ I32 count; I32 shift; SV** src; - SV** dst; + SV** dst; /* first, move source pointer to the next item in the source list */ ++PL_markstack_ptr[-1]; @@ -761,7 +824,7 @@ PP(pp_mapwhile) * irrelevant. --jhi */ if (shift < count) shift = count; /* Avoid shifting too often --Ben Tilly */ - + EXTEND(SP,shift); src = SP; dst = (SP += shift); @@ -771,9 +834,9 @@ PP(pp_mapwhile) *dst-- = *src--; } /* copy the new items down to the destination list */ - dst = PL_stack_base + (PL_markstack_ptr[-2] += items) - 1; + dst = PL_stack_base + (PL_markstack_ptr[-2] += items) - 1; while (items--) - *dst-- = SvTEMP(TOPs) ? POPs : sv_mortalcopy(POPs); + *dst-- = SvTEMP(TOPs) ? POPs : sv_mortalcopy(POPs); } LEAVE; /* exit inner scope */ @@ -810,179 +873,6 @@ PP(pp_mapwhile) } } -PP(pp_sort) -{ - djSP; dMARK; dORIGMARK; - register SV **up; - SV **myorigmark = ORIGMARK; - register I32 max; - HV *stash; - GV *gv; - CV *cv; - I32 gimme = GIMME; - OP* nextop = PL_op->op_next; - I32 overloading = 0; - bool hasargs = FALSE; - I32 is_xsub = 0; - - if (gimme != G_ARRAY) { - SP = MARK; - RETPUSHUNDEF; - } - - ENTER; - SAVEVPTR(PL_sortcop); - if (PL_op->op_flags & OPf_STACKED) { - if (PL_op->op_flags & OPf_SPECIAL) { - OP *kid = cLISTOP->op_first->op_sibling; /* pass pushmark */ - kid = kUNOP->op_first; /* pass rv2gv */ - kid = kUNOP->op_first; /* pass leave */ - PL_sortcop = kid->op_next; - stash = CopSTASH(PL_curcop); - } - else { - cv = sv_2cv(*++MARK, &stash, &gv, 0); - if (cv && SvPOK(cv)) { - STRLEN n_a; - char *proto = SvPV((SV*)cv, n_a); - if (proto && strEQ(proto, "$$")) { - hasargs = TRUE; - } - } - if (!(cv && CvROOT(cv))) { - if (cv && CvXSUB(cv)) { - is_xsub = 1; - } - else if (gv) { - SV *tmpstr = sv_newmortal(); - gv_efullname3(tmpstr, gv, Nullch); - DIE(aTHX_ "Undefined sort subroutine \"%s\" called", - SvPVX(tmpstr)); - } - else { - DIE(aTHX_ "Undefined subroutine in sort"); - } - } - - if (is_xsub) - PL_sortcop = (OP*)cv; - else { - PL_sortcop = CvSTART(cv); - SAVEVPTR(CvROOT(cv)->op_ppaddr); - CvROOT(cv)->op_ppaddr = PL_ppaddr[OP_NULL]; - - SAVEVPTR(PL_curpad); - PL_curpad = AvARRAY((AV*)AvARRAY(CvPADLIST(cv))[1]); - } - } - } - else { - PL_sortcop = Nullop; - stash = CopSTASH(PL_curcop); - } - - up = myorigmark + 1; - while (MARK < SP) { /* This may or may not shift down one here. */ - /*SUPPRESS 560*/ - if ((*up = *++MARK)) { /* Weed out nulls. */ - SvTEMP_off(*up); - if (!PL_sortcop && !SvPOK(*up)) { - STRLEN n_a; - if (SvAMAGIC(*up)) - overloading = 1; - else - (void)sv_2pv(*up, &n_a); - } - up++; - } - } - max = --up - myorigmark; - if (PL_sortcop) { - if (max > 1) { - PERL_CONTEXT *cx; - SV** newsp; - bool oldcatch = CATCH_GET; - - SAVETMPS; - SAVEOP(); - - CATCH_SET(TRUE); - PUSHSTACKi(PERLSI_SORT); - if (!hasargs && !is_xsub) { - if (PL_sortstash != stash || !PL_firstgv || !PL_secondgv) { - SAVESPTR(PL_firstgv); - SAVESPTR(PL_secondgv); - PL_firstgv = gv_fetchpv("a", TRUE, SVt_PV); - PL_secondgv = gv_fetchpv("b", TRUE, SVt_PV); - PL_sortstash = stash; - } -#ifdef USE_THREADS - sv_lock((SV *)PL_firstgv); - sv_lock((SV *)PL_secondgv); -#endif - SAVESPTR(GvSV(PL_firstgv)); - SAVESPTR(GvSV(PL_secondgv)); - } - - PUSHBLOCK(cx, CXt_NULL, PL_stack_base); - if (!(PL_op->op_flags & OPf_SPECIAL)) { - cx->cx_type = CXt_SUB; - cx->blk_gimme = G_SCALAR; - PUSHSUB(cx); - if (!CvDEPTH(cv)) - (void)SvREFCNT_inc(cv); /* in preparation for POPSUB */ - } - PL_sortcxix = cxstack_ix; - - if (hasargs && !is_xsub) { - /* This is mostly copied from pp_entersub */ - AV *av = (AV*)PL_curpad[0]; - -#ifndef USE_THREADS - cx->blk_sub.savearray = GvAV(PL_defgv); - GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av); -#endif /* USE_THREADS */ - cx->blk_sub.oldcurpad = PL_curpad; - cx->blk_sub.argarray = av; - } - qsortsv((myorigmark+1), max, - is_xsub ? sortcv_xsub : hasargs ? sortcv_stacked : sortcv); - - POPBLOCK(cx,PL_curpm); - PL_stack_sp = newsp; - POPSTACK; - CATCH_SET(oldcatch); - } - } - else { - if (max > 1) { - MEXTEND(SP, 20); /* Can't afford stack realloc on signal. */ - qsortsv(ORIGMARK+1, max, - (PL_op->op_private & OPpSORT_NUMERIC) - ? ( (PL_op->op_private & OPpSORT_INTEGER) - ? ( overloading ? amagic_i_ncmp : sv_i_ncmp) - : ( overloading ? amagic_ncmp : sv_ncmp)) - : ( (PL_op->op_private & OPpLOCALE) - ? ( overloading - ? amagic_cmp_locale - : sv_cmp_locale_static) - : ( overloading ? amagic_cmp : sv_cmp_static))); - if (PL_op->op_private & OPpSORT_REVERSE) { - SV **p = ORIGMARK+1; - SV **q = ORIGMARK+max; - while (p < q) { - SV *tmp = *p; - *p++ = *q; - *q-- = tmp; - } - } - } - } - LEAVE; - PL_stack_sp = ORIGMARK + max; - return nextop; -} - /* Range stuff. */ PP(pp_range) @@ -997,7 +887,7 @@ PP(pp_range) PP(pp_flip) { - djSP; + dSP; if (GIMME == G_ARRAY) { RETURNOP(((LOGOP*)cUNOP->op_first)->op_other); @@ -1005,10 +895,17 @@ PP(pp_flip) else { dTOPss; SV *targ = PAD_SV(PL_op->op_targ); - - if ((PL_op->op_private & OPpFLIP_LINENUM) - ? (PL_last_in_gv && SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv))) - : SvTRUE(sv) ) { + int flip; + + if (PL_op->op_private & OPpFLIP_LINENUM) { + struct io *gp_io; + flip = PL_last_in_gv + && (gp_io = GvIO(PL_last_in_gv)) + && SvIV(sv) == (IV)IoLINES(gp_io); + } else { + flip = SvTRUE(sv); + } + if (flip) { sv_setiv(PAD_SV(cUNOP->op_first->op_targ), 1); if (PL_op->op_flags & OPf_SPECIAL) { sv_setiv(targ, 1); @@ -1029,7 +926,7 @@ PP(pp_flip) PP(pp_flop) { - djSP; + dSP; if (GIMME == G_ARRAY) { dPOPPOPssrl; @@ -1084,7 +981,8 @@ PP(pp_flop) SV *targ = PAD_SV(cUNOP->op_first->op_targ); sv_inc(targ); if ((PL_op->op_private & OPpFLIP_LINENUM) - ? (PL_last_in_gv && SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv))) + ? (GvIO(PL_last_in_gv) + && SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv))) : SvTRUE(sv) ) { sv_setiv(PAD_SV(((UNOP*)cUNOP->op_first)->op_first->op_targ), 0); sv_catpv(targ, "E0"); @@ -1100,7 +998,6 @@ PP(pp_flop) STATIC I32 S_dopoptolabel(pTHX_ char *label) { - dTHR; register I32 i; register PERL_CONTEXT *cx; @@ -1109,28 +1006,28 @@ S_dopoptolabel(pTHX_ char *label) switch (CxTYPE(cx)) { case CXt_SUBST: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s", + OP_NAME(PL_op)); break; case CXt_SUB: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting subroutine via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting subroutine via %s", + OP_NAME(PL_op)); break; case CXt_FORMAT: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting format via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting format via %s", + OP_NAME(PL_op)); break; case CXt_EVAL: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting eval via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting eval via %s", + OP_NAME(PL_op)); break; case CXt_NULL: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting pseudo-block via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting pseudo-block via %s", + OP_NAME(PL_op)); return -1; case CXt_LOOP: if (!cx->blk_loop.label || @@ -1156,7 +1053,6 @@ Perl_dowantarray(pTHX) I32 Perl_block_gimme(pTHX) { - dTHR; I32 cxix; cxix = dopoptosub(cxstack_ix); @@ -1177,17 +1073,29 @@ Perl_block_gimme(pTHX) } } +I32 +Perl_is_lvalue_sub(pTHX) +{ + I32 cxix; + + cxix = dopoptosub(cxstack_ix); + assert(cxix >= 0); /* We should only be called from inside subs */ + + if (cxstack[cxix].blk_sub.lval && CvLVALUE(cxstack[cxix].blk_sub.cv)) + return cxstack[cxix].blk_sub.lval; + else + return 0; +} + STATIC I32 S_dopoptosub(pTHX_ I32 startingblock) { - dTHR; return dopoptosub_at(cxstack, startingblock); } STATIC I32 S_dopoptosub_at(pTHX_ PERL_CONTEXT *cxstk, I32 startingblock) { - dTHR; I32 i; register PERL_CONTEXT *cx; for (i = startingblock; i >= 0; i--) { @@ -1208,7 +1116,6 @@ S_dopoptosub_at(pTHX_ PERL_CONTEXT *cxstk, I32 startingblock) STATIC I32 S_dopoptoeval(pTHX_ I32 startingblock) { - dTHR; I32 i; register PERL_CONTEXT *cx; for (i = startingblock; i >= 0; i--) { @@ -1227,7 +1134,6 @@ S_dopoptoeval(pTHX_ I32 startingblock) STATIC I32 S_dopoptoloop(pTHX_ I32 startingblock) { - dTHR; I32 i; register PERL_CONTEXT *cx; for (i = startingblock; i >= 0; i--) { @@ -1235,28 +1141,28 @@ S_dopoptoloop(pTHX_ I32 startingblock) switch (CxTYPE(cx)) { case CXt_SUBST: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s", + OP_NAME(PL_op)); break; case CXt_SUB: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting subroutine via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting subroutine via %s", + OP_NAME(PL_op)); break; case CXt_FORMAT: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting format via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting format via %s", + OP_NAME(PL_op)); break; case CXt_EVAL: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting eval via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting eval via %s", + OP_NAME(PL_op)); break; case CXt_NULL: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting pseudo-block via %s", - PL_op_name[PL_op->op_type]); + Perl_warner(aTHX_ WARN_EXITING, "Exiting pseudo-block via %s", + OP_NAME(PL_op)); return -1; case CXt_LOOP: DEBUG_l( Perl_deb(aTHX_ "(Found loop #%ld)\n", (long)i)); @@ -1269,7 +1175,6 @@ S_dopoptoloop(pTHX_ I32 startingblock) void Perl_dounwind(pTHX_ I32 cxix) { - dTHR; register PERL_CONTEXT *cx; I32 optype; @@ -1303,42 +1208,6 @@ Perl_dounwind(pTHX_ I32 cxix) } } -/* - * Closures mentioned at top level of eval cannot be referenced - * again, and their presence indirectly causes a memory leak. - * (Note that the fact that compcv and friends are still set here - * is, AFAIK, an accident.) --Chip - * - * XXX need to get comppad et al from eval's cv rather than - * relying on the incidental global values. - */ -STATIC void -S_free_closures(pTHX) -{ - dTHR; - SV **svp = AvARRAY(PL_comppad_name); - I32 ix; - for (ix = AvFILLp(PL_comppad_name); ix >= 0; ix--) { - SV *sv = svp[ix]; - if (sv && sv != &PL_sv_undef && *SvPVX(sv) == '&') { - SvREFCNT_dec(sv); - svp[ix] = &PL_sv_undef; - - sv = PL_curpad[ix]; - if (CvCLONE(sv)) { - SvREFCNT_dec(CvOUTSIDE(sv)); - CvOUTSIDE(sv) = Nullcv; - } - else { - SvREFCNT_dec(sv); - sv = NEWSV(0,0); - SvPADTMP_on(sv); - PL_curpad[ix] = sv; - } - } - } -} - void Perl_qerror(pTHX_ SV *err) { @@ -1384,8 +1253,9 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) } } } - else + else { sv_setpvn(ERRSV, message, msglen); + } } else message = SvPVx(ERRSV, msglen); @@ -1417,6 +1287,12 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) LEAVE; + /* LEAVE could clobber PL_curcop (see save_re_context()) + * XXX it might be better to find a way to avoid messing with + * PL_curcop in save_re_context() instead, but this is a more + * minimal fix --GSAR */ + PL_curcop = cx->blk_oldcop; + if (optype == OP_REQUIRE) { char* msg = SvPVx(ERRSV, n_a); DIE(aTHX_ "%sCompilation failed in require", @@ -1434,7 +1310,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) #endif PerlIO *serr = Perl_error_log; - PerlIO_write(serr, message, msglen); + PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen); (void)PerlIO_flush(serr); #ifdef USE_SFIO errno = e; @@ -1447,7 +1323,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) PP(pp_xor) { - djSP; dPOPTOPssrl; + dSP; dPOPTOPssrl; if (SvTRUE(left) != SvTRUE(right)) RETSETYES; else @@ -1456,7 +1332,7 @@ PP(pp_xor) PP(pp_andassign) { - djSP; + dSP; if (!SvTRUE(TOPs)) RETURN; else @@ -1465,7 +1341,7 @@ PP(pp_andassign) PP(pp_orassign) { - djSP; + dSP; if (SvTRUE(TOPs)) RETURN; else @@ -1474,7 +1350,7 @@ PP(pp_orassign) PP(pp_caller) { - djSP; + dSP; register I32 cxix = dopoptosub(cxstack_ix); register PERL_CONTEXT *cx; register PERL_CONTEXT *ccstack = cxstack; @@ -1487,7 +1363,7 @@ PP(pp_caller) if (MAXARG) count = POPi; - EXTEND(SP, 10); + for (;;) { /* we may be in a higher stacklevel, so dig down deeper */ while (cxix < 0 && top_si->si_type != PERLSI_MAIN) { @@ -1496,8 +1372,10 @@ PP(pp_caller) cxix = dopoptosub_at(ccstack, top_si->si_cxix); } if (cxix < 0) { - if (GIMME != G_ARRAY) + if (GIMME != G_ARRAY) { + EXTEND(SP, 1); RETPUSHUNDEF; + } RETURN; } if (PL_DBsub && cxix >= 0 && @@ -1519,6 +1397,7 @@ PP(pp_caller) stashname = CopSTASHPV(cx->blk_oldcop); if (GIMME != G_ARRAY) { + EXTEND(SP, 1); if (!stashname) PUSHs(&PL_sv_undef); else { @@ -1529,6 +1408,8 @@ PP(pp_caller) RETURN; } + EXTEND(SP, 10); + if (!stashname) PUSHs(&PL_sv_undef); else @@ -1602,10 +1483,10 @@ PP(pp_caller) SV * mask ; SV * old_warnings = cx->blk_oldcop->cop_warnings ; - if (old_warnings == pWARN_NONE || + if (old_warnings == pWARN_NONE || (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0)) mask = newSVpvn(WARN_NONEstring, WARNsize) ; - else if (old_warnings == pWARN_ALL || + else if (old_warnings == pWARN_ALL || (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON)) mask = newSVpvn(WARN_ALLstring, WARNsize) ; else @@ -1617,7 +1498,7 @@ PP(pp_caller) PP(pp_reset) { - djSP; + dSP; char *tmps; STRLEN n_a; @@ -1644,7 +1525,7 @@ PP(pp_dbstate) if (PL_op->op_private || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace)) { - djSP; + dSP; register CV *cv; register PERL_CONTEXT *cx; I32 gimme = G_ARRAY; @@ -1656,7 +1537,8 @@ PP(pp_dbstate) if (!cv) DIE(aTHX_ "No DB::DB routine defined"); - if (CvDEPTH(cv) >= 1 && !(PL_debug & (1<<30))) /* don't do recursive DB::DB call */ + if (CvDEPTH(cv) >= 1 && !(PL_debug & DEBUG_DB_RECURSE_FLAG)) + /* don't do recursive DB::DB call */ return NORMAL; ENTER; @@ -1688,7 +1570,7 @@ PP(pp_scope) PP(pp_enteriter) { - djSP; dMARK; + dSP; dMARK; register PERL_CONTEXT *cx; I32 gimme = GIMME_V; SV **svp; @@ -1700,20 +1582,21 @@ PP(pp_enteriter) ENTER; SAVETMPS; -#ifdef USE_THREADS +#ifdef USE_5005THREADS if (PL_op->op_flags & OPf_SPECIAL) { - dTHR; svp = &THREADSV(PL_op->op_targ); /* per-thread variable */ SAVEGENERICSV(*svp); *svp = NEWSV(0,0); } else -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ if (PL_op->op_targ) { +#ifndef USE_ITHREADS svp = &PL_curpad[PL_op->op_targ]; /* "my" variable */ SAVESPTR(*svp); -#ifdef USE_ITHREADS - iterdata = (void*)PL_op->op_targ; +#else + SAVEPADSV(PL_op->op_targ); + iterdata = INT2PTR(void*, PL_op->op_targ); cxtype |= CXp_PADVAR; #endif } @@ -1766,7 +1649,7 @@ PP(pp_enteriter) PP(pp_enterloop) { - djSP; + dSP; register PERL_CONTEXT *cx; I32 gimme = GIMME_V; @@ -1782,7 +1665,7 @@ PP(pp_enterloop) PP(pp_leaveloop) { - djSP; + dSP; register PERL_CONTEXT *cx; I32 gimme; SV **newsp; @@ -1822,7 +1705,7 @@ PP(pp_leaveloop) PP(pp_return) { - djSP; dMARK; + dSP; dMARK; I32 cxix; register PERL_CONTEXT *cx; bool popsub2 = FALSE; @@ -1862,8 +1745,6 @@ PP(pp_return) POPEVAL(cx); if (CxTRYBLOCK(cx)) break; - if (AvFILLp(PL_comppad_name) >= 0) - free_closures(); lex_end(); if (optype == OP_REQUIRE && (MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) ) @@ -1933,7 +1814,7 @@ PP(pp_return) PP(pp_last) { - djSP; + dSP; I32 cxix; register PERL_CONTEXT *cx; I32 pop2 = 0; @@ -2073,7 +1954,7 @@ PP(pp_redo) STATIC OP * S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) { - OP *kid; + OP *kid = Nullop; OP **ops = opstack; static char too_deep[] = "Target of goto is too deeply nested"; @@ -2090,7 +1971,6 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) } *ops = 0; if (o->op_flags & OPf_KIDS) { - dTHR; /* First try all the kids at this level, since that's likeliest. */ for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && @@ -2121,7 +2001,7 @@ PP(pp_dump) PP(pp_goto) { - djSP; + dSP; OP *retop = 0; I32 ix; register PERL_CONTEXT *cx; @@ -2172,7 +2052,7 @@ PP(pp_goto) if (cxix < cxstack_ix) dounwind(cxix); TOPBLOCK(cx); - if (CxTYPE(cx) == CXt_EVAL && cx->blk_eval.old_op_type == OP_ENTEREVAL) + if (CxREALEVAL(cx)) DIE(aTHX_ "Can't goto subroutine from an eval-string"); mark = PL_stack_sp; if (CxTYPE(cx) == CXt_SUB && cx->blk_sub.hasargs) { @@ -2184,10 +2064,10 @@ PP(pp_goto) EXTEND(PL_stack_sp, items); /* @_ could have been extended. */ Copy(AvARRAY(av), PL_stack_sp, items, SV*); PL_stack_sp += items; -#ifndef USE_THREADS +#ifndef USE_5005THREADS SvREFCNT_dec(GvAV(PL_defgv)); GvAV(PL_defgv) = cx->blk_sub.savearray; -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ /* abandon @_ if it got reified */ if (AvREAL(av)) { (void)sv_2mortal((SV*)av); /* delay until return */ @@ -2199,7 +2079,7 @@ PP(pp_goto) } else if (CvXSUB(cv)) { /* put GvAV(defgv) back onto stack */ AV* av; -#ifdef USE_THREADS +#ifdef USE_5005THREADS av = (AV*)PL_curpad[0]; #else av = GvAV(PL_defgv); @@ -2240,8 +2120,8 @@ PP(pp_goto) PL_stack_sp--; /* There is no cv arg. */ /* Push a mark for the start of arglist */ - PUSHMARK(mark); - (void)(*CvXSUB(cv))(aTHXo_ cv); + PUSHMARK(mark); + (void)(*CvXSUB(cv))(aTHX_ cv); /* Pop the current context like a decent sub should */ POPBLOCK(cx, PL_curpm); /* Do _not_ use PUTBACK, keep the XSUB's return stack! */ @@ -2311,33 +2191,33 @@ PP(pp_goto) svp = AvARRAY(padlist); } } -#ifdef USE_THREADS +#ifdef USE_5005THREADS if (!cx->blk_sub.hasargs) { AV* av = (AV*)PL_curpad[0]; - + items = AvFILLp(av) + 1; if (items) { /* Mark is at the end of the stack. */ EXTEND(SP, items); Copy(AvARRAY(av), SP + 1, items, SV*); SP += items; - PUTBACK ; + PUTBACK ; } } -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ SAVEVPTR(PL_curpad); PL_curpad = AvARRAY((AV*)svp[CvDEPTH(cv)]); -#ifndef USE_THREADS +#ifndef USE_5005THREADS if (cx->blk_sub.hasargs) -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ { AV* av = (AV*)PL_curpad[0]; SV** ary; -#ifndef USE_THREADS +#ifndef USE_5005THREADS cx->blk_sub.savearray = GvAV(PL_defgv); GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av); -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ cx->blk_sub.oldcurpad = PL_curpad; cx->blk_sub.argarray = av; ++mark; @@ -2371,7 +2251,7 @@ PP(pp_goto) */ SV *sv = GvSV(PL_DBsub); CV *gotocv; - + if (PERLDB_SUB_NN) { SvIVX(sv) = PTR2IV(cv); /* Already upgraded, saved */ } else { @@ -2403,6 +2283,8 @@ PP(pp_goto) if (label && *label) { OP *gotoprobe = 0; + bool leaving_eval = FALSE; + PERL_CONTEXT *last_eval_cx = 0; /* find label */ @@ -2412,8 +2294,15 @@ PP(pp_goto) cx = &cxstack[ix]; switch (CxTYPE(cx)) { case CXt_EVAL: - gotoprobe = PL_eval_root; /* XXX not good for nested eval */ - break; + leaving_eval = TRUE; + if (CxREALEVAL(cx)) { + gotoprobe = (last_eval_cx ? + last_eval_cx->blk_eval.old_eval_root : + PL_eval_root); + last_eval_cx = cx; + break; + } + /* else fall through */ case CXt_LOOP: gotoprobe = cx->blk_oldcop->op_sibling; break; @@ -2451,6 +2340,17 @@ PP(pp_goto) if (!retop) DIE(aTHX_ "Can't find label %s", label); + /* if we're leaving an eval, check before we pop any frames + that we're not going to punt, otherwise the error + won't be caught */ + + if (leaving_eval && *enterops && enterops[1]) { + I32 i; + for (i = 1; enterops[i]; i++) + if (enterops[i]->op_type == OP_ENTERITER) + DIE(aTHX_ "Can't \"goto\" into the middle of a foreach loop"); + } + /* pop unwanted frames */ if (ix < cxstack_ix) { @@ -2498,7 +2398,7 @@ PP(pp_goto) PP(pp_exit) { - djSP; + dSP; I32 anum; if (MAXARG < 1) @@ -2508,6 +2408,7 @@ PP(pp_exit) #ifdef VMS if (anum == 1 && (PL_op->op_private & OPpEXIT_VMSISH)) anum = 0; + VMSISH_HUSHED = VMSISH_HUSHED || (PL_op->op_private & OPpHUSH_VMSISH); #endif } PL_exit_flags |= PERL_EXIT_EXPECTED; @@ -2519,7 +2420,7 @@ PP(pp_exit) #ifdef NOTYET PP(pp_nswitch) { - djSP; + dSP; NV value = SvNVx(GvSV(cCOP->cop_gv)); register I32 match = I_32(value); @@ -2538,7 +2439,7 @@ PP(pp_nswitch) PP(pp_cswitch) { - djSP; + dSP; register I32 match; if (PL_multiline) @@ -2601,7 +2502,6 @@ S_docatch_body(pTHX) STATIC OP * S_docatch(pTHX_ OP *o) { - dTHR; int ret; OP *oldop = PL_op; volatile PERL_SI *cursi = PL_curstackinfo; @@ -2694,16 +2594,12 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp) #else SAVEVPTR(PL_op); #endif -#ifdef EBCDIC - PL_hints = HINT_BYTE; -#else - PL_hints = 0; -#endif + PL_hints &= HINT_UTF8; PL_op = &dummy; PL_op->op_type = OP_ENTEREVAL; PL_op->op_flags = 0; /* Avoid uninit warning. */ - PUSHBLOCK(cx, CXt_EVAL, SP); + PUSHBLOCK(cx, CXt_EVAL|(PL_curcop == &PL_compiling ? 0 : CXp_REAL), SP); PUSHEVAL(cx, 0, Nullgv); rop = doeval(G_SCALAR, startop); POPBLOCK(cx,PL_curpm); @@ -2722,7 +2618,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp) return rop; } -/* With USE_THREADS, eval_owner must be held on entry to doeval */ +/* With USE_5005THREADS, eval_owner must be held on entry to doeval */ STATIC OP * S_doeval(pTHX_ int gimme, OP** startop) { @@ -2763,11 +2659,14 @@ S_doeval(pTHX_ int gimme, OP** startop) PL_compcv = (CV*)NEWSV(1104,0); sv_upgrade((SV *)PL_compcv, SVt_PVCV); CvEVAL_on(PL_compcv); -#ifdef USE_THREADS + assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL); + cxstack[cxstack_ix].blk_eval.cv = PL_compcv; + +#ifdef USE_5005THREADS CvOWNER(PL_compcv) = 0; New(666, CvMUTEXP(PL_compcv), 1, perl_mutex); MUTEX_INIT(CvMUTEXP(PL_compcv)); -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ PL_comppad = newAV(); av_push(PL_comppad, Nullsv); @@ -2776,11 +2675,11 @@ S_doeval(pTHX_ int gimme, OP** startop) PL_comppad_name_fill = 0; PL_min_intro_pending = 0; PL_padix = 0; -#ifdef USE_THREADS +#ifdef USE_5005THREADS av_store(PL_comppad_name, 0, newSVpvn("@_", 2)); PL_curpad[0] = (SV*)newAV(); SvPADMY_on(PL_curpad[0]); /* XXX Needed? */ -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ comppadlist = newAV(); AvREAL_off(comppadlist); @@ -2794,7 +2693,7 @@ S_doeval(pTHX_ int gimme, OP** startop) CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(caller); } - SAVEFREESV(PL_compcv); + SAVEMORTALIZESV(PL_compcv); /* must remain until end of current statement */ /* make sure we compile in the right package */ @@ -2813,8 +2712,6 @@ S_doeval(pTHX_ int gimme, OP** startop) PL_error_count = 0; PL_curcop = &PL_compiling; PL_curcop->cop_arybase = 0; - SvREFCNT_dec(PL_rs); - PL_rs = newSVpvn("\n", 1); if (saveop && saveop->op_flags & OPf_SPECIAL) PL_in_eval |= EVAL_KEEPERR; else @@ -2852,18 +2749,14 @@ S_doeval(pTHX_ int gimme, OP** startop) Perl_croak(aTHX_ "%sCompilation failed in regexp", (*msg ? msg : "Unknown error\n")); } - SvREFCNT_dec(PL_rs); - PL_rs = SvREFCNT_inc(PL_nrs); -#ifdef USE_THREADS +#ifdef USE_5005THREADS MUTEX_LOCK(&PL_eval_mutex); PL_eval_owner = 0; COND_SIGNAL(&PL_eval_cond); MUTEX_UNLOCK(&PL_eval_mutex); -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ RETPUSHUNDEF; } - SvREFCNT_dec(PL_rs); - PL_rs = SvREFCNT_inc(PL_nrs); CopLINE_set(&PL_compiling, 0); if (startop) { *startop = PL_eval_root; @@ -2898,12 +2791,12 @@ S_doeval(pTHX_ int gimme, OP** startop) SP = PL_stack_base + POPMARK; /* pop original mark */ PL_op = saveop; /* The caller may need it. */ PL_lex_state = LEX_NOTPARSING; /* $^S needs this. */ -#ifdef USE_THREADS +#ifdef USE_5005THREADS MUTEX_LOCK(&PL_eval_mutex); PL_eval_owner = 0; COND_SIGNAL(&PL_eval_cond); MUTEX_UNLOCK(&PL_eval_mutex); -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ RETURNOP(PL_eval_start); } @@ -2942,37 +2835,40 @@ S_doopen_pmc(pTHX_ const char *name, const char *mode) PP(pp_require) { - djSP; + dSP; register PERL_CONTEXT *cx; SV *sv; char *name; STRLEN len; - char *tryname; + char *tryname = Nullch; SV *namesv = Nullsv; SV** svp; - I32 gimme = G_SCALAR; + I32 gimme = GIMME_V; PerlIO *tryrsfp = 0; STRLEN n_a; int filter_has_file = 0; GV *filter_child_proc = 0; SV *filter_state = 0; SV *filter_sub = 0; + SV *hook_sv = 0; + SV *encoding; + OP *op; sv = POPs; if (SvNIOKp(sv)) { - if (SvPOK(sv) && SvNOK(sv)) { /* require v5.6.1 */ + if (SvPOK(sv) && SvNOK(sv) && SvNV(sv)) { /* require v5.6.1 */ UV rev = 0, ver = 0, sver = 0; - I32 len; + STRLEN len; U8 *s = (U8*)SvPVX(sv); U8 *end = (U8*)SvPVX(sv) + SvCUR(sv); if (s < end) { - rev = utf8_to_uv_chk(s, &len, 0); + rev = utf8n_to_uvchr(s, end - s, &len, 0); s += len; if (s < end) { - ver = utf8_to_uv_chk(s, &len, 0); + ver = utf8n_to_uvchr(s, end - s, &len, 0); s += len; if (s < end) - sver = utf8_to_uv_chk(s, &len, 0); + sver = utf8n_to_uvchr(s, end - s, &len, 0); } } if (PERL_REVISION < rev @@ -2985,6 +2881,9 @@ PP(pp_require) "v%d.%d.%d, stopped", rev, ver, sver, PERL_REVISION, PERL_VERSION, PERL_SUBVERSION); } + if (ckWARN(WARN_PORTABLE)) + Perl_warner(aTHX_ WARN_PORTABLE, + "v-string in use/require non-portable"); RETPUSHYES; } else if (!SvPOKp(sv)) { /* require 5.005_03 */ @@ -3003,7 +2902,7 @@ PP(pp_require) if (sver == 0 && (rev > 5 || (rev == 5 && ver >= 100))) { DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required--" "this is only v%d.%d.%d, stopped" - " (did you mean v%"UVuf".%"UVuf".0?)", + " (did you mean v%"UVuf".%03"UVuf"?)", rev, ver, sver, PERL_REVISION, PERL_VERSION, PERL_SUBVERSION, rev, ver/100); } @@ -3028,22 +2927,27 @@ PP(pp_require) /* prepare to compile file */ +#ifdef MACOS_TRADITIONAL if (PERL_FILE_IS_ABSOLUTE(name) - || (*name == '.' && (name[1] == '/' || - (name[1] == '.' && name[2] == '/')))) + || (*name == ':' && name[1] != ':' && strchr(name+2, ':'))) { tryname = name; tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE); -#ifdef MACOS_TRADITIONAL /* We consider paths of the form :a:b ambiguous and interpret them first as global then as local */ - if (!tryrsfp && name[0] == ':' && name[1] != ':' && strchr(name+2, ':')) + if (!tryrsfp && *name == ':' && name[1] != ':' && strchr(name+2, ':')) goto trylocal; } - else + else trylocal: { #else + if (PERL_FILE_IS_ABSOLUTE(name) + || (*name == '.' && (name[1] == '/' || + (name[1] == '.' && name[2] == '/')))) + { + tryname = name; + tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE); } else { #endif @@ -3062,12 +2966,14 @@ trylocal: { int count; SV *loader = dirsv; - if (SvTYPE(SvRV(loader)) == SVt_PVAV) { + if (SvTYPE(SvRV(loader)) == SVt_PVAV + && !sv_isobject(loader)) + { loader = *av_fetch((AV *)SvRV(loader), 0, TRUE); } Perl_sv_setpvf(aTHX_ namesv, "/loader/0x%"UVxf"/%s", - PTR2UV(SvANY(loader)), name); + PTR2UV(SvRV(dirsv)), name); tryname = SvPVX(namesv); tryrsfp = 0; @@ -3079,7 +2985,10 @@ trylocal: { PUSHs(dirsv); PUSHs(sv); PUTBACK; - count = call_sv(loader, G_ARRAY); + if (sv_isobject(loader)) + count = call_method("INC", G_ARRAY); + else + count = call_sv(loader, G_ARRAY); SPAGAIN; if (count > 0) { @@ -3145,6 +3054,7 @@ trylocal: { LEAVE; if (tryrsfp) { + hook_sv = dirsv; break; } @@ -3233,8 +3143,14 @@ trylocal: { SETERRNO(0, SS$_NORMAL); /* Assume success here to prevent recursive requirement. */ - (void)hv_store(GvHVn(PL_incgv), name, strlen(name), - newSVpv(CopFILE(&PL_compiling), 0), 0 ); + len = strlen(name); + /* Check whether a hook in @INC has already filled %INC */ + if (!hook_sv || !(svp = hv_fetch(GvHVn(PL_incgv), name, len, 0))) { + (void)hv_store(GvHVn(PL_incgv), name, len, + (hook_sv ? SvREFCNT_inc(hook_sv) + : newSVpv(CopFILE(&PL_compiling), 0)), + 0 ); + } ENTER; SAVETMPS; @@ -3244,18 +3160,18 @@ trylocal: { PL_rsfp = tryrsfp; SAVEHINTS(); -#ifdef EBCDIC - PL_hints = HINT_BYTE; -#else PL_hints = 0; -#endif SAVESPTR(PL_compiling.cop_warnings); 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 + else if (PL_taint_warn) + PL_compiling.cop_warnings = newSVpvn(WARN_TAINTstring, WARNsize); + else PL_compiling.cop_warnings = pWARN_STD ; + SAVESPTR(PL_compiling.cop_io); + PL_compiling.cop_io = Nullsv; if (filter_sub || filter_child_proc) { SV *datasv = filter_add(run_user_filter, Nullsv); @@ -3274,15 +3190,25 @@ trylocal: { CopLINE_set(&PL_compiling, 0); PUTBACK; -#ifdef USE_THREADS +#ifdef USE_5005THREADS MUTEX_LOCK(&PL_eval_mutex); if (PL_eval_owner && PL_eval_owner != thr) while (PL_eval_owner) COND_WAIT(&PL_eval_cond, &PL_eval_mutex); PL_eval_owner = thr; MUTEX_UNLOCK(&PL_eval_mutex); -#endif /* USE_THREADS */ - return DOCATCH(doeval(G_SCALAR, NULL)); +#endif /* USE_5005THREADS */ + + /* Store and reset encoding. */ + encoding = PL_encoding; + PL_encoding = Nullsv; + + op = DOCATCH(doeval(gimme, NULL)); + + /* Restore encoding. */ + PL_encoding = encoding; + + return op; } PP(pp_dofile) @@ -3292,7 +3218,7 @@ PP(pp_dofile) PP(pp_entereval) { - djSP; + dSP; register PERL_CONTEXT *cx; dPOPss; I32 gimme = GIMME_V, was = PL_sub_generation; @@ -3309,7 +3235,7 @@ PP(pp_entereval) ENTER; lex_start(sv); SAVETMPS; - + /* switch to eval mode */ if (PERLDB_NAMEEVAL && CopLINE(PL_curcop)) { @@ -3341,6 +3267,13 @@ PP(pp_entereval) PL_compiling.cop_warnings = newSVsv(PL_curcop->cop_warnings); SAVEFREESV(PL_compiling.cop_warnings); } + SAVESPTR(PL_compiling.cop_io); + if (specialCopIO(PL_curcop->cop_io)) + PL_compiling.cop_io = PL_curcop->cop_io; + else { + PL_compiling.cop_io = newSVsv(PL_curcop->cop_io); + SAVEFREESV(PL_compiling.cop_io); + } push_return(PL_op->op_next); PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP); @@ -3351,14 +3284,14 @@ PP(pp_entereval) if (PERLDB_LINE && PL_curstash != PL_debstash) save_lines(CopFILEAV(&PL_compiling), PL_linestr); PUTBACK; -#ifdef USE_THREADS +#ifdef USE_5005THREADS MUTEX_LOCK(&PL_eval_mutex); if (PL_eval_owner && PL_eval_owner != thr) while (PL_eval_owner) COND_WAIT(&PL_eval_cond, &PL_eval_mutex); PL_eval_owner = thr; MUTEX_UNLOCK(&PL_eval_mutex); -#endif /* USE_THREADS */ +#endif /* USE_5005THREADS */ ret = doeval(gimme, NULL); if (PERLDB_INTER && was != PL_sub_generation /* Some subs defined here. */ && ret != PL_op->op_next) { /* Successive compilation. */ @@ -3369,7 +3302,7 @@ PP(pp_entereval) PP(pp_leaveeval) { - djSP; + dSP; register SV **mark; SV **newsp; PMOP *newpm; @@ -3411,9 +3344,6 @@ PP(pp_leaveeval) } PL_curpm = newpm; /* Don't pop $1 et al till now */ - if (AvFILLp(PL_comppad_name) >= 0) - free_closures(); - #ifdef DEBUGGING assert(CvDEPTH(PL_compcv) == 1); #endif @@ -3440,7 +3370,7 @@ PP(pp_leaveeval) PP(pp_entertry) { - djSP; + dSP; register PERL_CONTEXT *cx; I32 gimme = GIMME_V; @@ -3450,7 +3380,6 @@ PP(pp_entertry) push_return(cLOGOP->op_other->op_next); PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), SP); PUSHEVAL(cx, 0, 0); - PL_eval_root = PL_op; /* Only needed so that goto works right. */ PL_in_eval = EVAL_INEVAL; sv_setpv(ERRSV,""); @@ -3460,7 +3389,7 @@ PP(pp_entertry) PP(pp_leavetry) { - djSP; + dSP; register SV **mark; SV **newsp; PMOP *newpm; @@ -3511,20 +3440,20 @@ S_doparseform(pTHX_ SV *sv) STRLEN len; register char *s = SvPV_force(sv, len); register char *send = s + len; - register char *base; + register char *base = Nullch; register I32 skipspaces = 0; - bool noblank; - bool repeat; + bool noblank = FALSE; + bool repeat = FALSE; bool postspace = FALSE; U16 *fops; register U16 *fpc; - U16 *linepc; + U16 *linepc = 0; register I32 arg; bool ischop; if (len == 0) Perl_croak(aTHX_ "Null picture in formline"); - + New(804, fops, (send - s)*3+10, U16); /* Almost certainly too long... */ fpc = fops; @@ -3552,7 +3481,7 @@ S_doparseform(pTHX_ SV *sv) case ' ': case '\t': skipspaces++; continue; - + case '\n': case 0: arg = s - base; skipspaces++; @@ -3627,6 +3556,24 @@ S_doparseform(pTHX_ SV *sv) } *fpc++ = s - base; /* fieldsize for FETCH */ *fpc++ = FF_DECIMAL; + *fpc++ = arg; + } + else if (*s == '0' && s[1] == '#') { /* Zero padded decimals */ + arg = ischop ? 512 : 0; + base = s - 1; + s++; /* skip the '0' first */ + while (*s == '#') + s++; + if (*s == '.') { + char *f; + s++; + f = s; + while (*s == '#') + s++; + arg |= 256 + (s - f); + } + *fpc++ = s - base; /* fieldsize for FETCH */ + *fpc++ = FF_0DECIMAL; *fpc++ = arg; } else { @@ -3679,599 +3626,12 @@ S_doparseform(pTHX_ SV *sv) } Copy(fops, s, arg, U16); Safefree(fops); - sv_magic(sv, Nullsv, 'f', Nullch, 0); + sv_magic(sv, Nullsv, PERL_MAGIC_fm, Nullch, 0); SvCOMPILED_on(sv); } -/* - * The mergesort implementation is by Peter M. Mcilroy . - * - * The original code was written in conjunction with BSD Computer Software - * Research Group at University of California, Berkeley. - * - * See also: "Optimistic Merge Sort" (SODA '92) - * - * The integration to Perl is by John P. Linderman . - * - * The code can be distributed under the same terms as Perl itself. - * - */ - -#ifdef TESTHARNESS -#include -typedef void SV; -#define pTHXo_ -#define pTHX_ -#define STATIC -#define New(ID,VAR,N,TYPE) VAR=(TYPE *)malloc((N)*sizeof(TYPE)) -#define Safefree(VAR) free(VAR) -typedef int (*SVCOMPARE_t) (pTHXo_ SV*, SV*); -#endif /* TESTHARNESS */ - -typedef char * aptr; /* pointer for arithmetic on sizes */ -typedef SV * gptr; /* pointers in our lists */ - -/* Binary merge internal sort, with a few special mods -** for the special perl environment it now finds itself in. -** -** Things that were once options have been hotwired -** to values suitable for this use. In particular, we'll always -** initialize looking for natural runs, we'll always produce stable -** output, and we'll always do Peter McIlroy's binary merge. -*/ - -/* Pointer types for arithmetic and storage and convenience casts */ - -#define APTR(P) ((aptr)(P)) -#define GPTP(P) ((gptr *)(P)) -#define GPPP(P) ((gptr **)(P)) - - -/* byte offset from pointer P to (larger) pointer Q */ -#define BYTEOFF(P, Q) (APTR(Q) - APTR(P)) - -#define PSIZE sizeof(gptr) - -/* If PSIZE is power of 2, make PSHIFT that power, if that helps */ - -#ifdef PSHIFT -#define PNELEM(P, Q) (BYTEOFF(P,Q) >> (PSHIFT)) -#define PNBYTE(N) ((N) << (PSHIFT)) -#define PINDEX(P, N) (GPTP(APTR(P) + PNBYTE(N))) -#else -/* Leave optimization to compiler */ -#define PNELEM(P, Q) (GPTP(Q) - GPTP(P)) -#define PNBYTE(N) ((N) * (PSIZE)) -#define PINDEX(P, N) (GPTP(P) + (N)) -#endif - -/* Pointer into other corresponding to pointer into this */ -#define POTHER(P, THIS, OTHER) GPTP(APTR(OTHER) + BYTEOFF(THIS,P)) - -#define FROMTOUPTO(src, dst, lim) do *dst++ = *src++; while(src= 2 * PTHRESH. We only try to form long runs when -** PTHRESH adjacent pairs compare in the same way, suggesting overall order. -** -** Unless otherwise specified, pair pointers address the first of two elements. -** -** b and b+1 are a pair that compare with sense ``sense''. -** b is the ``bottom'' of adjacent pairs that might form a longer run. -** -** p2 parallels b in the list2 array, where runs are defined by -** a pointer chain. -** -** t represents the ``top'' of the adjacent pairs that might extend -** the run beginning at b. Usually, t addresses a pair -** that compares with opposite sense from (b,b+1). -** However, it may also address a singleton element at the end of list1, -** or it may be equal to ``last'', the first element beyond list1. -** -** r addresses the Nth pair following b. If this would be beyond t, -** we back it off to t. Only when r is less than t do we consider the -** run long enough to consider checking. -** -** q addresses a pair such that the pairs at b through q already form a run. -** Often, q will equal b, indicating we only are sure of the pair itself. -** However, a search on the previous cycle may have revealed a longer run, -** so q may be greater than b. -** -** p is used to work back from a candidate r, trying to reach q, -** which would mean b through r would be a run. If we discover such a run, -** we start q at r and try to push it further towards t. -** If b through r is NOT a run, we detect the wrong order at (p-1,p). -** In any event, after the check (if any), we have two main cases. -** -** 1) Short run. b <= q < p <= r <= t. -** b through q is a run (perhaps trivial) -** q through p are uninteresting pairs -** p through r is a run -** -** 2) Long run. b < r <= q < t. -** b through q is a run (of length >= 2 * PTHRESH) -** -** Note that degenerate cases are not only possible, but likely. -** For example, if the pair following b compares with opposite sense, -** then b == q < p == r == t. -*/ - - -static void -dynprep(pTHX_ gptr *list1, gptr *list2, size_t nmemb, SVCOMPARE_t cmp) -{ - int sense; - register gptr *b, *p, *q, *t, *p2; - register gptr c, *last, *r; - gptr *savep; - - b = list1; - last = PINDEX(b, nmemb); - sense = (cmp(aTHX_ *b, *(b+1)) > 0); - for (p2 = list2; b < last; ) { - /* We just started, or just reversed sense. - ** Set t at end of pairs with the prevailing sense. - */ - for (p = b+2, t = p; ++p < last; t = ++p) { - if ((cmp(aTHX_ *t, *p) > 0) != sense) break; - } - q = b; - /* Having laid out the playing field, look for long runs */ - do { - p = r = b + (2 * PTHRESH); - if (r >= t) p = r = t; /* too short to care about */ - else { - while (((cmp(aTHX_ *(p-1), *p) > 0) == sense) && - ((p -= 2) > q)); - if (p <= q) { - /* b through r is a (long) run. - ** Extend it as far as possible. - */ - p = q = r; - while (((p += 2) < t) && - ((cmp(aTHX_ *(p-1), *p) > 0) == sense)) q = p; - r = p = q + 2; /* no simple pairs, no after-run */ - } - } - if (q > b) { /* run of greater than 2 at b */ - savep = p; - p = q += 2; - /* pick up singleton, if possible */ - if ((p == t) && - ((t + 1) == last) && - ((cmp(aTHX_ *(p-1), *p) > 0) == sense)) - savep = r = p = q = last; - p2 = NEXT(p2) = p2 + (p - b); - if (sense) while (b < --p) { - c = *b; - *b++ = *p; - *p = c; - } - p = savep; - } - while (q < p) { /* simple pairs */ - p2 = NEXT(p2) = p2 + 2; - if (sense) { - c = *q++; - *(q-1) = *q; - *q++ = c; - } else q += 2; - } - if (((b = p) == t) && ((t+1) == last)) { - NEXT(p2) = p2 + 1; - b++; - } - q = r; - } while (b < t); - sense = !sense; - } - return; -} - - -/* Overview of bmerge variables: -** -** list1 and list2 address the main and auxiliary arrays. -** They swap identities after each merge pass. -** Base points to the original list1, so we can tell if -** the pointers ended up where they belonged (or must be copied). -** -** When we are merging two lists, f1 and f2 are the next elements -** on the respective lists. l1 and l2 mark the end of the lists. -** tp2 is the current location in the merged list. -** -** p1 records where f1 started. -** After the merge, a new descriptor is built there. -** -** p2 is a ``parallel'' pointer in (what starts as) descriptor space. -** It is used to identify and delimit the runs. -** -** In the heat of determining where q, the greater of the f1/f2 elements, -** belongs in the other list, b, t and p, represent bottom, top and probe -** locations, respectively, in the other list. -** They make convenient temporary pointers in other places. -*/ - -STATIC void -S_qsortsv(pTHX_ gptr *list1, size_t nmemb, SVCOMPARE_t cmp) -{ - int i, run; - int sense; - register gptr *f1, *f2, *t, *b, *p, *tp2, *l1, *l2, *q; - gptr *aux, *list2, *p2, *last; - gptr *base = list1; - gptr *p1; - - if (nmemb <= 1) return; /* sorted trivially */ - New(799,list2,nmemb,gptr); /* allocate auxilliary array */ - aux = list2; - dynprep(aTHX_ list1, list2, nmemb, cmp); - last = PINDEX(list2, nmemb); - while (NEXT(list2) != last) { - /* More than one run remains. Do some merging to reduce runs. */ - l2 = p1 = list1; - for (tp2 = p2 = list2; p2 != last;) { - /* The new first run begins where the old second list ended. - ** Use the p2 ``parallel'' pointer to identify the end of the run. - */ - f1 = l2; - t = NEXT(p2); - f2 = l1 = POTHER(t, list2, list1); - if (t != last) t = NEXT(t); - l2 = POTHER(t, list2, list1); - p2 = t; - while (f1 < l1 && f2 < l2) { - /* If head 1 is larger than head 2, find ALL the elements - ** in list 2 strictly less than head1, write them all, - ** then head 1. Then compare the new heads, and repeat, - ** until one or both lists are exhausted. - ** - ** In all comparisons (after establishing - ** which head to merge) the item to merge - ** (at pointer q) is the first operand of - ** the comparison. When we want to know - ** if ``q is strictly less than the other'', - ** we can't just do - ** cmp(q, other) < 0 - ** because stability demands that we treat equality - ** as high when q comes from l2, and as low when - ** q was from l1. So we ask the question by doing - ** cmp(q, other) <= sense - ** and make sense == 0 when equality should look low, - ** and -1 when equality should look high. - */ - - - if (cmp(aTHX_ *f1, *f2) <= 0) { - q = f2; b = f1; t = l1; - sense = -1; - } else { - q = f1; b = f2; t = l2; - sense = 0; - } - - - /* ramp up - ** - ** Leave t at something strictly - ** greater than q (or at the end of the list), - ** and b at something strictly less than q. - */ - for (i = 1, run = 0 ;;) { - if ((p = PINDEX(b, i)) >= t) { - /* off the end */ - if (((p = PINDEX(t, -1)) > b) && - (cmp(aTHX_ *q, *p) <= sense)) - t = p; - else b = p; - break; - } else if (cmp(aTHX_ *q, *p) <= sense) { - t = p; - break; - } else b = p; - if (++run >= RTHRESH) i += i; - } - - - /* q is known to follow b and must be inserted before t. - ** Increment b, so the range of possibilities is [b,t). - ** Round binary split down, to favor early appearance. - ** Adjust b and t until q belongs just before t. - */ - - b++; - while (b < t) { - p = PINDEX(b, (PNELEM(b, t) - 1) / 2); - if (cmp(aTHX_ *q, *p) <= sense) { - t = p; - } else b = p + 1; - } - - - /* Copy all the strictly low elements */ - - if (q == f1) { - FROMTOUPTO(f2, tp2, t); - *tp2++ = *f1++; - } else { - FROMTOUPTO(f1, tp2, t); - *tp2++ = *f2++; - } - } - - - /* Run out remaining list */ - if (f1 == l1) { - if (f2 < l2) FROMTOUPTO(f2, tp2, l2); - } else FROMTOUPTO(f1, tp2, l1); - p1 = NEXT(p1) = POTHER(tp2, list2, list1); - } - t = list1; - list1 = list2; - list2 = t; - last = PINDEX(list2, nmemb); - } - if (base == list2) { - last = PINDEX(list1, nmemb); - FROMTOUPTO(list1, list2, last); - } - Safefree(aux); - return; -} - - -#ifdef PERL_OBJECT -#undef this -#define this pPerl -#include "XSUB.h" -#endif - - -static I32 -sortcv(pTHXo_ SV *a, SV *b) -{ - dTHR; - I32 oldsaveix = PL_savestack_ix; - I32 oldscopeix = PL_scopestack_ix; - I32 result; - GvSV(PL_firstgv) = a; - GvSV(PL_secondgv) = b; - PL_stack_sp = PL_stack_base; - PL_op = PL_sortcop; - CALLRUNOPS(aTHX); - if (PL_stack_sp != PL_stack_base + 1) - Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); - result = SvIV(*PL_stack_sp); - while (PL_scopestack_ix > oldscopeix) { - LEAVE; - } - leave_scope(oldsaveix); - return result; -} - -static I32 -sortcv_stacked(pTHXo_ SV *a, SV *b) -{ - dTHR; - I32 oldsaveix = PL_savestack_ix; - I32 oldscopeix = PL_scopestack_ix; - I32 result; - AV *av; - -#ifdef USE_THREADS - av = (AV*)PL_curpad[0]; -#else - av = GvAV(PL_defgv); -#endif - - if (AvMAX(av) < 1) { - SV** ary = AvALLOC(av); - if (AvARRAY(av) != ary) { - AvMAX(av) += AvARRAY(av) - AvALLOC(av); - SvPVX(av) = (char*)ary; - } - if (AvMAX(av) < 1) { - AvMAX(av) = 1; - Renew(ary,2,SV*); - SvPVX(av) = (char*)ary; - } - } - AvFILLp(av) = 1; - - AvARRAY(av)[0] = a; - AvARRAY(av)[1] = b; - PL_stack_sp = PL_stack_base; - PL_op = PL_sortcop; - CALLRUNOPS(aTHX); - if (PL_stack_sp != PL_stack_base + 1) - Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); - result = SvIV(*PL_stack_sp); - while (PL_scopestack_ix > oldscopeix) { - LEAVE; - } - leave_scope(oldsaveix); - return result; -} - static I32 -sortcv_xsub(pTHXo_ SV *a, SV *b) -{ - dSP; - I32 oldsaveix = PL_savestack_ix; - I32 oldscopeix = PL_scopestack_ix; - I32 result; - CV *cv=(CV*)PL_sortcop; - - SP = PL_stack_base; - PUSHMARK(SP); - EXTEND(SP, 2); - *++SP = a; - *++SP = b; - PUTBACK; - (void)(*CvXSUB(cv))(aTHXo_ cv); - if (PL_stack_sp != PL_stack_base + 1) - Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); - result = SvIV(*PL_stack_sp); - while (PL_scopestack_ix > oldscopeix) { - LEAVE; - } - leave_scope(oldsaveix); - return result; -} - - -static I32 -sv_ncmp(pTHXo_ SV *a, SV *b) -{ - NV nv1 = SvNV(a); - NV nv2 = SvNV(b); - return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0; -} - -static I32 -sv_i_ncmp(pTHXo_ SV *a, SV *b) -{ - IV iv1 = SvIV(a); - IV iv2 = SvIV(b); - return iv1 < iv2 ? -1 : iv1 > iv2 ? 1 : 0; -} -#define tryCALL_AMAGICbin(left,right,meth,svp) STMT_START { \ - *svp = Nullsv; \ - if (PL_amagic_generation) { \ - if (SvAMAGIC(left)||SvAMAGIC(right))\ - *svp = amagic_call(left, \ - right, \ - CAT2(meth,_amg), \ - 0); \ - } \ - } STMT_END - -static I32 -amagic_ncmp(pTHXo_ register SV *a, register SV *b) -{ - SV *tmpsv; - tryCALL_AMAGICbin(a,b,ncmp,&tmpsv); - if (tmpsv) { - NV d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_ncmp(aTHXo_ a, b); -} - -static I32 -amagic_i_ncmp(pTHXo_ register SV *a, register SV *b) -{ - SV *tmpsv; - tryCALL_AMAGICbin(a,b,ncmp,&tmpsv); - if (tmpsv) { - NV d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_i_ncmp(aTHXo_ a, b); -} - -static I32 -amagic_cmp(pTHXo_ register SV *str1, register SV *str2) -{ - SV *tmpsv; - tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv); - if (tmpsv) { - NV d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_cmp(str1, str2); -} - -static I32 -amagic_cmp_locale(pTHXo_ register SV *str1, register SV *str2) -{ - SV *tmpsv; - tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv); - if (tmpsv) { - NV d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_cmp_locale(str1, str2); -} - -static I32 -run_user_filter(pTHXo_ int idx, SV *buf_sv, int maxlen) +run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen) { SV *datasv = FILTER_DATA(idx); int filter_has_file = IoLINES(datasv); @@ -4290,7 +3650,7 @@ run_user_filter(pTHXo_ int idx, SV *buf_sv, int maxlen) } if (filter_sub && len >= 0) { - djSP; + dSP; int count; ENTER; @@ -4340,18 +3700,3 @@ run_user_filter(pTHXo_ int idx, SV *buf_sv, int maxlen) return len; } -#ifdef PERL_OBJECT - -static I32 -sv_cmp_locale_static(pTHXo_ register SV *str1, register SV *str2) -{ - return sv_cmp_locale(str1, str2); -} - -static I32 -sv_cmp_static(pTHXo_ register SV *str1, register SV *str2) -{ - return sv_cmp(str1, str2); -} - -#endif /* PERL_OBJECT */