File Coverage

blib/lib/XML/LibXML/Error.pm
Criterion Covered Total %
statement 180 194 92.7
branch 32 42 76.1
condition 11 17 64.7
subroutine 49 54 90.7
pod 3 6 50.0
total 275 313 87.8


line stmt bran cond sub pod time code
1             # $Id: Error.pm,v 1.1.2.1 2004/04/20 20:09:48 pajas Exp $
2             #
3             # This is free software, you may use it and distribute it under the same terms as
4             # Perl itself.
5             #
6             # Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas
7             #
8             #
9             package XML::LibXML::Error;
10              
11 67     67   458 use strict;
  67         131  
  67         1983  
12 67     67   361 use warnings;
  67         142  
  67         1847  
13              
14             # To avoid a "Deep recursion on subroutine as_string" warning
15 67     67   384 no warnings 'recursion';
  67         184  
  67         2334  
16              
17 67     67   41492 use Encode ();
  67         726065  
  67         1931  
18              
19 67     67   471 use vars qw(@error_domains $VERSION $WARNINGS);
  67         148  
  67         8532  
20             use overload
21             '""' => \&as_string,
22             'eq' => sub {
23 0     0   0 ("$_[0]" eq "$_[1]")
24             },
25             'cmp' => sub {
26 14     14   4443 ("$_[0]" cmp "$_[1]")
27             },
28 67     67   80123 fallback => 1;
  67         68000  
  67         779  
29              
30             $WARNINGS = 0; # 0: suppress, 1: report via warn, 2: report via die
31             $VERSION = "2.0209"; # VERSION TEMPLATE: DO NOT CHANGE
32              
33 67     67   9403 use constant XML_ERR_NONE => 0;
  67         163  
  67         4044  
34 67     67   457 use constant XML_ERR_WARNING => 1; # A simple warning
  67         160  
  67         3499  
35 67     67   460 use constant XML_ERR_ERROR => 2; # A recoverable error
  67         177  
  67         3416  
36 67     67   404 use constant XML_ERR_FATAL => 3; # A fatal error
  67         144  
  67         3668  
37              
38 67     67   422 use constant XML_ERR_FROM_NONE => 0;
  67         155  
  67         3881  
39 67     67   452 use constant XML_ERR_FROM_PARSER => 1; # The XML parser
  67         163  
  67         4295  
40 67     67   504 use constant XML_ERR_FROM_TREE => 2; # The tree module
  67         186  
  67         3393  
41 67     67   471 use constant XML_ERR_FROM_NAMESPACE => 3; # The XML Namespace module
  67         170  
  67         3552  
42 67     67   473 use constant XML_ERR_FROM_DTD => 4; # The XML DTD validation
  67         166  
  67         3950  
43 67     67   532 use constant XML_ERR_FROM_HTML => 5; # The HTML parser
  67         1354  
  67         4007  
44 67     67   483 use constant XML_ERR_FROM_MEMORY => 6; # The memory allocator
  67         153  
  67         3392  
45 67     67   399 use constant XML_ERR_FROM_OUTPUT => 7; # The serialization code
  67         170  
  67         3425  
46 67     67   475 use constant XML_ERR_FROM_IO => 8; # The Input/Output stack
  67         148  
  67         3410  
47 67     67   460 use constant XML_ERR_FROM_FTP => 9; # The FTP module
  67         183  
  67         3449  
48 67     67   476 use constant XML_ERR_FROM_HTTP => 10; # The FTP module
  67         180  
  67         3432  
49 67     67   454 use constant XML_ERR_FROM_XINCLUDE => 11; # The XInclude processing
  67         160  
  67         3345  
50 67     67   436 use constant XML_ERR_FROM_XPATH => 12; # The XPath module
  67         151  
  67         3302  
51 67     67   448 use constant XML_ERR_FROM_XPOINTER => 13; # The XPointer module
  67         173  
  67         3587  
52 67     67   472 use constant XML_ERR_FROM_REGEXP => 14; # The regular expressions module
  67         141  
  67         3325  
53 67     67   445 use constant XML_ERR_FROM_DATATYPE => 15; # The W3C XML Schemas Datatype module
  67         182  
  67         3387  
54 67     67   437 use constant XML_ERR_FROM_SCHEMASP => 16; # The W3C XML Schemas parser module
  67         189  
  67         3789  
55 67     67   461 use constant XML_ERR_FROM_SCHEMASV => 17; # The W3C XML Schemas validation module
  67         153  
  67         3368  
