Perl 5.8.3 patches from the BS2000 port - part 2
[p5sagit/p5-mst-13.2.git] / pp_ctl.c
index 3c08f22..48e3618 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -59,6 +59,7 @@ PP(pp_regcreset)
     /* XXXX Should store the old value to allow for tie/overload - and
        restore in regcomp, where marked with XXXX. */
     PL_reginterp_cnt = 0;
+    TAINT_NOT;
     return NORMAL;
 }
 
@@ -158,14 +159,11 @@ PP(pp_substcont)
     char *orig = cx->sb_orig;
     register REGEXP *rx = cx->sb_rx;
     SV *nsv = Nullsv;
-
-    { 
-      REGEXP *old = PM_GETRE(pm);
-      if(old != rx) {
+    REGEXP *old = PM_GETRE(pm);
+    if(old != rx) {
        if(old) 
-         ReREFCNT_dec(old);
+           ReREFCNT_dec(old);
        PM_SETRE(pm,rx);
-      }
     }
 
     rxres_restore(&cx->sb_rxres, rx);
@@ -258,7 +256,8 @@ PP(pp_substcont)
            sv_pos_b2u(sv, &i);
        mg->mg_len = i;
     }
-    ReREFCNT_inc(rx);
+    if (old != rx)
+       ReREFCNT_inc(rx);
     cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
     rxres_save(&cx->sb_rxres, rx);
     RETURNOP(pm->op_pmreplstart);
