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