1 package Test::Valgrind::Parser::Suppressions::Text;
8 Test::Valgrind::Parser::Suppressions::Text - Parse valgrind suppressions output as text blocks.
16 our $VERSION = '1.02';
20 This class provides a default C<parse_suppressions> method, so that real tools for which suppressions are meaningful can exploit it by inheriting.
22 It's not meant to be used directly as a tool.
26 use base qw/Test::Valgrind::Carp/;
32 Just a croaking stub to remind you not to use this class as a real tool.
34 If your tool both inherit from this class and from C<Test::Valgrind::Tool>, and that you want to dispatch the call to your C<new> to its ancestors', be careful with C<SUPER> which may end up calling this dieing version of C<new>.
35 The solution is to either put C<Test::Valgrind::Tool> first in the C<@ISA> list or to explicitely call C<Test::Valgrind::Tool::new> instead of C<SUPER::new>.
39 sub new { shift->_croak('This mock tool isn\'t meant to be used directly') }
41 =head2 C<report_class>
43 Generated reports are C<Test::Valgrind::Report::Suppressions> objects.
44 Their C<data> member contains the raw text of the suppression.
48 sub report_class { 'Test::Valgrind::Report::Suppressions' }
50 =head2 C<parse $session, $fh>
52 Parses the filehandle C<$fh> fed with the output of F<valgrind --gen-suppressions=all> and sends a report to the session C<$session> for each suppression.
57 my ($self, $sess, $fh) = @_;
59 my ($s, $in) = ('', 0);
63 s/^\s*#\s//; # Strip comments
65 next if /^==/; # Valgrind info line
66 next if /valgrind/; # and /\Q$file\E/;
68 s/^\s*//; # Strip leading spaces
69 s/<[^>]+>//; # Strip tags
70 s/\s*$//; # Strip trailing spaces
73 if ($_ eq '{') { # A suppression block begins
75 } elsif ($_ eq '}') { # A suppression block ends
76 # With valgrind 3.4.0, we can replace unknown series of frames by '...'
77 if ($sess->version ge '3.4.0') {
79 ++$unknown_tail while $s =~ s/(\n)\s*obj:\*\s*$/$1/;
80 $s .= "...\n" if $unknown_tail;
83 push @supps, $s; # Add the suppression that just ended to the list
84 $s = ''; # Reset the state
86 } elsif ($in) { # We're inside a suppresion block
87 $s .= "$_\n"; # Append the current line to the state
94 if (/\bfun:(m|c|re)alloc\b/) {
97 my %call; # Frames to append (if the value is 1) or to prepend (if it's 0)
98 if ($t eq 'm') { # malloc can also be called by calloc or realloc
99 $call{$_} = 1 for qw/calloc realloc/;
100 } elsif ($t eq 're') { # realloc can also call malloc or free
101 $call{$_} = 0 for qw/malloc free/;
102 } elsif ($t eq 'c') { # calloc can also call malloc
103 $call{$_} = 0 for qw/malloc/;
109 $d =~ s/\b(fun:${t}alloc)\b/$call{$_} ? "$1\nfun:$_" : "fun:$_\n$1"/e;
110 # Remove one line for each line added or valgrind will hate us
111 $d =~ s/\n(.+?)\s*$/\n/;
118 $sess->report($self->report_class($sess)->new(
120 kind => 'Suppression',
122 )) for @supps, @extra;
127 L<Test::Valgrind>, L<Test::Valgrind::Tool>.
131 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
133 You can contact me by mail or on C<irc.perl.org> (vincent).
137 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>.
138 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
142 You can find documentation for this module with the perldoc command.
144 perldoc Test::Valgrind::Parser::Suppressions::Text
146 =head1 COPYRIGHT & LICENSE
148 Copyright 2009 Vincent Pit, all rights reserved.
150 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
154 # End of Test::Valgrind::Parser::Suppressions::Text
156 package Test::Valgrind::Report::Suppressions;
158 use base qw/Test::Valgrind::Report/;
160 sub kinds { shift->SUPER::kinds(), 'Suppression' }
163 my ($self, $kind) = @_;
165 $self->SUPER::valid_kind($kind) or $kind eq 'Suppression'
168 1; # End of Test::Valgrind::Report::Suppressions