File Coverage

inc/XML/SAX.pm
Criterion Covered Total %
statement 46 141 32.6
branch 4 32 12.5
condition n/a
subroutine 13 18 72.2
pod 0 7 0.0
total 63 198 31.8


line stmt bran cond sub pod time code
1             #line 1
2             # $Id: SAX.pm,v 1.29 2007/06/27 09:09:12 grant Exp $
3              
4             package XML::SAX;
5 1     1   6  
  1         2  
  1         50  
6 1     1   5 use strict;
  1         2  
  1         76  
7             use vars qw($VERSION @ISA @EXPORT_OK);
8              
9             $VERSION = '0.16';
10 1     1   6  
  1         3  
  1         36  
11             use Exporter ();
12             @ISA = ('Exporter');
13              
14             @EXPORT_OK = qw(Namespaces Validation);
15 1     1   6  
  1         2  
  1         81  
16 1     1   6 use File::Basename qw(dirname);
  1         2  
  1         17  
17 1     1   262 use File::Spec ();
  1         3  
  1         68  
18 1     1   7 use Symbol qw(gensym);
  1         2  
  1         29  
19             use XML::SAX::ParserFactory (); # loaded for simplicity
20 1     1   5  
  1         2  
  1         73  
21             use constant PARSER_DETAILS => "ParserDetails.ini";
22 1     1   6  
  1         2  
  1         52  
23 1     1   6 use constant Namespaces => "http://xml.org/sax/features/namespaces";
  1         2  
  1         2812  
