Remove pgrminclude and associated scripts

Per git log, the last time someone tried to do something with
pgrminclude was around 2011.  And it's always had a tendency of
causing trouble when it was active.  Also, pgcominclude is redundant
with headerscheck.

Discussion: https://www.postgresql.org/message-id/flat/2d4dc7b2-cb2e-49b1-b8ca-ba5f7024f05b%40eisentraut.org
This commit is contained in:
Peter Eisentraut 2024-12-24 14:02:42 +01:00
parent 1eb7cb21c2
commit 5af699066f
6 changed files with 0 additions and 610 deletions

View File

@ -1,68 +1,5 @@
src/tools/pginclude/README
NOTE: headerscheck and headerscheck --cplusplus are in current use,
and any problems they find should generally get fixed. The other
scripts in this directory have not been used in some time, and have
issues. pgrminclude in particular has a history of creating more
problems than it fixes. Be very wary of applying their results
blindly.
pginclude
=========
These utilities help clean up #include file usage. They should be run
in this order so that the include files have the proper includes before
the C files are tested.
pgfixinclude change #include's to <> or ""
pgcompinclude [-v]
report which #include files can not compile on their own
pgrminclude [-v]
remove extra #include's
pgcheckdefines
check for #ifdef tests on symbols defined in files that
weren't included --- this is a necessary sanity check on
pgrminclude
pgdefine create macro calls for all defines in the file (used by
the above routines)
It is also a good idea to sort the pg-specific include files in
alphabetic order. This is best done with a text editor. Typical usage
order would be:
pgfixinclude
sort include references
run multiple times:
pgcompinclude
pgrminclude /src/include
pgrminclude /
pgcheckdefines
There is a complexity when modifying /src/include. If include file 1
includes file 2, and file 2 includes file 3, then when file 1 is
processed, it needs only file 2, not file 3. However, if later, include
file 2 is processed, and file 3 is not needed by file 2 and is removed,
file 1 might then need to include file 3. For this reason, the
pgcompinclude and pgrminclude /src/include steps must be run several
times until all includes compile cleanly.
Also, tests should be done with configure settings of --enable-cassert
and EXEC_BACKEND on and off. It is also wise to test a WIN32 compile.
Another tools that does a similar task is at:
http://code.google.com/p/include-what-you-use/
An include file visualizer script is available at:
http://archives.postgresql.org/pgsql-hackers/2011-09/msg00311.php
headerscheck
============

View File

@ -1,305 +0,0 @@
#! /usr/bin/perl
# Copyright (c) 2021-2024, 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 FATAL => 'all';
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;
}

View File

@ -1,47 +0,0 @@
:
# report which #include files can not compile on their own
# takes -v option to display compile failure message and line numbers
# src/tools/pginclude/pgcompinclude
: ${CC:=cc}
: ${PGSRC:=src}
if ! pgdefine
then echo "pgdefine must be in your PATH" 1>&2
exit 1
fi
trap "rm -f /tmp/$$.c /tmp/$$.o /tmp/$$ /tmp/$$a" 0 1 2 3 15
find . \( -name .git -a -prune \) -o -name '*.h' -type f -print | while read FILE
do
sed 's/->[a-zA-Z0-9_\.]*//g' "$FILE" >/tmp/$$a
echo "#include \"postgres.h\"" >/tmp/$$.c
# suppress fcinfo errors
echo "struct {Datum arg[1];} *fcinfo;" >>/tmp/$$.c
echo "#include \"/tmp/$$a\"" >>/tmp/$$.c
echo "Datum include_test(void);" >>/tmp/$$.c
echo "Datum include_test() {" >>/tmp/$$.c
pgdefine "$FILE" >>/tmp/$$.c
echo "return (Datum)0;" >>/tmp/$$.c
echo "}" >>/tmp/$$.c
# Use -O1 to get warnings only generated by optimization,
# but -O2 is too slow.
$CC -fsyntax-only -Werror -Wall -Wmissing-prototypes \
-Wmissing-declarations -I$PGSRC/include -I$PGSRC/backend \
-I$PGSRC/interfaces/libpq -I`dirname $FILE` $CFLAGS -O1 -c /tmp/$$.c \
-o /tmp/$$.o >/tmp/$$ 2>&1
if [ "$?" -ne 0 ]
then echo "$FILE"
if [ "$1" = "-v" ]
then cat /tmp/$$
nl /tmp/$$.c
echo
fi
fi
done

