1#!/bin/sh
2#
3# List specified macros
4#
5
6set -e
7
8: ${CC:=cc}
9: ${CPPFLAGS:=}
10: ${MACRO:=.}
11: ${VENDOR:=}
12: ${INCLUDE:=}
13: ${TMPFILE:=.$(basename $0).c}
14: ${PREPEND:=}
15: ${EXPAND:=no}
16
17NL="
18"
19
20usage() {
21	cat <<-EOF
22	usage: $(basename $0) -m:v:i:t:xh
23	  -i INCLUDE  include file (e.g. <errno.h>)
24	  -m REGEX    regular expression macro name filter
25	  -s PATH     path to supplemental list, one per line
26	  -t TMPFILE  compiler intermediate tmp file
27	  -v VENDOR   compiler vendor name (e.g. gcc, clang, sunpro)
28	  -x          expand macros
29	  -h          print this usage message
30
31	Report bugs to <william@25thandClement.com>
32	EOF
33}
34
35while getopts i:m:s:t:v:xh OPT; do
36	case "${OPT}" in
37	i)
38		case "${OPTARG}" in
39		\<*)
40			INCLUDE="${INCLUDE}#include ${OPTARG}${NL}"
41			;;
42		\"*)
43			INCLUDE="${INCLUDE}#include ${OPTARG}${NL}"
44			;;
45		*)
46			INCLUDE="${INCLUDE}#include <${OPTARG}>${NL}"
47			;;
48		esac
49		;;
50	m)
51		MACRO="${OPTARG}"
52		;;
53	s)
54		PREPEND="${OPTARG}"
55		;;
56	t)
57		TMPFILE="${OPTARG}"
58		;;
59	v)
60		VENDOR="${OPTARG}"
61		;;
62	x)
63		EXPAND=yes
64		;;
65	h)
66		usage
67		exit 0
68		;;
69	*)
70		usage >&2
71		exit 1
72		;;
73	esac
74done
75
76
77vendor() {
78	SCRIPT="$(dirname $0)/vendor.cc"
79
80	if [ -n "${SCRIPT}" -a -x "${SCRIPT}" ]; then
81		env CC="${CC}" ${SCRIPT}
82	else
83		${CC} -E - <<-EOF | awk '/sunpro/||/clang/||/gcc/||/other/{ print $1; exit; }'
84			#if defined __SUNPRO_C
85			sunpro
86			#elif defined __clang__
87			clang
88			#elif defined __GNUC__
89			gcc
90			#else
91			other
92			#endif
93		EOF
94	fi
95}
96
97
98filter() {
99	awk "\$1~/^#define/ && \$2~/${MACRO}/{ print \$2 }"
100}
101
102
103macros() {
104	if [ -n "${PREPEND}" ]; then
105		cat "${PREPEND}"
106	fi
107
108	case "${VENDOR:-$(vendor)}" in
109	*sunpro*)
110		trap "rm -f ${TMPFILE}" EXIT
111		echo "${INCLUDE}" >| ${TMPFILE}
112		${CC} ${CPPFLAGS} -xM ${TMPFILE} | awk '/\.h$/{ print $2 }' | sort -u | xargs cat | filter
113		rm ${TMPFILE}
114		;;
115	*)
116		echo "${INCLUDE}" | ${CC} ${CPPFLAGS} -dM -E - | filter
117		;;
118	esac
119}
120
121expand() {
122	if [ "${EXPAND}" = "yes" ]; then
123		(echo "${INCLUDE}"; awk '{ print "\"<<<< "$1" >>>>\" "$1 }') | ${CC} ${CPPFLAGS} -E - | awk '$1~/^"<<<</{ print $2""substr($0, index($0, ">>>>") + 5) }'
124	else
125		cat
126	fi
127}
128
129macros | sort -u | expand
130