blob: 8754a032534af7bf435a783694e61a4082f2cfac [file] [log] [blame]
#!/bin/sh
usage()
{
cat <<EOF
Usage: $0 <input> <output>
Generate xlat header files from <input> (a file or dir of files) and write
the generated headers to <output>.
EOF
exit 1
}
cond_xlat()
{
local line val m def xlat
line="$1"; shift
val="$(printf %s "${line}" | sed -n 's/^\([^[:space:]]\+\).*$/\1/p')"
m="${val%%|*}"
def="$(printf %s "${line}" |
sed -n 's/^[^[:space:]]\+[[:space:]]\+\([^[:space:]].*\)$/\1/p')"
if [ "${m}" = "${m#1<<}" ]; then
xlat="XLAT(${val}),"
else
m="${m#1<<}"
xlat=" { ${val}, \"${m}\" },"
fi
if [ -z "${def}" ]; then
cat <<-EOF
#if defined(${m}) || (defined(HAVE_DECL_${m}) && HAVE_DECL_${m})
${xlat}
#endif
EOF
else
cat <<-EOF
#if !(defined(${m}) || (defined(HAVE_DECL_${m}) && HAVE_DECL_${m}))
# define ${m} ${def}
#endif
${xlat}
EOF
fi
}
gen_header()
{
local input="$1" output="$2" name="$3"
echo "generating ${output}"
(
local defs="${0%/*}/../defs.h"
local prefix
if grep -x "extern const struct xlat ${name}\\[\\];" "${defs}" > /dev/null; then
prefix=
else
prefix='static '
fi
cat <<-EOF
/* Generated by $0 from $1; do not edit. */
${prefix}const struct xlat ${name}[] = {
EOF
local unconditional= unterminated= line
while read line; do
LC_COLLATE=C
case ${line} in
'#unconditional')
unconditional=1
;;
'#unterminated')
unterminated=1
;;
[A-Z_]*) # symbolic constants
if [ -n "${unconditional}" ]; then
echo " XLAT(${line}),"
else
cond_xlat "${line}"
fi
;;
'1<<'[A-Z_]*) # symbolic constants with shift
m="${line%% *}"
if [ -n "${unconditional}" ]; then
echo " { ${line}, \"${line#1<<}\" },"
else
cond_xlat "${line}"
fi
;;
[0-9]*) # numeric constants
echo " XLAT(${line}),"
;;
*) # verbatim lines
echo "${line}"
;;
esac
done < "${input}"
if [ -n "${unterminated}" ]; then
echo " /* this array should remain not NULL-terminated */"
else
echo " XLAT_END"
fi
echo "};"
) >"${output}"
}
gen_make()
{
local output="$1"
local name
shift
echo "generating ${output}"
(
printf "XLAT_INPUT_FILES = "
printf 'xlat/%s.in ' "$@"
echo
printf "XLAT_HEADER_FILES = "
printf 'xlat/%s.h ' "$@"
echo
for name; do
printf '$(top_srcdir)/xlat/%s.h: $(top_srcdir)/xlat/%s.in $(top_srcdir)/xlat/gen.sh\n' \
"${name}" "${name}"
echo ' $(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@'
done
) >"${output}"
}
gen_git()
{
local output="$1"
shift
echo "generating ${output}"
(
printf '/%s\n' .gitignore Makemodule.am
printf '/%s.h\n' "$@"
) >"${output}"
}
main()
{
case $# in
0) set -- "${0%/*}" "${0%/*}" ;;
2) ;;
*) usage ;;
esac
local input="$1"
local output="$2"
local name
local jobs=0
local ncpus="$(getconf _NPROCESSORS_ONLN)"
[ "${ncpus}" -ge 1 ] ||
ncpus=1
if [ -d "${input}" ]; then
local f names=
for f in "${input}"/*.in; do
[ -f "${f}" ] || continue
name=${f##*/}
name=${name%.in}
gen_header "${f}" "${output}/${name}.h" "${name}" &
names="${names} ${name}"
: $(( jobs += 1 ))
if [ ${jobs} -ge ${ncpus} ]; then
jobs=0
wait
fi
done
gen_git "${output}/.gitignore" ${names}
gen_make "${output}/Makemodule.am" ${names}
wait
else
name=${input##*/}
name=${name%.in}
gen_header "${input}" "${output}" "${name}"
fi
}
main "$@"