1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#!/usr/bin/env perl
2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#-------------------------------------------------------------------
4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Check header files and #include directives
5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (1) include/*.h must not include pub_core_...h
7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (2) coregrind/pub_core_xyzzy.h may include pub_tool_xyzzy.h
8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#     other coregrind headers may not include pub_tool_xyzzy.h
9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (3) coregrind/ *.c must not include pub_tool_xyzzy.h
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (4) tool *.[ch] files must not include pub_core_...h
11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (5) include pub_core/tool_clreq.h instead of valgrind.h except in tools'
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#     export headers
13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#-------------------------------------------------------------------
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovuse strict;
16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovuse warnings;
17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovuse File::Basename;
18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovuse Getopt::Long;
19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $this_script = basename($0);
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# The list of top-level directories is divided into three sets:
23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (1) coregrind directories
25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (2) tool directories
26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# (3) directories to ignore
27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#
28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# If a directory is found that does not belong to any of those sets, the
29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# script will terminate unsuccessfully.
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy %coregrind_dirs = (
32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "include" => 1,
33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "coregrind" => 1,
34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    );
35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy %tool_dirs = (
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "none" => 1,
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "lackey" => 1,
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "massif" => 1,
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "memcheck" => 1,
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "drd" => 1,
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "helgrind", => 1,
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "callgrind" => 1,
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "cachegrind" => 1,
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "shared" => 1,
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "exp-bbv" => 1,
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "exp-dhat" => 1,
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "exp-sgcheck" => 1
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    );
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy %dirs_to_ignore = (
52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    ".deps" => 1,
53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    ".svn" => 1,
54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    ".git" => 1,            # allow git mirrors of the svn repo
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    ".in_place" => 1,
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "Inst" => 1,            # the nightly scripts creates this
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "VEX" => 1,
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "docs" => 1,
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "auxprogs" => 1,
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "autom4te.cache" => 1,
61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "nightly" => 1,
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "perf" => 1,
63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "tests" => 1,
64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "gdbserver_tests" => 1,
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "mpi" => 1
66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    );
67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy %tool_export_header = (
69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "drd/drd.h" => 1,
70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "helgrind/helgrind.h" => 1,
71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "memcheck/memcheck.h" => 1,
72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    "callgrind/callgrind.h" => 1
73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    );
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $usage=<<EOF;
76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovUSAGE
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  $this_script
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    [--debug]          Debugging output
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    dir ...            Directories to process
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovEOF
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $debug = 0;
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovmy $num_errors = 0;
87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov&main;
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub main {
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    GetOptions( "debug"  => \$debug ) || die $usage;
92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $argc = $#ARGV + 1;
94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($argc < 1) {
96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        die $usage;
97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    foreach my $dir (@ARGV) {
100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        process_dir(undef, $dir, 0);
101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $rc = ($num_errors == 0) ? 0 : 1;
104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    exit $rc;
105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub process_dir {
108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path, $dir, $depth) = @_;
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $hdir;
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if ($depth == 0) {
112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# The root directory is always processed
113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } elsif ($depth == 1) {
114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Toplevel directories
115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return if ($dirs_to_ignore{$dir});
116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if (! $tool_dirs{$dir} && ! $coregrind_dirs{$dir}) {
118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            die "Unknown directory '$dir'. Please update $this_script\n";
119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } else {
121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Subdirectories
122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return if ($dirs_to_ignore{$dir});
123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "DIR = $dir   DEPTH = $depth\n" if ($debug);
126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    chdir($dir) || die "Cannot chdir '$dir'\n";
128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    opendir($hdir, ".") || die "cannot open directory '.'";
130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    while (my $file = readdir($hdir)) {
132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        next if ($file eq ".");
133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        next if ($file eq "..");
134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Subdirectories
136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if (-d $file) {
137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $full_path = defined $path ? "$path/$file" : $file;
138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            process_dir($full_path, $file, $depth + 1);
139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            next;
140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Regular files; only interested in *.c and *.h
143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        next if (! ($file =~ /\.[ch]$/));
144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        my $path_name = defined $path ? "$path/$file" : $file;
145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        process_file($path_name);
146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    close($hdir);
148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    chdir("..") || die "Cannot chdir '..'\n";
149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Return 1, if file is located in <valgrind>/include
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub is_coregrind_export_header {
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return ($path_name =~ /^include\//) ? 1 : 0;
158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Return 1, if file is located underneath <valgrind>/coregrind
162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub is_coregrind_file {
164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return ($path_name =~ /^coregrind\//) ? 1 : 0;
167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Return 1, if file is located underneath <valgrind>/<tool>
171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub is_tool_file {
173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    for my $tool (keys %tool_dirs) {
176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        return 1 if ($path_name =~ /^$tool\//);
177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return 0
179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Return array of files #include'd by file.
183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub get_included_files {
185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my @includes = ();
187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $file = basename($path_name);
188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    open(FILE, "<$file") || die "Cannot open file '$file'";
190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    while (my $line = <FILE>) {
192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($line =~ /^\s*#\s*include "([^"]*)"/) {
193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            push @includes, $1;
194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($line =~ /^\s*#\s*include <([^>]*)>/) {
196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            push @includes, $1;
197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    close FILE;
200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    return @includes;
201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Check a file from <valgrind>/include
205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub check_coregrind_export_header {
207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    foreach my $inc (get_included_files($path_name)) {
210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        $inc = basename($inc);
211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Must not include pub_core_....
212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($inc =~ /pub_core_/) {
213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            error("File $path_name must not include $inc\n");
214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Only pub_tool_clreq.h may include valgrind.h
216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if (($inc eq "valgrind.h") && ($path_name ne "include/pub_tool_clreq.h")) {
217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            error("File $path_name should include pub_tool_clreq.h instead of $inc\n");
218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Check a file from <valgrind>/coregrind
224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub check_coregrind_file {
226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $file = basename($path_name);
228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    foreach my $inc (get_included_files($path_name)) {
230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        print "\tINCLUDE $inc\n" if ($debug);
231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Only pub_tool_xyzzy.h may include pub_core_xyzzy.h
232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($inc =~ /pub_tool_/) {
233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            my $buddy = $inc;
234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            $buddy =~ s/pub_tool/pub_core/;
235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if ($file ne $buddy) {
236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                error("File $path_name must not include $inc\n");
237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Must not include valgrind.h
240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($inc eq "valgrind.h") {
241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            error("File $path_name should include pub_core_clreq.h instead of $inc\n");
242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Check a file from <valgrind>/<tool>
248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#---------------------------------------------------------------------
249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub check_tool_file {
250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my $file = basename($path_name);
252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    foreach my $inc (get_included_files($path_name)) {
254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        print "\tINCLUDE $inc\n" if ($debug);
255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Must not include pub_core_...
256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($inc =~ /pub_core_/) {
257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            error("File $path_name must not include $inc\n");
258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# Must not include valgrind.h unless this is an export header
260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        if ($inc eq "valgrind.h" && ! $tool_export_header{$path_name}) {
261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            error("File $path_name should include pub_tool_clreq.h instead of $inc\n");
262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        }
263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub process_file {
267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($path_name) = @_;
268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print "FILE = $path_name\n" if ($debug);
270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    if (is_coregrind_export_header($path_name)) {
272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        check_coregrind_export_header($path_name);
273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } elsif (is_coregrind_file($path_name)) {
274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        check_coregrind_file($path_name);
275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    } elsif (is_tool_file($path_name)) {
276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        check_tool_file($path_name);
277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    }
278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsub error {
281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    my ($message) = @_;
282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    print STDERR "*** $message";
283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    ++$num_errors;
284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
285