Upgrade to Cwd 2.20
[p5sagit/p5-mst-13.2.git] / pp_ctl.c
index ca0ad45..0c1067a 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -187,10 +187,13 @@ PP(pp_substcont)
        {
            SV *targ = cx->sb_targ;
 
-           if (DO_UTF8(dstr) && !SvUTF8(targ))
-               sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv);
-           else
-               sv_catpvn(dstr, s, cx->sb_strend - s);
+           assert(cx->sb_strend >= s);
+           if(cx->sb_strend > s) {
+                if (DO_UTF8(dstr) && !SvUTF8(targ))
+                     sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv);
+                else
+                     sv_catpvn(dstr, s, cx->sb_strend - s);
+           }
            cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
 
 #ifdef PERL_COPY_ON_WRITE
@@ -1058,8 +1061,9 @@ PP(pp_flip)
 #define RANGE_IS_NUMERIC(left,right) ( \
        SvNIOKp(left)  || (SvOK(left)  && !SvPOKp(left))  || \
        SvNIOKp(right) || (SvOK(right) && !SvPOKp(right)) || \
-       (((!SvOK(left) && SvOK(right)) || (looks_like_number(left) && \
-         SvPOKp(left) && *SvPVX(left) != '0')) && looks_like_number(right)))
+       (((!SvOK(left) && SvOK(right)) || ((!SvOK(left) || \
+          looks_like_number(left)) && SvPOKp(left) && *SvPVX(left) != '0')) \
+         && (!SvOK(right) || looks_like_number(right))))
 
 PP(pp_flop)
 {
@@ -1067,9 +1071,9 @@ PP(pp_flop)
 
     if (GIMME == G_ARRAY) {
        dPOPPOPssrl;
-       register I32 i, j;
+       register IV i, j;
        register SV *sv;
-       I32 max;
+       IV max;
 
        if (SvGMAGICAL(left))
            mg_get(left);
@@ -1077,7 +1081,8 @@ PP(pp_flop)
            mg_get(right);
 
        if (RANGE_IS_NUMERIC(left,right)) {
-           if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
+           if ((SvOK(left) && SvNV(left) < IV_MIN) ||
+               (SvOK(right) && SvNV(right) > IV_MAX))
                DIE(aTHX_ "Range iterator outside integer range");
            i = SvIV(left);
            max = SvIV(right);
@@ -1790,24 +1795,37 @@ PP(pp_enteriter)
        cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
        if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
            dPOPss;
-           if (RANGE_IS_NUMERIC(sv,(SV*)cx->blk_loop.iterary)) {
-               if (SvNV(sv) < IV_MIN ||
-                   SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
+           SV *right = (SV*)cx->blk_loop.iterary;
+           if (RANGE_IS_NUMERIC(sv,right)) {
+               if ((SvOK(sv) && SvNV(sv) < IV_MIN) ||
+                   (SvOK(right) && SvNV(right) >= IV_MAX))
                    DIE(aTHX_ "Range iterator outside integer range");
                cx->blk_loop.iterix = SvIV(sv);
-               cx->blk_loop.itermax = SvIV((SV*)cx->blk_loop.iterary);
+               cx->blk_loop.itermax = SvIV(right);
            }
            else {
                STRLEN n_a;
                cx->blk_loop.iterlval = newSVsv(sv);
-               SvPV_force(cx->blk_loop.iterlval,n_a);
+               (void) SvPV_force(cx->blk_loop.iterlval,n_a);
+               (void) SvPV(right,n_a);
            }
        }
+       else if (PL_op->op_private & OPpITER_REVERSED) {
+           cx->blk_loop.itermax = -1;
+           cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary);
+
+       }
     }
     else {
        cx->blk_loop.iterary = PL_curstack;
        AvFILLp(PL_curstack) = SP - PL_stack_base;
-       cx->blk_loop.iterix = MARK - PL_stack_base;
+       if (PL_op->op_private & OPpITER_REVERSED) {
+           cx->blk_loop.itermax = MARK - PL_stack_base;
+           cx->blk_loop.iterix = cx->blk_oldsp;
+       }
+       else {
+           cx->blk_loop.iterix = MARK - PL_stack_base;
+       }
     }
 
     RETURN;
@@ -2325,7 +2343,7 @@ PP(pp_goto)
                else {
                    if (CvDEPTH(cv) == 100 && ckWARN(WARN_RECURSION))
                        sub_crush_depth(cv);
-                   pad_push(padlist, CvDEPTH(cv), cx->blk_sub.hasargs);
+                   pad_push(padlist, CvDEPTH(cv), 1);
                }
                PAD_SET_CUR(padlist, CvDEPTH(cv));
                if (cx->blk_sub.hasargs)
@@ -2774,7 +2792,7 @@ Locate the CV corresponding to the currently executing sub or eval.
 If db_seqp is non_null, skip CVs that are in the DB package and populate
 *db_seqp with the cop sequence number at the point that the DB:: code was
 entered. (allows debuggers to eval in the scope of the breakpoint rather
-than in in the scope of the debuger itself).
+than in in the scope of the debugger itself).
 
 =cut
 */