File Coverage

blib/lib/Exception/SEH/Parser.pm
Criterion Covered Total %
statement 68 73 93.1
branch 9 14 64.2
condition 3 9 33.3
subroutine 17 17 100.0
pod 0 12 0.0
total 97 125 77.6


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             package Exception::SEH::Parser;
3              
4 24     24   130 use strict;
  24         42  
  24         748  
5              
6 24     24   120 use Carp ();
  24         45  
  24         394  
7 24     24   116 use Devel::Declare ();
  24         41  
  24         344  
8 24     24   22640 use B::Hooks::OP::PPAddr;
  24         19250  
  24         1306  
9 24     24   23590 use Scope::Upper qw(EVAL);
  24         27509  
  24         28548  
10              
11             sub DEBUG() { 0 }
12              
13             sub INITIAL() { -1 }
14             sub TRY() { 0 }
15             sub CATCH() { 1 }
16             sub FINALLY() { 2 }
17              
18             our $VERSION = '0.01003';
19              
20             sub new{
21 352     352 0 574 my ($class, $offset) = @_;
22              
23 352         357 print STDERR "new called at $offset\r\n" if DEBUG;
24 352         1690 bless {
25             offset => $offset,
26             }, $class;
27             }
28              
29             #err handler
30              
31             sub panic{
32 33     33 0 41 my ($self, $err) = @_;
33              
34 33 50       260 if (EVAL > 0){
35 33         382 Carp::croak $err;
36             }else{
37 0         0 print STDERR 'Exception::SEH - ', $err, "\n\n";
38 0         0 die;
39             }
40             }
41              
42             #token manip
43              
44             sub skip_word{
45 132     132 0 178 my $self = shift;
46              
47 132         153 print STDERR "skip_word called at $self->{offset}\r\n" if DEBUG;
48              
49 132 50       550 if (my $len = Devel::Declare::toke_scan_word($self->{'offset'}, 1)) {
50 132         405 $self->{'offset'} += $len;
51             }
52             }
53              
54             sub get_word{
55 352     352 0 441 my $self = shift;
56              
57 352         361 print STDERR "get_word called at $self->{offset}\r\n" if DEBUG;
58              
59 352 100       1566 if (my $len = Devel::Declare::toke_scan_word($self->{'offset'}, 1)) {
60 306         1867 return substr(Devel::Declare::get_linestr(), $self->{'offset'}, $len);
61             }
62 46         138 return '';
63             }
64              
65             sub skip_spaces{
66 545     545 0 954 my $self = shift;
67              
68 545         544 print STDERR "skip_spaces called at $self->{offset}\r\n" if DEBUG;
69              
70 545         2677 $self->{'offset'} += Devel::Declare::toke_skipspace($self->{'offset'});
71             }
72              
73             sub get_symbols{
74 457     457 0 583 my ($self, $len) = @_;
75              
76 457         426 print STDERR "get_symbols called at $self->{offset} for $len\r\n" if DEBUG;
77              
78 457         2530 return substr(Devel::Declare::get_linestr(), $self->{'offset'}, $len);
79             }
80              
81              
82             sub extract_args{
83 66     66 0 81 my $self = shift;
84              
85 66         104 print STDERR "extract_args called at $self->{offset}\r\n" if DEBUG;
86              
87 66         157 my $linestr = Devel::Declare::get_linestr();
88 66 50       196 if (substr($linestr, $self->{'offset'}, 1) eq '(') {
89 66         384 my $length = Devel::Declare::toke_scan_str($self->{'offset'});
90 66         170 my $proto = Devel::Declare::get_lex_stuff();
91 66         115 Devel::Declare::clear_lex_stuff();
92              
93 66         113 $linestr = Devel::Declare::get_linestr();
94 66 50 33     487 if (
      33        
95             $length < 0
96             ||
97             $self->{'offset'} + $length > length($linestr)
98             ||
99             $self->{'offset'} < 0
100             ){
101 0         0 $self->panic("Unbalanced text supplied as catch argument");
102             }
103 66         137 substr($linestr, $self->{'offset'}, $length) = '';
104 66         121 Devel::Declare::set_linestr($linestr);
105              
106 66         180 return $proto;
107             }
108 0         0 return '';
109             }
110              
111             #injectors
112              
113             sub inject{
114 949     949 0 1282 my ($self, $string) = @_;
115              
116 949         1973 $self->substitute($string, 0);
117             }
118              
119             sub cutoff{
120 117     117 0 160 my ($self, $len) = @_;
121              
122 117         227 $self->substitute('', $len);
123             }
124              
125             sub substitute{
126 1066     1066 0 1415 my ($self, $string, $replace_len) = @_;
127              
128 1066         921 print STDERR "inject called at $self->{offset} for '$string'\r\n" if DEBUG;
129              
130 1066         2482 my $linestr = Devel::Declare::get_linestr;
131 1066 50 33     5463 if (
132             $self->{'offset'} > length($linestr)
133             ||
134             $self->{'offset'} < 0
135             ){
136 0         0 $self->panic("Parser tried to inject data outside program source, stopping");
137             }
138 1066         1759 substr($linestr, $self->{'offset'}, $replace_len) = $string;
139 1066         2066 Devel::Declare::set_linestr($linestr);
140              
141 1066         4910 $self->{'offset'} += length($string);
142             }
143              
144             sub inject_if_block{
145 230     230 0 327 my ($self, $inject) = @_;
146              
147 230         240 print STDERR "inject_if_block called at $self->{offset} for '$inject'\r\n" if DEBUG;
148              
149 230 100       398 if ($self->get_symbols(1) eq '{'){
150 220         348 $self->{'offset'} += 1;
151 220         458 $self->inject($inject);
152             }else{
153 10         17 $self->panic('Code block expected');
154             }
155             }
156              
157             sub get_injector{
158 230     230 0 552 my ($self, $func, @args) = @_;
159              
160 230         535 return " BEGIN { $func(".join(',', map { "'$_'" } @args).") } ";
  230         1438  
161             }
162              
163             1;
164              
165             =head1 NAME
166              
167             Exception::SEH::Parser - parses source for L and is not intended for external use.
168              
169             =head1 AUTHOR
170              
171             Copyright (c) 2009 by Sergey Aleynikov.
172             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
173              
174             =cut