File Coverage

blib/lib/XML/SAX/EventMethodMaker.pm
Criterion Covered Total %
statement 115 246 46.7
branch 51 218 23.3
condition 8 12 66.6
subroutine 23 46 50.0
pod 41 43 95.3
total 238 565 42.1


line stmt bran cond sub pod time code
1             package XML::SAX::EventMethodMaker;
2             {
3             $XML::SAX::EventMethodMaker::VERSION = '0.46';
4             }
5             # ABSTRACT: SAX event names, creation of methods from templates
6              
7              
8             @ISA = qw( Exporter );
9             @EXPORT_OK = qw(
10             sax_event_names
11             missing_methods
12             compile_methods
13             compile_missing_methods
14             );
15             %EXPORT_TAGS = ( all => \@EXPORT_OK );
16              
17 16     16   7756 use strict ;
  16         32  
  16         3222  
18              
19             ## First, a table in easy to maintain format :)
20             ##
21             ## Key to flags field:
22             ## = SAX versions supported in. We'll need to make this more
23             ## powerful (support ranges) if we get in to subversions.
24             my %event_flags = (
25             Han => "Handler",
26             DTD => "DTDHandler",
27             Cnt => "ContentHandler",
28             Doc => "DocumentHandler",
29             Dec => "DeclHandler",
30             Err => "ErrorHandler",
31             Ent => "EntityResolver",
32             Lex => "LexicalHandler",
33             );
34              
35              
36             my %parse_method_flags = (
37             Parse => "ParseMethods",
38             );
39              
40              
41             my %event_table = qw(
42             start_document Han;1Doc;Cnt
43             end_document Han;1Doc;Cnt
44             start_element Han;1Doc;Cnt
45             end_element Han;1Doc;Cnt
46             characters Han;1Doc;Cnt
47             start_prefix_mapping Han;----;Cnt
48             end_prefix_mapping Han;----;Cnt
49             processing_instruction Han;1Doc;Cnt
50             ignorable_whitespace Han;1Doc;Cnt
51             skipped_entity Han;----;Cnt
52             set_document_locator Han;1Doc;Cnt
53             notation_decl Han;----;----;DTD
54             unparsed_entity_decl Han;----;----;DTD
55             element_decl Han;----;----;----;----;Dec
56             attribute_decl Han;----;----;----;----;Dec
57             internal_entity_decl Han;----;----;----;----;Dec
58             external_entity_decl Han;----;----;----;----;Dec
59             comment Han;----;----;----;Lex
60             start_dtd Han;----;----;----;Lex
61             end_dtd Han;----;----;----;Lex
62             start_cdata Han;----;----;----;Lex
63             end_cdata Han;----;----;----;Lex
64             start_entity Han;----;----;----;Lex
65             end_entity Han;----;----;----;Lex
66             warning Han;----;----;----;----;----;Err
67             error Han;----;----;----;----;----;Err
68             fatal_error Han;----;----;----;----;----;Err
69             resolve_entity Han;----;----;----;----;----;----;Ent
70              
71             xml_decl 1Han;----;----;1DTD
72             attlist_decl 1Han;----;----;1DTD
73             doctype_decl 1Han;----;----;1DTD
74             entity_decl 1Han;----;----;1DTD
75             entity_reference 1Han;1Doc
76             );
77              
78             my %parse_methods_table = qw(
79             parse 1:2Parse
80             parse_file 2Parse
81             parse_string 2Parse
82             parse_uri 2Parse
83             );
84              
85              
86 16     16   93 use Carp;
  16         33  
  16         13223  
