--- /dev/null
+#! /bin/bash -eu
+
+# Generate xlat .in file based on the existing file and Linux UAPI headers.
+#
+# Copyright (c) 2018 The strace developers.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+warn()
+{
+ printf >&2 '%s: %s\n' "$0" "$*"
+}
+
+fatal()
+{
+ warn "$@"
+ exit 1
+}
+
+usage()
+{
+ s="${0//?/ }"
+ cat >&2 <<-EOF
+ $0 -f VAL_PRINT_FMT \\
+ $s -p REGEXP_PATTERN \\
+ $s -d LINUX_SRC_DIR \\
+ $s -c COMMON_DEFS_GLOB_PATTERN \\
+ $s -a ARCH_DEFS_FILE \\
+ $s < xlat/xlat_file_name.in
+
+ Examples:
+ $0 -f 'd' -p 'MADV_' -d '/path/to/linux' -c 'asm-generic/mman-common.h' -a 'asm/mman.h' < xlat/madvise_cmds.in
+ $0 -f '#x' -p '_?MAP_' -d '/path/to/linux' -c 'asm-generic/mman*.h' -a 'asm/mman.h' < xlat/mmap_flags.in
+ $0 -f '#o' -p '[_OF]' -d '/path/to/linux' -c 'asm-generic/fcntl.h' -a 'asm/fcntl.h' < xlat/open_mode_flags.in
+ $0 -f 'u' -p 'SO_' -d '/path/to/linux' -c 'asm-generic/socket.h' -a 'asm/socket.h' < xlat/sock_options.in
+ EOF
+ exit 1
+}
+
+VAL_PRINT_FMT=
+REGEXP_PATTERN=
+COMMON_DEFS_GLOB_PATTERN=
+ARCH_DEFS_FILE=
+LINUX_SRC=
+
+comment_re='[^/]*\/\*.*\*\/.*'
+comment_glob='*/\**\*/*'
+
+while [ 0 -lt "$#" ]; do
+ case "$1" in
+ -p)
+ shift
+ REGEXP_PATTERN="$1"
+ ;;
+ -d)
+ shift
+ LINUX_SRC="$1"
+ ;;
+ -c)
+ shift
+ COMMON_DEFS_GLOB_PATTERN="$1"
+ ;;
+ -a)
+ shift
+ ARCH_DEFS_FILE="$1"
+ ;;
+ -f)
+ shift
+ VAL_PRINT_FMT="$1"
+ ;;
+ -[h?])
+ usage
+ ;;
+ -*)
+ fatal "$1: unknown option"
+ ;;
+ *)
+ fatal "$1: unexpected argument"
+ ;;
+ esac
+
+ shift
+done
+
+for v in \
+ VAL_PRINT_FMT \
+ REGEXP_PATTERN \
+ COMMON_DEFS_GLOB_PATTERN \
+ ARCH_DEFS_FILE \
+ LINUX_SRC \
+ ; do
+ eval [ -n \"\$$v\" ] || fatal "$v has not been specified"
+done
+
+printf "/* Generated by %s -f '%s' -p '%s' -c '%s' -a '%s' */\\n" \
+ "$0" "$VAL_PRINT_FMT" "$REGEXP_PATTERN" \
+ "$COMMON_DEFS_GLOB_PATTERN" "$ARCH_DEFS_FILE"
+
+sed -rn '/^\/\* Generated by .*\*\//d;s/^((# .*|'"$comment_re"'|'"$REGEXP_PATTERN"'[^[:space:]]*).*)?$/\2/p' |
+uniq |
+while read name_ rest; do
+ # Empty lines, comments, and "# " directives are passed verbatim.
+ case "$name_ $rest" in
+ \ )
+ echo
+ continue ;;
+ \#\ *|${comment_glob})
+ printf '%s\n' "$name_ $rest"
+ continue ;;
+ esac
+ sed -rn 's/#define[[:space:]]+('"$name_"')[[:space:]]+([x[:xdigit:]]+).*$/\2\t\1/p' \
+ $LINUX_SRC/include/uapi/$COMMON_DEFS_GLOB_PATTERN |
+ sort -n | {
+ def=
+ name=
+ read def name ||:
+
+ if [ -n "$def" ]; then
+ warn "$name_ is defined to $def"
+ else
+ warn "No def for $name_"
+ name="$name_"
+ fi
+
+ grep -oEH '#define[[:space:]]+'"$name"'[[:space:]]+(0x[[:xdigit:]]+|[[:digit:]]+)' \
+ $LINUX_SRC/arch/*/include/uapi/$ARCH_DEFS_FILE |
+ sed -rn 's|^[^#]*/arch/([^/]+)/include/uapi/'"$ARCH_DEFS_FILE"':#define[[:space:]]+'"$name"'[[:space:]]+([^[:space:]]+)([[:space:]].*)?$|\1\t\2|p' |
+ sed s/parisc/hppa/ |
+ sort |
+ awk -vname="$name" -vdef="$def" -vfmt="$VAL_PRINT_FMT" '
+ # Like strtonum, but also supports octal and hexadecimal
+ # representation.
+ # Taken from https://www.gnu.org/software/gawk/manual/html_node/Strtonum-Function.html
+ function mystrtonum(str, ret, n, i, k, c)
+ {
+ if (str ~ /^0[0-7]*$/) {
+ # octal
+ n = length(str)
+ ret = 0
+ for (i = 1; i <= n; i++) {
+ c = substr(str, i, 1)
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("1234567", c)
+
+ ret = ret * 8 + k
+ }
+ } else if (str ~ /^0[xX][[:xdigit:]]+$/) {
+ # hexadecimal
+ str = substr(str, 3) # lop off leading 0x
+ n = length(str)
+ ret = 0
+
+ for (i = 1; i <= n; i++) {
+ c = substr(str, i, 1)
+ c = tolower(c)
+ # index() returns 0 if c not in string,
+ # includes c == "0"
+ k = index("123456789abcdef", c)
+
+ ret = ret * 16 + k
+ }
+ } else if (str ~ \
+ /^[-+]?([0-9]+([.][0-9]*([Ee][0-9]+)?)?|([.][0-9]+([Ee][-+]?[0-9]+)?))$/) {
+ # decimal number, possibly floating point
+ ret = str + 0
+ } else {
+ ret = "NOT-A-NUMBER"
+ }
+
+ return ret
+ }
+
+ BEGIN {
+ d = mystrtonum(def)
+ }
+
+ {
+ i = mystrtonum($2)
+ if (i == d) next
+ if (a[i])
+ a[i] = a[i] " || defined __" $1 "__"
+ else
+ a[i] = "defined __" $1 "__"
+ }
+
+ END {
+ iftext = "#if"
+ for (i in a) {
+ printf("%s %s\n%s\t%" fmt "\n", iftext, a[i],
+ name, i)
+ iftext = "#elif"
+ }
+
+ if (iftext != "#if")
+ print "#else"
+
+ if (def == "")
+ printf("%s\n", name)
+ else
+ printf("%s\t%" fmt "\n", name, d)
+
+ if (iftext != "#if")
+ print "#endif"
+ }' |
+ sed -e 's/defined __arm64__/& || defined __aarch64__/g' \
+ -e 's/defined __x86__/defined __x86_64__ || defined __i386__/g'
+ }
+done