File Coverage

blib/lib/Carp/Clan.pm
Criterion Covered Total %
statement 100 130 76.9
branch 36 68 52.9
condition 7 18 38.8
subroutine 14 14 100.0
pod 0 4 0.0
total 157 234 67.0


line stmt bran cond sub pod time code
1             # ABSTRACT: Report errors from perspective of caller of a "clan" of modules
2              
3             ##
4             ## Based on Carp.pm from Perl 5.005_03.
5             ## Last modified 22-May-2016 by Kent Fredric.
6             ## Should be reasonably backwards compatible.
7             ##
8             ## This module is free software and can
9             ## be used, modified and redistributed
10             ## under the same terms as Perl itself.
11             ##
12              
13             @DB::args = (); # Avoid warning "used only once" in Perl 5.003
14              
15             package Carp::Clan; # git description: v6.06-8-g0cfdd10
16              
17 3     3   2855 use strict;
  3         6  
  3         73  
18 3     3   13 use overload ();
  3         5  
  3         3262  
19              
20             # Original comments by Andy Wardley 09-Apr-1998.
21              
22             # The $Max(EvalLen|(Arg(Len|Nums)) variables are used to specify how
23             # the eval text and function arguments should be formatted when printed.
24              
25             our $MaxEvalLen = 0; # How much eval '...text...' to show. 0 = all.
26             our $MaxArgLen = 64; # How much of each argument to print. 0 = all.
27             our $MaxArgNums = 8; # How many arguments to print. 0 = all.
28              
29             our $Verbose = 0; # If true then make _shortmsg call _longmsg instead.
30              
31             our $VERSION = '6.07';
32              
33             # _longmsg() crawls all the way up the stack reporting on all the function
34             # calls made. The error string, $error, is originally constructed from the
35             # arguments passed into _longmsg() via confess(), cluck() or _shortmsg().
36             # This gets appended with the stack trace messages which are generated for
37             # each function call on the stack.
38              
39             sub _longmsg {
40 52 50   52   80 return (@_) if ( ref $_[0] );
41 52         54 local $_; # Protect surrounding program - just in case...
42 52         68 my ( $pack, $file, $line, $sub, $hargs, $eval, $require, @parms, $push );
43 52         79 my $error = join( '', @_ );
44 52         55 my $msg = '';
45 52         51 my $i = 0;
46 52         56 while (
47             do {
48             {
49              
50 472         467 package # hide from PAUSE
51             DB;
52 472         1861 ( $pack, $file, $line, $sub, $hargs, undef, $eval, $require )
53             = caller( $i++ )
54             }
55             }
56             )
57             {
58 420 100       621 next if ( $pack eq 'Carp::Clan' );
59 368 100       440 if ( $error eq '' ) {
60 316 50       436 if ( defined $eval ) {
    100          
61 0 0       0 $eval =~ s/([\\\'])/\\$1/g unless ($require); # Escape \ and '
62 0         0 $eval
63 0         0 =~ s/([\x00-\x1F\x7F-\xFF])/sprintf("\\x%02X",ord($1))/eg;
64 0 0 0     0 substr( $eval, $MaxEvalLen ) = '...'
65             if ( $MaxEvalLen && length($eval) > $MaxEvalLen );
66 0 0       0 if ($require) { $sub = "require $eval"; }
  0         0  
67 0         0 else { $sub = "eval '$eval'"; }
68             }
69 52         56 elsif ( $sub eq '(eval)' ) { $sub = 'eval {...}'; }
70             else {
71 264         300 @parms = ();
72 264 50       331 if ($hargs) {
73 264         251 $push = 0;
74 264         385 @parms = @DB::args
75             ; # We may trash some of the args so we take a copy
76 264 50 33     605 if ( $MaxArgNums and @parms > $MaxArgNums ) {
77 0         0 $#parms = $MaxArgNums;
78 0         0 pop(@parms);
79 0         0 $push = 1;
80             }
81 264         327 for (@parms) {
82 528 50       620 if ( defined $_ ) {
83 528 50       580 if ( ref $_ ) {
84 0         0 $_ = overload::StrVal($_);
85             }
86             else {
87 528 100       1145 unless ( /^-?\d+(?:\.\d+(?:[eE][+-]\d+)?)?$/
88             ) # Looks numeric
89             {
90 396         483 s/([\\\'])/\\$1/g; # Escape \ and '
91 396         407 s/([\x00-\x1F\x7F-\xFF])/sprintf("\\x%02X",ord($1))/eg;
  0         0  
92 396 50 33     797 substr( $_, $MaxArgLen ) = '...'
93             if ( $MaxArgLen
94             and length($_) > $MaxArgLen );
95 396         641 $_ = "'$_'";
96             }
97             }
98             }
99 0         0 else { $_ = 'undef'; }
100             }
101 264 50       365 push( @parms, '...' ) if ($push);
102             }
103 264         456 $sub .= '(' . join( ', ', @parms ) . ')';
104             }
105 316 50       378 if ( $msg eq '' ) { $msg = "$sub called"; }
  0         0  
106 316         416 else { $msg .= "\t$sub called"; }
107             }
108             else {
109 52         75 $msg = quotemeta($sub);
110 52 50       157 if ( $error =~ /\b$msg\b/ ) { $msg = $error; }
  0         0  
111             else {
112 52 50       105 if ( $sub =~ /::/ ) { $msg = "$sub(): $error"; }
  52         90  
113 0         0 else { $msg = "$sub: $error"; }
114             }
115             }
116 368 50       658 $msg .= " at $file line $line\n" unless ( $error =~ /\n$/ );
117 368         402 $error = '';
118             }
119 52   33     75 $msg ||= $error;
120 52         95 $msg =~ tr/\0//d; # Circumvent die's incorrect handling of NUL characters
121 52         226 $msg;
122             }
123              
124             # _shortmsg() is called by carp() and croak() to skip all the way up to
125             # the top-level caller's package and report the error from there. confess()
126             # and cluck() generate a full stack trace so they call _longmsg() to
127             # generate that. In verbose mode _shortmsg() calls _longmsg() so you
128             # always get a stack trace.
129              
130             sub _shortmsg {
131 44     44   52 my $pattern = shift;
132 44         47 my $verbose = shift;
133 44 50       76 return (@_) if ( ref $_[0] );
134 44 50 33     125 goto &_longmsg if ( $Verbose or $verbose );
135 44         49 my ( $pack, $file, $line, $sub );
136 44         68 my $error = join( '', @_ );
137 44         50 my $msg = '';
138 44         44 my $i = 0;
139 44         237 while ( ( $pack, $file, $line, $sub ) = caller( $i++ ) ) {
140 232 100 100     1228 next if ( $pack eq 'Carp::Clan' or $pack =~ /$pattern/ );
141 36 50       53 if ( $error eq '' ) { $msg = "$sub() called"; }
  0         0  
142             else {
143 36         56 $msg = quotemeta($sub);
144 36 50       186 if ( $error =~ /\b$msg\b/ ) { $msg = $error; }
  0         0  
145             else {
146 36 50       77 if ( $sub =~ /::/ ) { $msg = "$sub(): $error"; }
  36         68  
147 0         0 else { $msg = "$sub: $error"; }
148             }
149             }
150 36 50       84 $msg .= " at $file line $line\n" unless ( $error =~ /\n$/ );
151 36         50 $msg =~ tr/\0//d; # Circumvent die's incorrect handling of NUL characters
152 36         167 return $msg;
153             }
154 8         27 goto &_longmsg;
155             }
156              
157             # In the two identical regular expressions (immediately after the two occurrences of
158             # "quotemeta") above, the "\b ... \b" helps to avoid confusion between function names
159             # which are prefixes of each other, e.g. "My::Class::print" and "My::Class::println".
160              
161             # The following four functions call _longmsg() or _shortmsg() depending on
162             # whether they should generate a full stack trace (confess() and cluck())
163             # or simply report the caller's package (croak() and carp()), respectively.
164             # confess() and croak() die, carp() and cluck() warn.
165              
166             # Following code kept for calls with fully qualified subroutine names:
167             # (For backward compatibility with the original Carp.pm)
168              
169             sub croak {
170 2     2 0 42 my $callpkg = caller(0);
171 2 50       6 my $pattern = ( $callpkg eq 'main' ) ? '^:::' : "^$callpkg\$";
172 2         4 die _shortmsg( $pattern, 0, @_ );
173             }
174 2     2 0 29 sub confess { die _longmsg(@_); }
175              
176             sub carp {
177 2     2 0 40 my $callpkg = caller(0);
178 2 50       5 my $pattern = ( $callpkg eq 'main' ) ? '^:::' : "^$callpkg\$";
179 2         5 warn _shortmsg( $pattern, 0, @_ );
180             }
181 2     2 0 48 sub cluck { warn _longmsg(@_); }
182              
183             # The following method imports a different closure for every caller.
184             # I.e., different modules can use this module at the same time
185             # and in parallel and still use different patterns.
186              
187             sub import {
188 21     21   691 my $pkg = shift;
189 21         34 my $callpkg = caller(0);
190 21 100       49 my $pattern = ( $callpkg eq 'main' ) ? '^:::' : "^$callpkg\$";
191 21         25 my $verbose = 0;
192 21         28 my $item;
193             my $file;
194              
195 21         32 for $item (@_) {
196 17 50       62 if ( $item =~ /^\d/ ) {
    50          
197 0 0       0 if ( $VERSION < $item ) {
198 0         0 $file = "$pkg.pm";
199 0         0 $file =~ s!::!/!g;
200 0         0 $file = $INC{$file};
201 0         0 die _shortmsg( '^:::', 0,
202             "$pkg $item required--this is only version $VERSION ($file)"
203             );
204             }
205             }
206 0         0 elsif ( $item =~ /^verbose$/i ) { $verbose = 1; }
207 17         22 else { $pattern = $item; }
208             }
209              
210             # Speed up pattern matching in Perl versions >= 5.005:
211             # (Uses "eval ''" because qr// is a syntax error in previous Perl versions)
212 21 50       42 if ( $] >= 5.005 ) {
213 21         1044 eval '$pattern = qr/$pattern/;';
214             }
215             else {
216 0         0 eval { $pkg =~ /$pattern/; };
  0         0  
217             }
218 21 50       76 if ($@) {
219 0         0 $@ =~ s/\s+$//;
220 0         0 $@ =~ s/\s+at\s.+$//;
221 0         0 die _shortmsg( '^:::', 0, $@ );
222             }
223             {
224 21         26 local ($^W) = 0;
  21         60  
225 3     3   19 no strict "refs";
  3         6  
  3         837  
226 21     20   69 *{"${callpkg}::croak"} = sub { die _shortmsg( $pattern, $verbose, @_ ); };
  21         86  
  20         333  
227 21     20   45 *{"${callpkg}::confess"} = sub { die _longmsg ( @_ ); };
  21         68  
  20         453  
228 21     20   38 *{"${callpkg}::carp"} = sub { warn _shortmsg( $pattern, $verbose, @_ ); };
  21         66  
  20         1149  
229 21     20   37 *{"${callpkg}::cluck"} = sub { warn _longmsg ( @_ ); };
  21         111  
  20         646  
230             }
231             }
232              
233             1;
234              
235             __END__