24             use constant Validation => "http://xml.org/sax/features/validation";
25              
26             my $known_parsers = undef;
27              
28             # load_parsers takes the ParserDetails.ini file out of the same directory
29             # that XML::SAX is in, and looks at it. Format in POD below
30              
31             #line 45
32              
33             sub load_parsers {
34             my $class = shift;
35             my $dir = shift;
36            
37             # reset parsers
38             $known_parsers = [];
39            
40             # get directory from wherever XML::SAX is installed
41             if (!$dir) {
42             $dir = $INC{'XML/SAX.pm'};
43             $dir = dirname($dir);
44             }
45            
46             my $fh = gensym();
47 1     1 0 2 if (!open($fh, File::Spec->catfile($dir, "SAX", PARSER_DETAILS))) {
48 1         3 XML::SAX->do_warn("could not find " . PARSER_DETAILS . " in $dir/SAX\n");
49             return $class;
50             }
51 1         2  
52             $known_parsers = $class->_parse_ini_file($fh);
53              
54 1 50       3 return $class;
55 1         3 }
56 1         69  
57             sub _parse_ini_file {
58             my $class = shift;
59 1         7 my ($fh) = @_;
60 1 50       109  
61 1         8 my @config;
62 1         4
63             my $lineno = 0;
64             while (defined(my $line = <$fh>)) {
65 0         0 $lineno++;
66             my $original = $line;
67 0         0 # strip whitespace
68             $line =~ s/\s*$//m;
69             $line =~ s/^\s*//m;
70             # strip comments
71 0     0   0 $line =~ s/[#;].*$//m;
72 0         0 # ignore blanks
73             next if $line =~ /^$/m;
74 0         0
75             # heading
76 0         0 if ($line =~ /^\[\s*(.*)\s*\]$/m) {
77 0         0 push @config, { Name => $1 };
78 0         0 next;
79 0         0 }
80            
81 0         0 # instruction
82 0         0 elsif ($line =~ /^(.*?)\s*?=\s*(.*)$/) {
83             unless(@config) {
84 0         0 push @config, { Name => '' };
85             }
86 0 0       0 $config[-1]{Features}{$1} = $2;
87             }
88              
89 0 0       0 # not whitespace, comment, or instruction
    0          
90 0         0 else {
91 0         0 die "Invalid line in ini: $lineno\n>>> $original\n";
92             }
93             }
94              
95             return \@config;
96 0 0       0 }
97 0         0  
98             sub parsers {
99 0         0 my $class = shift;
100             if (!$known_parsers) {
101             $class->load_parsers();
102             }
103             return $known_parsers;
104 0         0 }
105              
106             sub remove_parser {
107             my $class = shift;
108 0         0 my ($parser_module) = @_;
109              
110             if (!$known_parsers) {
111             $class->load_parsers();
112 1     1 0 1 }
113 1 50       4
114 1         5 @$known_parsers = grep { $_->{Name} ne $parser_module } @$known_parsers;
115              
116 1         13 return $class;
117             }
118            
119             sub add_parser {
120 0     0 0 0 my $class = shift;
121 0         0 my ($parser_module) = @_;
122              
123 0 0       0 if (!$known_parsers) {
124 0         0 $class->load_parsers();
125             }
126            
127 0         0 # first load module, then query features, then push onto known_parsers,
  0         0  
128            
129 0         0 my $parser_file = $parser_module;
130             $parser_file =~ s/::/\//g;
131             $parser_file .= ".pm";
132              
133 0     0 0 0 require $parser_file;
134 0         0  
135             my @features = $parser_module->supported_features();
136 0 0       0
137 0         0 my $new = { Name => $parser_module };
138             foreach my $feature (@features) {
139             $new->{Features}{$feature} = 1;
140             }
141              
142 0         0 # If exists in list already, move to end.
143 0         0 my $done = 0;
144 0         0 my $pos = undef;
145             for (my $i = 0; $i < @$known_parsers; $i++) {
146 0         0 my $p = $known_parsers->[$i];
147             if ($p->{Name} eq $parser_module) {
148 0         0 $pos = $i;
149             }
150 0         0 }
151 0         0 if (defined $pos) {
152 0         0 splice(@$known_parsers, $pos, 1);
153             push @$known_parsers, $new;
154             $done++;
155             }
156 0         0  
157 0         0 # Otherwise (not in list), add at end of list.
158 0         0 if (!$done) {
159 0         0 push @$known_parsers, $new;
160 0 0       0 }
161 0         0
162             return $class;
163             }
164 0 0       0  
165 0         0 sub save_parsers {
166 0         0 my $class = shift;
167 0         0
168             ### DEBIAN MODIFICATION
169             print "\n";
170             print "Please use 'update-perl-sax-parsers(8) to register this parser.'\n";
171 0 0       0 print "See /usr/share/doc/libxml-sax-perl/README.Debian.gz for more info.\n";
172 0         0 print "\n";
173              
174             return $class; # rest of the function is disabled on Debian.
175 0         0 ### END DEBIAN MODIFICATION
176              
177             # get directory from wherever XML::SAX is installed
178             my $dir = $INC{'XML/SAX.pm'};
179 0     0 0 0 $dir = dirname($dir);
180            
181             my $file = File::Spec->catfile($dir, "SAX", PARSER_DETAILS);
182 0         0 chmod 0644, $file;
183 0         0 unlink($file);
184 0         0
185 0         0 my $fh = gensym();
186             open($fh, ">$file") ||
187 0         0 die "Cannot write to $file: $!";
188              
189             foreach my $p (@$known_parsers) {
190             print $fh "[$p->{Name}]\n";
191 0         0 foreach my $key (keys %{$p->{Features}}) {
192 0         0 print $fh "$key = $p->{Features}{$key}\n";
193             }
194 0         0 print $fh "\n";
195 0         0 }
196 0         0  
197             print $fh "\n";
198 0         0  
199 0 0       0 close $fh;
200              
201             return $class;
202 0         0 }
203 0         0  
204 0         0 sub save_parsers_debian {
  0         0  
205 0         0 my $class = shift;
206             my ($parser_module,$directory, $priority) = @_;
207 0         0  
208             # add parser
209             $known_parsers = [];
210 0         0 $class->add_parser($parser_module);
211            
212 0         0 # get parser's ParserDetails file
213             my $file = $parser_module;
214 0         0 $file = "${priority}-$file" if $priority != 0;
215             $file = File::Spec->catfile($directory, $file);
216             chmod 0644, $file;
217             unlink($file);
218 0     0 0 0
219 0         0 my $fh = gensym();
220             open($fh, ">$file") ||
221             die "Cannot write to $file: $!";
222 0         0  
223 0         0 foreach my $p (@$known_parsers) {
224             print $fh "[$p->{Name}]\n";
225             foreach my $key (keys %{$p->{Features}}) {
226 0         0 print $fh "$key = $p->{Features}{$key}\n";
227 0 0       0 }
228 0         0 print $fh "\n";
229 0         0 }
230 0         0  
231             print $fh "\n";
232 0         0  
233 0 0       0 close $fh;
234              
235             return $class;
236 0         0 }
237 0         0  
238 0         0 sub do_warn {
  0         0  
239 0         0 my $class = shift;
240             # Don't output warnings if running under Test::Harness
241 0         0 warn(@_) unless $ENV{HARNESS_ACTIVE};
242             }
243              
244 0         0 1;
245             __END__