77
82
# files it #include's. Then extract all the symbols it tests for defined-ness,
78
83
# and check each one against the previously built hashtable.
80
foreach $file (@hfiles, @cfiles) {
81
($fname, $fpath) = fileparse($file);
82
chdir $fpath or die "can't chdir to $fpath: $!";
84
# Ask 'make' to parse the makefile so we can get the correct flags to
85
# use. CPPFLAGS in particular varies for each subdirectory. If we are
86
# processing a .h file, we might be in a subdirectory that has no
87
# Makefile, in which case we have to fake it. Note that there seems
88
# no easy way to prevent make from recursing into subdirectories and
89
# hence printing multiple definitions --- we keep the last one, which
90
# should come from the current Makefile.
92
if (-f "Makefile" || -f "GNUmakefile") {
93
$MAKECMD = "$MAKE -qp";
99
while (($tmp = dirname($tmp)) ne '.') {
100
$top_builddir = $top_builddir . "/..";
102
$MAKECMD = "$MAKE -qp 'subdir=$subdir' 'top_builddir=$top_builddir' -f '$top_builddir/src/Makefile.global'";
104
open PIPE, "$MAKECMD |"
105
or die "can't fork: $!";
107
if (m/^CPPFLAGS :?= (.*)/) {
109
} elsif (m/^CFLAGS :?= (.*)/) {
111
} elsif (m/^CFLAGS_SL :?= (.*)/) {
113
} elsif (m/^PTHREAD_CFLAGS :?= (.*)/) {
114
$PTHREAD_CFLAGS = $1;
115
} elsif (m/^CC :?= (.*)/) {
119
# If make exits with status 1, it's not an error, it just means make
120
# thinks some files may not be up-to-date. Only complain on status 2.
122
die "$MAKE failed in $fpath\n" if $? != 0 && $? != 256;
124
# Expand out stuff that might be referenced in CFLAGS
125
$CFLAGS =~ s/\$\(CFLAGS_SL\)/$CFLAGS_SL/;
126
$CFLAGS =~ s/\$\(PTHREAD_CFLAGS\)/$PTHREAD_CFLAGS/;
129
# Run the compiler (which had better be gcc) to get the inclusions.
130
# "gcc -H" reports inclusions on stderr as "... filename" where the
131
# number of dots varies according to nesting depth.
134
$COMPILE = "$CC $CPPFLAGS $CFLAGS -H -E $fname";
135
open PIPE, "$COMPILE 2>&1 >/dev/null |"
136
or die "can't fork: $!";
140
# Ignore system headers (absolute paths); but complain if a
141
# .c file includes a system header before any PG header.
142
if ($include =~ m|^/|) {
143
warn "$file includes $include before any Postgres inclusion\n"
144
if $#includes == -1 && $file =~ m/\.c$/;
147
# Strip any "./" (assume this appears only at front)
148
$include =~ s|^\./||;
149
# Make path relative to top of tree
151
while ($include =~ s|^\.\./||) {
152
$ipath = dirname($ipath) . "/";
155
push @includes, $ipath . $include;
160
# The compiler might fail, particularly if we are checking a file that's
161
# not supposed to be compiled at all on the current platform, so don't
162
# quit on nonzero status.
163
close PIPE or warn "$COMPILE failed in $fpath\n";
166
# Scan the file to find #ifdef, #ifndef, and #if defined() constructs
167
# We assume #ifdef isn't continued across lines, and that defined(foo)
168
# isn't split across lines either
171
or die "can't open $file: $!";
175
if ($line =~ m/^\s*#\s*ifdef\s+(\w+)/) {
179
if ($line =~ m/^\s*#\s*ifndef\s+(\w+)/) {
183
if ($line =~ m/^\s*#\s*if\s+/) {
187
while ($line =~ s/\bdefined(\s+|\s*\(\s*)(\w+)//) {
191
if (!($line =~ m/\\$/)) {
198
chdir $topdir or die "can't chdir to $topdir: $!";
85
foreach $file (@hfiles, @cfiles)
87
($fname, $fpath) = fileparse($file);
88
chdir $fpath or die "can't chdir to $fpath: $!";
91
# Ask 'make' to parse the makefile so we can get the correct flags to
92
# use. CPPFLAGS in particular varies for each subdirectory. If we are
93
# processing a .h file, we might be in a subdirectory that has no
94
# Makefile, in which case we have to fake it. Note that there seems
95
# no easy way to prevent make from recursing into subdirectories and
96
# hence printing multiple definitions --- we keep the last one, which
97
# should come from the current Makefile.
99
if (-f "Makefile" || -f "GNUmakefile")
101
$MAKECMD = "$MAKE -qp";
107
$top_builddir = "..";
109
while (($tmp = dirname($tmp)) ne '.')
111
$top_builddir = $top_builddir . "/..";
114
"$MAKE -qp 'subdir=$subdir' 'top_builddir=$top_builddir' -f '$top_builddir/src/Makefile.global'";
116
open PIPE, "$MAKECMD |"
117
or die "can't fork: $!";
120
if (m/^CPPFLAGS :?= (.*)/)
124
elsif (m/^CFLAGS :?= (.*)/)
128
elsif (m/^CFLAGS_SL :?= (.*)/)
132
elsif (m/^PTHREAD_CFLAGS :?= (.*)/)
134
$PTHREAD_CFLAGS = $1;
136
elsif (m/^CC :?= (.*)/)
142
# If make exits with status 1, it's not an error, it just means make
143
# thinks some files may not be up-to-date. Only complain on status 2.
145
die "$MAKE failed in $fpath\n" if $? != 0 && $? != 256;
147
# Expand out stuff that might be referenced in CFLAGS
148
$CFLAGS =~ s/\$\(CFLAGS_SL\)/$CFLAGS_SL/;
149
$CFLAGS =~ s/\$\(PTHREAD_CFLAGS\)/$PTHREAD_CFLAGS/;
152
# Run the compiler (which had better be gcc) to get the inclusions.
153
# "gcc -H" reports inclusions on stderr as "... filename" where the
154
# number of dots varies according to nesting depth.
157
$COMPILE = "$CC $CPPFLAGS $CFLAGS -H -E $fname";
158
open PIPE, "$COMPILE 2>&1 >/dev/null |"
159
or die "can't fork: $!";
166
# Ignore system headers (absolute paths); but complain if a
167
# .c file includes a system header before any PG header.
168
if ($include =~ m|^/|)
170
warn "$file includes $include before any Postgres inclusion\n"
171
if $#includes == -1 && $file =~ m/\.c$/;
175
# Strip any "./" (assume this appears only at front)
176
$include =~ s|^\./||;
178
# Make path relative to top of tree
180
while ($include =~ s|^\.\./||)
182
$ipath = dirname($ipath) . "/";
185
push @includes, $ipath . $include;
193
# The compiler might fail, particularly if we are checking a file that's
194
# not supposed to be compiled at all on the current platform, so don't
195
# quit on nonzero status.
196
close PIPE or warn "$COMPILE failed in $fpath\n";
199
# Scan the file to find #ifdef, #ifndef, and #if defined() constructs
200
# We assume #ifdef isn't continued across lines, and that defined(foo)
201
# isn't split across lines either
204
or die "can't open $file: $!";
209
if ($line =~ m/^\s*#\s*ifdef\s+(\w+)/)
214
if ($line =~ m/^\s*#\s*ifndef\s+(\w+)/)
219
if ($line =~ m/^\s*#\s*if\s+/)
225
while ($line =~ s/\bdefined(\s+|\s*\(\s*)(\w+)//)
230
if (!($line =~ m/\\$/))
238
chdir $topdir or die "can't chdir to $topdir: $!";
203
243
# Check an is-defined reference
205
# Ignore if symbol isn't defined in any PG include files
206
if (! defined $defines{$symbol}) {
210
# Try to match source(s) of symbol to the inclusions of the current file
211
# (including itself). We consider it OK if any one matches.
213
# Note: these tests aren't bulletproof; in theory the inclusion might
214
# occur after the use of the symbol. Given our normal file layout,
215
# however, the risk is minimal.
217
foreach $deffile (keys %{ $defines{$symbol} }) {
218
return if $deffile eq $file;
219
foreach $reffile (@includes) {
220
return if $deffile eq $reffile;
224
# If current file is a .h file, it's OK for it to assume that one of the
225
# base headers (postgres.h or postgres_fe.h) has been included.
227
if ($file =~ m/\.h$/) {
228
foreach $deffile (keys %{ $defines{$symbol} }) {
229
return if $deffile eq 'src/include/c.h';
230
return if $deffile eq 'src/include/postgres.h';
231
return if $deffile eq 'src/include/postgres_fe.h';
232
return if $deffile eq 'src/include/pg_config.h';
233
return if $deffile eq 'src/include/pg_config_manual.h';
237
@places = keys %{ $defines{$symbol} };
238
print "$file references $symbol, defined in @places\n";
239
# print "includes: @includes\n";
247
# Ignore if symbol isn't defined in any PG include files
248
if (!defined $defines{$symbol})
254
# Try to match source(s) of symbol to the inclusions of the current file
255
# (including itself). We consider it OK if any one matches.
257
# Note: these tests aren't bulletproof; in theory the inclusion might
258
# occur after the use of the symbol. Given our normal file layout,
259
# however, the risk is minimal.
261
foreach $deffile (keys %{ $defines{$symbol} })
263
return if $deffile eq $file;
264
foreach $reffile (@includes)
266
return if $deffile eq $reffile;
271
# If current file is a .h file, it's OK for it to assume that one of the
272
# base headers (postgres.h or postgres_fe.h) has been included.
274
if ($file =~ m/\.h$/)
276
foreach $deffile (keys %{ $defines{$symbol} })
278
return if $deffile eq 'src/include/c.h';
279
return if $deffile eq 'src/include/postgres.h';
280
return if $deffile eq 'src/include/postgres_fe.h';
281
return if $deffile eq 'src/include/pg_config.h';
282
return if $deffile eq 'src/include/pg_config_manual.h';
287
@places = keys %{ $defines{$symbol} };
288
print "$file references $symbol, defined in @places\n";
290
# print "includes: @includes\n";