1 package Test::Valgrind::Parser::XML::Twig;
8 Test::Valgrind::Parser::XML::Twig - Parse valgrind XML output with XML::Twig.
16 our $VERSION = '1.10';
20 use base qw/Test::Valgrind::Parser::XML Test::Valgrind::Carp XML::Twig/;
22 BEGIN { XML::Twig->add_options('Stash'); }
25 '/valgrindoutput/protocolversion' => \&handle_version,
26 '/valgrindoutput/error' => \&handle_error,
35 $class = ref($class) || $class;
38 my $stash = delete $args{stash} || { };
40 bless $class->XML::Twig::new(
41 elt_class => __PACKAGE__ . '::Elt',
43 twig_roots => { map { $_ => 1 } keys %handlers },
44 twig_handlers => { map { $_ => $handlers{$_} } keys %handlers },
48 sub stash { shift->{Stash} }
50 =head2 C<protocol_version>
52 The version of the protocol that the stream is currently conforming to.
56 eval "sub $_ { \@_ <= 1 ? \$_[0]->{$_} : (\$_[0]->{$_} = \$_[1]) }"
57 for qw/_session protocol_version/;
59 # We must store the session in ourselves because it's only possible to pass
60 # arguments to XML::Twig objects by a global stash.
63 my ($self, $sess) = @_;
65 $self->SUPER::start($sess);
66 $self->_session($sess);
72 my ($self, $sess, $fh) = @_;
74 $self->XML::Twig::parse($fh);
81 my ($self, $sess) = @_;
83 $self->_session(undef);
84 $self->SUPER::finish($sess);
90 my ($twig, $node) = @_;
92 $twig->protocol_version($node->text);
98 my ($twig, $node) = @_;
100 my $id = $node->kid('unique')->text;
101 my $kind = $node->kid('kind')->text;
106 if ($twig->protocol_version >= 4) {
107 $xwhat = $node->first_child('xwhat');
108 $what = $xwhat->kid('text')->text if defined $xwhat;
110 $what = $node->kid('what')->text unless defined $what;
111 $data->{what} = $what;
113 $data->{stack} = [ map $_->listify_frame,
114 $node->kid('stack')->children('frame') ];
116 for (qw/leakedbytes leakedblocks/) {
117 my $kid = ($xwhat || $node)->first_child($_);
119 $data->{$_} = int $kid->text;
122 if (my $auxwhat = $node->first_child('auxwhat')) {
123 if (my $stack = $auxwhat->next_sibling('stack')) {
124 $data->{auxstack} = [ map $_->listify_frame, $stack->children('frame') ];
126 $data->{auxwhat} = $auxwhat->text;
129 if (my $origin = $node->first_child('origin')) {
130 $data->{origwhat} = $origin->kid('what')->text;
131 $data->{origstack} = [ map $_->listify_frame,
132 $origin->kid('stack')->children('frame') ];
135 my $sess = $twig->_session;
137 $sess->report($sess->report_class($sess)->new(
148 L<Test::Valgrind>, L<Test::Valgrind::Parser>, L<Test::Valgrind::Parser::XML>.
154 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
156 You can contact me by mail or on C<irc.perl.org> (vincent).
160 Please report any bugs or feature requests to C<bug-test-valgrind at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Valgrind>.
161 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
165 You can find documentation for this module with the perldoc command.
167 perldoc Test::Valgrind::Parser::XML::Twig
169 =head1 COPYRIGHT & LICENSE
171 Copyright 2009 Vincent Pit, all rights reserved.
173 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
177 # End of Test::Valgrind::Parser::XML::Twig
179 package Test::Valgrind::Parser::XML::Twig::Elt;
181 our $VERSION = '1.10';
183 BEGIN { require XML::Twig; }
185 use base qw/XML::Twig::Elt Test::Valgrind::Carp/;
188 my ($self, $what) = @_;
189 my $node = $self->first_child($what);
190 $self->_croak("Couldn't get first $what child node") unless $node;
197 return unless $frame->tag eq 'frame';
201 my $x = $frame->first_child($_);
202 $x ? $x->text : undef
203 } qw/ip obj fn dir file line/
207 1; # End of Test::Valgrind::Parser::XML::Twig::Elt