File Coverage

blib/lib/Devel/Trace/Subs.pm
Criterion Covered Total %
statement 101 101 100.0
branch 34 34 100.0
condition 22 30 73.3
subroutine 18 19 94.7
pod 4 4 100.0
total 179 188 95.2


line stmt bran cond sub pod time code
1             package Devel::Trace::Subs;
2 5     5   127903 use 5.008;
  5         19  
3 5     5   23 use strict;
  5         11  
  5         136  
4 5     5   26 use warnings;
  5         12  
  5         145  
5              
6 5     5   4957 use Data::Dumper;
  5         43303  
  5         336  
7 5     5   2911 use Devel::Trace::Subs::HTML qw(html);
  5         16  
  5         498  
8 5     5   3368 use Devel::Trace::Subs::Text qw(text);
  5         19  
  5         342  
9 5     5   40 use Exporter;
  5         12  
  5         201  
10 5     5   5829 use Storable;
  5         19653  
  5         377  
11 5     5   4226 use Symbol qw(delete_package);
  5         5036  
  5         5918  
12              
13             our $VERSION = '0.22';
14              
15             our @ISA = qw(Exporter);
16             our @EXPORT_OK = qw(
17             trace
18             trace_dump
19             install_trace
20             remove_trace
21             );
22              
23             $SIG{INT} = sub { 'this ensures END runs if ^C is pressed'; };
24              
25             sub trace {
26              
27 14 100   14 1 72030 return unless $ENV{DTS_ENABLE};
28              
29 13         23 my $flush_flow = $ENV{DTS_FLUSH_FLOW};
30              
31 13         40 _env();
32              
33 13         29 my $data = _store();
34              
35 13         60 my $flow_count = ++$ENV{DTS_FLOW_COUNT};
36              
37 13   50     97 my $flow = {
38             name => $flow_count,
39             value => (caller(1))[3] || 'main()'
40             };
41              
42 13         24 push @{$data->{flow}}, $flow;
  13         32  
43              
44 13   50     23 push @{$data->{stack}}, {
  13   50     204  
      50        
      50        
      50        
45             in => (caller(1))[3] || '-',
46             package => (caller(1))[0] || '-',
47             sub => (caller(2))[3] || '-',
48             filename => (caller(1))[1] || '-',
49             line => (caller(1))[2] || '-',
50             };
51              
52 13         26 _store($data);
53              
54 13 100       2378 if ($flush_flow){
55 1         9 print "\n** $flow->{name} :: $flow->{value} **\n";
56             }
57              
58 13 100       185 if (defined wantarray){
59 1         3 return $data;
60             }
61             }
62             sub trace_dump {
63              
64 11 100   11 1 489 if (! $ENV{DTS_PID}){
65 1         7 die "\nCan't call trace_dump() without calling trace()\n\n" .
66             'Make sure to set $ENV{DTS_ENABLE} = 1;' . "\n\n";
67             }
68              
69 10         37 my %p = @_;
70              
71 10         20 my $want = $p{want};
72 10         14 my $out_type = $p{type};
73 10         16 my $file = $p{file};
74              
75 10         20 my $data = _store();
76              
77 10 100 100     50 if ($want && $want eq 'stack'){
78 3 100 100     17 if ($out_type && $out_type eq 'html') {
79             html(
80             file => $file,
81             want => $want,
82             data => $data->{stack}
83 1         7 );
84             }
85             else {
86             text(
87             want => 'stack',
88             data => $data->{stack},
89 2         10 file => $file
90             );
91             }
92             }
93 10 100 100     12242 if ($want && $want eq 'flow'){
94 3 100 100     15 if ($out_type && $out_type eq 'html') {
95             html(
96             file => $file,
97             want => $want,
98             data => $data->{flow}
99 1         6 );
100             }
101             else {
102             text(
103             want => 'flow',
104             data => $data->{flow},
105 2         11 file => $file
106             );
107             }
108             }
109 10 100       8207 if (! $want){
110 4 100 100     19 if ($out_type && $out_type eq 'html') {
111 1         6 html(
112             file => $file,
113             data => $data
114             );
115             }
116             else {
117             text(
118             data => {
119             flow => $data->{flow},
120             stack => $data->{stack}
121             },
122 3         21 file => $file
123             );
124             }
125             }
126             }
127             sub install_trace {
128              
129 5     5 1 247055 eval {
130 5         1101 require Devel::Examine::Subs;
131 5         210992 Devel::Examine::Subs->import();
132             };
133              
134 5 100       30 $@ = 1 if $ENV{EVAL_TEST}; # for test coverage
135              
136 5 100       16 if ($@){
137 1         16 die "can't load Devel::Examine::Subs!: $@";
138             }
139              
140 4         14 my %p = @_;
141              
142 4         11 my $file = $p{file};
143 4         7 my $extensions = $p{extensions};
144 4         8 my $inject = $p{inject};
145              
146 4         22 my $des_use = Devel::Examine::Subs->new(file => $file,);
147              
148 3         398 remove_trace(file => $file);
149              
150             # this is a DES pre_proc
151              
152 3         186320 $des_use->inject(inject_use => _inject_use());
153              
154 3         184040 my $des = Devel::Examine::Subs->new(
155             file => $file,
156             extensions => $extensions,
157             );
158              
159 3   33     452 $inject = $p{inject} || _inject_code();
160              
161 3         13 $des->inject(
162             inject_after_sub_def => $inject,
163             );
164            
165             }
166             sub remove_trace {
167            
168 7     7 1 198670 eval {
169 7         1054 require Devel::Examine::Subs;
170 7         200033 Devel::Examine::Subs->import();
171             };
172              
173 7 100       35 $@ = 1 if $ENV{EVAL_TEST}; # for test coverage
174              
175 7 100       25 if ($@){
176 1         15 die "can't load Devel::Examine::Subs!: $@";
177             }
178            
179 6         22 my %p = @_;
180 6         12 my $file = $p{file};
181              
182 6         33 my $des = Devel::Examine::Subs->new( file => $file );
183              
184 5         567 $des->remove(delete => [qr/injected by Devel::Trace::Subs/]);
185             }
186             sub _inject_code {
187             return [
188 3     3   19 'trace() if $ENV{DTS_ENABLE}; # injected by Devel::Trace::Subs',
189             ];
190             }
191             sub _inject_use {
192             return [
193 3     3   22 'use Devel::Trace::Subs qw(trace trace_dump); ' .
194             '# injected by Devel::Trace::Subs',
195             ];
196             }
197             sub _env {
198              
199 13     13   28 my $pid = $$;
200 13         45 $ENV{DTS_PID} = $pid;
201              
202 13         21 return $pid;
203             }
204             sub _store {
205              
206 38     38   850 my $data = shift;
207              
208 38         152 my $store = "DTS_" . join('_', ($$ x 3)) . ".dat";
209              
210 38         128 $ENV{DTS_STORE} = $store;
211              
212 38         45 my $struct;
213              
214 38 100       447 if (-f $store){
215 34         106 $struct = retrieve($store);
216             }
217             else {
218 4         8 $struct = {};
219             }
220              
221 38 100       3446 return $struct if ! $data;
222              
223 14         51 store($data, $store);
224              
225             }
226       0     sub _fold_placeholder {};
227              
228             END {
229 5 100   5   16580 unlink $ENV{DTS_STORE} if $ENV{DTS_STORE};
230             }
231              
232             __END__