87              
88             ## Now, tear that apart so it's queryable
89             my %events_db;
90              
91             for my $event ( keys %event_table, keys %parse_methods_table ) {
92             my $flags = exists $event_table{$event}
93             ? $event_table{$event}
94             : $parse_methods_table{$event};
95              
96             for ( split /[;-]+/, $flags ) {
97             my ( $versions, $type ) = /^([\d:]*)(.*)/
98             or die "Couldn't parse '$_'";
99              
100             my @versions = split /\D+/, $versions;
101              
102             die "Unknown flag '$_'"
103             unless exists $event_flags{$type}
104             || exists $parse_method_flags{$type};
105              
106             @versions = ( 1, 2 ) unless @versions;
107              
108             $type = exists $event_flags{$type}
109             ? $event_flags{$type}
110             : $parse_method_flags{$type};
111              
112             push @{$events_db{$type}}, $event;
113             for my $version ( @versions ) {
114             push @{$events_db{"$version,$type"}}, $event;
115             $events_db{$version}->{$event} = undef
116             unless $type eq "ParseMethods";
117             }
118             }
119             }
120              
121             #use Data::Dumper; local $Data::Dumper::Indent=1; warn Dumper( \%events_db );
122              
123              
124             my %legal_query_terms = map {
125             ( $_ => undef );
126             } ( 1, 2, values %event_flags, values %parse_method_flags );
127            
128              
129             sub sax_event_names {
130             ## This should be really common
131 74 100   74 1 8402 return keys %event_table unless @_;
132              
133             {
134 41         73 my @baduns = grep ! exists $legal_query_terms{$_}, @_;
  41         173  
135 41 50       140 croak "Illegal sax_event_name query term(s): ",
136             join ", ", map "'$_'", @baduns
137             if @baduns;
138             }
139              
140 41         90 my @versions;
141             my @types;
142 41         139 while (@_) {
143 65 100       380 $_[0] =~ /^\d+$/
144             ? push @versions, shift
145             : push @types, shift;
146             }
147              
148             ## These might be relatively common as well.
149 41 100 100     191 return keys %{$events_db{$versions[0]}}
  2         13  
150             if @versions == 1 && ! @types;
151              
152 39 100 100     224 return @{$events_db{$types[0]}}
  22         203  
153             if ! @versions && @types == 1;
154              
155 17 100       43 @versions = (1,2) unless @versions;
156 17 100       40 @types = values %event_flags unless @types;
157              
158 24         31 my @keys = map {
159 17         27 my $version = $_;
160 46         57 map {
161 24         32 my $type = $_;
162 46         143 "$version,$type";
163             } @types
164             } @versions ;
165              
166 17         26 return keys %{{
167 552         1047 map {
168 17         24 map {
169 46         142 ( $_ => undef );
170 46         139 } @{$events_db{$_}}
171             } @keys
172             }};
173             }
174              
175              
176              
177             sub missing_methods {
178 15     15 1 36 my $where = shift;
179 15   33     97 $where = ref $where || $where;
180 16     16   97 no strict 'refs';
  16         39  
  16         22142  
181 15         39 return grep ! exists ${"${where}::"}{$_}, @_;
  495         1029  
182             }
183              
184              
185              
186             sub compile_methods {
187 45     45 1 132 my ( $where, $template ) = ( shift, shift );
188 45   33     363 $where = ref $where || $where;
189              
190 45         75 my @code;
191              
192 45         114 for ( @_ ) {
193 1006         1519 push @code, $template;
194 1006         6597 $code[-1] =~ s/|/$_/g;
195             }
196              
197 45 50   0 1 79478 eval join "", "package $where;", @code, "1" or die $@;
  0 0   0 1 0  
  0 0   15 1 0  
  0 0   11 1 0  
  0 0   23 1 0  
  0 50   0 1 0  
  0 50   0 1 0  
  0 100   10 1 0  
  0 100   1 1 0  
  15 0   22 1 692  
  15 0   4 1 44  
  15 0   0 1 46  
  7 0   0 1 295  
  11 0   0 1 225  
  11 0   0 1 36  
  23 50   0 1 1661  
  23 50   0 1 777  
  14 50   0 1 83  
  2 0   0 1 20  
  0 50   0 1 0  
  0 50   0 1 0  
  0 50   0 1 0  
  0 0   21 0 0  
  0 0   0 0 0  
  0 0   0 1 0  
  0 0   2 1 0  
  0 0   16 1 0  
  0 0   3 1 0  
  0 0   4 1 0  
  10 0   10 1 2575  
  10 0   1 1 38  
  10 0   22 1 36  
  10 0   4 1 88  
  1 0   0 1 162  
  1 0   0 1 2  
  1 0   0 1 4  
  4 0   0 1 230  
  26 0   0 1 22723  
  22 0   0 1 96  
  22 0       162  
  20 0       150  
  4 0       801  
  4 0       13  
  4 0       24  
  8 0       390  
  8 0       34  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 50       0  
  0 50       0  
  0 50       0  
  0 100       0  
  0 50       0  
  0 50       0  
  0 100       0  
  0 50       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 100       0  
  0 100       0  
  0 100       0  
  0 50       0  
  0 100       0  
  0 0       0  
  0 0       0  
  0 50       0  
  0 100       0  
  0 0       0  
  0 0       0  
  0 50       0  
  0 50       0  
  0 50       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  21         8031  
  21         105  
  21         90  
  21         169  
  19         39  
  19         132  
  19         1867  
  15         184  
  15         36  
  15         124  
  15         51  
  17         9466  
  17         29275  
  17         498111  
  17         245  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         1165  
  2         9  
  2         19  
  12         2119  
  16         260  
  16         79  
  5         357  
  3         16  
  3         15  
  8         1064  
  8         49  
  4         45  
  0         0  
  0         0  
  0         0  
  10         31371  
  10         59  
  10         33  
  10         102  
  0         0  
  1         161  
  1         3  
  1         4  
  26         12401  
  26         112  
  22         248  
  20         150  
  4         2466  
  4         12  
  4         26  
  8         433  
  8         29  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
  0            
198             }
199              
200              
201              
202             sub compile_missing_methods {
203 9     9 1 33 my ( $where, $template ) = ( shift, shift );
204              
205 9         41 compile_methods $where, $template, missing_methods $where, @_;
206             }
207              
208              
209             1;
210              
211             __END__