View File

@ -1,25 +0,0 @@
:
# create macro calls for all defines in the file
# src/tools/pginclude/pgdefine
trap "rm -f /tmp/$$" 0 1 2 3 15
for FILE
do
cat "$FILE" | grep "^#define" >/tmp/$$
cat /tmp/$$ | sed -n 's/^#define[ ][ ]*\([a-zA-Z0-9_]*\)[ ][ ]*[^ ].*\\\\$/\1;/p'
cat /tmp/$$ | sed -n 's/^#define[ ][ ]*\([a-zA-Z0-9_]*\)[ ][ ]*[^ ].*[^\\\\]$/(void)\1;/p'
(
cat /tmp/$$ | sed -n 's/^#define[ ][ ]*\([a-zA-Z0-9_]*([^)]*)\).*\\\\$/\1;/p'
cat /tmp/$$ | sed -n 's/^#define[ ][ ]*\([a-zA-Z0-9_]*([^)]*)\).*[^\\\\]$/(=void)\1;/p'
) |
sed 's/([a-zA-Z0-9_ ][a-zA-Z0-9_ ]*)/(0)/g' |
sed 's/([a-zA-Z0-9_ ]*,/(0,/g' |
sed 's/,[a-zA-Z0-9_ ]*,/,0,/g' |
sed 's/,[a-zA-Z0-9_ ]*)/,0)/g' |
# do not cast 'return' macros as (void)
sed 's/(=void)\(.*return\)/\1/g' |
sed 's/(=void)\(.*RETURN\)/\1/g' |
sed 's/(=void)/(void)/g'
done

View File

@ -1,21 +0,0 @@
:
# change #include's to <> or ""
# src/tools/pginclude/pgfixinclude
trap "rm -f /tmp/$$.c /tmp/$$.o /tmp/$$ /tmp/$$a /tmp/$$b" 0 1 2 3 15
find . \( -name .git -a -prune \) -o -type f -name '*.[chyls]' -print |
while read FILE
do
cat "$FILE" | grep "^#include" |
sed 's/^#include[ ]*[<"]\([^>"]*\).*$/\1/g' |
while read INCLUDE
do
if [ -s /usr/include/"$INCLUDE" ]
then cat "$FILE" |
sed 's;^#include[ ][ ]*[<"]'"$INCLUDE"'[>"]$;#include <'"$INCLUDE"'>;g' >/tmp/$$
else cat "$FILE" |
sed 's;^#include[ ][ ]*[<"]'"$INCLUDE"'[>"]$;#include "'"$INCLUDE"'";g' >/tmp/$$
fi
cat /tmp/$$ > "$FILE"
done
done

View File

