#!/usr/bin/env bash

# Run through all possible configuration combinations
#  permute [-n] [-s] [-v] [program...]
#   -n  Just display the combinations
#   -s  Just run the singles

# Needs to be run from the top of a source tree (where x3270, s3270, tcl3270
# and c3270 can be seen).

TD=${TD-/tmp}
ver=3.3
prog=${0##*/}

function usage()
{
    echo >&2 "usage $prog [-n] [-s] [-v] [program...]"
    exit 1
}

while (( $# > 0 ))
do	case $1 in
    	-n)	noop=1
		shift
		;;
	-s)	singles=1
	    	shift
		;;
	-v)	verbose=1
	    	shift
		;;
	-*)	usage
	    	;;
	*)	break
	esac
done

if [ $# -eq 0 ]
then	progs="x3270 s3270 tcl3270 c3270 pr3287"
else	progs="$@"
fi

# Run one iteration
#  $prog	program name
#  $c		configure options
#
#  $TD		temporary directory
#  $noop	if 1, display rather than run
function iterate()
{
	typeset rc=0

	if [ $noop ]
	then	echo $prog: $c
	else	./configure --without-pr3287 $c >/dev/null 2>&1 || (echo "$prog configure --without-pr3287 $c failed"; exit 1)
		make clean >/dev/null 2>&1
		if mk >$TD/mk$$ 2>&1
		then	echo -n "."
		else	echo
			echo "$prog failed: $c"
			[ $verbose ] && cat $TD/mk$$
			rc=1
		fi
		if grep 'warning:' $TD/mk$$
		then	echo "Warnings: $c"
		fi
		rm $TD/mk$$
	fi
	return $rc
}

# Compute the options for the given iteration.
#  $1		iteration
#
#  $n_opts	number of possible options for this program
#  $masks[]	bit mask for each option
#  $opts[]	name of each option
#  $nixpr	--without-pr3287 option, if applicable
function config_opts()
{
    	typeset -i x=$1
	typeset c=""
	typeset -i j=0

	while (( j < n_opts ))
	do	if (( x & ${masks[$j]} ))
		then	c="$c --${opts[$j]}"
		fi
		j=j+1
	done
	echo $c $nixpr
}

# Count the bits in $1.
#  $1		integer to evaluate
function cob()
{
	typeset -i n=$1 b=1 r=0
	while (( $b <= $n ))
	do	if (( $n & $b ))
		then	r=r+1
		fi
		b=b*2
	done
	echo $r
}

for prog in $progs
do	echo "Trying $prog."
	rm -rf $TD/$prog-$ver/
	p=$PWD
	cd $prog
	make -f Makefile.aux $prog-src.tgz
	cd $TD/
	tar -xzf ~-/$prog-src.tgz
	cd $prog-$ver/
	[ -f $p/$prog/.mk ] && cp $p/$prog/.mk .

	typeset -i b=1
	unset opts[@]
	if [ $prog = x3270 -o $prog = c3270 ]
	then	nixpr=--without-pr3287
	else	unset nixpr
	fi
	typeset -a opts masks
	typeset -i n_opts=0
	for opt in disable-ansi disable-apl disable-local-process disable-printer disable-script disable-tn3270e disable-trace disable-menus disable-keypad disable-ft disable-ssl disable-dbcs with-iconv disable-ipv6
	do	unset ok
		case $opt in
		disable-dbcs|disable-ssl|with-iconv|disable-ipv6)
			# apply to all
			ok=1
			;;
		disable-ansi|disable-apl|disable-local-process|disable-tn3270e|disable-trace|disable-ft)
			# apply to all except pr3287
			if [ $prog != pr3287 ]
			then	ok=1
			fi
			;;
		disable-printer|disable-menus)
			# only apply to x3270 and c3270
			if [ $prog = x3270 -o $prog = c3270 ]
			then	ok=1
			fi
			;;
		disable-script)
			# required for s3270 and tcl3270
			if [ $prog != s3270 -a $prog != tcl3270 -a $prog != pr3287 ]
			then	ok=1
			fi
			;;
		disable-keypad)
			# apply only to x3270
			if [ $prog = x3270 ]
			then	ok=1
			fi
			;;
		esac
		if [ "$ok" ]
		then	opts[$n_opts]=$opt
			masks[$n_opts]=$b
			b=b*2
			n_opts=n_opts+1
		fi
	done
	echo "$prog: possible options are [${opts[@]}]: $b combinations"

	# Loop through the singles.
	typeset -i x=0
	while (( x < b ))
	do	c=$(config_opts $x)
		iterate || exit 1
		if (( $x == 0 ))
		then	x=1
		else	x=x*2
		fi
	done

	# Loop through everything else.
	if [ ! "$singles" ]
	then
		typeset -i x=0
		while (( x < b ))
		do	c=$(config_opts $x)
			typeset nb=$(cob $x)
			if (( nb > 1 ))
			then	iterate
			fi
			x=x+1
		done
	fi

	echo

	cd ..
	rm -rf $prog-$ver/
	cd $p
done
