#!/bin/sh
#
# Copyright (c) 2014-2015 Mike Frysinger <vapier@gentoo.org>
# Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
# 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.

usage()
{
	cat <<EOF
Usage: $0 <input> <output>

Generate xlat header files from <input> (a file or dir of files) and write
the generated headers to <output>.
EOF
	exit 1
}

cond_def()
{
	local line
	line="$1"; shift

	local val
	val="$(printf %s "$line" |
		sed -n 's/^\([^[:space:]]\+\).*$/\1/p')"

	local def
	def="$(printf %s "${line}" |
		sed -n 's/^[^[:space:]]\+[[:space:]]\+\([^[:space:]].*\)$/\1/p')"

	if [ -n "$def" ]; then
		cat <<-EOF
		#if !(defined($val) || (defined(HAVE_DECL_$val) && HAVE_DECL_$val))
		# define $val $def
		#endif
		EOF
	fi
}

cond_xlat()
{
	local line val m def xlat
	line="$1"; shift

	val="$(printf %s "${line}" | sed -n 's/^\([^[:space:]]\+\).*$/\1/p')"
	m="${val%%|*}"
	def="$(printf %s "${line}" |
	       sed -n 's/^[^[:space:]]\+[[:space:]]\+\([^[:space:]].*\)$/\1/p')"

	if [ "${m}" = "${m#1<<}" ]; then
		xlat=" XLAT(${val}),"
	else
		m="${m#1<<}"
		xlat=" { ${val}, \"${m}\" },"
	fi

	if [ -z "${def}" ]; then
		cat <<-EOF
		#if defined(${m}) || (defined(HAVE_DECL_${m}) && HAVE_DECL_${m})
		 ${xlat}
		#endif
		EOF
	else
		echo "$xlat"
	fi
}

gen_header()
{
	local input="$1" output="$2" name="$3"
	echo "generating ${output}"
	(
	local defs="${0%/*}/../defs.h"
	local mpers="${0%/*}/../mpers_xlat.h"
	local decl="extern const struct xlat ${name}[];"
	local in_defs= in_mpers=

	if grep -F -x "$decl" "$defs" > /dev/null; then
		in_defs=1
	elif grep -F -x "$decl" "$mpers" > /dev/null; then
		in_mpers=1
	fi

	echo "/* Generated by $0 from $1; do not edit. */"

	local unconditional= unterminated= line
	# 1st pass: output directives.
	while read line; do
		LC_COLLATE=C
		case $line in
		'#unconditional')
			unconditional=1
			;;
		'#unterminated')
			unterminated=1
			;;
		'#'*)
			echo "${line}"
			;;
		[A-Z_]*)
			[ -n "$unconditional" ] ||
				cond_def "$line"
			;;
		esac
	done < "$input"

	echo
	if [ -n "$in_defs" ]; then
		cat <<-EOF
			#ifndef IN_MPERS

		EOF
	elif [ -n "$in_mpers" ]; then
		cat <<-EOF
			#ifdef IN_MPERS

			${decl}

			#else

			# if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
			static
			# endif
		EOF
	else
		cat <<-EOF
			#ifdef IN_MPERS

			# error static const struct xlat ${name} in mpers mode

			#else

			static
		EOF
	fi
	echo "const struct xlat ${name}[] = {"

	unconditional=
	# 2nd pass: output everything.
	while read line; do
		LC_COLLATE=C
		case ${line} in
		'#unconditional')
			unconditional=1
			;;
		'#unterminated')
			# processed during 1st pass
			;;
		[A-Z_]*)	# symbolic constants
			if [ -n "${unconditional}" ]; then
				echo " XLAT(${line}),"
			else
				cond_xlat "${line}"
			fi
			;;
		'1<<'[A-Z_]*)	# symbolic constants with shift
			if [ -n "${unconditional}" ]; then
				echo " { ${line}, \"${line#1<<}\" },"
			else
				cond_xlat "${line}"
			fi
			;;
		[0-9]*)	# numeric constants
			echo " XLAT(${line}),"
			;;
		*)	# verbatim lines
			echo "${line}"
			;;
		esac
	done < "${input}"
	if [ -n "${unterminated}" ]; then
		echo " /* this array should remain not NULL-terminated */"
	else
		echo " XLAT_END"
	fi

	cat <<-EOF
		};

		#endif /* !IN_MPERS */
	EOF
	) >"${output}"
}

gen_make()
{
	local output="$1"
	local name
	shift
	echo "generating ${output}"
	(
		printf "XLAT_INPUT_FILES = "
		printf 'xlat/%s.in ' "$@"
		echo
		printf "XLAT_HEADER_FILES = "
		printf 'xlat/%s.h ' "$@"
		echo
		for name; do
			printf '$(top_srcdir)/xlat/%s.h: $(top_srcdir)/xlat/%s.in $(top_srcdir)/xlat/gen.sh\n' \
				"${name}" "${name}"
			echo '	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@'
		done
	) >"${output}"
}

gen_git()
{
	local output="$1"
	shift
	echo "generating ${output}"
	(
		printf '/%s\n' .gitignore Makemodule.am
		printf '/%s.h\n' "$@"
	) >"${output}"
}

main()
{
	case $# in
	0) set -- "${0%/*}" "${0%/*}" ;;
	2) ;;
	*) usage ;;
	esac

	local input="$1"
	local output="$2"
	local name
	local jobs=0
	local ncpus="$(getconf _NPROCESSORS_ONLN)"
	[ "${ncpus}" -ge 1 ] ||
		ncpus=1

	if [ -d "${input}" ]; then
		local f names=
		for f in "${input}"/*.in; do
			[ -f "${f}" ] || continue
			name=${f##*/}
			name=${name%.in}
			gen_header "${f}" "${output}/${name}.h" "${name}" &
			names="${names} ${name}"
			: $(( jobs += 1 ))
			if [ ${jobs} -ge ${ncpus} ]; then
				jobs=0
				wait
			fi
		done
		gen_git "${output}/.gitignore" ${names}
		gen_make "${output}/Makemodule.am" ${names}
		wait
	else
		name=${input##*/}
		name=${name%.in}
		gen_header "${input}" "${output}" "${name}"
	fi
}

main "$@"
