1#!/bin/sh
2
3# src/tools/find_typedef
4
5# This script attempts to find all typedef's in the postgres binaries
6# by using 'objdump' or local equivalent to print typedef debugging symbols.
7# We need this because pgindent needs a list of typedef names.
8#
9# For this program to work, you must have compiled all code with
10# debugging symbols.
11#
12# We intentionally examine all files in the targeted directories so as to
13# find both .o files and executables.  Therefore, ignore error messages about
14# unsuitable files being fed to objdump.
15#
16# This is known to work on Linux and on some BSDen, including macOS.
17#
18# Caution: on the platforms we use, this only prints typedefs that are used
19# to declare at least one variable or struct field.  If you have say
20# "typedef struct foo { ... } foo;", and then the structure is only ever
21# referenced as "struct foo", "foo" will not be reported as a typedef,
22# causing pgindent to indent the typedef definition oddly.  This is not a
23# huge problem, since by definition there's just the one misindented line.
24#
25# We get typedefs by reading "STABS":
26#    http://www.informatik.uni-frankfurt.de/doc/texi/stabs_toc.html
27
28
29if [ "$#" -eq 0 -o ! -d "$1" ]
30then	echo "Usage:  $0 postgres_binary_directory [...]" 1>&2
31	exit 1
32fi
33
34for DIR
35do	# if objdump -W is recognized, only one line of error should appear
36	if [ `objdump -W 2>&1 | wc -l` -eq 1 ]
37	then	# Linux
38		objdump -W "$DIR"/* |
39		egrep -A3 '\(DW_TAG_typedef\)' |
40		awk ' $2 == "DW_AT_name" {print $NF}'
41	elif [ `readelf -w 2>&1 | wc -l` -gt 1 ]
42	then	# FreeBSD, similar output to Linux
43		readelf -w "$DIR"/* |
44		egrep -A3 '\(DW_TAG_typedef\)' |
45		awk ' $1 == "DW_AT_name" {print $NF}'
46	fi
47done |
48grep -v ' ' | # some typedefs have spaces, remove them
49sort |
50uniq |
51# these are used both for typedefs and variable names
52# so do not include them
53egrep -v '^(date|interval|timestamp|ANY)$'
54