#!/bin/sh set -e test $# -ge 1 lowercase () { printf '%s\n' "$*" | tr '[A-Z]' '[a-z]'; } symbols="$(lowercase "$1")" shift 1 trailing_zeroes () { r=0 x=$1 while (( (x & 1) == 0 )); do : $(( r++ )) x=$(( x >> 1 )) done if (( x > 1 )); then printf 'Invalid bitmask value: %s = %#x: multiple bits set\n' $2 $1 >&2 exit 1 fi printf '%i\n' $r } ifzero= printf 'static const char *\n' printf 'extract_symbol_%s(struct libsyscalls_symbol_printer_data *data, ' "$symbols" printf 'unsigned long long int *valuep, char *fallback_out) /* 1 */\n' printf '{\n' printf ' const char *ret;\n' printf ' signed char bit = trailing_zeroes(*valuep);\n' printf ' *fallback_out = %s;\n' "'x'" printf ' switch (bit) {\n' while read name value; do if test $value = 0; then ifzero="$name"; continue; fi printf ' case %i: ret = "%s"; break;\n' $(trailing_zeroes $value $name) $name done if test -n "$ifzero"; then printf ' case -1: return "%s";\n' $ifzero fi printf ' default:\n' if test $# -ge 1; then for use; do printf ' if ((ret = extract_symbol_%s(data, valuep, fallback_out))) return ret;\n' "$(lowercase "$use")" done fi printf ' return NULL;\n' printf ' }\n' printf ' *valuep ^= 1ULL << (unsigned)bit;\n' if test $# = 0; then printf ' (void) data;\n' fi printf ' return ret;\n' printf '}\n'