48ceaee384
When there were fewer xlat headers, this didn't matter as much. But now with >200, trying to run them all in parallel can easily fork bomb smaller systems. * xlat/gen.sh (main): Do not more jobs than # of cpus.
180 lines
3.2 KiB
Bash
Executable File
180 lines
3.2 KiB
Bash
Executable File
#!/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 "$@"
|