#!/bin/sh
# $Id: tdindent,v 1.29 2014/04/14 23:02:04 tom Exp $
#****************************************************************************
#* Copyright (c) 2010 Thomas E. Dickey                                      *
#*                                                                          *
#* Permission is hereby granted, free of charge, to any person obtaining a  *
#* copy of this software and associated documentation files (the            *
#* "Software"), to deal in the Software without restriction, including      *
#* without limitation the rights to use, copy, modify, merge, publish,      *
#* distribute, distribute with modifications, sublicense, and/or sell       *
#* copies of the Software, and to permit persons to whom the Software is    *
#* furnished to do so, subject to the following conditions:                 *
#*                                                                          *
#* The above copyright notice and this permission notice shall be included  *
#* in all copies or substantial portions of the Software.                   *
#*                                                                          *
#* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
#* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
#* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
#* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
#* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
#* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
#* THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
#*                                                                          *
#* Except as contained in this notice, the name(s) of the above copyright   *
#* holders shall not be used in advertising or otherwise to promote the     *
#* sale, use or other dealings in this Software without prior written       *
#* authorization.                                                           *
#****************************************************************************/
# this was ncu-indent, before integrating with cindent package in 2010.

: ${INDENT_PROG:=indent}
: ${INDENT_DATA:=.}

NOOP=no
OPTS="-npro"
SPCS=no
USED=no
TEST_D=no
TEST_N=no

PROFILE=
EXPAND=cat

while test $# != 0
do
	OPT2=
	name="$1"
	shift

	case $name in
	-n|-vn|-nv)
		NOOP=yes
		OPTS="$OPTS -v"
		;;
	-s)
		SPCS=yes
		;;
	-h|-help|--help)
		cat <<-EOF
		This is a wrapper for the $INDENT_PROG program, which adds options.
		Unrecognized options are passed to $INDENT_PROG, which does not use
		getopt.

		The wrapper pre/post-filters the source to provide for macros which
		would confuse $INDENT_PROG.

		Options:
		  -h             help (shows this message)
		  -n             no-op (perform indent and show difference without saving)
		  --profile file get settings (look in current, home or $INDENT_DATA)
		  -s             convert tabs to spaces in the updated file
		  -D             test: show differences from pre-filtering
		  -N             test: suppress indent, to test pre/post-filtering
EOF
		exit
		;;
	-version|--version)
		cat <<-EOF
		This is a wrapper for `$INDENT_PROG -version`
