| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Attribute::Handlers::Clean; | 
| 2 | 4 |  |  | 4 |  | 208590 | use 5.006; | 
|  | 4 |  |  |  |  | 36 |  | 
| 3 | 4 |  |  | 4 |  | 23 | use Carp; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 284 |  | 
| 4 | 4 |  |  | 4 |  | 26 | use warnings; | 
|  | 4 |  |  |  |  | 7 |  | 
|  | 4 |  |  |  |  | 144 |  | 
| 5 | 4 |  |  | 4 |  | 23 | use strict; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 450 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | our $VERSION = '1.02'; # remember to update version in POD! | 
| 8 |  |  |  |  |  |  | our $AUTOLOAD; | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | my %symcache; | 
| 11 |  |  |  |  |  |  | sub findsym { | 
| 12 | 74 |  |  | 74 | 1 | 154 | my ($pkg, $ref, $type) = @_; | 
| 13 | 74 | 100 |  |  |  | 278 | return $symcache{$pkg,$ref} if $symcache{$pkg,$ref}; | 
| 14 | 73 |  | 33 |  |  | 334 | $type ||= ref($ref); | 
| 15 | 4 |  |  | 4 |  | 29 | no strict 'refs'; | 
|  | 4 |  |  |  |  | 6 |  | 
|  | 4 |  |  |  |  | 424 |  | 
| 16 | 73 |  |  |  |  | 111 | my $symtab = \%{$pkg."::"}; | 
|  | 73 |  |  |  |  | 238 |  | 
| 17 | 73 |  |  |  |  | 1861 | for (keys %$symtab) { | 
| 18 | 5393 |  |  |  |  | 9249 | for my $sym ($$symtab{$_}) { | 
| 19 | 5393 | 100 | 100 |  |  | 9772 | if (ref $sym && $sym == $ref) { | 
| 20 | 8 |  |  |  |  | 16 | return $symcache{$pkg,$ref} = \*{"$pkg:\:$_"}; | 
|  | 8 |  |  |  |  | 125 |  | 
| 21 |  |  |  |  |  |  | } | 
| 22 | 4 |  |  | 4 |  | 25 | use strict; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 1576 |  | 
| 23 | 5385 | 100 |  |  |  | 9600 | next unless ref (\$sym) eq 'GLOB'; | 
| 24 |  |  |  |  |  |  | return $symcache{$pkg,$ref} = \$sym | 
| 25 | 5371 | 100 | 100 |  |  | 7048 | if *{$sym}{$type} && *{$sym}{$type} == $ref; | 
|  | 5371 |  |  |  |  | 16231 |  | 
|  | 2660 |  |  |  |  | 11551 |  | 
| 26 |  |  |  |  |  |  | } | 
| 27 |  |  |  |  |  |  | } | 
| 28 |  |  |  |  |  |  | } | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | my %validtype = ( | 
| 31 |  |  |  |  |  |  | VAR		=> [qw[SCALAR ARRAY HASH]], | 
| 32 |  |  |  |  |  |  | ANY		=> [qw[SCALAR ARRAY HASH CODE]], | 
| 33 |  |  |  |  |  |  | ""		=> [qw[SCALAR ARRAY HASH CODE]], | 
| 34 |  |  |  |  |  |  | SCALAR	=> [qw[SCALAR]], | 
| 35 |  |  |  |  |  |  | ARRAY	=> [qw[ARRAY]], | 
| 36 |  |  |  |  |  |  | HASH	=> [qw[HASH]], | 
| 37 |  |  |  |  |  |  | CODE	=> [qw[CODE]], | 
| 38 |  |  |  |  |  |  | ); | 
| 39 |  |  |  |  |  |  | my %lastattr; | 
| 40 |  |  |  |  |  |  | my @declarations; | 
| 41 |  |  |  |  |  |  | my %raw; | 
| 42 |  |  |  |  |  |  | my %phase; | 
| 43 |  |  |  |  |  |  | my %sigil = (SCALAR=>'$', ARRAY=>'@', HASH=>'%'); | 
| 44 |  |  |  |  |  |  | my $global_phase = 0; | 
| 45 |  |  |  |  |  |  | my %global_phases = ( | 
| 46 |  |  |  |  |  |  | BEGIN	=> 0, | 
| 47 |  |  |  |  |  |  | CHECK	=> 1, | 
| 48 |  |  |  |  |  |  | INIT	=> 2, | 
| 49 |  |  |  |  |  |  | END		=> 3, | 
| 50 |  |  |  |  |  |  | ); | 
| 51 |  |  |  |  |  |  | my @global_phases = qw(BEGIN CHECK INIT END); | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | sub _usage_AH_ { | 
| 54 | 0 |  |  | 0 |  | 0 | croak "Usage: use $_[0] autotie => {AttrName => TieClassName,...}"; | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | my $qual_id = qr/^[_a-z]\w*(::[_a-z]\w*)*$/i; | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | sub import { | 
| 60 | 7 |  |  | 7 |  | 1096 | my $class = shift @_; | 
| 61 |  |  |  |  |  |  | { | 
| 62 | 7 |  |  |  |  | 14 | my @caller_0 = caller 0; | 
|  | 7 |  |  |  |  | 42 |  | 
| 63 | 7 |  |  |  |  | 33 | my @caller_1 = caller 1; | 
| 64 |  |  |  |  |  |  | # Allow just calling "package->import" inside of subclses own import method, to mean their caller should get the same import effect from this module - in the same style of warnings->unimport | 
| 65 | 7 | 50 | 33 |  |  | 55 | my $caller = (@caller_1 and $caller_1[3] eq "$caller_0[0]::import") ? $caller_1[0] : $caller_0[0]; | 
| 66 | 4 |  |  | 4 |  | 31 | no strict 'refs'; | 
|  | 4 |  |  |  |  | 9 |  | 
|  | 4 |  |  |  |  | 2466 |  | 
| 67 | 7 |  |  |  |  | 95 | warnings->unimport('reserved'); | 
| 68 | 7 | 100 | 66 |  |  | 33 | push (@{"${caller}::ISA"}, $class) unless $caller eq $class or grep {$_ eq $class} @{"${caller}::ISA"}; | 
|  | 6 |  |  |  |  | 88 |  | 
|  | 3 |  |  |  |  | 12 |  | 
|  | 7 |  |  |  |  | 44 |  | 
| 69 | 7 |  |  |  |  | 16 | for (@{$validtype{ANY}}) { | 
|  | 7 |  |  |  |  | 33 |  | 
| 70 | 28 | 100 |  |  |  | 42 | *{"${caller}::MODIFY_${_}_ATTRIBUTES"} = _gen_handler_AH_() unless defined *{"${caller}::MODIFY_${_}_ATTRIBUTES"}; | 
|  | 20 |  |  |  |  | 94 |  | 
|  | 28 |  |  |  |  | 130 |  | 
| 71 |  |  |  |  |  |  | } | 
| 72 |  |  |  |  |  |  | } | 
| 73 | 7 | 100 |  |  |  | 105 | return unless $class eq __PACKAGE__; | 
| 74 | 6 |  |  |  |  | 538 | while (@_) { | 
| 75 | 1 |  |  |  |  | 3 | my $cmd = shift; | 
| 76 | 1 | 50 |  |  |  | 8 | if ($cmd =~ /^autotie((?:ref)?)$/) { | 
| 77 | 1 | 50 |  |  |  | 5 | my $tiedata = ($1 ? '$ref, ' : '') . '@$data'; | 
| 78 | 1 |  |  |  |  | 2 | my $mapping = shift; | 
| 79 | 1 | 50 |  |  |  | 13 | _usage_AH_ $class unless ref($mapping) eq 'HASH'; | 
| 80 | 1 |  |  |  |  | 7 | while (my($attr, $tieclass) = each %$mapping) { | 
| 81 | 3 |  |  |  |  | 24 | $tieclass =~ s/^([_a-z]\w*(::[_a-z]\w*)*)(.*)/$1/is; | 
| 82 | 3 |  | 50 |  |  | 23 | my $args = $3||'()'; | 
| 83 | 3 | 50 | 33 | 1 |  | 241 | _usage_AH_ $class unless $attr =~ $qual_id && $tieclass =~ $qual_id && eval "use base q\0$tieclass\0; 1"; | 
|  | 1 |  | 33 | 1 |  | 9 |  | 
|  | 1 |  |  | 1 |  | 3 |  | 
|  | 1 |  |  |  |  | 45 |  | 
|  | 1 |  |  |  |  | 45 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 38 |  | 
|  | 1 |  |  |  |  | 8 |  | 
| 84 | 3 | 50 |  |  |  | 25 | if ($tieclass->isa('Exporter')) { | 
| 85 | 0 |  |  |  |  | 0 | local $Exporter::ExportLevel = 2; | 
| 86 | 0 |  |  |  |  | 0 | $tieclass->import(eval $args); | 
| 87 |  |  |  |  |  |  | } | 
| 88 | 3 |  |  |  |  | 9 | $attr =~ s/__CALLER__/caller(1)/e; | 
|  | 0 |  |  |  |  | 0 |  | 
| 89 | 3 | 100 |  |  |  | 13 | $attr = caller()."::".$attr unless $attr =~ /::/; | 
| 90 | 3 | 50 |  |  |  | 540 | eval '# line '.__LINE__.' "'.__FILE__.qq{" | 
| 91 | 1 |  |  |  |  | 7 | sub $attr : ATTR(VAR) { | 
|  | 1 |  |  |  |  | 77 |  | 
|  | 1 |  |  |  |  | 2 |  | 
| 92 | 1 |  |  |  |  | 3 | my (\$ref, \$data) = \@_[2,4]; | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 50 |  | 
| 93 | 1 | 50 |  |  |  | 43 | my \$was_arrayref = ref \$data eq 'ARRAY'; | 
|  | 1 | 50 |  |  |  | 3 |  | 
|  | 1 | 50 |  |  |  | 7 |  | 
| 94 | 1 |  | 33 |  |  | 6 | \$data = [ \$data ] unless \$was_arrayref; | 
|  | 1 |  | 33 |  |  | 30 |  | 
|  | 1 |  | 33 |  |  | 2 |  | 
| 95 | 1 | 50 |  |  |  | 2 | my \$type = ref(\$ref)||"value (".(\$ref||"").")"; | 
|  | 1 | 50 |  |  |  | 6 |  | 
|  | 1 | 50 |  |  |  | 31 |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | (\$type eq 'SCALAR') ? | 
| 97 |  |  |  |  |  |  | tie \$\$ref,'$tieclass',$tiedata : | 
| 98 |  |  |  |  |  |  | (\$type eq 'ARRAY') ? | 
| 99 |  |  |  |  |  |  | tie \@\$ref,'$tieclass',$tiedata : | 
| 100 |  |  |  |  |  |  | (\$type eq 'HASH') ? | 
| 101 |  |  |  |  |  |  | tie \%\$ref,'$tieclass',$tiedata : | 
| 102 |  |  |  |  |  |  | die "Can't autotie a \$type\n"; | 
| 103 | 1 |  |  | 1 |  | 7 | } 1 | 
|  | 1 |  |  | 1 |  | 2 |  | 
|  | 1 |  |  | 1 |  | 44 |  | 
|  | 1 |  |  |  |  | 43 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 31 |  | 
|  | 1 |  |  |  |  | 6 |  | 
| 104 |  |  |  |  |  |  | } or die "Internal error: $@"; | 
| 105 |  |  |  |  |  |  | } | 
| 106 |  |  |  |  |  |  | } else { | 
| 107 | 0 |  |  |  |  | 0 | croak "Can't understand $_"; | 
| 108 |  |  |  |  |  |  | } | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | # On older perls, code attribute handlers run before the sub gets placed | 
| 113 |  |  |  |  |  |  | # in its package.  Since the :ATTR handlers need to know the name of the | 
| 114 |  |  |  |  |  |  | # sub they're applied to, the name lookup (via findsym) needs to be | 
| 115 |  |  |  |  |  |  | # delayed: we do it immediately before we might need to find attribute | 
| 116 |  |  |  |  |  |  | # handlers from their name.  However, on newer perls (which fix some | 
| 117 |  |  |  |  |  |  | # problems relating to attribute application), a sub gets placed in its | 
| 118 |  |  |  |  |  |  | # package before its attributes are processed.  In this case, the | 
| 119 |  |  |  |  |  |  | # delayed name lookup might be too late, because the sub we're looking | 
| 120 |  |  |  |  |  |  | # for might have already been replaced.  So we need to detect which way | 
| 121 |  |  |  |  |  |  | # round this perl does things, and time the name lookup accordingly. | 
| 122 |  |  |  |  |  |  | BEGIN { | 
| 123 | 4 |  |  | 4 |  | 773 | my $delayed; | 
| 124 |  |  |  |  |  |  | sub Attribute::Handlers::Clean::_TEST_::MODIFY_CODE_ATTRIBUTES { | 
| 125 |  |  |  |  |  |  | $delayed = \&Attribute::Handlers::Clean::_TEST_::t != $_[1]; | 
| 126 |  |  |  |  |  |  | return (); | 
| 127 |  |  |  |  |  |  | } | 
| 128 | 4 |  |  | 4 |  | 2343 | sub Attribute::Handlers::Clean::_TEST_::t :T { } | 
|  | 4 |  |  |  |  | 4940 |  | 
|  | 4 |  |  |  |  | 24 |  | 
| 129 | 4 |  |  | 100 |  | 27 | *_delayed_name_resolution = sub() { $delayed }; | 
|  | 99 |  |  |  |  | 303 |  | 
| 130 | 4 |  |  |  |  | 32 | undef &Attribute::Handlers::Clean::_TEST_::MODIFY_CODE_ATTRIBUTES; | 
| 131 | 4 |  |  |  |  | 441 | undef &Attribute::Handlers::Clean::_TEST_::t; | 
| 132 |  |  |  |  |  |  | } | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | sub _resolve_lastattr { | 
| 135 | 21 | 50 |  | 22 |  | 47 | return unless $lastattr{ref}; | 
| 136 | 21 | 50 |  |  |  | 62 | my $sym = findsym @lastattr{'pkg','ref'} or die "Internal error: $lastattr{pkg} symbol went missing"; | 
| 137 | 21 |  |  |  |  | 90 | my $name = *{$sym}{NAME}; | 
|  | 21 |  |  |  |  | 52 |  | 
| 138 | 21 | 50 | 66 |  |  | 94 | warn "Declaration of $name attribute in package $lastattr{pkg} may clash with future reserved word\n" if $^W and $name !~ /[A-Z]/; | 
| 139 | 21 |  |  |  |  | 33 | foreach ( @{$validtype{$lastattr{type}}} ) { | 
|  | 21 |  |  |  |  | 68 |  | 
| 140 | 4 |  |  | 4 |  | 29 | no strict 'refs'; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 1713 |  | 
| 141 | 47 |  |  |  |  | 75 | *{"$lastattr{pkg}::_ATTR_${_}_${name}"} = $lastattr{ref}; | 
|  | 47 |  |  |  |  | 227 |  | 
| 142 |  |  |  |  |  |  | } | 
| 143 | 21 |  |  |  |  | 73 | %lastattr = (); | 
| 144 |  |  |  |  |  |  | } | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | sub AUTOLOAD { | 
| 147 | 0 | 0 |  | 1 |  | 0 | return if $AUTOLOAD =~ /::DESTROY$/; | 
| 148 | 0 |  |  |  |  | 0 | my ($class) = $AUTOLOAD =~ m/(.*)::/g; | 
| 149 | 0 | 0 |  |  |  | 0 | $AUTOLOAD =~ m/_ATTR_(.*?)_(.*)/ or croak "Can't locate class method '$AUTOLOAD' via package '$class'"; | 
| 150 | 0 |  |  |  |  | 0 | croak "Attribute handler '$2' doesn't handle $1 attributes"; | 
| 151 |  |  |  |  |  |  | } | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | my $builtin = qr/lvalue|method|locked|unique|shared/; | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | sub _gen_handler_AH_() { | 
| 156 |  |  |  |  |  |  | sub { | 
| 157 | 74 | 50 |  | 74 |  | 17096 | _resolve_lastattr if _delayed_name_resolution; | 
| 158 | 74 |  |  |  |  | 208 | my ($pkg, $ref, @attrs) = @_; | 
| 159 | 74 |  |  |  |  | 287 | my (undef, $filename, $linenum) = caller 2; | 
| 160 | 74 |  |  |  |  | 183 | foreach (@attrs) { | 
| 161 | 75 | 50 |  |  |  | 618 | my ($attr, $data) = /^([a-z_]\w*)(?:[(](.*)[)])?$/is or next; | 
| 162 | 75 | 100 |  |  |  | 230 | if ($attr eq 'ATTR') { | 
| 163 | 4 |  |  | 4 |  | 34 | no strict 'refs'; | 
|  | 4 |  |  |  |  | 7 |  | 
|  | 4 |  |  |  |  | 2624 |  | 
| 164 | 21 |  | 100 |  |  | 53 | $data ||= "ANY"; | 
| 165 | 21 |  |  |  |  | 79 | $raw{$ref} = $data =~ s/\s*,?\s*RAWDATA\s*,?\s*//; | 
| 166 | 21 | 100 |  |  |  | 84 | $phase{$ref}{BEGIN} = 1 if $data =~ s/\s*,?\s*(BEGIN)\s*,?\s*//; | 
| 167 | 21 | 100 |  |  |  | 58 | $phase{$ref}{INIT} = 1 if $data =~ s/\s*,?\s*(INIT)\s*,?\s*//; | 
| 168 | 21 | 100 |  |  |  | 56 | $phase{$ref}{END} = 1 if $data =~ s/\s*,?\s*(END)\s*,?\s*//; | 
| 169 | 21 | 100 | 100 |  |  | 75 | $phase{$ref}{CHECK} = 1 if $data =~ s/\s*,?\s*(CHECK)\s*,?\s*// || ! keys %{$phase{$ref}}; | 
|  | 20 |  |  |  |  | 156 |  | 
| 170 |  |  |  |  |  |  | # Added for cleanup to not pollute next call. | 
| 171 | 21 | 50 |  |  |  | 80 | (%lastattr = ()), croak "Can't have two ATTR specifiers on one subroutine" if keys %lastattr; | 
| 172 | 21 | 50 |  |  |  | 61 | croak "Bad attribute type: ATTR($data)" unless $validtype{$data}; | 
| 173 | 21 |  |  |  |  | 76 | %lastattr=(pkg=>$pkg,ref=>$ref,type=>$data); | 
| 174 | 21 | 50 |  |  |  | 80 | _resolve_lastattr unless _delayed_name_resolution; | 
| 175 |  |  |  |  |  |  | } else { | 
| 176 | 54 |  |  |  |  | 117 | my $type = ref $ref; | 
| 177 | 54 |  |  |  |  | 342 | my $handler = $pkg->can("_ATTR_${type}_${attr}"); | 
| 178 | 54 | 50 |  |  |  | 143 | next unless $handler; | 
| 179 | 54 |  |  |  |  | 228 | my $decl = [$pkg, $ref, $attr, $data, $raw{$handler}, $phase{$handler}, $filename, $linenum]; | 
| 180 | 54 |  |  |  |  | 112 | foreach my $gphase (@global_phases) { | 
| 181 |  |  |  |  |  |  | _apply_handler_AH_($decl,$gphase) | 
| 182 | 216 | 100 |  |  |  | 579 | if $global_phases{$gphase} <= $global_phase; | 
| 183 |  |  |  |  |  |  | } | 
| 184 | 54 | 100 |  |  |  | 119 | if ($global_phase != 0) { | 
| 185 |  |  |  |  |  |  | # if _gen_handler_AH_ is being called after | 
| 186 |  |  |  |  |  |  | # CHECK it's for a lexical, so make sure | 
| 187 |  |  |  |  |  |  | # it didn't want to run anything later | 
| 188 | 35 |  |  |  |  | 82 | local $Carp::CarpLevel = 2; | 
| 189 | 35 | 100 |  |  |  | 475 | carp "Won't be able to apply END handler" if $phase{$handler}{END}; | 
| 190 |  |  |  |  |  |  | } else { | 
| 191 | 19 |  |  |  |  | 99 | push @declarations, $decl | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  | } | 
| 194 | 74 |  |  |  |  | 168 | $_ = undef; | 
| 195 |  |  |  |  |  |  | } | 
| 196 | 73 | 50 |  |  |  | 139 | return grep {defined && !/$builtin/} @attrs; | 
|  | 74 |  |  |  |  | 384 |  | 
| 197 |  |  |  |  |  |  | } | 
| 198 | 20 |  |  | 20 |  | 102 | } | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | sub _apply_handler_AH_ { | 
| 201 | 181 |  |  | 181 |  | 340 | my ($declaration, $phase) = @_; | 
| 202 | 181 |  |  |  |  | 445 | my ($pkg, $ref, $attr, $data, $raw, $handlerphase, $filename, $linenum) = @$declaration; | 
| 203 | 181 | 100 |  |  |  | 1500 | return unless $handlerphase->{$phase}; | 
| 204 |  |  |  |  |  |  | # print STDERR "Handling $attr on $ref in $phase with [$data]\n"; | 
| 205 | 53 |  |  |  |  | 109 | my $type = ref $ref; | 
| 206 | 53 |  |  |  |  | 128 | my $handler = "_ATTR_${type}_${attr}"; | 
| 207 | 53 |  |  |  |  | 122 | my $sym = findsym($pkg, $ref); | 
| 208 | 53 | 50 | 66 |  |  | 441 | $sym ||= $type eq 'CODE' ? 'ANON' : 'LEXICAL'; | 
| 209 | 4 |  |  | 4 |  | 37 | no warnings; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 663 |  | 
| 210 | 53 | 100 | 66 |  |  | 190 | if (!$raw && defined($data)) { | 
| 211 | 45 | 50 |  |  |  | 103 | if ($data ne '') { | 
| 212 | 45 |  |  | 4 |  | 3755 | my $evaled = eval( | 
|  | 4 |  |  | 4 |  | 31 |  | 
|  | 4 |  |  | 4 |  | 8 |  | 
|  | 4 |  |  | 4 |  | 513 |  | 
|  | 4 |  |  | 3 |  | 25 |  | 
|  | 4 |  |  | 3 |  | 8 |  | 
|  | 4 |  |  | 2 |  | 165 |  | 
|  | 4 |  |  | 2 |  | 27 |  | 
|  | 4 |  |  | 2 |  | 11 |  | 
|  | 4 |  |  | 2 |  | 117 |  | 
|  | 4 |  |  | 2 |  | 30 |  | 
|  | 4 |  |  | 2 |  | 19 |  | 
|  | 4 |  |  | 2 |  | 165 |  | 
|  | 3 |  |  | 2 |  | 17 |  | 
|  | 3 |  |  | 2 |  | 333 |  | 
|  | 3 |  |  | 2 |  | 85 |  | 
|  | 3 |  |  | 1 |  | 2080 |  | 
|  | 3 |  |  | 1 |  | 10 |  | 
|  | 3 |  |  | 1 |  | 115 |  | 
|  | 3 |  |  | 1 |  | 18 |  | 
|  | 3 |  |  | 1 |  | 8 |  | 
|  | 3 |  |  | 1 |  | 67 |  | 
|  | 3 |  |  | 1 |  | 20 |  | 
|  | 3 |  |  | 1 |  | 33 |  | 
|  | 3 |  |  | 1 |  | 111 |  | 
|  | 3 |  |  | 1 |  | 346 |  | 
|  | 3 |  |  | 1 |  | 13 |  | 
|  | 3 |  |  | 1 |  | 66 |  | 
|  | 3 |  |  | 1 |  | 15 |  | 
|  | 3 |  |  | 1 |  | 9 |  | 
|  | 3 |  |  | 1 |  | 103 |  | 
|  | 3 |  |  | 1 |  | 17 |  | 
|  | 3 |  |  | 1 |  | 10 |  | 
|  | 3 |  |  | 1 |  | 88 |  | 
|  | 2 |  |  | 1 |  | 14 |  | 
|  | 2 |  |  | 1 |  | 4 |  | 
|  | 2 |  |  | 1 |  | 94 |  | 
|  | 2 |  |  | 1 |  | 15 |  | 
|  | 2 |  |  | 1 |  | 6 |  | 
|  | 2 |  |  | 1 |  | 81 |  | 
|  | 2 |  |  | 1 |  | 41 |  | 
|  | 2 |  |  | 1 |  | 5 |  | 
|  | 2 |  |  | 1 |  | 95 |  | 
|  | 2 |  |  | 1 |  | 34 |  | 
|  | 2 |  |  | 1 |  | 7 |  | 
|  | 2 |  |  | 1 |  | 83 |  | 
|  | 2 |  |  | 1 |  | 12 |  | 
|  | 2 |  |  | 1 |  | 4 |  | 
|  | 2 |  |  | 1 |  | 93 |  | 
|  | 1 |  |  | 1 |  | 6 |  | 
|  | 1 |  |  | 1 |  | 2 |  | 
|  | 1 |  |  | 1 |  | 40 |  | 
|  | 1 |  |  | 1 |  | 7 |  | 
|  | 1 |  |  | 1 |  | 2 |  | 
|  | 1 |  |  | 1 |  | 31 |  | 
|  | 1 |  |  | 1 |  | 6 |  | 
|  | 1 |  |  | 1 |  | 2 |  | 
|  | 1 |  |  | 1 |  | 53 |  | 
|  | 1 |  |  | 1 |  | 7 |  | 
|  | 1 |  |  | 1 |  | 2 |  | 
|  | 1 |  |  | 1 |  | 30 |  | 
|  | 1 |  |  | 1 |  | 6 |  | 
|  | 1 |  |  | 1 |  | 1 |  | 
|  | 1 |  |  | 1 |  | 53 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 33 |  | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 52 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 31 |  | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 51 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 34 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 51 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 30 |  | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 49 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 31 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 38 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 43 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 42 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 30 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 38 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 49 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 40 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 44 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 39 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 43 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 41 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 41 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 42 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 29 |  | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 52 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 29 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 53 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 64 |  | 
|  | 1 |  |  |  |  | 36 |  | 
|  | 1 |  |  |  |  | 45 |  | 
|  | 1 |  |  |  |  | 4 |  | 
|  | 1 |  |  |  |  | 45 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 40 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 40 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 31 |  | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 49 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 31 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 51 |  | 
|  | 1 |  |  |  |  | 8 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 33 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 43 |  | 
|  | 1 |  |  |  |  | 7 |  | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 30 |  | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 56 |  | 
| 213 |  |  |  |  |  |  | " | 
| 214 |  |  |  |  |  |  | package $pkg; | 
| 215 |  |  |  |  |  |  | no warnings; | 
| 216 |  |  |  |  |  |  | no strict; | 
| 217 |  |  |  |  |  |  | local \$SIG{__WARN__}=sub{die}; | 
| 218 |  |  |  |  |  |  | [$data] | 
| 219 |  |  |  |  |  |  | " | 
| 220 |  |  |  |  |  |  | ); | 
| 221 | 45 | 100 |  |  |  | 190 | $data = $evaled unless $@; | 
| 222 |  |  |  |  |  |  | } else { | 
| 223 | 0 |  |  |  |  | 0 | $data = undef; | 
| 224 |  |  |  |  |  |  | } | 
| 225 |  |  |  |  |  |  | } | 
| 226 |  |  |  |  |  |  | $pkg->$handler( | 
| 227 |  |  |  |  |  |  | $sym, | 
| 228 | 53 | 100 | 33 |  |  | 291 | (ref $sym eq 'GLOB' ? *{$sym}{ref $ref} || $ref : $ref), | 
| 229 |  |  |  |  |  |  | $attr, | 
| 230 |  |  |  |  |  |  | $data, | 
| 231 |  |  |  |  |  |  | $phase, | 
| 232 |  |  |  |  |  |  | $filename, | 
| 233 |  |  |  |  |  |  | $linenum, | 
| 234 |  |  |  |  |  |  | ); | 
| 235 | 53 |  |  |  |  | 16131 | return 1; | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | { | 
| 239 | 4 |  |  | 4 |  | 32 | no warnings 'void'; | 
|  | 4 |  |  |  |  | 8 |  | 
|  | 4 |  |  |  |  | 916 |  | 
| 240 |  |  |  |  |  |  | CHECK { | 
| 241 | 4 |  |  | 4 |  | 3014 | $global_phase++; | 
| 242 | 4 | 50 |  |  |  | 14 | _resolve_lastattr if _delayed_name_resolution; | 
| 243 | 4 |  |  |  |  | 617 | foreach my $decl (@declarations) { | 
| 244 | 19 |  |  |  |  | 44 | _apply_handler_AH_($decl, 'CHECK'); | 
| 245 |  |  |  |  |  |  | } | 
| 246 |  |  |  |  |  |  | } | 
| 247 |  |  |  |  |  |  | INIT { | 
| 248 | 4 |  |  | 4 |  | 250 | $global_phase++; | 
| 249 | 4 |  |  |  |  | 17 | foreach my $decl (@declarations) { | 
| 250 | 19 |  |  |  |  | 48 | _apply_handler_AH_($decl, 'INIT'); | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  | } | 
| 253 |  |  |  |  |  |  | } | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  | END { | 
| 256 | 4 |  |  | 4 |  | 2054 | $global_phase++; | 
| 257 | 4 |  |  |  |  | 45 | foreach my $decl (@declarations) { | 
| 258 | 19 |  |  |  |  | 36 | _apply_handler_AH_($decl, 'END'); | 
| 259 |  |  |  |  |  |  | } | 
| 260 |  |  |  |  |  |  | } | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | 1; | 
| 263 |  |  |  |  |  |  |  | 
| 264 |  |  |  |  |  |  | __END__ |