Change 33941 by [EMAIL PROTECTED] on 2008/05/27 22:58:13

        Integrate:
        [ 33297]
        Subject: [PATCH] Read-only variable tests
        From: "Jerry D. Hedden" <[EMAIL PROTECTED]>
        Date: Fri, 8 Feb 2008 14:06:41 -0500
        Message-ID: <[EMAIL PROTECTED]>
        
        with one less TODO test
        
        [ 33311]
        Subject: Re: [perl #50706] %^H affecting outside file scopes
        From: Rick Delaney <[EMAIL PROTECTED]>
        Date: Tue, 12 Feb 2008 14:05:22 -0500
        Message-ID: <[EMAIL PROTECTED]>
        
        [ 33312]
        Add missing file to MANIFEST, to go with change #33311
        
        [ 33313]
        Subject: [PATCH t/op/pat.t] Re: [perl #50496] Bug Report: 'keys %+' 
does not return the correct keys.
        From: Abigail <[EMAIL PROTECTED]>
        Date: Thu, 7 Feb 2008 17:53:30 +0100
        Message-ID: <[EMAIL PROTECTED]>
        
        with tweaks (one more test marked TODO)
        
        [ 33317]
        Typo catch, by Abigail
        
        [ 33322]
        Correctly reference count the hints hash
        
        [ 33323]
        Fix macro name in comment
        
        [ 33324]
        Fix perlbug 50114 and document what the code does a bit better
        
        [ 33325]
        Fix bug 50496 -- regcomp.c=~s/lastcloseparen/lastparen/g
        -- lastcloseparen is literally the index of the last paren closed
        -- lastparen is index of the highest index paren that has been closed.
        In nested parens, they will be completely different.
        'ab'=~/(a(b))/ will have: lastparen = 2, lastcloseparen = 1
        'ab'=~/(a)(b)/ will have: lastparen = lastcloseparen = 2
        
        [ 33327]
        Subject: [ patch ] silence 2 possibly uninitialized vars
        From: Jim Cromie <[EMAIL PROTECTED]>
        Date: Sat, 16 Feb 2008 18:02:19 -0700
        Message-ID: <[EMAIL PROTECTED]>

Affected files ...

... //depot/maint-5.10/perl/MANIFEST#26 integrate
... //depot/maint-5.10/perl/lib/Internals.t#2 integrate
... //depot/maint-5.10/perl/op.c#10 integrate
... //depot/maint-5.10/perl/pp_ctl.c#14 integrate
... //depot/maint-5.10/perl/regcomp.c#13 integrate
... //depot/maint-5.10/perl/t/lib/Sans_mypragma.pm#1 branch
... //depot/maint-5.10/perl/t/lib/mypragma.t#2 integrate
... //depot/maint-5.10/perl/t/op/pat.t#9 integrate
... //depot/maint-5.10/perl/t/op/re_tests#4 integrate
... //depot/maint-5.10/perl/toke.c#6 integrate

Differences ...

==== //depot/maint-5.10/perl/MANIFEST#26 (text) ====
Index: perl/MANIFEST
--- perl/MANIFEST#25~33921~     2008-05-24 09:32:36.000000000 -0700
+++ perl/MANIFEST       2008-05-27 15:58:13.000000000 -0700
@@ -3582,6 +3582,7 @@
 t/lib/sample-tests/too_many            Test data for Test::Harness
 t/lib/sample-tests/vms_nit             Test data for Test::Harness
 t/lib/sample-tests/with_comments       Test data for Test::Harness
+t/lib/Sans_mypragma.pm                 Test module for t/lib/mypragma.t
 t/lib/strict/refs              Tests of "use strict 'refs'" for strict.t
 t/lib/strict/subs              Tests of "use strict 'subs'" for strict.t
 t/lib/strict/vars              Tests of "use strict 'vars'" for strict.t

==== //depot/maint-5.10/perl/lib/Internals.t#2 (text) ====
Index: perl/lib/Internals.t
--- perl/lib/Internals.t#1~32694~       2007-12-22 01:23:09.000000000 -0800
+++ perl/lib/Internals.t        2008-05-27 15:58:13.000000000 -0700
@@ -7,39 +7,146 @@
     }
 }
 
