#! /usr/bin/perl

# Copyright (c) 2021, PostgreSQL Global Development Group

#
# 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 strict;
use warnings;

use Cwd;
use File::Basename;

my $topdir = cwd();

# Programs to use
my $FIND = "find";
my $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.
#
my (@cfiles, @hfiles);

open my $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.
#
my %defines;

foreach my $hfile (@hfiles)
{
	open my $fh, '<', $hfile
	  or die "can't open $hfile: $!";
	while (<$fh>)
	{
		if (m/^\s*#\s*define\s+(\w+)/)
		{
			$defines{$1}{$hfile} = 1;
		}
	}
	close $fh;
}

#
# 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 my $file (@hfiles, @cfiles)
{
	my ($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.
	#
	my $MAKECMD;

	if (-f "Makefile" || -f "GNUmakefile")
	{
		$MAKECMD = "$MAKE -qp";
	}
	else
	{
		my $subdir = $fpath;
		chop $subdir;
		my $top_builddir = "..";
		my $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'";
	}

	my ($CPPFLAGS, $CFLAGS, $CFLAGS_SL, $PTHREAD_CFLAGS, $CC);

	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.
	#
	my @includes = ();
	my $COMPILE  = "$CC $CPPFLAGS $CFLAGS -H -E $fname";
	open $pipe, '-|', "$COMPILE 2>&1 >/dev/null"
	  or die "can't fork: $!";
	while (<$pipe>)
	{
		if (m/^\.+ (.*)/)
		{
			my $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
			my $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 my $fh, '<', $fname
	  or die "can't open $file: $!";
	my $inif = 0;
	while (<$fh>)
	{
		my $line = $_;
		if ($line =~ m/^\s*#\s*ifdef\s+(\w+)/)
		{
			checkit($file, $1, @includes);
		}
		if ($line =~ m/^\s*#\s*ifndef\s+(\w+)/)
		{
			checkit($file, $1, @includes);
		}
		if ($line =~ m/^\s*#\s*if\s+/)
		{
			$inif = 1;
		}
		if ($inif)
		{
			while ($line =~ s/\bdefined(\s+|\s*\(\s*)(\w+)//)
			{
				checkit($file, $2, @includes);
			}
			if (!($line =~ m/\\$/))
			{
				$inif = 0;
			}
		}
	}
	close $fh;

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

exit 0;

# Check an is-defined reference
sub checkit
{
	my ($file, $symbol, @includes) = @_;

	# 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 my $deffile (keys %{ $defines{$symbol} })
	{
		return if $deffile eq $file;
		foreach my $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 my $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';
		}
	}

	#
	my @places = keys %{ $defines{$symbol} };
	print "$file references $symbol, defined in @places\n";

	# print "includes: @includes\n";

	return;
}
