• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2
3usage()
4{
5	cat <<EOF
6Usage: $0 <input> <output>
7
8Generate xlat header files from <input> (a file or dir of files) and write
9the generated headers to <output>.
10EOF
11	exit 1
12}
13
14cond_xlat()
15{
16	local line val m def xlat
17	line="$1"; shift
18
19	val="$(printf %s "${line}" | sed -n 's/^\([^[:space:]]\+\).*$/\1/p')"
20	m="${val%%|*}"
21	def="$(printf %s "${line}" |
22	       sed -n 's/^[^[:space:]]\+[[:space:]]\+\([^[:space:]].*\)$/\1/p')"
23
24	if [ "${m}" = "${m#1<<}" ]; then
25		xlat="XLAT(${val}),"
26	else
27		m="${m#1<<}"
28		xlat=" { ${val}, \"${m}\" },"
29	fi
30
31	if [ -z "${def}" ]; then
32		cat <<-EOF
33		#if defined(${m}) || (defined(HAVE_DECL_${m}) && HAVE_DECL_${m})
34		 ${xlat}
35		#endif
36		EOF
37	else
38		cat <<-EOF
39		#if !(defined(${m}) || (defined(HAVE_DECL_${m}) && HAVE_DECL_${m}))
40		# define ${m} ${def}
41		#endif
42		 ${xlat}
43		EOF
44	fi
45}
46
47gen_header()
48{
49	local input="$1" output="$2" name="$3"
50	echo "generating ${output}"
51	(
52	local defs="${0%/*}/../defs.h"
53	local prefix
54	if grep -x "extern const struct xlat ${name}\\[\\];" "${defs}" > /dev/null; then
55		prefix=
56	else
57		prefix='static '
58	fi
59
60	cat <<-EOF
61		/* Generated by $0 from $1; do not edit. */
62
63		${prefix}const struct xlat ${name}[] = {
64	EOF
65	local unconditional= unterminated= line
66	while read line; do
67		LC_COLLATE=C
68		case ${line} in
69		'#unconditional')
70			unconditional=1
71			;;
72		'#unterminated')
73			unterminated=1
74			;;
75		[A-Z_]*)	# symbolic constants
76			if [ -n "${unconditional}" ]; then
77				echo " XLAT(${line}),"
78			else
79				cond_xlat "${line}"
80			fi
81			;;
82		'1<<'[A-Z_]*)	# symbolic constants with shift
83			m="${line%% *}"
84			if [ -n "${unconditional}" ]; then
85				echo " { ${line}, \"${line#1<<}\" },"
86			else
87				cond_xlat "${line}"
88			fi
89			;;
90		[0-9]*)	# numeric constants
91			echo " XLAT(${line}),"
92			;;
93		*)	# verbatim lines
94			echo "${line}"
95			;;
96		esac
97	done < "${input}"
98	if [ -n "${unterminated}" ]; then
99		echo " /* this array should remain not NULL-terminated */"
100	else
101		echo " XLAT_END"
102	fi
103	echo "};"
104	) >"${output}"
105}
106
107gen_make()
108{
109	local output="$1"
110	local name
111	shift
112	echo "generating ${output}"
113	(
114		printf "XLAT_INPUT_FILES = "
115		printf 'xlat/%s.in ' "$@"
116		echo
117		printf "XLAT_HEADER_FILES = "
118		printf 'xlat/%s.h ' "$@"
119		echo
120		for name; do
121			printf '$(top_srcdir)/xlat/%s.h: $(top_srcdir)/xlat/%s.in $(top_srcdir)/xlat/gen.sh\n' \
122				"${name}" "${name}"
123			echo '	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@'
124		done
125	) >"${output}"
126}
127
128gen_git()
129{
130	local output="$1"
131	shift
132	echo "generating ${output}"
133	(
134		printf '/%s\n' .gitignore Makemodule.am
135		printf '/%s.h\n' "$@"
136	) >"${output}"
137}
138
139main()
140{
141	case $# in
142	0) set -- "${0%/*}" "${0%/*}" ;;
143	2) ;;
144	*) usage ;;
145	esac
146
147	local input="$1"
148	local output="$2"
149	local name
150	local jobs=0
151	local ncpus="$(getconf _NPROCESSORS_ONLN)"
152	[ "${ncpus}" -ge 1 ] ||
153		ncpus=1
154
155	if [ -d "${input}" ]; then
156		local f names=
157		for f in "${input}"/*.in; do
158			[ -f "${f}" ] || continue
159			name=${f##*/}
160			name=${name%.in}
161			gen_header "${f}" "${output}/${name}.h" "${name}" &
162			names="${names} ${name}"
163			: $(( jobs += 1 ))
164			if [ ${jobs} -ge ${ncpus} ]; then
165				jobs=0
166				wait
167			fi
168		done
169		gen_git "${output}/.gitignore" ${names}
170		gen_make "${output}/Makemodule.am" ${names}
171		wait
172	else
173		name=${input##*/}
174		name=${name%.in}
175		gen_header "${input}" "${output}" "${name}"
176	fi
177}
178
179main "$@"
180