File Coverage

blib/lib/XML/LibXML/Error.pm
Criterion Covered Total %
statement 181 194 93.3
branch 33 42 78.5
condition 11 17 64.7
subroutine 49 54 90.7
pod 3 6 50.0
total 277 313 88.5


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   395 use strict;
  67         114  
  67         1643  
12 67     67   279 use warnings;
  67         102  
  67         1577  
13              
14             # To avoid a "Deep recursion on subroutine as_string" warning
15 67     67   307 no warnings 'recursion';
  67         141  
  67         2041  
16              
17 67     67   34292 use Encode ();
  67         614233  
  67         1786  
18              
19 67     67   447 use vars qw(@error_domains $VERSION $WARNINGS);
  67         125  
  67         7304  
20             use overload
21             '""' => \&as_string,
22             'eq' => sub {
23 0     0   0 ("$_[0]" eq "$_[1]")
24             },
25             'cmp' => sub {
26 12     12   3164 ("$_[0]" cmp "$_[1]")
27             },
28 67     67   66268 fallback => 1;
  67         56016  
  67         705  
29              
30             $WARNINGS = 0; # 0: suppress, 1: report via warn, 2: report via die
31             $VERSION = "2.0208"; # VERSION TEMPLATE: DO NOT CHANGE
32              
33 67     67   7058 use constant XML_ERR_NONE => 0;
  67         137  
  67         4075  
34 67     67   378 use constant XML_ERR_WARNING => 1; # A simple warning
  67         139  
  67         2832  
35 67     67   354 use constant XML_ERR_ERROR => 2; # A recoverable error
  67         131  
  67         2976  
36 67     67   363 use constant XML_ERR_FATAL => 3; # A fatal error
  67         122  
  67         2970  
37              
38 67     67   361 use constant XML_ERR_FROM_NONE => 0;
  67         155  
  67         3446  
39 67     67   408 use constant XML_ERR_FROM_PARSER => 1; # The XML parser
  67         137  
  67         3635  
40 67     67   428 use constant XML_ERR_FROM_TREE => 2; # The tree module
  67         126  
  67         3019  
41 67     67   394 use constant XML_ERR_FROM_NAMESPACE => 3; # The XML Namespace module
  67         140  
  67         3056  
42 67     67   384 use constant XML_ERR_FROM_DTD => 4; # The XML DTD validation
  67         142  
  67         2965  
43 67     67   422 use constant XML_ERR_FROM_HTML => 5; # The HTML parser
  67         1309  
  67         3836  
44 67     67   439 use constant XML_ERR_FROM_MEMORY => 6; # The memory allocator
  67         128  
  67         2795  
45 67     67   345 use constant XML_ERR_FROM_OUTPUT => 7; # The serialization code
  67         143  
  67         3017  
46 67     67   370 use constant XML_ERR_FROM_IO => 8; # The Input/Output stack
  67         159  
  67         2894  
47 67     67   385 use constant XML_ERR_FROM_FTP => 9; # The FTP module
  67         127  
  67         2882  
48 67     67   374 use constant XML_ERR_FROM_HTTP => 10; # The FTP module
  67         126  
  67         2927  
49 67     67   363 use constant XML_ERR_FROM_XINCLUDE => 11; # The XInclude processing
  67         118  
  67         2939  
50 67     67   369 use constant XML_ERR_FROM_XPATH => 12; # The XPath module
  67         107  
  67         2757  
51 67     67   367 use constant XML_ERR_FROM_XPOINTER => 13; # The XPointer module
  67         146  
  67         2987  
52 67     67   369 use constant XML_ERR_FROM_REGEXP => 14; # The regular expressions module
  67         114  
  67         2943  
53 67     67   370 use constant XML_ERR_FROM_DATATYPE => 15; # The W3C XML Schemas Datatype module
  67         138  
  67         2990  
54 67     67   382 use constant XML_ERR_FROM_SCHEMASP => 16; # The W3C XML Schemas parser module
  67         154  
  67         3251  
55 67     67   425 use constant XML_ERR_FROM_SCHEMASV => 17; # The W3C XML Schemas validation module
  67         133  
  67         2761  
56 67     67   372 use constant XML_ERR_FROM_RELAXNGP => 18; # The Relax-NG parser module
  67         143  
  67         2837  
57 67     67   365 use constant XML_ERR_FROM_RELAXNGV => 19; # The Relax-NG validator module
  67         132  
  67         2903  
58 67     67   382 use constant XML_ERR_FROM_CATALOG => 20; # The Catalog module
  67         132  
  67         2784  
59 67     67   368 use constant XML_ERR_FROM_C14N => 21; # The Canonicalization module
  67         131  
  67         3154  
60 67     67   408 use constant XML_ERR_FROM_XSLT => 22; # The XSLT engine from libxslt
  67         125  
  67         3505  