EOF
		;;
	-profile|--profile)
		if test $# = 0
		then
			echo "?? missing parameter for $name"
			$0 -h
			exit 1
		fi
		if test -f "$1"
		then
			PROFILE="$1"
		elif test -f "$HOME/$1"
		then
			PROFILE="$HOME/$1"
		elif test -f "$INDENT_DATA/$1"
		then
			PROFILE="$INDENT_DATA/$1"
		else
			echo "?? cannot find profile $1"
			$0 -h
			exit 1
		fi
		shift
		case `$INDENT_PROG -version 2>/dev/null` in
		*.*-2*)
			OPTS="--profile $PROFILE"
			;;
		*)
			OPTS=`sed -e '/\/\*/,/\*\//d' -e 's/[ 	]*\([0-9]\)/\1/g' $PROFILE | tr '\n' ' '`
			OPTS="-npro $OPTS"
			;;
		esac
		test "$NOOP" = yes && OPTS="$OPTS -v"
		;;
	-D)
		TEST_D=yes
		;;
	-N)
		TEST_N=yes
		NOOP=yes
		;;
	-*)
		OPTS="$OPTS $name"
		;;
	*.[ch]|*.hh|*.cc|*.cpp|*.[yl])
		case $name in
		*.[yl])
			OPT2="-ly"
			;;
		esac
		if test "$SPCS" = yes
		then
			if test -n "$PROFILE"
			then
				SPCS=`sed -e 's/-/_/g' $PROFILE |fgrep __tab_size|sed -e 's/^__tab_size[ 	]*//' -e 's/[ 	].*//'`
				if test -z "$SPCS"
				then
					SPCS=`sed -e 's/-/_/g' $PROFILE |fgrep __ts|sed -e 's/^__ts[ 	]*//' -e 's/[ 	].*//'`
				fi
				test -z "$SPCS" && SPCS=8
			else
				SPCS=8
			fi
			EXPAND="expand -t $SPCS"
		fi
		USED=yes
		save="${name}".a$$
		test="${name}".b$$
		rm -f "$save" "$test"
		mv "$name" "$save"
		# (pre-filter) temporarily comment-out macros which confuse indent
		sed \
			-e '/EMPTY_MODULE(/s/)$/);/' \
			-e 's,\(MODULEID(\),//\1,' \
			-e '/MODULE_ID(/s/)$/);/' \
			-e 's,\<GCC_UNUSED[ 	]*\([;]\),\1//GCC_UNUSED,' \
			-e 's,\<GCC_NORETURN\(.*\);,;//GCC_NORETURN\1,' \
			-e 's,\<GCC_PRINTFLIKE(\(.*\);,;//GCC_PRINTFLIKE(\1,' \
			-e 's,\<GCC_SCANFLIKE(\(.*\);,;//GCC_SCANFLIKE(\1,' \
			-e 's,\(\<NCURSES_EXPORT_VAR\>.*;\),//\1,' \
			-e 's,\(\<MARK_END_OF_PROLOG\>\),\1;,' \
			-e 's,\(\<YY_RULE_SETUP\>\),\1;,' \
			-e 's,\(\<YY_BREAK\>\),\1;,' \
			"$save" >"$test"
		cp "$test" "$name"
		# show the result of pre-filtering for the -D option
		if test $TEST_D = yes ; then
			echo ".. pre-filtering"
			diff -u "$save" "$name"
		fi
		chmod u+w "$name"
		# if the -N option is given, simply echo the command rather than
		# performing it.
		if test $TEST_N = yes ; then
			echo "$INDENT_PROG $OPTS $OPT2 $name"
		else
			$INDENT_PROG $OPTS $OPT2 "$name"
		fi
		# (post-filter) restore the file.  There is an extra chunk used to
		# handle multiple GCC_xxx's on the same line.
		sed \
			-e '/EMPTY_MODULE(/s/);$/)/' \
			-e 's,//\(MODULEID(\),\1,' \
			-e '/MODULE_ID(/s/);$/)/' \
			-e 's,[ 	]*\([;]\)[ 	]*//GCC_UNUSED\(.*\), GCC_UNUSED\1\2,' \
			-e 's,;[ 	]*//GCC_NORETURN\(.*\);, GCC_NORETURN\1;,' \
			-e 's,;[ 	]*//GCC_PRINTFLIKE(\(.*\);, GCC_PRINTFLIKE(\1;,' \
			-e 's,;[ 	]*//GCC_SCANFLIKE(\(.*\);, GCC_SCANFLIKE(\1;,' \
			-e 's,;[	]*//\(GCC_.*\), \1;,' \
			-e 's,\(\<GCC_[^ 	][^ 	]*\)[ 	][ 	]*\(\<GCC_[^ 	]\),\1 \2,g' \
			-e 's,//\(\<NCURSES_EXPORT_VAR\>[ ]*\),\1,' \
			-e 's,\(\<MARK_END_OF_PROLOG\>\);,\1,' \
			-e 's,\(\<YY_RULE_SETUP\>\);,\1,' \
			-e 's,\(\<YY_BREAK\>\);,\1,' \
			"$name" | $EXPAND >"$test"
		mv "$test" "$name"
		rm -f "${name}~"
		if test $NOOP = yes ; then
			if (cmp -s "$name" "$save" ) then
				echo "** no change: $name"
			else
				diff -u "$save" "$name"
			fi
			rm -f "$name"
			mv "$save" "$name"
		elif ( cmp -s "$name" "$save" ) ; then
			echo "** unchanged $name"
			rm -f "${name}"
			mv "$save" "$name"
		else
			echo "** updated $name"
			rm -f "$save"
		fi
		;;
	*)
		USED=yes
		echo "** ignored:   $name"
		;;
	esac
done
if test $USED = no
then
	echo "?? no filenames given"
	$0 -h
	exit 1
fi
# vi:ts=4 sw=4