56 67     67   401 use constant XML_ERR_FROM_RELAXNGP => 18; # The Relax-NG parser module
  67         224  
  67         3430  
57 67     67   470 use constant XML_ERR_FROM_RELAXNGV => 19; # The Relax-NG validator module
  67         519  
  67         3493  
58 67     67   438 use constant XML_ERR_FROM_CATALOG => 20; # The Catalog module
  67         187  
  67         3333  
59 67     67   445 use constant XML_ERR_FROM_C14N => 21; # The Canonicalization module
  67         184  
  67         4136  
60 67     67   447 use constant XML_ERR_FROM_XSLT => 22; # The XSLT engine from libxslt
  67         144  
  67         3701  
61 67     67   427 use constant XML_ERR_FROM_VALID => 23; # The DTD validation module with valid context
  67         148  
  67         5619  
62 67     67   462 use constant XML_ERR_FROM_CHECK => 24; # The error-checking module
  67         200  
  67         3540  
63 67     67   421 use constant XML_ERR_FROM_WRITER => 25; # The xmlwriter module
  67         151  
  67         3494  
64 67     67   432 use constant XML_ERR_FROM_MODULE => 26; # The dynamically-loaded module module
  67         165  
  67         3324  
65 67     67   427 use constant XML_ERR_FROM_I18N => 27; # The module handling character conversion
  67         164  
  67         3244  
66 67     67   419 use constant XML_ERR_FROM_SCHEMATRONV=> 28; # The Schematron validator module
  67         155  
  67         11397  
