]> granicus.if.org Git - strace/blob - xlat/gen.sh
8754a032534af7bf435a783694e61a4082f2cfac
[strace] / xlat / gen.sh
1 #!/bin/sh
2
3 usage()
4 {
5         cat <<EOF
6 Usage: $0 <input> <output>
7
8 Generate xlat header files from <input> (a file or dir of files) and write
9 the generated headers to <output>.
10 EOF
11         exit 1
12 }
13
14 cond_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
47 gen_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
107 gen_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
128 gen_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
139 main()
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
179 main "$@"