File Coverage

blib/lib/XML/SAX/PurePerl/DocType.pm
Criterion Covered Total %
statement 37 81 45.6
branch 10 42 23.8
condition 1 27 3.7
subroutine 6 10 60.0
pod 0 8 0.0
total 54 168 32.1


line stmt bran cond sub pod time code
1             # $Id$
2              
3             package XML::SAX::PurePerl;
4              
5 12     12   60 use strict;
  12         24  
  12         503  
6 12     12   69 use XML::SAX::PurePerl::Productions qw($PubidChar);
  12         19  
  12         16311  
7              
8             sub doctypedecl {
9 19     19 0 40 my ($self, $reader) = @_;
10            
11 19         63 my $data = $reader->data(9);
12 19 100       112 if ($data =~ /^
13 1         5 $reader->move_along(9);
14 1 50       4 $self->skip_whitespace($reader) ||
15             $self->parser_error("No whitespace after doctype declaration", $reader);
16            
17 1   33     7 my $root_name = $self->Name($reader) ||
18             $self->parser_error("Doctype declaration has no root element name", $reader);
19            
20 1 50       5 if ($self->skip_whitespace($reader)) {
21             # might be externalid...
22 1         116 my %dtd = $self->ExternalID($reader);
23             # TODO: Call SAX event
24             }
25            
26 1         5 $self->skip_whitespace($reader);
27            
28 1         4 $self->InternalSubset($reader);
29            
30 1 50       4 $reader->match('>') or $self->parser_error("Doctype not closed", $reader);
31            
32 1         6 return 1;
33             }
34            
35 18         101 return 0;
36             }
37              
38             sub ExternalID {
39 1     1 0 3 my ($self, $reader) = @_;
40            
41 1         5 my $data = $reader->data(6);
42            
43 1 50       7 if ($data =~ /^SYSTEM/) {
    0          
44 1         5 $reader->move_along(6);
45 1 50       3 $self->skip_whitespace($reader) ||
46             $self->parser_error("No whitespace after SYSTEM identifier", $reader);
47 1         4 return (SYSTEM => $self->SystemLiteral($reader));
48             }
49             elsif ($data =~ /^PUBLIC/) {
50 0         0 $reader->move_along(6);
51 0 0       0 $self->skip_whitespace($reader) ||
52             $self->parser_error("No whitespace after PUBLIC identifier", $reader);
53            
54 0   0     0 my $quote = $self->quote($reader) ||
55             $self->parser_error("Not a quote character in PUBLIC identifier", $reader);
56            
57 0         0 my $data = $reader->data;
58 0         0 my $pubid = '';
59 0         0 while(1) {
60 0 0       0 $self->parser_error("EOF while looking for end of PUBLIC identifiier", $reader)
61             unless length($data);
62            
63 0 0       0 if ($data =~ /^([^$quote]*)$quote/) {
64 0         0 $pubid .= $1;
65 0         0 $reader->move_along(length($1) + 1);
66 0         0 last;
67             }
68             else {
69 0         0 $pubid .= $data;
70 0         0 $reader->move_along(length($data));
71 0         0 $data = $reader->data;
72             }
73             }
74            
75 0 0       0 if ($pubid !~ /^($PubidChar)+$/) {
76 0         0 $self->parser_error("Invalid characters in PUBLIC identifier", $reader);
77             }
78            
79 0 0       0 $self->skip_whitespace($reader) ||
80             $self->parser_error("Not whitespace after PUBLIC ID in DOCTYPE", $reader);
81            
82 0         0 return (PUBLIC => $pubid,
83             SYSTEM => $self->SystemLiteral($reader));
84             }
85             else {
86 0         0 return;
87             }
88            
89 0         0 return 1;
90             }
91              
92             sub SystemLiteral {
93 1     1 0 3 my ($self, $reader) = @_;
94            
95 1         5 my $quote = $self->quote($reader);
96            
97 1         4 my $data = $reader->data;
98 1         3 my $systemid = '';
99 1         1 while (1) {
100 1 50       12 $self->parser_error("EOF found while looking for end of Sytem Literal", $reader)
101             unless length($data);
102 1 50       100 if ($data =~ /^([^$quote]*)$quote/) {
103 1         4 $systemid .= $1;
104 1         5 $reader->move_along(length($1) + 1);
105 1         15 return $systemid;
106             }
107             else {
108 0         0 $systemid .= $data;
109 0         0 $reader->move_along(length($data));
110 0         0 $data = $reader->data;
111             }
112             }
113             }
114              
115             sub InternalSubset {
116 1     1 0 3 my ($self, $reader) = @_;
117            
118 1 50       10 return 0 unless $reader->match('[');
119            
120 0           1 while $self->IntSubsetDecl($reader);
121            
122 0 0         $reader->match(']') or $self->parser_error("No close bracket on internal subset (found: " . $reader->data, $reader);
123 0           $self->skip_whitespace($reader);
124 0           return 1;
125             }
126              
127             sub IntSubsetDecl {
128 0     0 0   my ($self, $reader) = @_;
129              
130 0   0       return $self->DeclSep($reader) || $self->markupdecl($reader);
131             }
132              
133             sub DeclSep {
134 0     0 0   my ($self, $reader) = @_;
135              
136 0 0         if ($self->skip_whitespace($reader)) {
137 0           return 1;
138             }
139              
140 0 0         if ($self->PEReference($reader)) {
141 0           return 1;
142             }
143            
144             # if ($self->ParsedExtSubset($reader)) {
145             # return 1;
146             # }
147            
148 0           return 0;
149             }
150              
151             sub PEReference {
152 0     0 0   my ($self, $reader) = @_;
153            
154 0 0         return 0 unless $reader->match('%');
155            
156 0   0       my $peref = $self->Name($reader) ||
157             $self->parser_error("PEReference did not find a Name", $reader);
158             # TODO - load/parse the peref
159            
160 0 0         $reader->match(';') or $self->parser_error("Invalid token in PEReference", $reader);
161 0           return 1;
162             }
163              
164             sub markupdecl {
165 0     0 0   my ($self, $reader) = @_;
166            
167 0 0 0       if ($self->elementdecl($reader) ||
      0        
      0        
      0        
      0        
168             $self->AttlistDecl($reader) ||
169             $self->EntityDecl($reader) ||
170             $self->NotationDecl($reader) ||
171             $self->PI($reader) ||
172             $self->Comment($reader))
173             {
174 0           return 1;
175             }
176            
177 0           return 0;
178             }
179              
180             1;