67              
68             @error_domains = ("", "parser", "tree", "namespace", "validity",
69             "HTML parser", "memory", "output", "I/O", "ftp",
70             "http", "XInclude", "XPath", "xpointer", "regexp",
71             "Schemas datatype", "Schemas parser", "Schemas validity",
72             "Relax-NG parser", "Relax-NG validity",
73             "Catalog", "C14N", "XSLT", "validity", "error-checking",
74             "xmlwriter", "dynamic loading", "i18n",
75             "Schematron validity");
76              
77             my $MAX_ERROR_PREV_DEPTH = 100;
78              
79             for my $field (qw
80             str1 str2 str3 num1 num2 __prev_depth>) {
81 700     700   2801 my $method = sub { $_[0]{$field} };
82 67     67   538 no strict 'refs';
  67         180  
  67         65146  
83             *$field = $method;
84             }
85              
86             {
87              
88             sub new {
89 465     465 0 823 my ($class,$xE) = @_;
90 465         637 my $terr;
91 465 100       1002 if (ref($xE)) {
92 461         2209 my ($context,$column) = $xE->context_and_column();
93 461 100       6602 $terr =bless {
94             domain => $xE->domain(),
95             level => $xE->level(),
96             code => $xE->code(),
97             message => $xE->message(),
98             file => $xE->file(),
99             line => $xE->line(),
100             str1 => $xE->str1(),
101             str2 => $xE->str2(),
102             str3 => $xE->str3(),
103             num1 => $xE->num1(),
104             num2 => $xE->num2(),
105             __prev_depth => 0,
106             (defined($context) ?
107             (
108             context => $context,
109             column => $column,
110             ) : ()),
111             }, $class;
112             } else {
113             # !!!! problem : got a flat error
114             # warn("PROBLEM: GOT A FLAT ERROR $xE\n");
115 4         31 $terr =bless {
116             domain => 0,
117             level => 2,
118             code => -1,
119             message => $xE,
120             file => undef,
121             line => undef,
122             str1 => undef,
123             str2 => undef,
124             str3 => undef,
125             num1 => undef,
126             num2 => undef,
127             __prev_depth => 0,
128             }, $class;
129             }
130 465         1134 return $terr;
131             }
132              
133             sub _callback_error {
134             #print "CALLBACK\n";
135 464     464   3879 my ($xE,$prev) = @_;
136 464         694 my $terr;
137 464         1012 $terr=XML::LibXML::Error->new($xE);
138 464 100 66     2136 if ($terr->{level} == XML_ERR_WARNING and $WARNINGS!=2) {
139 6 50       38 warn $terr if $WARNINGS;
140 6         108 return $prev;
141             }
142             #unless ( defined $terr->{file} and length $terr->{file} ) {
143             # this would make it easier to recognize parsed strings
144             # but it breaks old implementations
145             # [CG] $terr->{file} = 'string()';
146             #}
147             #warn "Saving the error ",$terr->dump;
148              
149 458 100       896 if (ref($prev))
150             {
151 298 50       611 if ($prev->__prev_depth() >= $MAX_ERROR_PREV_DEPTH)
152             {
153 0         0 return $prev;
154             }
155 298         510 $terr->{_prev} = $prev;
156 298         481 $terr->{__prev_depth} = $prev->__prev_depth() + 1;
157             }
158             else
159             {
160 160 50 33     528 $terr->{_prev} = defined($prev) && length($prev) ? XML::LibXML::Error->new($prev) : undef;
161             }
162 458         17598 return $terr;
163             }
164             sub _instant_error_callback {
165 0     0   0 my $xE = shift;
166 0         0 my $terr= XML::LibXML::Error->new($xE);
167 0         0 print "Reporting an instanteous error ",$terr->dump;
168 0         0 die $terr;
169             }
170             sub _report_warning {
171 3     3   18 my ($saved_error) = @_;
172             #print "CALLBACK WARN\n";
173 3 50       17 if ( defined $saved_error ) {
174             #print "reporting a warning ",$saved_error->dump;
175 3         36 warn $saved_error;
176             }
177             }
178             sub _report_error {
179 153     153   459 my ($saved_error) = @_;
180             #print "CALLBACK ERROR: $saved_error\n";
181 153 50       516 if ( defined $saved_error ) {
182 153         787 die $saved_error;
183             }
184             }
185             }
186              
187              
188             # backward compatibility
189 0     0 0 0 sub int1 { $_[0]->num1 }
190 0     0 0 0 sub int2 { $_[0]->num2 }
191              
192             sub domain {
193 956     956 1 3509 my ($self)=@_;
194 956 50       1893 return undef unless ref($self);
195 956         1411 my $domain = $self->{domain};
196             # Newer versions of libxml2 might yield errors in domains that aren't
197             # listed above. Invent something reasonable in that case.
198 956 100       2878 return $domain < @error_domains ? $error_domains[$domain] : "domain_$domain";
199             }
200              
201             sub as_string {
202 953     953 1 18585 my ($self)=@_;
203 953         1585 my $msg = "";
204 953         1188 my $level;
205              
206 953 100       1877 if (defined($self->{_prev})) {
207 567         1216 $msg = $self->{_prev}->as_string;
208             }
209              
210 953 50 66     4113 if ($self->{level} == XML_ERR_NONE) {
    50          
    50          
211 0         0 $level = "";
212             } elsif ($self->{level} == XML_ERR_WARNING) {
213 0         0 $level = "warning";
214             } elsif ($self->{level} == XML_ERR_ERROR ||
215             $self->{level} == XML_ERR_FATAL) {
216 953         1464 $level = "error";
217             }
218 953         1322 my $where="";
219 953 100 66     1900 if (defined($self->{file})) {
    100          
220 816         1732 $where="$self->{file}:$self->{line}";
221             } elsif (($self->{domain} == XML_ERR_FROM_PARSER)
222             and
223             $self->{line}) {
224 58         126 $where="Entity: line $self->{line}";
225             }
226 953 50       1717 if ($self->{nodename}) {
227 0         0 $where.=": element ".$self->{nodename};
228             }
229 953 100       2559 $msg.=$where.": " if $where ne "";
230 953         1820 $msg.=$self->domain." ".$level." :";
231 953   50     2227 my $str=$self->{message}||"";
232 953         1541 chomp($str);
233 953         1778 $msg.=" ".$str."\n";
234 953 100 100     2868 if (($self->{domain} == XML_ERR_FROM_XPATH) and
    100          
235             defined($self->{str1})) {
236 20         38 $msg.=$self->{str1}."\n";
237 20         50 $msg.=(" " x $self->{num1})."^\n";
238             } elsif (defined $self->{context}) {
239             # If the error relates to character-encoding problems in the context,
240             # then doing textual operations on it will spew warnings that
241             # XML::LibXML can do nothing to fix. So just disable all such
242             # warnings. This has the pleasing benefit of making the test suite
243             # run warning-free.
244 67     67   567 no warnings 'utf8';
  67         249  
  67         16741  
245 838         1936 my $context = Encode::encode('UTF-8', $self->{context});
246 838         36781 $msg.=$context."\n";
247 838         1718 $context = substr($context,0,$self->{column});
248 838         9525 $context=~s/[^\t]/ /g;
249 838         1818 $msg.=$context."^\n";
250             }
251 953         4308 return $msg;
252             }
253              
254             sub dump {
255 0     0 1   my ($self)=@_;
256 0           require Data::Dumper;
257 0           return Data::Dumper->new([$self],['error'])->Dump;
258             }
259              
260             1;