#! /usr/bin/perl -w

#
# This script looks for symbols that are referenced in #ifdef or defined()
# tests without having #include'd the file that defines them.  Since this
# situation won't necessarily lead to any compiler message, it seems worth
# having an automated check for it.  In particular, use this to audit the
# results of pgrminclude!
#
# Usage: configure and build a PG source tree (non-VPATH), then start this
# script at the top level.  It's best to enable as many configure options
# as you can, especially --enable-cassert which is known to affect include
# requirements.  NB: you MUST use gcc, unless you have another compiler that
# can be persuaded to spit out the names of referenced include files.
#
# The results are necessarily platform-dependent, so use care in interpreting
# them.  We try to process all .c files, even those not intended for the
# current platform, so there will be some phony failures.
#
# src/tools/pginclude/pgcheckdefines
#

use Cwd;
use File::Basename;

$topdir = cwd();

# Programs to use
$FIND = "find";
$MAKE = "make";

#
# Build arrays of all the .c and .h files in the tree
#
# We ignore .h files under src/include/port/, since only the one exposed as
# src/include/port.h is interesting.  (XXX Windows ports have additional
# files there?)  Ditto for .h files in src/backend/port/ subdirectories.
# Including these .h files would clutter the list of define'd symbols and
# cause a lot of false-positive results.
#
open PIPE, "$FIND * -type f -name '*.c' |"
    or die "can't fork: $!";
while (<PIPE>) {
    chomp;
    push @cfiles, $_;
}
close PIPE or die "$FIND failed: $!";

open PIPE, "$FIND * -type f -name '*.h' |"
    or die "can't fork: $!";
while (<PIPE>) {
    chomp;
    push @hfiles, $_ unless
	m|^src/include/port/| ||
	m|^src/backend/port/\w+/|;
}
close PIPE or die "$FIND failed: $!";

#
# For each .h file, extract all the symbols it #define's, and add them to
# a hash table.  To cover the possibility of multiple .h files defining
# the same symbol, we make each hash entry a hash of filenames.
#
foreach $hfile (@hfiles) {
    open HFILE, $hfile
	or die "can't open $hfile: $!";
    while (<HFILE>) {
	if (m/^\s*#\s*define\s+(\w+)/) {
	    $defines{$1}{$hfile} = 1;
	}
    }
    close HFILE;
}

