File Coverage

blib/lib/true.pm
Criterion Covered Total %
statement 42 43 97.6
branch 10 14 71.4
condition 5 6 83.3
subroutine 11 11 100.0
pod 0 1 0.0
total 68 75 90.6


line stmt bran cond sub pod time code
1             package true;
2              
3 11     11   103015 use strict;
  11         26  
  11         305  
4 11     11   52 use warnings;
  11         21  
  11         267  
5              
6 11     11   4837 use B::Hooks::OP::Annotation;
  11         6823  
  11         321  
7 11     11   4351 use B::Hooks::OP::Check;
  11         12608  
  11         333  
8 11     11   4806 use Devel::StackTrace;
  11         37282  
  11         312  
9 11     11   74 use XSLoader;
  11         22  
  11         268  
10              
11             # XXX this declaration must be on a single line
12             # https://metacpan.org/pod/version#How-to-declare()-a-dotted-decimal-version
13 11     11   4053 use version 0.77; our $VERSION = version->declare('v1.0.1');
  11         18643  
  11         95  
14              
15             our %TRUE;
16              
17             # set the logger from the first rule which matches the $TRUE_PM_DEBUG
18             # environment variable:
19             #
20             # - warn with a backtrace (cluck) if it's an integer > 1
21             # - warn (without a backtrace) if it's truthy
22             # - otherwise (default), do nothing
23             #
24             our $DEBUG = do {
25             my $debug = $ENV{TRUE_PM_DEBUG} || '0';
26             $debug = $debug =~ /^\d+$/ ? int($debug) : 1;
27             $debug && ($debug > 1 ? do { require Carp; \&Carp::cluck } : sub { warn(@_) });
28             };
29              
30             XSLoader::load(__PACKAGE__, $VERSION);
31              
32             sub _debug($) {
33 45 50   45   107 $DEBUG->(@_, $/) if ($DEBUG);
34             }
35              
36             # return the full path of the file that's currently being compiled.
37             # XXX CopFILE(&PL_compiling) gives the wrong result here (it works in the
38             # OP-checker in the XS).
39             sub ccfile() {
40 64     64 0 115 my ($file, $source, $line);
41 64         241 my $trace = Devel::StackTrace->new;
42              
43             # find the innermost require frame
44             #
45             # for "use Foo::Bar" or "require Foo::Bar", the evaltext contains
46             # "Foo/Bar.pm", and the filename/line refer to the file where the
47             # use/require statement appeared.
48              
49             # work from the innermost frame out
50 64         15564 while (my $frame = $trace->next_frame) {
51 470 100       42482 next unless ($frame->is_require);
52              
53 61         377 my $required = $frame->evaltext;
54              
55 61 50       356 if (defined($file = $INC{$required})) {
56 61         134 $source = $frame->filename;
57 61         461 $line = $frame->line;
58             } else { # shouldn't happen
59 0         0 warn "true: can't find required file ($required) in \%INC";
60             }
61              
62 61         285 last;
63             }
64              
65 64 50       1138 return wantarray ? ($file, $source, $line) : $file;
66             }
67              
68             sub import {
69 56     56   53296 my ($file, $source, $line) = ccfile();
70              
71 56 100 100     935 if (defined($file) && not($TRUE{$file})) {
72 41         80 $TRUE{$file} = 1;
73 41         183 _debug "true: enabling true for $file at $source line $line";
74 41         2896 xs_enter();
75             }
76             }
77              
78             sub unimport {
79 8     8   102 my ($file, $source, $line) = ccfile();
80              
81 8 100 66     194 if (defined($file) && $TRUE{$file}) {
82 4         18 _debug "true: disabling true for $file at $source line $line";
83 4         8 delete $TRUE{$file};
84 4 50       118 xs_leave() unless (%TRUE);
85             }
86             }
87              
88             1;
89              
90             __END__