X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/be708cc0141c68546a70e3d19f68ad41bef15add..c355877e9e68fb3e29329a13c757988acfe97ffd:/pp_ctl.c diff --git a/pp_ctl.c b/pp_ctl.c index 4b81fe5..d461873 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1,6 +1,6 @@ /* pp_ctl.c * - * Copyright (c) 1991-2001, Larry Wall + * Copyright (c) 1991-2002, 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,20 +26,8 @@ #define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o)) -static I32 sortcv(pTHX_ SV *a, SV *b); -static I32 sortcv_stacked(pTHX_ SV *a, SV *b); -static I32 sortcv_xsub(pTHX_ SV *a, SV *b); -static I32 sv_ncmp(pTHX_ SV *a, SV *b); -static I32 sv_i_ncmp(pTHX_ SV *a, SV *b); -static I32 amagic_ncmp(pTHX_ SV *a, SV *b); -static I32 amagic_i_ncmp(pTHX_ SV *a, SV *b); -static I32 amagic_cmp(pTHX_ SV *a, SV *b); -static I32 amagic_cmp_locale(pTHX_ SV *a, SV *b); static I32 run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen); -#define sv_cmp_static Perl_sv_cmp -#define sv_cmp_locale_static Perl_sv_cmp_locale - PP(pp_wantarray) { dSP; @@ -105,7 +93,7 @@ PP(pp_regcomp) /* Check against the last compiled regexp. */ if (!PM_GETRE(pm) || !PM_GETRE(pm)->precomp || - PM_GETRE(pm)->prelen != len || + PM_GETRE(pm)->prelen != (I32)len || memNE(PM_GETRE(pm)->precomp, t, len)) { if (PM_GETRE(pm)) { @@ -170,8 +158,10 @@ PP(pp_substcont) register REGEXP *rx = cx->sb_rx; rxres_restore(&cx->sb_rxres, rx); + PL_reg_match_utf8 = SvUTF8(cx->sb_targ) ? 1 : 0; if (cx->sb_iters++) { + I32 saviters = cx->sb_iters; if (cx->sb_iters > cx->sb_maxiters) DIE(aTHX_ "Substitution loop"); @@ -213,6 +203,7 @@ PP(pp_substcont) POPSUBST(cx); RETURNOP(pm->op_next); } + cx->sb_iters = saviters; } if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) { m = s; @@ -405,7 +396,7 @@ PP(pp_formline) else { sv = &PL_sv_no; if (ckWARN(WARN_SYNTAX)) - Perl_warner(aTHX_ WARN_SYNTAX, "Not enough format arguments"); + Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Not enough format arguments"); } break; @@ -414,7 +405,7 @@ PP(pp_formline) itemsize = len; if (DO_UTF8(sv)) { itemsize = sv_len_utf8(sv); - if (itemsize != len) { + if (itemsize != (I32)len) { I32 itembytes; if (itemsize > fieldsize) { itemsize = fieldsize; @@ -456,7 +447,7 @@ PP(pp_formline) itemsize = len; if (DO_UTF8(sv)) { itemsize = sv_len_utf8(sv); - if (itemsize != len) { + if (itemsize != (I32)len) { I32 itembytes; if (itemsize <= fieldsize) { send = chophere = s + itemsize; @@ -883,179 +874,6 @@ PP(pp_mapwhile) } } -PP(pp_sort) -{ - dSP; dMARK; dORIGMARK; - register SV **up; - SV **myorigmark = ORIGMARK; - register I32 max; - HV *stash; - GV *gv; - CV *cv = 0; - 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_5005THREADS - 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_5005THREADS - cx->blk_sub.savearray = GvAV(PL_defgv); - GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av); -#endif /* USE_5005THREADS */ - 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)) - : ( IN_LOCALE_RUNTIME - ? ( 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) @@ -1078,13 +896,16 @@ PP(pp_flip) else { dTOPss; SV *targ = PAD_SV(PL_op->op_targ); - int flip; + int flip = 0; 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); + if (GvIO(PL_last_in_gv)) { + flip = SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv)); + } + else { + GV *gv = gv_fetchpv(".", TRUE, SVt_PV); + if (gv && GvSV(gv)) flip = SvIV(sv) == SvIV(GvSV(gv)); + } } else { flip = SvTRUE(sv); } @@ -1162,11 +983,23 @@ PP(pp_flop) else { dTOPss; SV *targ = PAD_SV(cUNOP->op_first->op_targ); + int flop = 0; sv_inc(targ); - if ((PL_op->op_private & OPpFLIP_LINENUM) - ? (GvIO(PL_last_in_gv) - && SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv))) - : SvTRUE(sv) ) { + + if (PL_op->op_private & OPpFLIP_LINENUM) { + if (GvIO(PL_last_in_gv)) { + flop = SvIV(sv) == (IV)IoLINES(GvIOp(PL_last_in_gv)); + } + else { + GV *gv = gv_fetchpv(".", TRUE, SVt_PV); + if (gv && GvSV(gv)) flop = SvIV(sv) == SvIV(GvSV(gv)); + } + } + else { + flop = SvTRUE(sv); + } + + if (flop) { sv_setiv(PAD_SV(((UNOP*)cUNOP->op_first)->op_first->op_targ), 0); sv_catpv(targ, "E0"); } @@ -1189,27 +1022,27 @@ S_dopoptolabel(pTHX_ char *label) switch (CxTYPE(cx)) { case CXt_SUBST: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s", OP_NAME(PL_op)); return -1; case CXt_LOOP: @@ -1324,27 +1157,27 @@ S_dopoptoloop(pTHX_ I32 startingblock) switch (CxTYPE(cx)) { case CXt_SUBST: if (ckWARN(WARN_EXITING)) - Perl_warner(aTHX_ WARN_EXITING, "Exiting substitution via %s", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(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", + Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s", OP_NAME(PL_op)); return -1; case CXt_LOOP: @@ -1407,6 +1240,9 @@ OP * Perl_die_where(pTHX_ char *message, STRLEN msglen) { STRLEN n_a; + IO *io; + MAGIC *mg; + if (PL_in_eval) { I32 cxix; register PERL_CONTEXT *cx; @@ -1432,7 +1268,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) sv_catpvn(err, message, msglen); if (ckWARN(WARN_MISC)) { STRLEN start = SvCUR(err)-msglen-sizeof(prefix)+1; - Perl_warner(aTHX_ WARN_MISC, SvPVX(err)+start); + Perl_warner(aTHX_ packWARN(WARN_MISC), SvPVX(err)+start); } } } @@ -1486,7 +1322,19 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen) } if (!message) message = SvPVx(ERRSV, msglen); - { + + /* if STDERR is tied, print to it instead */ + if (PL_stderrgv && (io = GvIOp(PL_stderrgv)) + && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) { + dSP; ENTER; + PUSHMARK(SP); + XPUSHs(SvTIED_obj((SV*)io, mg)); + XPUSHs(sv_2mortal(newSVpvn(message, msglen))); + PUTBACK; + call_method("PRINT", G_SCALAR); + LEAVE; + } + else { #ifdef USE_SFIO /* SFIO can really mess with your errno */ int e = errno; @@ -1597,7 +1445,7 @@ PP(pp_caller) PUSHs(&PL_sv_undef); else PUSHs(sv_2mortal(newSVpv(stashname, 0))); - PUSHs(sv_2mortal(newSVpv(CopFILE(cx->blk_oldcop), 0))); + PUSHs(sv_2mortal(newSVpv(OutCopFILE(cx->blk_oldcop), 0))); PUSHs(sv_2mortal(newSViv((I32)CopLINE(cx->blk_oldcop)))); if (!MAXARG) RETURN; @@ -1712,7 +1560,7 @@ PP(pp_dbstate) register CV *cv; register PERL_CONTEXT *cx; I32 gimme = G_ARRAY; - I32 hasargs; + U8 hasargs; GV *gv; gv = PL_DBgv; @@ -2137,7 +1985,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"; @@ -2322,7 +2170,7 @@ PP(pp_goto) cx->blk_sub.hasargs = 0; } cx->blk_sub.cv = cv; - cx->blk_sub.olddepth = CvDEPTH(cv); + cx->blk_sub.olddepth = (U16)CvDEPTH(cv); CvDEPTH(cv)++; if (CvDEPTH(cv) < 2) (void)SvREFCNT_inc(cv); @@ -2591,6 +2439,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; @@ -2686,6 +2535,7 @@ S_docatch(pTHX_ OP *o) { int ret; OP *oldop = PL_op; + OP *retop; volatile PERL_SI *cursi = PL_curstackinfo; dJMPENV; @@ -2693,6 +2543,15 @@ S_docatch(pTHX_ OP *o) assert(CATCH_GET == TRUE); #endif PL_op = o; + + /* Normally, the leavetry at the end of this block of ops will + * pop an op off the return stack and continue there. By setting + * the op to Nullop, we force an exit from the inner runops() + * loop. DAPM. + */ + retop = pop_return(); + push_return(Nullop); + #ifdef PERL_FLEXIBLE_EXCEPTIONS redo_body: CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_docatch_body)); @@ -2707,11 +2566,15 @@ S_docatch(pTHX_ OP *o) #endif break; case 3: + /* die caught by an inner eval - continue inner loop */ if (PL_restartop && cursi == PL_curstackinfo) { PL_op = PL_restartop; PL_restartop = 0; goto redo_body; } + /* a die in this eval - continue in outer loop */ + if (!PL_restartop) + break; /* FALL THROUGH */ default: JMPENV_POP; @@ -2721,7 +2584,7 @@ S_docatch(pTHX_ OP *o) } JMPENV_POP; PL_op = oldop; - return Nullop; + return retop; } OP * @@ -2793,7 +2656,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, AV** avp) *avp = (AV*)SvREFCNT_inc(PL_comppad); LEAVE; if (PL_curcop == &PL_compiling) - PL_compiling.op_private = PL_hints; + PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK); #ifdef OP_IN_REGISTER op = PL_opsave; #endif @@ -3033,9 +2896,11 @@ PP(pp_require) SV *filter_state = 0; SV *filter_sub = 0; SV *hook_sv = 0; + SV *encoding; + OP *op; sv = POPs; - if (SvNIOKp(sv)) { + if (SvNIOKp(sv) && PL_op->op_type != OP_DOFILE) { if (SvPOK(sv) && SvNOK(sv) && SvNV(sv)) { /* require v5.6.1 */ UV rev = 0, ver = 0, sver = 0; STRLEN len; @@ -3062,7 +2927,7 @@ PP(pp_require) PERL_VERSION, PERL_SUBVERSION); } if (ckWARN(WARN_PORTABLE)) - Perl_warner(aTHX_ WARN_PORTABLE, + Perl_warner(aTHX_ packWARN(WARN_PORTABLE), "v-string in use/require non-portable"); RETPUSHYES; } @@ -3080,11 +2945,11 @@ PP(pp_require) /* help out with the "use 5.6" confusion */ 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".%03"UVuf"?)", - rev, ver, sver, PERL_REVISION, PERL_VERSION, - PERL_SUBVERSION, rev, ver/100); + DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required" + " (did you mean v%"UVuf".%03"UVuf"?)--" + "this is only v%d.%d.%d, stopped", + rev, ver, sver, rev, ver/100, + PERL_REVISION, PERL_VERSION, PERL_SUBVERSION); } else { DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required--" @@ -3107,30 +2972,22 @@ PP(pp_require) /* prepare to compile file */ -#ifdef MACOS_TRADITIONAL - if (PERL_FILE_IS_ABSOLUTE(name) - || (*name == ':' && name[1] != ':' && strchr(name+2, ':'))) - { + if (path_is_absolute(name)) { tryname = name; tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE); - /* We consider paths of the form :a:b ambiguous and interpret them first - as global then as local - */ - if (!tryrsfp && *name == ':' && name[1] != ':' && strchr(name+2, ':')) - goto trylocal; } - 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); +#ifdef MACOS_TRADITIONAL + if (!tryrsfp) { + char newname[256]; + + MacPerl_CanonDir(name, newname, 1); + if (path_is_absolute(newname)) { + tryname = newname; + tryrsfp = doopen_pmc(newname,PERL_SCRIPT_MODE); + } } - else { #endif + if (!tryrsfp) { AV *ar = GvAVn(PL_incgv); I32 i; #ifdef VMS @@ -3253,10 +3110,21 @@ trylocal: { } } else { + if (!path_is_absolute(name) +#ifdef MACOS_TRADITIONAL + /* We consider paths of the form :a:b ambiguous and interpret them first + as global then as local + */ + || (*name == ':' && name[1] != ':' && strchr(name+2, ':')) +#endif + ) { char *dir = SvPVx(dirsv, n_a); #ifdef MACOS_TRADITIONAL - char buf[256]; - Perl_sv_setpvf(aTHX_ namesv, "%s%s", MacPerl_CanonDir(dir, buf), name+(name[0] == ':')); + char buf1[256]; + char buf2[256]; + + MacPerl_CanonDir(name, buf2, 1); + Perl_sv_setpvf(aTHX_ namesv, "%s%s", MacPerl_CanonDir(dir, buf1, 0), buf2+(buf2[0] == ':')); #else #ifdef VMS char *unixdir; @@ -3270,20 +3138,13 @@ trylocal: { #endif TAINT_PROPER("require"); tryname = SvPVX(namesv); -#ifdef MACOS_TRADITIONAL - { - /* Convert slashes in the name part, but not the directory part, to colons */ - char * colon; - for (colon = tryname+strlen(dir); colon = strchr(colon, '/'); ) - *colon++ = ':'; - } -#endif tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE); if (tryrsfp) { if (tryname[0] == '.' && tryname[1] == '/') tryname += 2; break; } + } } } } @@ -3323,10 +3184,14 @@ trylocal: { SETERRNO(0, SS$_NORMAL); /* Assume success here to prevent recursive requirement. */ - (void)hv_store(GvHVn(PL_incgv), name, strlen(name), - (hook_sv ? SvREFCNT_inc(hook_sv) - : 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; @@ -3342,6 +3207,8 @@ trylocal: { 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 PL_compiling.cop_warnings = pWARN_STD ; SAVESPTR(PL_compiling.cop_io); @@ -3372,7 +3239,17 @@ trylocal: { PL_eval_owner = thr; MUTEX_UNLOCK(&PL_eval_mutex); #endif /* USE_5005THREADS */ - return DOCATCH(doeval(gimme, NULL)); + + /* 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) @@ -3457,7 +3334,7 @@ PP(pp_entereval) MUTEX_UNLOCK(&PL_eval_mutex); #endif /* USE_5005THREADS */ ret = doeval(gimme, NULL); - if (PERLDB_INTER && was != PL_sub_generation /* Some subs defined here. */ + if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */ && ret != PL_op->op_next) { /* Successive compilation. */ strcpy(safestr, "_<(eval )"); /* Anything fake and short. */ } @@ -3557,13 +3434,14 @@ PP(pp_leavetry) register SV **mark; SV **newsp; PMOP *newpm; + OP* retop; I32 gimme; register PERL_CONTEXT *cx; I32 optype; POPBLOCK(cx,newpm); POPEVAL(cx); - pop_return(); + retop = pop_return(); TAINT_NOT; if (gimme == G_VOID) @@ -3595,7 +3473,7 @@ PP(pp_leavetry) LEAVE; sv_setpv(ERRSV,""); - RETURN; + RETURNOP(retop); } STATIC void @@ -3654,14 +3532,14 @@ S_doparseform(pTHX_ SV *sv) if (postspace) *fpc++ = FF_SPACE; *fpc++ = FF_LITERAL; - *fpc++ = arg; + *fpc++ = (U16)arg; } postspace = FALSE; if (s <= send) skipspaces--; if (skipspaces) { *fpc++ = FF_SKIP; - *fpc++ = skipspaces; + *fpc++ = (U16)skipspaces; } skipspaces = 0; if (s <= send) @@ -3672,7 +3550,7 @@ S_doparseform(pTHX_ SV *sv) arg = fpc - linepc + 1; else arg = 0; - *fpc++ = arg; + *fpc++ = (U16)arg; } if (s < send) { linepc = fpc; @@ -3695,7 +3573,7 @@ S_doparseform(pTHX_ SV *sv) arg = (s - base) - 1; if (arg) { *fpc++ = FF_LITERAL; - *fpc++ = arg; + *fpc++ = (U16)arg; } base = s - 1; @@ -3720,7 +3598,7 @@ S_doparseform(pTHX_ SV *sv) } *fpc++ = s - base; /* fieldsize for FETCH */ *fpc++ = FF_DECIMAL; - *fpc++ = arg; + *fpc++ = (U16)arg; } else if (*s == '0' && s[1] == '#') { /* Zero padded decimals */ arg = ischop ? 512 : 0; @@ -3738,7 +3616,7 @@ S_doparseform(pTHX_ SV *sv) } *fpc++ = s - base; /* fieldsize for FETCH */ *fpc++ = FF_0DECIMAL; - *fpc++ = arg; + *fpc++ = (U16)arg; } else { I32 prespace = 0; @@ -3767,7 +3645,7 @@ S_doparseform(pTHX_ SV *sv) *fpc++ = ischop ? FF_CHECKCHOP : FF_CHECKNL; if (prespace) - *fpc++ = prespace; + *fpc++ = (U16)prespace; *fpc++ = FF_ITEM; if (ismore) *fpc++ = FF_MORE; @@ -3794,582 +3672,6 @@ S_doparseform(pTHX_ SV *sv) 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 pTHX_ -#define STATIC -#define New(ID,VAR,N,TYPE) VAR=(TYPE *)malloc((N)*sizeof(TYPE)) -#define Safefree(VAR) free(VAR) -typedef int (*SVCOMPARE_t) (pTHX_ 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; -} - -static I32 -sortcv(pTHX_ SV *a, SV *b) -{ - 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(pTHX_ SV *a, SV *b) -{ - I32 oldsaveix = PL_savestack_ix; - I32 oldscopeix = PL_scopestack_ix; - I32 result; - AV *av; - -#ifdef USE_5005THREADS - 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(pTHX_ 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))(aTHX_ 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(pTHX_ 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(pTHX_ 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(pTHX_ 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(aTHX_ a, b); -} - -static I32 -amagic_i_ncmp(pTHX_ 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(aTHX_ a, b); -} - -static I32 -amagic_cmp(pTHX_ 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(pTHX_ 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(pTHX_ int idx, SV *buf_sv, int maxlen) { @@ -4439,3 +3741,22 @@ run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen) 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_ char *name) +{ + if (PERL_FILE_IS_ABSOLUTE(name) +#ifdef MACOS_TRADITIONAL + || (*name == ':')) +#else + || (*name == '.' && (name[1] == '/' || + (name[1] == '.' && name[2] == '/')))) +#endif + { + return TRUE; + } + else + return FALSE; +}