61 67     67   389 use constant XML_ERR_FROM_VALID => 23; # The DTD validation module with valid context
  67         120  
  67         2923  
62 67     67   426 use constant XML_ERR_FROM_CHECK => 24; # The error-checking module
  67         144  
  67         2988  
63 67     67   412 use constant XML_ERR_FROM_WRITER => 25; # The xmlwriter module
  67         151  
  67         2871  
64 67     67   427 use constant XML_ERR_FROM_MODULE => 26; # The dynamically-loaded module module
  67         153  
  67         2879  
65 67     67   402 use constant XML_ERR_FROM_I18N => 27; # The module handling character conversion
  67         123  
  67         2787  
66 67     67   399 use constant XML_ERR_FROM_SCHEMATRONV=> 28; # The Schematron validator module
  67         185  
  67         9971  
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 2828     2828   5812 my $method = sub { $_[0]{$field} };
82 67     67   436 no strict 'refs';
  67         149  
  67         55271  
83             *$field = $method;
84             }
85              
86             {
87              
88             sub new {
89 2582     2582 0 3572 my ($class,$xE) = @_;
90 2582         2561 my $terr;
91 2582 100       3763 if (ref($xE)) {
92 2578         12344 my ($context,$column) = $xE->context_and_column();
93 2578 100       21845 $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         28 $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 2582         4155 return $terr;
131             }
132              
133             sub _callback_error {
134             #print "CALLBACK\n";
135 2581     2581   7099 my ($xE,$prev) = @_;
136 2581         2697 my $terr;
137 2581         3708 $terr=XML::LibXML::Error->new($xE);
138 2581 100 66     5608 if ($terr->{level} == XML_ERR_WARNING and $WARNINGS!=2) {
139 6 50       19 warn $terr if $WARNINGS;
140 6         88 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 2575 100       3543 if (ref($prev))
150             {
151 2417 100       3133 if ($prev->__prev_depth() >= $MAX_ERROR_PREV_DEPTH)
152             {
153 2111         22689 return $prev;
154             }
155 306         406 $terr->{_prev} = $prev;
156 306         407 $terr->{__prev_depth} = $prev->__prev_depth() + 1;
157             }
158             else
159             {
160 158 50 33     425 $terr->{_prev} = defined($prev) && length($prev) ? XML::LibXML::Error->new($prev) : undef;
161             }
162 464         8398 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   10 my ($saved_error) = @_;
172             #print "CALLBACK WARN\n";
173 3 50       16 if ( defined $saved_error ) {
174             #print "reporting a warning ",$saved_error->dump;
175 3         25 warn $saved_error;
176             }
177             }
178             sub _report_error {
179 151     151   362 my ($saved_error) = @_;
180             #print "CALLBACK ERROR: $saved_error\n";
181 151 50       387 if ( defined $saved_error ) {
182 151         616 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 977     977 1 2600 my ($self)=@_;
194 977 50       1530 return undef unless ref($self);
195 977         1228 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 977 100       2379 return $domain < @error_domains ? $error_domains[$domain] : "domain_$domain";
199             }
200              
201             sub as_string {
202 974     974 1 14999 my ($self)=@_;
203 974         1082 my $msg = "";
204 974         942 my $level;
205              
206 974 100       1560 if (defined($self->{_prev})) {
207 594         1175 $msg = $self->{_prev}->as_string;
208             }
209              
210 974 50 66     3410 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 974         1187 $level = "error";
217             }
218 974         1084 my $where="";
219 974 100 66     1603 if (defined($self->{file})) {
    100          
220 823         1439 $where="$self->{file}:$self->{line}";
221             } elsif (($self->{domain} == XML_ERR_FROM_PARSER)
222             and
223             $self->{line}) {
224 72         112 $where="Entity: line $self->{line}";
225             }
226 974 50       1482 if ($self->{nodename}) {
227 0         0 $where.=": element ".$self->{nodename};
228             }
229 974 100       2123 $msg.=$where.": " if $where ne "";
230 974         1512 $msg.=$self->domain." ".$level." :";
231 974   50     1846 my $str=$self->{message}||"";
232 974         1238 chomp($str);
233 974         1458 $msg.=" ".$str."\n";
234 974 100 100     2347 if (($self->{domain} == XML_ERR_FROM_XPATH) and
    100          
235             defined($self->{str1})) {
236 20         29 $msg.=$self->{str1}."\n";
237 20         38 $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   498 no warnings 'utf8';
  67         122  
  67         14738  
245 859         1559 my $context = Encode::encode('UTF-8', $self->{context});
246 859         31356 $msg.=$context."\n";
247 859         1392 $context = substr($context,0,$self->{column});
248 859         7787 $context=~s/[^\t]/ /g;
249 859         1419 $msg.=$context."^\n";
250             }
251 974         3252 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;