-use Test::More tests => 33;
+use Test::More tests => 74;
 
+my $ro_err = qr/^Modification of a read-only value attempted/;
+
+### Read-only scalar
 my $foo;
-my @foo;
-my %foo;
 
 ok( !Internals::SvREADONLY $foo );
+$foo = 3;
+is($foo, 3);
+
 ok(  Internals::SvREADONLY $foo, 1 );
 ok(  Internals::SvREADONLY $foo );
+eval { $foo = 'foo'; };
+like($@, $ro_err, q/Can't modify read-only scalar/);
+eval { undef($foo); };
+like($@, $ro_err, q/Can't undef read-only scalar/);
+is($foo, 3);
+
 ok( !Internals::SvREADONLY $foo, 0 );
 ok( !Internals::SvREADONLY $foo );
+$foo = 'foo';
+is($foo, 'foo');
+
+### Read-only array
+my @foo;
 
 ok( !Internals::SvREADONLY @foo );
[EMAIL PROTECTED] = (1..3);
+is(scalar(@foo), 3);
+is($foo[2], 3);
+
 ok(  Internals::SvREADONLY @foo, 1 );
 ok(  Internals::SvREADONLY @foo );
+eval { undef(@foo); };
+like($@, $ro_err, q/Can't undef read-only array/);
+eval { delete($foo[2]); };
+like($@, $ro_err, q/Can't delete from read-only array/);
+eval { shift(@foo); };
+like($@, $ro_err, q/Can't shift read-only array/);
+eval { push(@foo, 'bork'); };
+like($@, $ro_err, q/Can't push onto read-only array/);
+eval { @foo = qw/foo bar/; };
+like($@, $ro_err, q/Can't reassign read-only array/);
+
 ok( !Internals::SvREADONLY @foo, 0 );
 ok( !Internals::SvREADONLY @foo );
+eval { @foo = qw/foo bar/; };
+is(scalar(@foo), 2);
+is($foo[1], 'bar');
+
+### Read-only array element
 
 ok( !Internals::SvREADONLY $foo[2] );
+$foo[2] = 'baz';
+is($foo[2], 'baz');
+
 ok(  Internals::SvREADONLY $foo[2], 1 );
 ok(  Internals::SvREADONLY $foo[2] );
+
+$foo[0] = 99;
+is($foo[0], 99, 'Rest of array still modifiable');
+
+shift(@foo);
+ok(  Internals::SvREADONLY $foo[1] );
+eval { $foo[1] = 'bork'; };
+like($@, $ro_err, 'Read-only array element moved');
+is($foo[1], 'baz');
+
+ok( !Internals::SvREADONLY $foo[2] );
+$foo[2] = 'qux';
+is($foo[2], 'qux');
+
+unshift(@foo, 'foo');
+ok( !Internals::SvREADONLY $foo[1] );
+ok(  Internals::SvREADONLY $foo[2] );
+
+eval { $foo[2] = 86; };
+like($@, $ro_err, q/Can't modify read-only array element/);
+eval { undef($foo[2]); };
+like($@, $ro_err, q/Can't undef read-only array element/);
+TODO: {
+    local $TODO = 'Due to restricted hashes implementation';
+    eval { delete($foo[2]); };
+    like($@, $ro_err, q/Can't delete read-only array element/);
+}
+
 ok( !Internals::SvREADONLY $foo[2], 0 );
 ok( !Internals::SvREADONLY $foo[2] );
+$foo[2] = 'xyzzy';
+is($foo[2], 'xyzzy');
+
+### Read-only hash
+my %foo;
 
 ok( !Internals::SvREADONLY %foo );
+%foo = ('foo' => 1, 2 => 'bar');
+is(scalar(keys(%foo)), 2);
+is($foo{'foo'}, 1);
+
 ok(  Internals::SvREADONLY %foo, 1 );
 ok(  Internals::SvREADONLY %foo );
+eval { undef(%foo); };
+like($@, $ro_err, q/Can't undef read-only hash/);
+TODO: {
+    local $TODO = 'Due to restricted hashes implementation';
+    eval { %foo = ('ping' => 'pong'); };
+    like($@, $ro_err, q/Can't modify read-only hash/);
+}
+eval { $foo{'baz'} = 123; };
+like($@, qr/Attempt to access disallowed key/, q/Can't add to a read-only 
hash/);
+
+# These ops are allow for Hash::Util functionality
+$foo{2} = 'qux';
+is($foo{2}, 'qux', 'Can modify elements in a read-only hash');
+my $qux = delete($foo{2});
+ok(! exists($foo{2}), 'Can delete keys from a read-only hash');
+is($qux, 'qux');
+$foo{2} = 2;
+is($foo{2}, 2, 'Can add back deleted keys in a read-only hash');
+
 ok( !Internals::SvREADONLY %foo, 0 );
 ok( !Internals::SvREADONLY %foo );
 
+### Read-only hash values
+
 ok( !Internals::SvREADONLY $foo{foo} );
+$foo{'foo'} = 'bar';
+is($foo{'foo'}, 'bar');
+
 ok(  Internals::SvREADONLY $foo{foo}, 1 );
 ok(  Internals::SvREADONLY $foo{foo} );
+eval { $foo{'foo'} = 88; };
+like($@, $ro_err, q/Can't modify a read-only hash value/);
+eval { undef($foo{'foo'}); };
+like($@, $ro_err, q/Can't undef a read-only hash value/);
+my $bar = delete($foo{'foo'});
+ok(! exists($foo{'foo'}), 'Can delete a read-only hash value');
+is($bar, 'bar');
+
 ok( !Internals::SvREADONLY $foo{foo}, 0 );
 ok( !Internals::SvREADONLY $foo{foo} );
 

==== //depot/maint-5.10/perl/op.c#10 (text) ====
Index: perl/op.c
--- perl/op.c#9~33895~  2008-05-21 00:11:50.000000000 -0700
+++ perl/op.c   2008-05-27 15:58:13.000000000 -0700
@@ -90,7 +90,7 @@
    magic type 'H'. This magic (itself) does nothing, but its presence causes
    the values to gain magic type 'h', which has entries for set and clear.
    C<Perl_magic_sethint> updates C<PL_compiling.cop_hints_hash> with a store
-   record, with deletes written by C<Perl_magic_clearhint>. C<SAVE_HINTS>
+   record, with deletes written by C<Perl_magic_clearhint>. C<SAVEHINTS>
    saves the current C<PL_compiling.cop_hints_hash> on the save stack, so that
    it will be correctly restored when any inner compiling scope is exited.
 */

==== //depot/maint-5.10/perl/pp_ctl.c#14 (text) ====
Index: perl/pp_ctl.c
--- perl/pp_ctl.c#13~33857~     2008-05-18 12:29:48.000000000 -0700
+++ perl/pp_ctl.c       2008-05-27 15:58:13.000000000 -0700
@@ -3485,6 +3485,11 @@
 
     SAVEHINTS();
     PL_hints = 0;
+    if (PL_compiling.cop_hints_hash) {
+       Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash);
+       PL_compiling.cop_hints_hash = NULL;
+    }
+
     SAVECOMPILEWARNINGS();
     if (PL_dowarn & G_WARN_ALL_ON)
         PL_compiling.cop_warnings = pWARN_ALL ;

==== //depot/maint-5.10/perl/regcomp.c#13 (text) ====
Index: perl/regcomp.c
--- perl/regcomp.c#12~33884~    2008-05-20 08:07:58.000000000 -0700
+++ perl/regcomp.c      2008-05-27 15:58:13.000000000 -0700
@@ -4422,7 +4422,17 @@
         regnode *first= scan;
         regnode *first_next= regnext(first);
        
-       /* Skip introductions and multiplicators >= 1. */
+       /*
+        * Skip introductions and multiplicators >= 1
+        * so that we can extract the 'meat' of the pattern that must 
+        * match in the large if() sequence following.
+        * NOTE that EXACT is NOT covered here, as it is normally
+        * picked up by the optimiser separately. 
+        *
+        * This is unfortunate as the optimiser isnt handling lookahead
+        * properly currently.
+        *
+        */
        while ((OP(first) == OPEN && (sawopen = 1)) ||
               /* An OR of *one* alternative - should not happen now. */
            (OP(first) == BRANCH && OP(first_next) != BRANCH) ||
@@ -4434,16 +4444,17 @@
            (PL_regkind[OP(first)] == CURLY && ARG1(first) > 0) ||
            (OP(first) == NOTHING && PL_regkind[OP(first_next)] != END ))
        {
-               
+               /* 
+                * the only op that could be a regnode is PLUS, all the rest
+                * will be regnode_1 or regnode_2.
+                *
+                */
                if (OP(first) == PLUS)
                    sawplus = 1;
                else
                    first += regarglen[OP(first)];
-               if (OP(first) == IFMATCH) {
-                   first = NEXTOPER(first);
-                   first += EXTRA_STEP_2ARGS;
-               } else  /* XXX possible optimisation for /(?=)/  */
-                   first = NEXTOPER(first);
+               
+               first = NEXTOPER(first);
                first_next= regnext(first);
        }
 
@@ -4974,6 +4985,8 @@
 SV*
 Perl_reg_named_buff_nextkey(pTHX_ REGEXP * const rx, const U32 flags)
 {
+    GET_RE_DEBUG_FLAGS_DECL;
+
     if (rx && RXp_PAREN_NAMES(rx)) {
         HV *hv = RXp_PAREN_NAMES(rx);
         HE *temphe;
@@ -4983,7 +4996,7 @@
             SV* sv_dat = HeVAL(temphe);
             I32 *nums = (I32*)SvPVX(sv_dat);
             for ( i = 0; i < SvIVX(sv_dat); i++ ) {
-                if ((I32)(rx->lastcloseparen) >= nums[i] &&
+                if ((I32)(rx->lastparen) >= nums[i] &&
                     rx->offs[nums[i]].start != -1 &&
                     rx->offs[nums[i]].end != -1)
                 {
@@ -5037,7 +5050,7 @@
             SV* sv_dat = HeVAL(temphe);
             I32 *nums = (I32*)SvPVX(sv_dat);
             for ( i = 0; i < SvIVX(sv_dat); i++ ) {
-                if ((I32)(rx->lastcloseparen) >= nums[i] &&
+                if ((I32)(rx->lastparen) >= nums[i] &&
                     rx->offs[nums[i]].start != -1 &&
                     rx->offs[nums[i]].end != -1)
                 {

==== //depot/maint-5.10/perl/t/lib/Sans_mypragma.pm#1 (text) ====
Index: perl/t/lib/Sans_mypragma.pm
--- /dev/null   2008-05-07 15:08:24.549929899 -0700
+++ perl/t/lib/Sans_mypragma.pm 2008-05-27 15:58:13.000000000 -0700
@@ -0,0 +1,7 @@
+package Sans_mypragma;
+
+sub affected {
+    mypragma::in_effect();
+}
+
+1;

==== //depot/maint-5.10/perl/t/lib/mypragma.t#2 (text) ====
Index: perl/t/lib/mypragma.t
--- perl/t/lib/mypragma.t#1~32694~      2007-12-22 01:23:09.000000000 -0800
+++ perl/t/lib/mypragma.t       2008-05-27 15:58:13.000000000 -0700
@@ -7,7 +7,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 13;
+use Test::More tests => 14;
 
 use mypragma (); # don't enable this pragma yet
 
@@ -22,7 +22,10 @@
        or die $@;
 
     use mypragma;
+    use Sans_mypragma;
     is(mypragma::in_effect(), 42, "pragma is in effect within this block");
+    is(Sans_mypragma::affected(), undef,
+       "pragma not in effect outside this file");
     eval qq{is(mypragma::in_effect(), 42,
               "pragma is in effect within this eval"); 1} or die $@;
 

==== //depot/maint-5.10/perl/t/op/pat.t#9 (xtext) ====
Index: perl/t/op/pat.t
--- perl/t/op/pat.t#8~33920~    2008-05-24 09:04:48.000000000 -0700
+++ perl/t/op/pat.t     2008-05-27 15:58:13.000000000 -0700
@@ -3787,6 +3787,45 @@
     ok(!$@,'lvalue $+{...} should not throw an exception');
 }
 {
+    #
+    # Almost the same as the block above, except that the capture is nested.
+    #
+    my $s = 'foo bar baz';
+    my (@k,@v,@fetch,$res);
+    my $count = 0;
+    my @names = qw($+{A} $+{B} $+{C} $+{D});
+    if ($s =~ /(?<D>(?<A>foo)\s+(?<B>bar)?\s+(?<C>baz))/) {
+       while (my ($k,$v) = each(%+)) {
+           $count++;
+       }
+       @k = sort keys(%+);
+       @v = sort values(%+);
+       $res = 1;
+       push @fetch,
+           [ "$+{A}", "$2" ],
+           [ "$+{B}", "$3" ],
+           [ "$+{C}", "$4" ],
+           [ "$+{D}", $1 ],
+       ;
+    }
+    foreach (0..3) {
+       if ($fetch[$_]) {
+           iseq($fetch[$_][0],$fetch[$_][1],$names[$_]);
+       } else {
+           ok(0, $names[$_]);
+       }
+    }
+    iseq($res,1,"$s~=/(?<D>(?<A>foo)\s+(?<B>bar)?\s+(?<C>baz))/");
+    iseq($count,4,"Got 4 keys in %+ via each -- bug 50496");
+    iseq([EMAIL PROTECTED], 4, 'Got 4 keys in %+ via keys -- bug 50496');
+    iseq("@k","A B C D", "Got expected keys -- bug 50496");
+    iseq("@v","bar baz foo foo bar baz", "Got expected values -- bug = 50496");
+    eval'
+       print for $+{this_key_doesnt_exist};
+    ';
+    ok(!$@,'lvalue $+{...} should not throw an exception');
+}
+{
     my $s='foo bar baz';
     my @res;
     if ('1234'=~/(?<A>1)(?<B>2)(?<A>3)(?<B>4)/) {
@@ -4679,7 +4718,7 @@
 
 # Don't forget to update this!
 BEGIN {
-    $::TestCount = 4024;
+    $::TestCount = 4034;
     print "1..$::TestCount\n";
 }
 

==== //depot/maint-5.10/perl/t/op/re_tests#4 (text) ====
Index: perl/t/op/re_tests
--- perl/t/op/re_tests#3~33920~ 2008-05-24 09:04:48.000000000 -0700
+++ perl/t/op/re_tests  2008-05-27 15:58:13.000000000 -0700
@@ -1341,3 +1341,6 @@
 .*\z   foo\n   y       -       -
 ^(?:(\d)x)?\d$ 1       y       ${\(defined($1)?1:0)}   0       
 .*?(?:(\w)|(\w))x      abx     y       $1-$2   b-
+
+0{50}  000000000000000000000000000000000000000000000000000     y       -       
-
+

==== //depot/maint-5.10/perl/toke.c#6 (text) ====
Index: perl/toke.c
--- perl/toke.c#5~33940~        2008-05-27 13:57:19.000000000 -0700
+++ perl/toke.c 2008-05-27 15:58:13.000000000 -0700
@@ -6614,7 +6614,7 @@
                    (*s == ':' && s[1] == ':'))
                {
 #ifdef PERL_MAD
-                   SV *nametoke;
+                   SV *nametoke = NULL;
 #endif
 
                    PL_expect = XBLOCK;
@@ -12290,8 +12290,8 @@
     bool eofmt = FALSE;
 #ifdef PERL_MAD
     char *tokenstart = s;
-    SV* savewhite;
-    
+    SV* savewhite = NULL;
+
     if (PL_madskills) {
        savewhite = PL_thiswhite;
        PL_thiswhite = 0;
End of Patch.

Reply via email to