#
# For each file (both .h and .c), run the compiler to get a list of what
# files it #include's.  Then extract all the symbols it tests for defined-ness,
# and check each one against the previously built hashtable.
#
foreach $file (@hfiles, @cfiles) {
    ($fname, $fpath) = fileparse($file);
    chdir $fpath or die "can't chdir to $fpath: $!";
    #
    # Ask 'make' to parse the makefile so we can get the correct flags to
    # use.  CPPFLAGS in particular varies for each subdirectory.  If we are
    # processing a .h file, we might be in a subdirectory that has no
    # Makefile, in which case we have to fake it.  Note that there seems
    # no easy way to prevent make from recursing into subdirectories and
    # hence printing multiple definitions --- we keep the last one, which
    # should come from the current Makefile.
    #
    if (-f "Makefile" || -f "GNUmakefile") {
	$MAKECMD = "$MAKE -qp";
    } else {
	$subdir = $fpath;
	chop $subdir;
	$top_builddir = "..";
	$tmp = $fpath;
	while (($tmp = dirname($tmp)) ne '.') {
	    $top_builddir = $top_builddir . "/..";
	}
	$MAKECMD = "$MAKE -qp 'subdir=$subdir' 'top_builddir=$top_builddir' -f '$top_builddir/src/Makefile.global'";
    }
    open PIPE, "$MAKECMD |"
	or die "can't fork: $!";
    while (<PIPE>) {
	if (m/^CPPFLAGS :?= (.*)/) {
	    $CPPFLAGS = $1;
	} elsif (m/^CFLAGS :?= (.*)/) {
	    $CFLAGS = $1;
	} elsif (m/^CFLAGS_SL :?= (.*)/) {
	    $CFLAGS_SL = $1;
	} elsif (m/^PTHREAD_CFLAGS :?= (.*)/) {
	    $PTHREAD_CFLAGS = $1;
	} elsif (m/^CC :?= (.*)/) {
	    $CC = $1;
	}
    }
    # If make exits with status 1, it's not an error, it just means make
    # thinks some files may not be up-to-date.  Only complain on status 2.
    close PIPE;
    die "$MAKE failed in $fpath\n" if $? != 0 && $? != 256;

    # Expand out stuff that might be referenced in CFLAGS
    $CFLAGS =~ s/\$\(CFLAGS_SL\)/$CFLAGS_SL/;
    $CFLAGS =~ s/\$\(PTHREAD_CFLAGS\)/$PTHREAD_CFLAGS/;

    #
    # Run the compiler (which had better be gcc) to get the inclusions.
    # "gcc -H" reports inclusions on stderr as "... filename" where the
    # number of dots varies according to nesting depth.
    #
    @includes = ();
    $COMPILE = "$CC $CPPFLAGS $CFLAGS -H -E $fname";
    open PIPE, "$COMPILE 2>&1 >/dev/null |"
	or die "can't fork: $!";
    while (<PIPE>) {
	if (m/^\.+ (.*)/) {
	    $include = $1;
	    # Ignore system headers (absolute paths); but complain if a
	    # .c file includes a system header before any PG header.
	    if ($include =~ m|^/|) {
		warn "$file includes $include before any Postgres inclusion\n"
		    if $#includes == -1 && $file =~ m/\.c$/;
		next;
	    }
	    # Strip any "./" (assume this appears only at front)
	    $include =~ s|^\./||;
	    # Make path relative to top of tree
	    $ipath = $fpath;
	    while ($include =~ s|^\.\./||) {
		$ipath = dirname($ipath) . "/";
	    }
	    $ipath =~ s|^\./||;
	    push @includes, $ipath . $include;
	} else {
	    warn "$CC: $_";
	}
    }
    # The compiler might fail, particularly if we are checking a file that's
    # not supposed to be compiled at all on the current platform, so don't
    # quit on nonzero status.
    close PIPE or warn "$COMPILE failed in $fpath\n";

    #
    # Scan the file to find #ifdef, #ifndef, and #if defined() constructs
    # We assume #ifdef isn't continued across lines, and that defined(foo)
    # isn't split across lines either
    #
    open FILE, $fname
	or die "can't open $file: $!";
    $inif = 0;
    while (<FILE>) {
	$line = $_;
	if ($line =~ m/^\s*#\s*ifdef\s+(\w+)/) {
	    $symbol = $1;
	    &checkit;
	}
	if ($line =~ m/^\s*#\s*ifndef\s+(\w+)/) {
	    $symbol = $1;
	    &checkit;
	}
	if ($line =~ m/^\s*#\s*if\s+/) {
	    $inif = 1;
	}
	if ($inif) {
	    while ($line =~ s/\bdefined(\s+|\s*\(\s*)(\w+)//) {
		$symbol = $2;
		&checkit;
	    }
	    if (!($line =~ m/\\$/)) {
		$inif = 0;
	    }
	}
    }
    close FILE;

    chdir $topdir or die "can't chdir to $topdir: $!";
}

exit 0;

# Check an is-defined reference
sub checkit {
    # Ignore if symbol isn't defined in any PG include files
    if (! defined $defines{$symbol}) {
	return;
    }
    #
    # Try to match source(s) of symbol to the inclusions of the current file
    # (including itself).  We consider it OK if any one matches.
    #
    # Note: these tests aren't bulletproof; in theory the inclusion might
    # occur after the use of the symbol.  Given our normal file layout,
    # however, the risk is minimal.
    #
    foreach $deffile (keys %{ $defines{$symbol} }) {
	return if $deffile eq $file;
	foreach $reffile (@includes) {
	    return if $deffile eq $reffile;
	}
    }
    #
    # If current file is a .h file, it's OK for it to assume that one of the
    # base headers (postgres.h or postgres_fe.h) has been included.
    #
    if ($file =~ m/\.h$/) {
	foreach $deffile (keys %{ $defines{$symbol} }) {
	    return if $deffile eq 'src/include/c.h';
	    return if $deffile eq 'src/include/postgres.h';
	    return if $deffile eq 'src/include/postgres_fe.h';
	    return if $deffile eq 'src/include/pg_config.h';
	    return if $deffile eq 'src/include/pg_config_manual.h';
	}
    }
    #
    @places = keys %{ $defines{$symbol} };
    print "$file references $symbol, defined in @places\n";
    # print "includes: @includes\n";
}
