From 76a262a1f87107ee70b200c60e78a16b013efaa6 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 9 Dec 2024 08:08:02 +0100 Subject: [PATCH 2/2] Remove pgrminclude and associated scripts --- src/tools/pginclude/README | 63 ------ src/tools/pginclude/pgcheckdefines | 305 ----------------------------- src/tools/pginclude/pgcompinclude | 47 ----- src/tools/pginclude/pgdefine | 25 --- src/tools/pginclude/pgfixinclude | 21 -- src/tools/pginclude/pgrminclude | 149 -------------- 6 files changed, 610 deletions(-) delete mode 100755 src/tools/pginclude/pgcheckdefines delete mode 100755 src/tools/pginclude/pgcompinclude delete mode 100755 src/tools/pginclude/pgdefine delete mode 100755 src/tools/pginclude/pgfixinclude delete mode 100755 src/tools/pginclude/pgrminclude diff --git a/src/tools/pginclude/README b/src/tools/pginclude/README index a685940da95..007d0397e79 100644 --- a/src/tools/pginclude/README +++ b/src/tools/pginclude/README @@ -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 ============ diff --git a/src/tools/pginclude/pgcheckdefines b/src/tools/pginclude/pgcheckdefines deleted file mode 100755 index 096bbbe8767..00000000000 --- a/src/tools/pginclude/pgcheckdefines +++ /dev/null @@ -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; -} diff --git a/src/tools/pginclude/pgcompinclude b/src/tools/pginclude/pgcompinclude deleted file mode 100755 index 12169db9f64..00000000000 --- a/src/tools/pginclude/pgcompinclude +++ /dev/null @@ -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 diff --git a/src/tools/pginclude/pgdefine b/src/tools/pginclude/pgdefine deleted file mode 100755 index 242d035a778..00000000000 --- a/src/tools/pginclude/pgdefine +++ /dev/null @@ -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 diff --git a/src/tools/pginclude/pgfixinclude b/src/tools/pginclude/pgfixinclude deleted file mode 100755 index 6721566495c..00000000000 --- a/src/tools/pginclude/pgfixinclude +++ /dev/null @@ -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 diff --git a/src/tools/pginclude/pgrminclude b/src/tools/pginclude/pgrminclude deleted file mode 100755 index 7cbd2e7c9ca..00000000000 --- a/src/tools/pginclude/pgrminclude +++ /dev/null @@ -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 -- 2.47.1