File Coverage

blib/lib/Log/Report/Minimal.pm
Criterion Covered Total %
statement 77 104 74.0
branch 22 52 42.3
condition 11 32 34.3
subroutine 20 35 57.1
pod 18 19 94.7
total 148 242 61.1


line stmt bran cond sub pod time code
1             # Copyrights 2013-2017 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5 4     4   105146 use warnings;
  4         29  
  4         162  
6 4     4   30 use strict;
  4         10  
  4         152  
7              
8             package Log::Report::Minimal;
9 4     4   22 use vars '$VERSION';
  4         7  
  4         210  
10             $VERSION = '1.04';
11              
12 4     4   38 use base 'Exporter';
  4         14  
  4         471  
13              
14 4     4   751 use Log::Report::Util;
  4         14  
  4         775  
15 4     4   43 use List::Util qw/first/;
  4         11  
  4         416  
16 4     4   29 use Scalar::Util qw/blessed/;
  4         8  
  4         191  
17              
18 4     4   1321 use Log::Report::Minimal::Domain ();
  4         10  
  4         6015  
19              
20             ### if you change anything here, you also have to change Log::Report::Minimal
21             my @make_msg = qw/__ __x __n __nx __xn N__ N__n N__w/;
22             my @functions = qw/report dispatcher try textdomain/;
23             my @reason_functions = qw/trace assert info notice warning
24             mistake error fault alert failure panic/;
25              
26             our @EXPORT_OK = (@make_msg, @functions, @reason_functions);
27              
28             sub trace(@); sub assert(@); sub info(@); sub notice(@); sub warning(@);
29             sub mistake(@); sub error(@); sub fault(@); sub alert(@); sub failure(@);
30             sub panic(@); sub report(@); sub textdomain($@);
31             sub __($); sub __x($@); sub __n($$$@); sub __nx($$$@); sub __xn($$$@);
32             sub N__($); sub N__n($$); sub N__w(@);
33              
34             my ($mode, %need);
35             sub need($)
36 4     4 0 12 { $mode = shift;
37 4         19 %need = map +($_ => 1), expand_reasons mode_accepts $mode;
38             }
39             need 'NORMAL';
40              
41             my %textdomains;
42             textdomain 'default';
43              
44             sub _interpolate(@)
45 3     3   15 { my ($msgid, %args) = @_;
46              
47 3         5 my $textdomain = $args{_domain};
48 3 50       7 unless($textdomain)
49 3         16 { my ($pkg) = caller 1;
50 3         19 $textdomain = pkg2domain $pkg;
51             }
52              
53 3         9 (textdomain $textdomain)->interpolate($msgid, \%args);
54             }
55              
56             #
57             # Some initiations
58             #
59              
60              
61             sub textdomain($@)
62 12 50 33 12 1 86 { if(@_==1 && blessed $_[0])
63 0         0 { my $domain = shift;
64 0         0 return $textdomains{$domain->name} = $domain;
65             }
66              
67 12 50       34 if(@_==2)
68             { # used for 'maintenance' and testing
69 0 0       0 return delete $textdomains{$_[0]} if $_[1] eq 'DELETE';
70 0 0       0 return $textdomains{$_[0]} if $_[1] eq 'EXISTS';
71             }
72              
73 12         29 my $name = shift;
74 12   66     79 my $domain = $textdomains{$name}
75             ||= Log::Report::Minimal::Domain->new(name => $name);
76              
77 12 50       61 @_ ? $domain->configure(@_, where => [caller]) : $domain;
78             }
79              
80              
81             # $^S = $EXCEPTIONS_BEING_CAUGHT; parse: undef, eval: 1, else 0
82              
83             sub _report($$@)
84 2     2   5 { my ($opts, $reason) = (shift, shift);
85              
86             # return when no-one needs it: skip unused trace() fast!
87 2 50       11 my $stop = exists $opts->{is_fatal} ? $opts->{is_fatal} : is_fatal $reason;
88 2 50 33     8 $need{$reason} || $stop or return;
89              
90 2 50       6 is_reason $reason
91             or error __x"token '{token}' not recognized as reason", token=>$reason;
92              
93             $opts->{errno} ||= $!+0 || $? || 1
94 2 50 0     6 if use_errno($reason) && !defined $opts->{errno};
      0        
      33        
95              
96 2         5 my $message = shift;
97 2 50       10 @_%2 and error __x"odd length parameter list with '{msg}'", msg => $message;
98              
99 2         8 my $show = lc($reason).': '.$message;
100              
101 2 100       6 if($stop)
102             { # ^S = EXCEPTIONS_BEING_CAUGHT, within eval or try
103 1   50     8 $! = $opts->{errno} || 0;
104 1         11 die "$show\n"; # call the die handler
105             }
106             else
107 1         13 { warn "$show\n"; # call the warn handler
108             }
109              
110 1         10 1;
111             }
112              
113              
114 0     0 1 0 sub dispatcher($@) { panic "no dispatchers available in ".__PACKAGE__ }
115              
116              
117             sub try(&@)
118 0     0 1 0 { my $code = shift;
119              
120 0 0       0 @_ % 2 and report {}, PANIC =>
121             __x"odd length parameter list for try(): forgot the terminating ';'?";
122              
123             #XXX MO: only needs the fatal subset, exclude the warns/prints
124              
125 0         0 eval { $code->() };
  0         0  
126             }
127              
128              
129             sub report(@)
130 0 0 0 0 1 0 { my %opt = @_ && ref $_[0] eq 'HASH' ? %{ (shift) } : ();
  0         0  
131 0         0 _report \%opt, @_;
132             }
133              
134 0     0 1 0 sub trace(@) {_report {}, TRACE => @_}
135 0     0 1 0 sub assert(@) {_report {}, ASSERT => @_}
136 0     0 1 0 sub info(@) {_report {}, INFO => @_}
137 0     0 1 0 sub notice(@) {_report {}, NOTICE => @_}
138 1     1 1 746 sub warning(@) {_report {}, WARNING => @_}
139 0     0 1 0 sub mistake(@) {_report {}, MISTAKE => @_}
140 1     1 1 105 sub error(@) {_report {}, ERROR => @_}
141 0     0 1 0 sub fault(@) {_report {}, FAULT => @_}
142 0     0 1 0 sub alert(@) {_report {}, ALERT => @_}
143 0     0 1 0 sub failure(@) {_report {}, FAILURE => @_}
144 0     0 1 0 sub panic(@) {_report {}, PANIC => @_}
145              
146              
147 3     3   168 sub __($) { shift }
148              
149              
150             sub __x($@)
151 1 50   1   6 { @_%2 or error __x"even length parameter list for __x at {where}"
152             , where => join(' line ', (caller)[1,2]);
153              
154 1         5 _interpolate @_, _expand => 1;
155             }
156              
157              
158             sub __n($$$@)
159 0     0   0 { my ($single, $plural, $count) = (shift, shift, shift);
160 0 0       0 _interpolate +($count==1 ? $single : $plural)
161             , _count => $count, @_;
162             }
163              
164              
165             sub __nx($$$@)
166 1     1   575 { my ($single, $plural, $count) = (shift, shift, shift);
167 1 50       22 _interpolate +($count==1 ? $single : $plural)
168             , _count => $count, _expand => 1, @_;
169             }
170              
171              
172             sub __xn($$$@) # repeated for prototype
173 1     1   1069 { my ($single, $plural, $count) = (shift, shift, shift);
174 1 50       11 _interpolate +($count==1 ? $single : $plural)
175             , _count => $count , _expand => 1, @_;
176             }
177              
178              
179 0     0 1 0 sub N__($) { $_[0] }
180 0     0 1 0 sub N__n($$) {@_}
181 1     1 1 526 sub N__w(@) {split " ", $_[0]}
182              
183             #------------------
184              
185             sub import(@)
186 5     5   41 { my $class = shift;
187              
188 5 100 100     40 my $to_level = @_ && $_[0] =~ m/^\+\d+$/ ? shift : 0;
189 5 100       25 my $textdomain = @_%2 ? shift : 'default';
190 5         12 my %opts = @_;
191 5   50     29 my $syntax = delete $opts{syntax} || 'SHORT';
192              
193 5         37 my ($pkg, $fn, $linenr) = caller $to_level;
194 5         28 pkg2domain $pkg, $textdomain, $fn, $linenr;
195 5         16 my $domain = textdomain $textdomain;
196              
197             need delete $opts{mode}
198 5 50       19 if defined $opts{mode};
199              
200 5         12 my @export;
201 5 50       16 if(my $in = $opts{import})
202 0 0       0 { push @export, ref $in eq 'ARRAY' ? @$in : $in;
203             }
204             else
205 5         25 { push @export, @functions, @make_msg;
206              
207 5   50     29 my $syntax = delete $opts{syntax} || 'SHORT';
208 5 50 0     17 if($syntax eq 'SHORT')
    0          
209 5         21 { push @export, @reason_functions
210             }
211             elsif($syntax ne 'REPORT' && $syntax ne 'LONG')
212 0         0 { error __x"syntax flag must be either SHORT or REPORT, not `{flag}'"
213             , flag => $syntax;
214             }
215             }
216              
217 5         883 $class->export_to_level(1+$to_level, undef, @export);
218              
219 5 50       3111 $domain->configure(%opts, where => [$pkg, $fn, $linenr ])
220             if %opts;
221             }
222              
223             1;