diff options
author | Zefram <zefram@fysh.org> | 2011-09-03 14:39:25 +0100 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2011-09-04 15:27:34 +0100 |
commit | 40c2103f9e420138a6aafe8d67a3f96ec99ef46d (patch) | |
tree | ff0244b203335aa52074c12e3ad6e2362e8ebd48 /dist/Carp | |
parent | 634ff085fbbf05cb775b782f4175b761595f6170 (diff) | |
download | perl-40c2103f9e420138a6aafe8d67a3f96ec99ef46d.tar.gz |
improve Carp portability to earlier perls
* avoid vivifying globs in utf8::
* skip caller override completeness check if it would leak
* regularise format of Carp::Heavy for CPAN indexing
Diffstat (limited to 'dist/Carp')
-rw-r--r-- | dist/Carp/lib/Carp.pm | 45 | ||||
-rw-r--r-- | dist/Carp/lib/Carp/Heavy.pm | 5 | ||||
-rw-r--r-- | dist/Carp/t/Carp.t | 40 | ||||
-rw-r--r-- | dist/Carp/t/vivify_gv.t | 16 |
4 files changed, 81 insertions, 25 deletions
diff --git a/dist/Carp/lib/Carp.pm b/dist/Carp/lib/Carp.pm index 52edcd8535..21fbba5421 100644 --- a/dist/Carp/lib/Carp.pm +++ b/dist/Carp/lib/Carp.pm @@ -4,6 +4,26 @@ package Carp; use strict; use warnings; +BEGIN { + no strict "refs"; + if(exists($::{"utf8::"}) && exists($utf8::{"is_utf8"}) && + defined(*{"utf8::is_utf8"}{CODE})) { + *is_utf8 = \&{"utf8::is_utf8"}; + } else { + *is_utf8 = sub { 0 }; + } +} + +BEGIN { + no strict "refs"; + if(exists($::{"utf8::"}) && exists($utf8::{"downgrade"}) && + defined(*{"utf8::downgrade"}{CODE})) { + *downgrade = \&{"utf8::downgrade"}; + } else { + *downgrade = sub {}; + } +} + our $VERSION = '1.22'; our $MaxEvalLen = 0; @@ -82,13 +102,29 @@ sub confess { die longmess @_ } sub carp { warn shortmess @_ } sub cluck { warn longmess @_ } +BEGIN { + if("$]" >= 5.015002 || ("$]" >= 5.014002 && "$]" < 5.015) || + ("$]" >= 5.012005 && "$]" < 5.013)) { + *CALLER_OVERRIDE_CHECK_OK = sub () { 1 }; + } else { + *CALLER_OVERRIDE_CHECK_OK = sub () { 0 }; + } +} + sub caller_info { my $i = shift(@_) + 1; my %call_info; my $cgc = _cgc(); { + # Some things override caller() but forget to implement the + # @DB::args part of it, which we need. We check for this by + # pre-populating @DB::args with a sentinel which no-one else + # has the address of, so that we can detect whether @DB::args + # has been properly populated. However, on earlier versions + # of perl this check tickles a bug in CORE::caller() which + # leaks memory. So we only check on fixed perls. + @DB::args = \$i if CALLER_OVERRIDE_CHECK_OK; package DB; - @DB::args = \$i; # A sentinel, which no-one else has the address of @call_info{ qw(pack file line sub has_args wantarray evaltext is_require) } = $cgc ? $cgc->($i) : caller($i); @@ -101,7 +137,7 @@ sub caller_info { my $sub_name = Carp::get_subname( \%call_info ); if ( $call_info{has_args} ) { my @args; - if ( @DB::args == 1 + if (CALLER_OVERRIDE_CHECK_OK && @DB::args == 1 && ref $DB::args[0] eq ref \$i && $DB::args[0] == \$i ) { @DB::args = (); # Don't let anyone see the address of $i @@ -155,7 +191,7 @@ sub format_arg { # Downgrade, and use [0-9] rather than \d, to avoid loading # Unicode tables, which would be liable to fail if we're # processing a syntax error. - utf8::downgrade($arg, 1) if "$]" >= 5.008; + downgrade($arg, 1); $arg = "'$arg'" unless $arg =~ /^-?[0-9.]+\z/; } else { @@ -165,8 +201,7 @@ sub format_arg { # The following handling of "control chars" is direct from # the original code - it is broken on Unicode though. # Suggestions? - no strict "refs"; - defined(*{"utf8::is_utf8"}{CODE}) && utf8::is_utf8($arg) + is_utf8($arg) or $arg =~ s/([[:cntrl:]]|[[:^ascii:]])/sprintf("\\x{%x}",ord($1))/eg; return $arg; } diff --git a/dist/Carp/lib/Carp/Heavy.pm b/dist/Carp/lib/Carp/Heavy.pm index 38f95d8a5a..83af3fef95 100644 --- a/dist/Carp/lib/Carp/Heavy.pm +++ b/dist/Carp/lib/Carp/Heavy.pm @@ -1,7 +1,6 @@ -package Carp; +package Carp::Heavy; -# On one line so MakeMaker will see it. -use Carp; our $VERSION = $Carp::VERSION; +our $VERSION = '1.22'; 1; diff --git a/dist/Carp/t/Carp.t b/dist/Carp/t/Carp.t index 9dd5a125fd..edb4020192 100644 --- a/dist/Carp/t/Carp.t +++ b/dist/Carp/t/Carp.t @@ -317,7 +317,9 @@ cluck_undef( 0, "undef", 2, undef, 4 ); # check that Carp respects CORE::GLOBAL::caller override after Carp # has been compiled -for my $bodge_job ( 2, 1, 0 ) { +for my $bodge_job ( 2, 1, 0 ) { SKIP: { + skip "can't safely detect incomplete caller override on perl $]", 6 + if $bodge_job && !Carp::CALLER_OVERRIDE_CHECK_OK; print '# ', ( $bodge_job ? 'Not ' : '' ), "setting \@DB::args in caller override\n"; if ( $bodge_job == 1 ) { @@ -365,24 +367,28 @@ for my $bodge_job ( 2, 1, 0 ) { $got, qr!A::long\($arg\) called at.+\b(?i:carp\.t) line \d+!, 'Correct arguments for A' ); -} - -eval <<'EOT'; -no warnings 'redefine'; -sub CORE::GLOBAL::caller { - my $height = $_[0]; - $height++; - return CORE::caller($height); -} -EOT +} } + +SKIP: { + skip "can't safely detect incomplete caller override on perl $]", 1 + unless Carp::CALLER_OVERRIDE_CHECK_OK; + eval q{ + no warnings 'redefine'; + sub CORE::GLOBAL::caller { + my $height = $_[0]; + $height++; + return CORE::caller($height); + } + }; -my $got = A::long(42); + my $got = A::long(42); -like( - $got, - qr!A::long\(\Q** Incomplete caller override detected; \E\@DB::args\Q were not set **\E\) called at.+\b(?i:carp\.t) line \d+!, - 'Correct arguments for A' -); + like( + $got, + qr!A::long\(\Q** Incomplete caller override detected; \E\@DB::args\Q were not set **\E\) called at.+\b(?i:carp\.t) line \d+!, + 'Correct arguments for A' + ); +} # UTF8-flagged strings should not cause Carp to try to load modules (even # implicitly via utf8_heavy.pl) after a syntax error [perl #82854]. diff --git a/dist/Carp/t/vivify_gv.t b/dist/Carp/t/vivify_gv.t new file mode 100644 index 0000000000..fdc018324b --- /dev/null +++ b/dist/Carp/t/vivify_gv.t @@ -0,0 +1,16 @@ +use warnings; +use strict; + +our $has_is_utf8; +BEGIN { $has_is_utf8 = exists($utf8::{"is_utf8"}); } + +our $has_downgrade; +BEGIN { $has_downgrade = exists($utf8::{"downgrade"}); } + +use Test::More tests => 3; + +BEGIN { use_ok "Carp"; } +ok(!(exists($utf8::{"is_utf8"}) xor $has_is_utf8)); +ok(!(exists($utf8::{"downgrade"}) xor $has_downgrade)); + +1; |