@@ -893,6 +892,7 @@ PP(pp_mapstart)
 PP(pp_mapwhile)
 {
     dSP;
+    I32 gimme = GIMME_V;
     I32 items = (SP - PL_stack_base) - *PL_markstack_ptr; /* how many new items */
     I32 count;
     I32 shift;
@@ -903,7 +903,7 @@ PP(pp_mapwhile)
     ++PL_markstack_ptr[-1];
 
     /* if there are new items, push them into the destination list */
-    if (items) {
+    if (items && gimme != G_VOID) {
        /* might need to make room back there first */
        if (items > PL_markstack_ptr[-1] - PL_markstack_ptr[-2]) {
            /* XXX this implementation is very pessimal because the stack
@@ -947,7 +947,6 @@ PP(pp_mapwhile)
 
     /* All done yet? */
     if (PL_markstack_ptr[-1] > *PL_markstack_ptr) {
-       I32 gimme = GIMME_V;
 
        (void)POPMARK;                          /* pop top */
        LEAVE;                                  /* exit outer scope */
@@ -1032,6 +1031,16 @@ PP(pp_flip)
     }
 }
 
+/* This code tries to decide if "$left .. $right" should use the
+   magical string increment, or if the range is numeric (we make
+   an exception for .."0" [#18165]). AMS 20021031. */
+
+#define RANGE_IS_NUMERIC(left,right) ( \
+       SvNIOKp(left)  || (SvOK(left)  && !SvPOKp(left))  || \
+       SvNIOKp(right) || (SvOK(right) && !SvPOKp(right)) || \
+       (looks_like_number(left) && SvPOKp(left) && *SvPVX(left) != '0' && \
+        looks_like_number(right)))
+
 PP(pp_flop)
 {
     dSP;
@@ -1047,15 +1056,7 @@ PP(pp_flop)
        if (SvGMAGICAL(right))
            mg_get(right);
 
-       /* This code tries to decide if "$left .. $right" should use the
-          magical string increment, or if the range is numeric (we make
-          an exception for .."0" [#18165]). AMS 20021031. */
-
-       if (SvNIOKp(left) || !SvPOKp(left) ||
-           SvNIOKp(right) || !SvPOKp(right) ||
-           (looks_like_number(left) && *SvPVX(left) != '0' &&
-            looks_like_number(right)))
-       {
+       if (RANGE_IS_NUMERIC(left,right)) {
            if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
                DIE(aTHX_ "Range iterator outside integer range");
            i = SvIV(left);
@@ -1402,6 +1403,9 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
 
            if (optype == OP_REQUIRE) {
                char* msg = SvPVx(ERRSV, n_a);
+               SV *nsv = cx->blk_eval.old_namesv;
+               (void)hv_store(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv),
+                               &PL_sv_undef, 0);
                DIE(aTHX_ "%sCompilation failed in require",
                    *msg ? msg : "Unknown error\n");
            }
@@ -1767,12 +1771,7 @@ PP(pp_enteriter)
        cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
        if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
            dPOPss;
-           /* See comment in pp_flop() */
-           if (SvNIOKp(sv) || !SvPOKp(sv) ||
-               SvNIOKp(cx->blk_loop.iterary) || !SvPOKp(cx->blk_loop.iterary) ||
-               (looks_like_number(sv) && *SvPVX(sv) != '0' &&
-                looks_like_number((SV*)cx->blk_loop.iterary)))
-           {
+           if (RANGE_IS_NUMERIC(sv,(SV*)cx->blk_loop.iterary)) {
                 if (SvNV(sv) < IV_MIN ||
                     SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
                     DIE(aTHX_ "Range iterator outside integer range");
@@ -1883,6 +1882,7 @@ PP(pp_return)
     switch (CxTYPE(cx)) {
     case CXt_SUB:
        popsub2 = TRUE;
+       cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
        break;
     case CXt_EVAL:
        if (!(PL_in_eval & EVAL_KEEPERR))
@@ -1942,15 +1942,16 @@ PP(pp_return)
     }
     PL_stack_sp = newsp;
 
+    LEAVE;
     /* Stack values are safe: */
     if (popsub2) {
+       cxstack_ix--;
        POPSUB(cx,sv);  /* release CV and @_ ... */
     }
     else
        sv = Nullsv;
     PL_curpm = newpm;  /* ... and pop $1 et al */
 
-    LEAVE;
     LEAVESUB(sv);
     if (clear_errsv)
        sv_setpv(ERRSV,"");
@@ -1985,6 +1986,7 @@ PP(pp_last)
        dounwind(cxix);
 
     POPBLOCK(cx,newpm);
+    cxstack_ix++; /* temporarily protect top context */
     mark = newsp;
     switch (CxTYPE(cx)) {
     case CXt_LOOP:
@@ -2026,6 +2028,8 @@ PP(pp_last)
     SP = newsp;
     PUTBACK;
 
+    LEAVE;
+    cxstack_ix--;
     /* Stack values are safe: */
     switch (pop2) {
     case CXt_LOOP:
@@ -2038,7 +2042,6 @@ PP(pp_last)
     }
     PL_curpm = newpm;  /* ... and pop $1 et al */
 
-    LEAVE;
     LEAVESUB(sv);
     return nextop;
 }
@@ -2673,7 +2676,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     SAVETMPS;
     /* switch to eval mode */
 
-    if (PL_curcop == &PL_compiling) {
+    if (IN_PERL_COMPILETIME) {
        SAVECOPSTASH_FREE(&PL_compiling);
        CopSTASH_set(&PL_compiling, PL_curstash);
     }
@@ -2706,14 +2709,14 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     PL_hints &= HINT_UTF8;
 
     /* we get here either during compilation, or via pp_regcomp at runtime */
-    runtime = PL_op && (PL_op->op_type == OP_REGCOMP);
+    runtime = IN_PERL_RUNTIME;
     if (runtime)
        runcv = find_runcv(NULL);
 
     PL_op = &dummy;
     PL_op->op_type = OP_ENTEREVAL;
     PL_op->op_flags = 0;                       /* Avoid uninit warning. */
-    PUSHBLOCK(cx, CXt_EVAL|(PL_curcop == &PL_compiling ? 0 : CXp_REAL), SP);
+    PUSHBLOCK(cx, CXt_EVAL|(IN_PERL_COMPILETIME ? 0 : CXp_REAL), SP);
     PUSHEVAL(cx, 0, Nullgv);
 
     if (runtime)
@@ -2729,7 +2732,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     /* XXX DAPM do this properly one year */
     *padp = (AV*)SvREFCNT_inc(PL_comppad);
     LEAVE;
-    if (PL_curcop == &PL_compiling)
+    if (IN_PERL_COMPILETIME)
        PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
 #ifdef OP_IN_REGISTER
     op = PL_opsave;
@@ -2838,7 +2841,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
        sv_setpv(ERRSV,"");
     if (yyparse() || PL_error_count || !PL_eval_root) {
        SV **newsp;                     /* Used by POPBLOCK. */
-       PERL_CONTEXT *cx;
+       PERL_CONTEXT *cx = &cxstack[cxstack_ix];
        I32 optype = 0;                 /* Might be reset by POPEVAL. */
        STRLEN n_a;
        
@@ -2857,6 +2860,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
        LEAVE;
        if (optype == OP_REQUIRE) {
            char* msg = SvPVx(ERRSV, n_a);
+           SV *nsv = cx->blk_eval.old_namesv;
+           (void)hv_store(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv),
+                          &PL_sv_undef, 0);
            DIE(aTHX_ "%sCompilation failed in require",
                *msg ? msg : "Unknown error\n");
        }
@@ -3045,9 +3051,12 @@ PP(pp_require)
        DIE(aTHX_ "Null filename used");
     TAINT_PROPER("require");
     if (PL_op->op_type == OP_REQUIRE &&
-      (svp = hv_fetch(GvHVn(PL_incgv), name, len, 0)) &&
-      *svp != &PL_sv_undef)
-       RETPUSHYES;
+       (svp = hv_fetch(GvHVn(PL_incgv), name, len, 0))) {
+       if (*svp != &PL_sv_undef)
+           RETPUSHYES;
+       else
+           DIE(aTHX_ "Compilation failed in require");
+    }
 
     /* prepare to compile file */
 
@@ -3163,6 +3172,7 @@ PP(pp_require)
                                                      PERL_SCRIPT_MODE);
                            }
                        }
+                       SP--;
                    }
 
                    PUTBACK;
@@ -3570,7 +3580,7 @@ S_doparseform(pTHX_ SV *sv)
 
     /* estimate the buffer size needed */
     for (base = s; s <= send; s++) {
-       if (*s == '\n' || *s == '@' || *s == '^')
+       if (*s == '\n' || *s == '\0' || *s == '@' || *s == '^')
            maxops += 10;
     }
     s = base;