two s/// bugfixes
Rafael Garcia-Suarez [Wed, 10 Oct 2001 17:23:44 +0000 (19:23 +0200)]
Message-Id: <20011010172344.C22440@rafael>

p4raw-id: //depot/perl@12392

pp_ctl.c
regexec.c
t/op/subst.t

index b14e27f..09c1a19 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -172,6 +172,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");
 
@@ -213,6 +214,7 @@ PP(pp_substcont)
            POPSUBST(cx);
            RETURNOP(pm->op_next);
        }
+       cx->sb_iters = saviters;
     }
     if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) {
        m = s;
index 58a7808..d65d70c 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -2536,11 +2536,18 @@ S_regmatch(pTHX_ regnode *prog)
            PL_curpad = AvARRAY((AV*)PL_regdata->data[n + 2]);
            PL_regendp[0] = PL_reg_magic->mg_len = locinput - PL_bostr;
 
-           CALLRUNOPS(aTHX);                   /* Scalar context. */
-           SPAGAIN;
-           ret = POPs;
-           PUTBACK;
-       
+           {
+               SV **before = SP;
+               CALLRUNOPS(aTHX);                       /* Scalar context. */
+               SPAGAIN;
+               if (SP == before)
+                   ret = Nullsv;   /* protect against empty (?{}) blocks. */
+               else {
+                   ret = POPs;
+                   PUTBACK;
+               }
+           }
+
            PL_op = oop;
            PL_curpad = ocurpad;
            PL_curcop = ocurcop;
index 10ad7fe..e5eb85b 100755 (executable)
@@ -7,7 +7,7 @@ BEGIN {
 }
 
 require './test.pl';
-plan( tests => 86 );
+plan( tests => 87 );
 
 $x = 'foo';
 $_ = "x";
@@ -298,7 +298,11 @@ s{  \d+          \b [,.;]? (?{ 'digits' })
     [^A-Za-z0-9\s]+          (?{ '$@%#' })
 }{$^R}xg;
 ok( $_ eq $foo );
-ok( $snum == 31, "# TODO \$snum == $snum, should be 31" );
+ok( $snum == 31 );
+
+$_ = 'a' x 6;
+$snum = s/a(?{})//g;
+ok( $_ eq '' && $snum == 6 );
 
 $_ = 'x' x 20; 
 $snum = s/(\d*|x)/<$1>/g;