drd: Improve thread startup code for non-Linux platforms
[valgrind.git] / helgrind / tests / filter_xml
blob6de080af460c1f9102a9671840baac63e6348091
1 #!/usr/bin/env perl
3 #---------------------------------------------------------------------
4 # Quick and dirty program to filter helgrind's XML output.
5 #
6 # The script works line-by-line and is generally unaware of XML structure
7 # and does not bother with issues of well-formedness.
9 # Consists of two parts
10 # (1) Global match and replace (see PATTERNS below)
11 # (2) Removal of stack frames
12 # Stack frames whose associated file name does not match any name in
13 # TOOL_FILES or in the list of files given on the command line
14 # will be discarded. For a sequence of one or more discarded frames
15 # a line <frame>...</frame> will be inserted.
17 #---------------------------------------------------------------------
19 use warnings;
20 use strict;
22 #---------------------------------------------------------------------
23 # A list of files specific to the tool at hand. Line numbers in
24 # these files will be removed from stack frames matching these files.
25 #---------------------------------------------------------------------
26 my @tool_files = ( "hg_intercepts.c", "vg_replace_malloc.c" );
28 # List of patterns and replacement strings.
29 # Each pattern must identify a substring which will be replaced.
30 my %patterns = (
31 "<pid>(.*)</pid>" => "...",
32 "<ppid>(.*)</ppid>" => "...",
33 "<time>(.*)</time>" => "...",
34 "<obj>(.*)</obj>" => "...",
35 "<dir>(.*)</dir>" => "...",
36 "<exe>(.*)</exe>" => "...",
37 "<tid>(.*)</tid>" => "...",
38 "<unique>(.*)</unique>" => "...",
39 "thread #([0-9]+)" => "x",
40 "0x([0-9a-zA-Z]+)" => "........",
41 "Using Valgrind-([^\\s]*)" => "X.Y.X",
42 "Copyright \\(C\\) ([0-9]{4}-[0-9]{4}).*" => "XXXX-YYYY",
43 '<fn>pthread_.*(@\*)</fn>' => ""
46 # List of XML sections to be ignored.
47 my %ignore_sections = (
48 "<errorcounts>" => "</errorcounts>",
49 "<suppcounts>" => "</suppcounts>"
53 # If FILE matches any of the FILES return 1
54 sub file_matches ($$) {
55 my ($file, $files) = @_;
56 my ($string, $qstring);
58 foreach $string (@$files) {
59 $qstring = quotemeta($string);
60 return 1 if ($file =~ /$qstring/);
63 return 0;
67 my $frame_buf = "";
68 my ($file, $lineno, $in_frame, $keep_frame, $num_discarded, $ignore_line);
70 $in_frame = $keep_frame = $num_discarded = $ignore_line = 0;
72 line:
73 while (<STDIN>) {
74 my $line = $_;
75 chomp($line);
77 # Check whether we're ignoring this piece of XML..
78 if ($ignore_line) {
79 foreach my $tag (keys %ignore_sections) {
80 if ($line =~ $ignore_sections{$tag}) {
81 print "$tag...$ignore_sections{$tag}\n";
82 $ignore_line = 0;
83 next line;
86 } else {
87 foreach my $tag (keys %ignore_sections) {
88 if ($line =~ $tag) {
89 $ignore_line = 1;
94 next if ($ignore_line);
96 # OK. This line is not to be ignored.
98 # Massage line by applying PATTERNS.
99 foreach my $key (keys %patterns) {
100 if ($line =~ $key) {
101 my $matched = quotemeta($1);
102 $line =~ s/$matched/$patterns{$key}/g;
106 # Handle frames
107 if ($in_frame) {
108 if ($line =~ /<\/frame>/) {
109 $frame_buf .= "$line\n";
110 # The end of a frame
111 if ($keep_frame) {
112 # First: If there were any preceding frames that were discarded
113 # print <frame>...</frame>
114 if ($num_discarded) {
115 print " <frame>...</frame>\n";
116 $num_discarded = 0;
118 # Secondly: Write out the frame itself
119 print "$frame_buf";
120 } else {
121 # We don't want to write this frame
122 ++$num_discarded;
124 $in_frame = $keep_frame = 0;
125 $file = "";
126 } elsif ($line =~ /<file>(.*)<\/file>/) {
127 $frame_buf .= "$line\n";
128 $file = $1;
129 if (file_matches($file, \@tool_files) ||
130 file_matches($file, \@ARGV)) {
131 $keep_frame = 1;
133 } elsif ($line =~ /<line>(.*)<\/line>/) {
134 # This code assumes that <file> always precedes <line>
135 $lineno = $1;
136 if (file_matches($file, \@tool_files)) {
137 $line =~ s/$1/.../;
139 $frame_buf .= "$line\n";
140 } else {
141 $frame_buf .= "$line\n";
143 } else {
144 # not within frame
145 if ($line =~ /<\/stack>/) {
146 print " <frame>...</frame>\n" if ($num_discarded);
147 $num_discarded = 0;
149 if ($line =~ /<frame>/) {
150 $in_frame = 1;
151 $frame_buf = "$line\n";
152 } else {
153 print "$line\n";
158 exit 0;