File Coverage

blib/lib/Religion.pm
Criterion Covered Total %
statement 31 44 70.4
branch 6 22 27.2
condition n/a
subroutine 7 8 87.5
pod 0 2 0.0
total 44 76 57.8


line stmt bran cond sub pod time code
1             package Religion;
2              
3             #v3
4              
5 1     1   5420 sub import {} #nothing to export
6              
7             sub TraceBack {
8             # Given a starting scope offset, returns (get ready):
9             #
10             # Bool/Int: Am I in an eval?/How many evals are around me?
11             # Integer: What is the line number of this scope?
12             # String: What is the filename or eval number of this scope?
13             # Integer: What is the line number of the nearest scope
14             # that is a file, not an eval?
15             # String: What is the filename of the nearest scope that
16             # that is a file, not an eval?
17             # String: If I were to print out a message to the user, what
18             # should I say to explain the relation of the nearest
19             # file scope to my current scope?
20              
21 4     4 0 8 my($level) = @_;
22 4         30 my($iline) = (caller($level))[2];
23 4         21 my($ifile) = (caller($level))[1];
24 4         8 my($nil,$ofile,$oline,$sub);
25 4         7 my($oscope)="";
26 4         7 my($eval)=0;
27              
28 4         36 while (($nil,$file,$line,$sub) = caller($level++)) {
29 9 100       39 if( $file =~ /^\(eval/ ) {
30 5         22 $oline = (caller($level))[2];
31 5         17 $oscope .= "the eval at line $oline of ";
32 5         35 $eval++;
33             } else {
34 4         21 return ($eval,$iline,$ifile,$line,$file,$oscope);
35             }
36             }
37              
38 0         0 die "Unable to trace scope"; # This can't happen.
39              
40             }
41              
42             sub TraceBackHandler {
43 3     3 0 7 my($sub,$oldhandler,$startlevel) = @_;
44            
45             return sub {
46 3     3   4 my($msg,$fmsg,@trace,$level,$eval);
47            
48             # This section has been moved out to $SIG{__DIE__} and WARN.
49            
50             #if(@_==1) {
51             # # Invoked by die(), warn(), etc.;
52             # $msg = $_[0];
53             # $msg =~ s/ at (\S+|\(.*\)) line \d+\.\n$//;
54             # $level=$startlevel;
55             # @trace = Religion::TraceBack($level+1);
56             #
57             # $fmsg = $msg . ((substr($msg,-1,1) ne "\n") ?
58             # " at line $trace[1] of $trace[5]$trace[4].\n"
59             # #" at $trace[2] line $trace[1].\n"
60             # : "");
61             #} else {
62 3         11 ($msg,$fmsg,$level,@trace) = @_;
63             #}
64            
65 3         8 my(@result);
66 3         5 my($result)="last";
67             #anonymous block:
68             {
69              
70 3         11 @result=&$sub($msg,$fmsg,$level+1,@trace);
71 0         0 $result="return";
72            
73 0 0       0 $msg = $result[0] if @result>0;
74 0 0       0 $fmsg = $result[1] if @result>1;
75 0 0       0 $level = $result[2]-1 if @result>2;
76 0 0       0 @trace[0..$#result-3] = @result[3..$#result] if @result>3;
77            
78 0 0       0 if(@result==1) {
79 0 0       0 $fmsg = $msg . ((substr($msg,-1,1) ne "\n") ?
80             " at line $trace[1] of $trace[5]$trace[4].\n"
81             #" at $trace[2] line $trace[1].\n"
82             : "");
83             }
84            
85 3         3 } continue {
86 3 50       42 $result="next" if $result ne "return";
87            
88 3 50       9 if($oldhandler) {
89 0         0 return &$oldhandler($msg,$fmsg,$level+1,@trace);
90             }
91             }
92            
93             # Return parsed info, whether we got single or multiple args
94 3 50       15 if( $result eq "return") {
    50          
95 0         0 ($msg,$fmsg,$level,@trace);
96             } elsif( $result eq "next") {
97 3         8 next;
98             } else {
99 0         0 last;
100             }
101             }
102 3         21 };
103              
104              
105             package Warn;
106              
107             $Handler = $PreHandler = "";
108              
109             $SIG{__WARN__} = sub {
110             local($^W) = 0;
111             my($msg,$fmsg,@trace,$level,@trace);
112              
113             $msg = $_[0];
114             $msg =~ s/ at (\S+|\(.*\)) line \d+\.\n$//;
115             $level=0;
116             @trace = Religion::TraceBack($level+1);
117              
118             $fmsg = $msg . ((substr($msg,-1,1) ne "\n") ?
119             " at line $trace[1] of $trace[5]$trace[4].\n"
120             #" at $trace[2] line $trace[1].\n"
121             : "");
122            
123             unshift(@trace,$msg,$fmsg,$level);
124              
125             my($ok)=0;
126             {
127             my(@result);
128             @result=&$PreHandler(@trace) if $PreHandler;
129            
130             @trace[0..$#result]=@result;
131             } continue {
132             $ok=1;
133             }
134             return if !$ok;
135              
136             my($ok)=0;
137             {
138             my(@result);
139             @result=&$Handler(@trace) if $Handler;
140            
141             #$result[2]++ if $#result>=2;
142             @trace[0..$#result]=@result;
143             } continue {
144             $ok=1;
145             }
146             return if !$ok;
147            
148             warn($trace[1]);
149             };
150              
151             package WarnHandler;
152              
153             sub new {
154 0     0   0 my($pkg,$sub) = @_;
155 0         0 return Religion::TraceBackHandler ($sub,$Warn::Handler,0);
156             };
157              
158             package WarnPreHandler;
159              
160             sub new {
161 1     1   16 my($pkg,$sub) = @_;
162 1         6 return Religion::TraceBackHandler ($sub,$Warn::PreHandler,0);
163             };
164              
165              
166             package Die;
167              
168             $Handler = $PreHandler = "";
169              
170             $SIG{__DIE__} = sub {
171             local($^W) = 0; # This cuts out warnings about exiting subs via
172             # next or last.
173             my($msg,$fmsg,@trace,$level,@trace);
174              
175             $msg = $_[0];
176             $msg =~ s/ at (\S+|\(.*\)) line \d+\.\n$//;
177             $level=0;
178             @trace = Religion::TraceBack($level+1);
179              
180             $fmsg = $msg . ((substr($msg,-1,1) ne "\n") ?
181             " at line $trace[1] of $trace[5]$trace[4].\n"
182             #" at $trace[2] line $trace[1].\n"
183             : "");
184            
185             unshift(@trace,$msg,$fmsg,$level);
186            
187             my($ok)=0;
188             {
189             my(@result);
190             @result = &$PreHandler(@trace) if $PreHandler;
191            
192             #$result[2]++ if $#result>=2;
193             @trace[0..$#result]=@result;
194             } continue {
195             $ok=1;
196             }
197             die($trace[1]) if !$ok;
198              
199             my($ok)=0;
200             {
201             my(@result);
202             @result = &$Handler(@trace) if $Handler;
203            
204             #$result[2]++ if $#result>=2;
205             @trace[0..$#result]=@result;
206             } continue {
207             $ok=1;
208             }
209            
210             die($trace[1]);
211             };
212              
213             package DieHandler;
214              
215             sub new {
216 1     1   16 my($pkg,$sub) = @_;
217 1         4 return Religion::TraceBackHandler ($sub,$Die::Handler,0);
218             };
219              
220             package DiePreHandler;
221              
222             sub new {
223 1     1   11 my($pkg,$sub) = @_;
224 1         5 return Religion::TraceBackHandler ($sub,$Die::PreHandler,0);
225             };
226              
227              
228             package Religion;
229              
230              
231             1;
232              
233             __END__;