blob: 75a7c6d5c706b049588b9cdee187752d95b779a7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
:
# 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
# supress 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
|