]> granicus.if.org Git - strace/blob - xlat/gen.sh
tests: simplify qual_inject-signal.test
[strace] / xlat / gen.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2014-2015 Mike Frysinger <vapier@gentoo.org>
4 # Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 # 3. The name of the author may not be used to endorse or promote products
16 #    derived from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 usage()
30 {
31         cat <<EOF
32 Usage: $0 <input> <output>
33
34 Generate xlat header files from <input> (a file or dir of files) and write
35 the generated headers to <output>.
36 EOF
37         exit 1
38 }
39
40 cond_def()
41 {
42         local line
43         line="$1"; shift
44
45         local val
46         val="$(printf %s "$line" |
47                 sed -r -n 's/^([^[:space:]]+).*$/\1/p')"
48
49         local def
50         def="$(printf %s "${line}" |
51                 sed -r -n 's/^[^[:space:]]+[[:space:]]+([^[:space:]].*)$/\1/p')"
52
53         if [ -n "$def" ]; then
54                 cat <<-EOF
55                 #if !(defined($val) || (defined(HAVE_DECL_$val) && HAVE_DECL_$val))
56                 # define $val $def
57                 #endif
58                 EOF
59         fi
60 }
61
62 print_xlat()
63 {
64         local val
65         val="$1"; shift
66
67         if [ -z "${val_type-}" ]; then
68                 echo " XLAT(${val}),"
69         else
70                 echo " XLAT_TYPE(${val_type}, ${val}),"
71         fi
72 }
73
74 print_xlat_pair()
75 {
76         local val str
77         val="$1"; shift
78         str="$1"; shift
79
80         if [ -z "${val_type-}" ]; then
81                 echo " XLAT_PAIR(${val}, \"${str}\"),"
82         else
83                 echo " XLAT_TYPE_PAIR(${val_type}, ${val}, \"${str}\"),"
84         fi
85 }
86
87 cond_xlat()
88 {
89         local line val m def xlat
90         line="$1"; shift
91
92         val="$(printf %s "${line}" | sed -r -n 's/^([^[:space:]]+).*$/\1/p')"
93         m="${val%%|*}"
94         def="$(printf %s "${line}" |
95                sed -r -n 's/^[^[:space:]]+[[:space:]]+([^[:space:]].*)$/\1/p')"
96
97         if [ "${m}" = "${m#1<<}" ]; then
98                 xlat="$(print_xlat "${val}")"
99         else
100                 xlat="$(print_xlat_pair "1ULL<<${val#1<<}" "${val}")"
101                 m="${m#1<<}"
102         fi
103
104         if [ -z "${def}" ]; then
105                 cat <<-EOF
106                 #if defined(${m}) || (defined(HAVE_DECL_${m}) && HAVE_DECL_${m})
107                  ${xlat}
108                 #endif
109                 EOF
110         else
111                 echo "$xlat"
112         fi
113 }
114
115 gen_header()
116 {
117         local input="$1" output="$2" name="$3"
118         echo "generating ${output}"
119         (
120         local defs="${0%/*}/../defs.h"
121         local mpers="${0%/*}/../mpers_xlat.h"
122         local decl="extern const struct xlat ${name}[];"
123         local in_defs= in_mpers=
124
125         if grep -F -x "$decl" "$defs" > /dev/null; then
126                 in_defs=1
127         elif grep -F -x "$decl" "$mpers" > /dev/null; then
128                 in_mpers=1
129         fi
130
131         echo "/* Generated by $0 from $1; do not edit. */"
132
133         local unconditional= unterminated= line
134         # 1st pass: output directives.
135         while read line; do
136                 LC_COLLATE=C
137                 case $line in
138                 '#stop')
139                         exit 0
140                         ;;
141                 '#conditional')
142                         unconditional=
143                         ;;
144                 '#unconditional')
145                         unconditional=1
146                         ;;
147                 '#unterminated')
148                         unterminated=1
149                         ;;
150                 '#val_type '*)
151                         # to be processed during 2nd pass
152                         ;;
153                 '#'*)
154                         echo "${line}"
155                         ;;
156                 [A-Z_]*)
157                         [ -n "$unconditional" ] ||
158                                 cond_def "$line"
159                         ;;
160                 esac
161         done < "$input"
162
163         echo
164         if [ -n "$in_defs" ]; then
165                 cat <<-EOF
166                         #ifndef IN_MPERS
167
168                 EOF
169         elif [ -n "$in_mpers" ]; then
170                 cat <<-EOF
171                         #ifdef IN_MPERS
172
173                         ${decl}
174
175                         #else
176
177                         # if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
178                         static
179                         # endif
180                 EOF
181         else
182                 cat <<-EOF
183                         #ifdef IN_MPERS
184
185                         # error static const struct xlat ${name} in mpers mode
186
187                         #else
188
189                         static
190                 EOF
191         fi
192         echo "const struct xlat ${name}[] = {"
193
194         unconditional= val_type=
195         # 2nd pass: output everything.
196         while read line; do
197                 LC_COLLATE=C
198                 case ${line} in
199                 '#conditional')
200                         unconditional=
201                         ;;
202                 '#unconditional')
203                         unconditional=1
204                         ;;
205                 '#unterminated')
206                         # processed during 1st pass
207                         ;;
208                 '#val_type '*)
209                         val_type="${line#\#val_type }"
210                         ;;
211                 [A-Z_]*)        # symbolic constants
212                         if [ -n "${unconditional}" ]; then
213                                 print_xlat "${line}"
214                         else
215                                 cond_xlat "${line}"
216                         fi
217                         ;;
218                 '1<<'[A-Z_]*)   # symbolic constants with shift
219                         if [ -n "${unconditional}" ]; then
220                                 print_xlat_pair "1ULL<<${line#1<<}" "${line}"
221                         else
222                                 cond_xlat "${line}"
223                         fi
224                         ;;
225                 [0-9]*) # numeric constants
226                         print_xlat "${line}"
227                         ;;
228                 *)      # verbatim lines
229                         echo "${line}"
230                         ;;
231                 esac
232         done < "${input}"
233         if [ -n "${unterminated}" ]; then
234                 echo " /* this array should remain not NULL-terminated */"
235         else
236                 echo " XLAT_END"
237         fi
238
239         cat <<-EOF
240                 };
241
242                 #endif /* !IN_MPERS */
243         EOF
244         ) >"${output}"
245 }
246
247 gen_make()
248 {
249         local output="$1"
250         local name
251         shift
252         echo "generating ${output}"
253         (
254                 printf "XLAT_INPUT_FILES = "
255                 printf 'xlat/%s.in ' "$@"
256                 echo
257                 printf "XLAT_HEADER_FILES = "
258                 printf 'xlat/%s.h ' "$@"
259                 echo
260                 for name; do
261                         printf '$(top_srcdir)/xlat/%s.h: $(top_srcdir)/xlat/%s.in $(top_srcdir)/xlat/gen.sh\n' \
262                                 "${name}" "${name}"
263                         echo '  $(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@'
264                 done
265         ) >"${output}"
266 }
267
268 gen_git()
269 {
270         local output="$1"
271         shift
272         echo "generating ${output}"
273         (
274                 printf '/%s\n' .gitignore Makemodule.am
275                 printf '/%s.h\n' "$@"
276         ) >"${output}"
277 }
278
279 main()
280 {
281         case $# in
282         0) set -- "${0%/*}" "${0%/*}" ;;
283         2) ;;
284         *) usage ;;
285         esac
286
287         local input="$1"
288         local output="$2"
289         local name
290         local jobs=0
291         local ncpus="$(getconf _NPROCESSORS_ONLN)"
292         [ "${ncpus}" -ge 1 ] ||
293                 ncpus=1
294
295         if [ -d "${input}" ]; then
296                 local f names=
297                 for f in "${input}"/*.in; do
298                         [ -f "${f}" ] || continue
299                         name=${f##*/}
300                         name=${name%.in}
301                         gen_header "${f}" "${output}/${name}.h" "${name}" &
302                         names="${names} ${name}"
303                         : $(( jobs += 1 ))
304                         if [ ${jobs} -ge ${ncpus} ]; then
305                                 jobs=0
306                                 wait
307                         fi
308                 done
309                 gen_git "${output}/.gitignore" ${names}
310                 gen_make "${output}/Makemodule.am" ${names}
311                 wait
312         else
313                 name=${input##*/}
314                 name=${name%.in}
315                 gen_header "${input}" "${output}" "${name}"
316         fi
317 }
318
319 main "$@"