line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Error::Pure::Utils; |
2
|
|
|
|
|
|
|
|
3
|
28
|
|
|
28
|
|
76691
|
use base qw(Exporter); |
|
28
|
|
|
|
|
1663
|
|
|
28
|
|
|
|
|
2973
|
|
4
|
28
|
|
|
28
|
|
240
|
use strict; |
|
28
|
|
|
|
|
55
|
|
|
28
|
|
|
|
|
653
|
|
5
|
28
|
|
|
28
|
|
134
|
use warnings; |
|
28
|
|
|
|
|
51
|
|
|
28
|
|
|
|
|
954
|
|
6
|
|
|
|
|
|
|
|
7
|
28
|
|
|
28
|
|
153
|
use Cwd qw(abs_path); |
|
28
|
|
|
|
|
51
|
|
|
28
|
|
|
|
|
1612
|
|
8
|
28
|
|
|
28
|
|
13211
|
use Readonly; |
|
28
|
|
|
|
|
105774
|
|
|
28
|
|
|
|
|
32092
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = 0.29; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Readonly::Array our @EXPORT_OK => qw(clean err_get err_helper err_msg err_msg_hr); |
13
|
|
|
|
|
|
|
Readonly::Scalar my $DOTS => '...'; |
14
|
|
|
|
|
|
|
Readonly::Scalar my $EMPTY_STR => q{}; |
15
|
|
|
|
|
|
|
Readonly::Scalar my $EVAL => 'eval {...}'; |
16
|
|
|
|
|
|
|
Readonly::Scalar my $UNDEF => 'undef'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Errors array. |
19
|
|
|
|
|
|
|
our @ERRORS; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Default initialization. |
22
|
|
|
|
|
|
|
our $LEVEL = 2; |
23
|
|
|
|
|
|
|
our $MAX_LEVELS = 50; |
24
|
|
|
|
|
|
|
our $MAX_EVAL = 100; |
25
|
|
|
|
|
|
|
our $MAX_ARGS = 10; |
26
|
|
|
|
|
|
|
our $MAX_ARG_LEN = 50; |
27
|
|
|
|
|
|
|
our $PROGRAM = $EMPTY_STR; # Program name in stack information. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Clean internal structure. |
30
|
|
|
|
|
|
|
sub clean { |
31
|
11
|
|
|
11
|
1
|
7019
|
@ERRORS = (); |
32
|
11
|
|
|
|
|
264
|
return; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Get and clean processed errors. |
36
|
|
|
|
|
|
|
sub err_get { |
37
|
10
|
|
|
10
|
1
|
1762
|
my $clean = shift; |
38
|
10
|
|
|
|
|
23
|
my @ret = @ERRORS; |
39
|
10
|
100
|
|
|
|
26
|
if ($clean) { |
40
|
1
|
|
|
|
|
5
|
clean(); |
41
|
|
|
|
|
|
|
} |
42
|
10
|
|
|
|
|
31
|
return @ret; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# Process error without die. |
46
|
|
|
|
|
|
|
sub err_helper { |
47
|
55
|
|
|
55
|
1
|
437
|
my @msg = @_; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# Check to undefined values in @msg and chomp. |
50
|
55
|
|
|
|
|
188
|
for (my $i = 0; $i < @msg; $i++) { |
51
|
79
|
100
|
|
|
|
189
|
if (! defined $msg[$i]) { |
52
|
7
|
|
|
|
|
27
|
$msg[$i] = $UNDEF; |
53
|
|
|
|
|
|
|
} else { |
54
|
72
|
|
|
|
|
201
|
chomp $msg[$i]; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# When is list blank, add undef. |
59
|
55
|
100
|
|
|
|
143
|
if (! @msg) { |
60
|
6
|
|
|
|
|
21
|
push @msg, $UNDEF; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# Get calling stack. |
64
|
55
|
|
|
|
|
129
|
my @stack = _get_stack(); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Create errors message. |
67
|
55
|
|
|
|
|
200
|
push @ERRORS, { |
68
|
|
|
|
|
|
|
'msg' => \@msg, |
69
|
|
|
|
|
|
|
'stack' => \@stack, |
70
|
|
|
|
|
|
|
}; |
71
|
|
|
|
|
|
|
|
72
|
55
|
|
|
|
|
214
|
return @ERRORS; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# Get first error messages array. |
76
|
|
|
|
|
|
|
sub err_msg { |
77
|
3
|
|
|
3
|
1
|
12
|
my $index = shift; |
78
|
3
|
100
|
|
|
|
8
|
if (! defined $index) { |
79
|
2
|
|
|
|
|
4
|
$index = -1; |
80
|
|
|
|
|
|
|
} |
81
|
3
|
|
|
|
|
6
|
my @err = err_get(); |
82
|
3
|
|
|
|
|
4
|
my @ret = @{$err[$index]->{'msg'}}; |
|
3
|
|
|
|
|
10
|
|
83
|
3
|
|
|
|
|
9
|
return @ret; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# Get first error message key, value pairs as hash reference. |
87
|
|
|
|
|
|
|
sub err_msg_hr { |
88
|
3
|
|
|
3
|
1
|
13
|
my $index = shift; |
89
|
3
|
100
|
|
|
|
8
|
if (! defined $index) { |
90
|
2
|
|
|
|
|
3
|
$index = -1; |
91
|
|
|
|
|
|
|
} |
92
|
3
|
|
|
|
|
7
|
my @err = err_get(); |
93
|
3
|
|
|
|
|
4
|
my @ret = @{$err[$index]->{'msg'}}; |
|
3
|
|
|
|
|
10
|
|
94
|
3
|
|
|
|
|
4
|
shift @ret; |
95
|
3
|
|
|
|
|
16
|
return {@ret}; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Get information about place of error. |
99
|
|
|
|
|
|
|
sub _get_stack { |
100
|
55
|
|
33
|
55
|
|
222
|
my $max_level = shift || $MAX_LEVELS; |
101
|
55
|
|
|
|
|
94
|
my @stack; |
102
|
55
|
|
|
|
|
122
|
my $tmp_level = $LEVEL; |
103
|
55
|
|
|
|
|
106
|
my ($class, $prog, $line, $sub, $hargs, $evaltext, $is_require); |
104
|
55
|
|
66
|
|
|
150
|
while ($tmp_level < $max_level |
105
|
143
|
|
|
|
|
1087
|
&& do { package DB; ($class, $prog, $line, $sub, $hargs, |
106
|
|
|
|
|
|
|
undef, $evaltext, $is_require) = caller($tmp_level++); }) { |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# Prog to absolute path. |
109
|
88
|
100
|
|
|
|
1455
|
if (-e $prog) { |
110
|
86
|
|
|
|
|
2720
|
$prog = abs_path($prog); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# Sub name. |
114
|
88
|
100
|
|
|
|
342
|
if (defined $evaltext) { |
|
|
100
|
|
|
|
|
|
115
|
2
|
50
|
|
|
|
6
|
if ($is_require) { |
116
|
0
|
|
|
|
|
0
|
$sub = "require $evaltext"; |
117
|
|
|
|
|
|
|
} else { |
118
|
2
|
|
|
|
|
5
|
$evaltext =~ s/\n;//sm; |
119
|
2
|
|
|
|
|
28
|
$evaltext =~ s/([\'])/\\$1/gsm; |
120
|
2
|
50
|
33
|
|
|
13
|
if ($MAX_EVAL |
121
|
|
|
|
|
|
|
&& length($evaltext) > $MAX_EVAL) { |
122
|
|
|
|
|
|
|
|
123
|
2
|
|
|
|
|
7
|
substr($evaltext, $MAX_EVAL, -1, |
124
|
|
|
|
|
|
|
$DOTS); |
125
|
|
|
|
|
|
|
} |
126
|
2
|
|
|
|
|
14
|
$sub = "eval '$evaltext'"; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# My eval name. |
130
|
|
|
|
|
|
|
} elsif ($sub eq '(eval)') { |
131
|
41
|
|
|
|
|
70
|
$sub = $EVAL; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# Other transformation. |
134
|
|
|
|
|
|
|
} else { |
135
|
45
|
|
|
|
|
482
|
$sub =~ s/^$class\:\:([^:]+)$/$1/gsmx; |
136
|
45
|
100
|
|
|
|
310
|
if ($sub =~ m/^Error::Pure::(.*)err$/smx) { |
137
|
43
|
|
|
|
|
82
|
$sub = 'err'; |
138
|
|
|
|
|
|
|
} |
139
|
45
|
50
|
33
|
|
|
141
|
if ($PROGRAM && $prog =~ m/^\(eval/sm) { |
140
|
0
|
|
|
|
|
0
|
$prog = $PROGRAM; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Args. |
145
|
88
|
|
|
|
|
150
|
my $i_args = $EMPTY_STR; |
146
|
88
|
100
|
|
|
|
168
|
if ($hargs) { |
147
|
45
|
|
|
|
|
118
|
my @args = @DB::args; |
148
|
45
|
50
|
33
|
|
|
220
|
if ($MAX_ARGS && $#args > $MAX_ARGS) { |
149
|
0
|
|
|
|
|
0
|
$#args = $MAX_ARGS; |
150
|
0
|
|
|
|
|
0
|
$args[-1] = $DOTS; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# Get them all. |
154
|
45
|
|
|
|
|
104
|
foreach my $arg (@args) { |
155
|
41
|
100
|
|
|
|
140
|
if (! defined $arg) { |
156
|
6
|
|
|
|
|
18
|
$arg = 'undef'; |
157
|
6
|
|
|
|
|
15
|
next; |
158
|
|
|
|
|
|
|
} |
159
|
35
|
50
|
|
|
|
95
|
if (ref $arg) { |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# Force string representation. |
162
|
0
|
|
|
|
|
0
|
$arg .= $EMPTY_STR; |
163
|
|
|
|
|
|
|
} |
164
|
35
|
|
|
|
|
69
|
$arg =~ s/'/\\'/gms; |
165
|
35
|
50
|
33
|
|
|
142
|
if ($MAX_ARG_LEN && length $arg> $MAX_ARG_LEN) { |
166
|
0
|
|
|
|
|
0
|
substr $arg, $MAX_ARG_LEN, -1, $DOTS; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# Quote (not for numbers). |
170
|
35
|
100
|
|
|
|
140
|
if ($arg !~ m/^-?[\d.]+$/ms) { |
171
|
33
|
|
|
|
|
99
|
$arg = "'$arg'"; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
} |
174
|
45
|
|
|
|
|
155
|
$i_args = '('.(join ', ', @args).')'; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# Information to stack. |
178
|
88
|
|
|
|
|
170
|
$sub =~ s/\n$//ms; |
179
|
88
|
|
|
|
|
470
|
push @stack, { |
180
|
|
|
|
|
|
|
'class' => $class, |
181
|
|
|
|
|
|
|
'prog' => $prog, |
182
|
|
|
|
|
|
|
'line' => $line, |
183
|
|
|
|
|
|
|
'sub' => $sub, |
184
|
|
|
|
|
|
|
'args' => $i_args |
185
|
|
|
|
|
|
|
}; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# Stack. |
189
|
55
|
|
|
|
|
164
|
return @stack; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
1; |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
__END__ |