]> git.vpit.fr Git - perl/modules/Test-Valgrind.git/blob - lib/Test/Valgrind/Parser/Suppressions/Text.pm
03a9556a1dc070477511c088ca439788a93dea6e
[perl/modules/Test-Valgrind.git] / lib / Test / Valgrind / Parser / Suppressions / Text.pm
1 package Test::Valgrind::Parser::Suppressions::Text;
2
3 use strict;
4 use warnings;
5
6 =head1 NAME
7
8 Test::Valgrind::Parser::Suppressions::Text - Parse valgrind suppressions output as text blocks.
9
10 =head1 VERSION
11
12 Version 1.10
13
14 =cut
15
16 our $VERSION = '1.10';
17
18 =head1 DESCRIPTION
19
20 This is a L<Test::Valgrind::Parser> object that can extract suppressions from C<valgrind>'s text output.
21
22 =cut
23
24 use base qw/Test::Valgrind::Parser::Text Test::Valgrind::Carp/;
25
26 =head1 METHODS
27
28 =head2 C<report_class>
29
30 Generated reports are C<Test::Valgrind::Report::Suppressions> objects.
31 Their C<data> member contains the raw text of the suppression.
32
33 =cut
34
35 sub report_class { 'Test::Valgrind::Report::Suppressions' }
36
37 =head2 C<parse $session, $fh>
38
39 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.
40
41 =cut
42
43 sub parse {
44  my ($self, $sess, $fh) = @_;
45
46  my ($s, $in) = ('', 0);
47  my @supps;
48
49  while (<$fh>) {
50   s/^\s*#\s//;        # Strip comments
51
52   next if /^==/;      # Valgrind info line
53   next if /valgrind/; # and /\Q$file\E/;
54
55   s/^\s*//;           # Strip leading spaces
56   s/<[^>]+>//;        # Strip tags
57   s/\s*$//;           # Strip trailing spaces
58   next unless length;
59
60   if ($_ eq '{') {      # A suppression block begins
61    $in = 1;
62   } elsif ($_ eq '}') { # A suppression block ends
63    # With valgrind 3.4.0, we can replace unknown series of frames by '...'
64    if ($sess->version ge '3.4.0') {
65     my $unknown_tail;
66     ++$unknown_tail while $s =~ s/(\n)\s*obj:\*\s*$/$1/;
67     $s .= "...\n" if $unknown_tail;
68    }
69
70    push @supps, $s;     # Add the suppression that just ended to the list
71    $s  = '';            # Reset the state
72    $in = 0;
73   } elsif ($in) {       # We're inside a suppresion block
74    $s .= "$_\n";        # Append the current line to the state
75   }
76  }
77
78  my @extra;
79
80  for (@supps) {
81   if (/\bfun:(m|c|re)alloc\b/) {
82    my $t = $1;
83
84    my %call; # Frames to append (if the value is 1) or to prepend (if it's 0)
85    if ($t eq 'm') {       # malloc can also be called by calloc or realloc
86     $call{$_} = 1 for qw/calloc realloc/;
87    } elsif ($t eq 're') { # realloc can also call malloc or free
88     $call{$_} = 0 for qw/malloc free/;
89    } elsif ($t eq 'c') {  # calloc can also call malloc
90     $call{$_} = 0 for qw/malloc/;
91    }
92
93    my $c = $_;
94    for (keys %call) {
95     my $d = $c;
96     $d =~ s/\b(fun:${t}alloc)\b/$call{$_} ? "$1\nfun:$_" : "fun:$_\n$1"/e;
97     # Remove one line for each line added or valgrind will hate us
98     $d =~ s/\n(.+?)\s*$/\n/;
99     push @extra, $d;
100    }
101   }
102  }
103
104  my $num;
105  $sess->report($self->report_class($sess)->new(
106   id   => ++$num,
107   kind => 'Suppression',
108   data => $_,
109  )) for @supps, @extra;
110 }
111
112 =head1 SEE ALSO
113
114 L<Test::Valgrind>, L<Test::Valgrind::Parser::Text>.
115
116 =head1 AUTHOR
117
118 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
119
120 You can contact me by mail or on C<irc.perl.org> (vincent).
121
122 =head1 BUGS
123
124 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>.
125 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
126
127 =head1 SUPPORT
128
129 You can find documentation for this module with the perldoc command.
130
131     perldoc Test::Valgrind::Parser::Suppressions::Text
132
133 =head1 COPYRIGHT & LICENSE
134
135 Copyright 2009 Vincent Pit, all rights reserved.
136
137 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
138
139 =cut
140
141 # End of Test::Valgrind::Parser::Suppressions::Text
142
143 package Test::Valgrind::Report::Suppressions;
144
145 use base qw/Test::Valgrind::Report/;
146
147 sub kinds { shift->SUPER::kinds(), 'Suppression' }
148
149 sub valid_kind {
150  my ($self, $kind) = @_;
151
152  $self->SUPER::valid_kind($kind) or $kind eq 'Suppression'
153 }
154
155 1; # End of Test::Valgrind::Report::Suppressions