File: Minimal.pm

package info (click to toggle)
liblog-report-optional-perl 1.01-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 132 kB
  • ctags: 53
  • sloc: perl: 448; makefile: 2
file content (210 lines) | stat: -rw-r--r-- 5,381 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# Copyrights 2013-2014 by [Mark Overmeer].
#  For other contributors see ChangeLog.
# See the manual pages for details on the licensing terms.
# Pod stripped from pm file by OODoc 2.01.
use warnings;
use strict;

package Log::Report::Minimal;
our $VERSION = '1.01';

use base 'Exporter';

use Log::Report::Util;
use List::Util        qw/first/;

use Log::Report::Minimal::Domain ();

### if you change anything here, you also have to change Log::Report::Minimal
my @make_msg         = qw/__ __x __n __nx __xn N__ N__n N__w/;
my @functions        = qw/report dispatcher try textdomain/;
my @reason_functions = qw/trace assert info notice warning
   mistake error fault alert failure panic/;

our @EXPORT_OK = (@make_msg, @functions, @reason_functions);

sub trace(@); sub assert(@); sub info(@); sub notice(@); sub warning(@);
sub mistake(@); sub error(@); sub fault(@); sub alert(@); sub failure(@);
sub panic(@); sub report(@); sub textdomain($@);
sub __($); sub __x($@); sub __n($$$@); sub __nx($$$@); sub __xn($$$@);
sub N__($); sub N__n($$); sub N__w(@);

my ($mode, %need);
sub need($)
{   $mode = shift;
    %need = map +($_ => 1), expand_reasons mode_accepts $mode;
}
need 'NORMAL';

my %textdomains;
textdomain 'default';

sub _interpolate(@)
{   my ($msgid, %args) = @_;

    my $textdomain = $args{_domain};
    unless($textdomain)
    {   my ($pkg) = caller 1;
        $textdomain = pkg2domain $pkg;
    }

    (textdomain $textdomain)->interpolate($msgid, \%args);
}

#
# Some initiations
#


sub textdomain($@)
{   my $name   = shift;
    my $domain = $textdomains{$name}
      ||= Log::Report::Minimal::Domain->new(name => $name);

    @_ ? $domain->configure(@_, where => [caller]) : $domain;
}


# $^S = $EXCEPTIONS_BEING_CAUGHT; parse: undef, eval: 1, else 0

sub _report($$@)
{   my ($opts, $reason) = (shift, shift);

    # return when no-one needs it: skip unused trace() fast!
    my $stop = exists $opts->{is_fatal} ? $opts->{is_fatal} : is_fatal $reason;
    $need{$reason} || $stop or return;

    is_reason $reason
        or error __x"token '{token}' not recognized as reason", token=>$reason;

    $opts->{errno} ||= $!+0 || $? || 1
        if use_errno($reason) && !defined $opts->{errno};

    my $message = shift;
    @_%2 and error __x"odd length parameter list with '{msg}'", msg => $message;

    my $show    = lc($reason).': '.$message;

    if($stop)
    {   # ^S = EXCEPTIONS_BEING_CAUGHT, within eval or try
        $! = $opts->{errno} || 0;
        die "$show\n";    # call the die handler
    }
    else
    {   warn "$show\n";   # call the warn handler
    }

    1;
}


sub dispatcher($@) { panic "no dispatchers available in ".__PACKAGE__ }


sub try(&@)
{   my $code = shift;

    @_ % 2 and report {}, PANIC =>
        __x"odd length parameter list for try(): forgot the terminating ';'?";

#XXX MO: only needs the fatal subset, exclude the warns/prints

    eval { $code->() };
}


sub report(@)
{   my %opt = @_ && ref $_[0] eq 'HASH' ? %{ (shift) } : ();
    _report \%opt, @_;
}

sub trace(@)   {_report {}, TRACE   => @_}
sub assert(@)  {_report {}, ASSERT  => @_}
sub info(@)    {_report {}, INFO    => @_}
sub notice(@)  {_report {}, NOTICE  => @_}
sub warning(@) {_report {}, WARNING => @_}
sub mistake(@) {_report {}, MISTAKE => @_}
sub error(@)   {_report {}, ERROR   => @_}
sub fault(@)   {_report {}, FAULT   => @_}
sub alert(@)   {_report {}, ALERT   => @_}
sub failure(@) {_report {}, FAILURE => @_}
sub panic(@)   {_report {}, PANIC   => @_}


sub __($) { shift }


sub __x($@)
{   @_%2 or error __x"even length parameter list for __x at {where}",
        where => join(' line ', (caller)[1,2]);

    _interpolate @_, _expand => 1;
} 


sub __n($$$@)
{   my ($single, $plural, $count) = (shift, shift, shift);
    _interpolate +($count==1 ? $single : $plural)
      , _count => $count, @_;
}


sub __nx($$$@)
{   my ($single, $plural, $count) = (shift, shift, shift);
    _interpolate +($count==1 ? $single : $plural)
      , _count => $count, _expand => 1, @_;
}


sub __xn($$$@)   # repeated for prototype
{   my ($single, $plural, $count) = (shift, shift, shift);
    _interpolate +($count==1 ? $single : $plural)
      , _count => $count , _expand => 1, @_;
}


sub N__($)   { $_[0] }
sub N__n($$) {@_}
sub N__w(@)  {split " ", $_[0]}

#------------------

sub import(@)
{   my $class = shift;

    my $to_level   = @_ && $_[0] =~ m/^\+\d+$/ ? shift : 0;
    my $textdomain = @_%2 ? shift : 'default';
    my %opts       = @_;
    my $syntax     = delete $opts{syntax} || 'SHORT';

    my ($pkg, $fn, $linenr) = caller $to_level;
    pkg2domain $pkg, $textdomain, $fn, $linenr;
    my $domain     = textdomain $textdomain;

    need delete $opts{mode}
        if defined $opts{mode};

    my @export;
    if(my $in = $opts{import})
    {   push @export, ref $in eq 'ARRAY' ? @$in : $in;
    }
    else
    {   push @export, @functions, @make_msg;

        my $syntax = delete $opts{syntax} || 'SHORT';
        if($syntax eq 'SHORT')
        {   push @export, @reason_functions
        }
        elsif($syntax ne 'REPORT' && $syntax ne 'LONG')
        {   error __x"syntax flag must be either SHORT or REPORT, not `{flag}'"
              , flag => $syntax;
        }
    }

    $class->export_to_level(1+$to_level, undef, @export);

    $domain->configure(%opts, where => [$pkg, $fn, $linenr ])
        if %opts;
}

1;