File Coverage

blib/lib/Acme/JavaTrace.pm
Criterion Covered Total %
statement 61 65 93.8
branch 22 26 84.6
condition 14 17 82.3
subroutine 7 8 87.5
pod n/a
total 104 116 89.6


line stmt bran cond sub pod time code
1             package Acme::JavaTrace;
2 5     5   81138 use strict;
  5         14  
  5         194  
3              
4             {
5 5     5   23 no strict;
  5         9  
  5         5264  
6             $VERSION = '0.08';
7             }
8              
9             # Install warn() and die() substitutes
10             $SIG{'__WARN__'} = \&_do_warn;
11             $SIG{'__DIE__' } = \&_do_die;
12              
13             my $stderr = '';
14             my $in_eval = 0;
15             my %options = (
16             showrefs => 0,
17             );
18              
19              
20             #
21             # import()
22             # ------
23             sub import {
24 4     4   39 my $class = shift;
25            
26 4         3700 for my $opt (@_) {
27 1 50       23 exists $options{$opt} ? $options{$opt} = not $options{$opt}
28             : CORE::warn "warning: Unknown option: $opt\n"
29             }
30             }
31              
32              
33             #
34             # _use_data_dumper()
35             # ----------------
36             sub _use_data_dumper {
37 1     1   9 require Data::Dumper;
38 1         42 import Data::Dumper;
39 1         17 $Data::Dumper::Indent = 1; # no fancy indent
40 1         2 $Data::Dumper::Terse = 1; # don't use $VAR unless needed
41 1         2 $Data::Dumper::Sortkeys = 1; # sort keys
42             #$Data::Dumper::Deparse = 1; # deparse code refs
43             {
44 1         1 local $^W = 0;
  1         23  
45 1     0   8 *Devel::SimpleTrace::_use_data_dumper = sub {};
  0         0  
46             }
47             }
48              
49              
50             #
51             # _do_warn()
52             # --------
53             sub _do_warn {
54 1     1   814 local $SIG{'__WARN__'} = 'DEFAULT';
55            
56 1         3 my $msg = join '', @_;
57 1         7 $msg =~ s/ at (.+?) line (\d+)\.$//;
58 1         2 $stderr .= $msg;
59 1 50       6 $stderr .= "\n" if substr($msg, -1, 1) ne "\n";
60            
61 1         6 _stack_trace($1, $2);
62            
63 1         8 print STDERR $stderr;
64 1         9 $stderr = '';
65 1         11 $in_eval = 0;
66             }
67              
68              
69             #
70             # _do_die()
71             # -------
72             sub _do_die {
73 13     13   360 local $SIG{'__WARN__'} = 'DEFAULT';
74 13         47 local $SIG{'__DIE__' } = 'DEFAULT';
75            
76 13 100 100     81 CORE::die @_ if ref $_[0] and not $options{showrefs};
77 12 100       128 CORE::die @_ if index($_[0], "\n\tat ") >= 0;
78 6         50 my @args = @_;
79            
80 6 100       22 _use_data_dumper() if ref $args[0];
81 6 100       15 my $msg = join '', map { ref $_ ? "Caught exception object: $_\: ".Dumper($_) : $_ } @args;
  6         54  
82 6         163 $msg =~ s/ at (.+?) line (\d+)\.$//;
83 6         15 $stderr .= $msg;
84 6 50       43 $stderr .= "\n" if substr($msg, -1, 1) ne "\n";
85            
86 6         24 _stack_trace($1, $2);
87            
88 6 50       24 if($in_eval) {
89 6         31 $@ = $stderr;
90 6         10 $stderr = '';
91 6         14 $in_eval = 0;
92 6         101 CORE::die $@
93            
94             } else {
95 0         0 print STDERR $stderr;
96 0         0 $stderr = '';
97 0         0 exit -1
98             }
99             }
100              
101              
102             #
103             # _stack_trace()
104             # ------------
105             sub _stack_trace {
106 7     7   37 my($file,$line) = @_;
107 7   100     28 $file ||= ''; $line ||= '';
  7   100     27  
108 7 100       46 $file =~ '(eval \d+)' and $file = '';
109            
110 7         11 my $level = 2;
111 7         28 my @stack = ( ['', $file, $line] ); # @stack = ( [ function, file, line ], ... )
112            
113 7         68 while(my @context = caller($level++)) {
114 58   50     114 $context[1] ||= ''; $context[2] ||= '';
  58   50     102  
115 58 100 100     260 $context[1] =~ '(eval \d+)' and $context[1] = '' and $in_eval = 1;
116 58 100 100     289 $context[3] eq '(eval)' and $context[3] = '' and $in_eval = 1;
117 58         88 $stack[-1][0] = $context[3];
118 58         563 push @stack, [ '', @context[1, 2] ];
119             }
120 7   50     52 $stack[-1][0] = (caller($level-2))[0].'::' || 'main::';
121            
122 7         23 for my $func (@stack) {
123 65 100       130 $$func[1] eq '' and $$func[1] = 'unknown source';
124 65 100       150 $$func[2] and $$func[1] .= ':';
125 65         209 $stderr .= "\tat $$func[0]($$func[1]$$func[2])\n";
126             }
127             }
128              
129              
130             1;
131              
132             __END__