@ -1,149 +0,0 @@
:
# remove extra #include's
# pgcompinclude must be run before and after pgrminclude. It must be
# run before because we don't want include dependencies to leak into
# the C program files, and after because removal of includes from headers
# can cause new include unfulfilled dependencies.
#
# Limitations: 2011-09-24
#
# Pgrminclude, when processing header files, can cause includes to be
# removed that require the addition of new illogical header files.
# This is dependent on what order the header files are processed.
# Manual review of header files now needed to satisfy pgcompinclude is
# required.
#
# C program files that have #ifdef blocks that contain code that cannot
# be compiled on the platform from which pgrminclude is run cannot be
# processed, and are skipped.
: ${CC:=cc}
: ${PGSRC:=src}
if ! pgdefine
then echo "pgdefine must be in your PATH" 1>&2
exit 1
fi
trap "rm -f /tmp/$$.c /tmp/$$.o /tmp/$$ /tmp/$$a /tmp/$$b" 0 1 2 3 15
if [ "$1" = "-v" ]
then VERBOSE="Y"
else VERBOSE=""
fi
verbose_output() {
if [ "$VERBOSE" ]
then cat /tmp/$$
cat /tmp/$$b
nl /tmp/$$.c
fi
}
process_includes_in_file() {
# loop through all includes mentioned in the file
cat "$FILE" |
grep "^#include\>" |
grep -v '/\* *pgrminclude *ignore *\*/' |
sed 's/^#include[ ]*[<"]\([^>"]*\).*$/\1/g' |
grep -v 'parser/kwlist\.h' |
grep -v '\.c$' |
while read INCLUDE
do if [ "$VERBOSE" ]
then echo "checking $FILE $INCLUDE"
fi
compile_file
done
}
compile_file() {
[ "$INCLUDE" -a -s /usr/include/"$INCLUDE" ] && continue
[ "$INCLUDE" = "postgres.h" ] && continue
[ "$INCLUDE" = "postgres_fe.h" ] && continue
[ "$INCLUDE" = "pg_config.h" ] && continue
[ "$INCLUDE" = "c.h" ] && continue
# Stringify macros will expand undefined identifiers, so skip files that use it
egrep -q '\<(CppAsString2?|CppConcat)\>' "$FILE" && continue
# preserve configure-specific includes
# these includes are surrounded by #ifdef's
grep -B1 '^#include[ ][ ]*[<"]'"$INCLUDE"'[>"]' "$FILE" |
egrep -q '^#if|^#else|^#elif' && continue
grep -A1 '^#include[ ][ ]*[<"]'"$INCLUDE"'[>"]' "$FILE" |
egrep -q '^#else|^#elif|^#endif' && continue
# Remove all #if and #ifdef blocks because the blocks
# might contain code that is not compiled on this platform.
cat "$FILE" |
grep -v "^#if" |
grep -v "^#else" |
grep -v "^#elif" |
grep -v "^#endif" |
# with #if blocks gone, now undef #defines to avoid redefine
# warning and failure
sed 's/#define[ ][ ]*\([A-Za-z0-9_]*\).*$/#undef \1\n&/' >/tmp/$$a
# set up initial file contents
grep -v '^#include[ ][ ]*[<"]'"$INCLUDE"'[>"]' \
/tmp/$$a >/tmp/$$b
if [ "$IS_INCLUDE" = "Y" ]
then echo "#include \"postgres.h\"" >/tmp/$$.c
# suppress fcinfo errors
echo "struct {Datum arg[1];} *fcinfo;" >>/tmp/$$.c
else >/tmp/$$.c
fi
echo "#include \"/tmp/$$b\"" >>/tmp/$$.c
if [ "$IS_INCLUDE" = "Y" ]
then echo "Datum include_test(void);" >>/tmp/$$.c
echo "Datum include_test() {" >>/tmp/$$.c
pgdefine "$FILE" >>/tmp/$$.c
echo "return (Datum)0;" >>/tmp/$$.c
echo "}" >>/tmp/$$.c
fi
# Use -O1 to get warnings only generated by optimization,
# but -O2 is too slow.
$CC -fsyntax-only -Werror -Wall -Wmissing-prototypes \
-Wmissing-declarations -I$PGSRC/include -I$PGSRC/backend \
-I$PGSRC/interfaces/libpq -I`dirname $FILE` $CFLAGS -O1 -c /tmp/$$.c \
-o /tmp/$$.o >/tmp/$$ 2>&1
if [ "$?" -eq 0 ]
then [ "$INCLUDE" -o "$VERBOSE" ] && echo "$FILE $INCLUDE"
grep -v '^#include[ ][ ]*[<"]'"$INCLUDE"'[>"]' \
"$FILE" >/tmp/$$b
mv /tmp/$$b "$FILE"
return 0
else return 1
fi
}
# Process include files first because they can affect the compilation
# of *.c files.
(find . \( -name .git -a -prune \) -o -type f -name '*.h' -print | sort;
find . \( -name .git -a -prune \) -o -type f -name '*.c' -print | sort) |
grep -v '/postgres.h$' |
grep -v '/postgres_fe.h$' |
grep -v '/pg_config.h$' |
grep -v '\./c.h$' |
while read FILE
do
if [ `expr $FILE : '.*\.h$'` -ne 0 ]
then IS_INCLUDE="Y"
else IS_INCLUDE="N"
fi
# Can we compile the file with all existing includes?
INCLUDE=""
compile_file
# If the file can't be compiled on its own, there is no sense
# trying to remove the include files.
if [ "$?" -ne 0 ]
then echo "cannot compile $FILE with existing includes"
verbose_output
else process_includes_in_file
fi
done