# This script provides a wannabe-generic library for compile-time package
# autoconfiguration
# Copyright (c) Petr Baudis, 2006
#
#
# Some design traits and large chunks of this script come from mplayer:
#
# Original version (C) 2000 Pontscho/fresh!mindworkz
#                      pontscho@makacs.poliod.hu
#
# History / Contributors: check the cvs log !
#
# Cleanups all over the place (c) 2001 pl
#
#
# This configure script is *not* autoconf-based and has different semantics.
# It attempts to autodetect all settings and options where possible. It is
# possible to override autodetection with the --enable-option/--disable-option
# command line parameters.  --enable-option forces the option on skipping
# autodetection. Yes, this means that compilation may fail and yes, this is not
# how autoconf-based configure scripts behave.
#
# configure generates config.mak.autogen, then included in the Makefile.
#
#############################################################################

# Prevent locale nonsense from breaking basic text processing utils
LC_ALL=C
export LC_ALL

# These macros only return an error code - NO display is done

compile_check() {
{
	echo
	cat "$1"
	echo
	echo "$_cc $CFLAGS $_inc_extra $_ld_static $_ld_extra -o $TMPO $@"
	rm -f "$TMPO"
	$_cc $CFLAGS $_inc_extra $_ld_static $_ld_extra -o "$TMPO" "$@" || return $?
	echo
	echo "ldd $TMPO"
	$_ldd "$TMPO" || return $?
	echo
} >>"$TMPLOG" 2>&1
}

cc_check() {
	compile_check $TMPC $@
}

# Try to run the compiled file
tmp_run() {
	"$TMPO" >> "$TMPLOG" 2>&1
}

# Display error message, flushes tempfile, exit
die () {
	echo
	echo "Error: $@" >&2
	echo >&2
	rm -f "$TMPO" "$TMPC" "$TMPS" "$TMPCPP"
	echo "Check \"$TMPLOG\" if you do not understand why it failed." >&2
	exit 1
}

# OS test booleans functions
issystem() {
	test "`echo $system_name | tr A-Z a-z`" = "`echo $1 | tr A-Z a-z`"
}
linux()   { issystem "Linux"   ; return "$?" ; }
sunos()   { issystem "SunOS"   ; return "$?" ; }
hpux()    { issystem "HP-UX"   ; return "$?" ; }
irix()    { issystem "IRIX"    ; return "$?" ; }
aix()     { issystem "AIX"     ; return "$?" ; }
cygwin()  { issystem "CYGWIN"  ; return "$?" ; }
freebsd() { issystem "FreeBSD" ; return "$?" ; }
netbsd()  { issystem "NetBSD"  ; return "$?" ; }
bsdos()   { issystem "BSD/OS"  ; return "$?" ; }
openbsd() { issystem "OpenBSD" ; return "$?" ; }
bsd()     { freebsd || netbsd || bsdos || openbsd ; return "$?" ; }
qnx()     { issystem "QNX"     ; return "$?" ; }
darwin()  { issystem "Darwin"  ; return "$?" ; }
gnu()     { issystem "GNU"     ; return "$?" ; }
mingw32() { issystem "MINGW32" ; return "$?" ; }
morphos() { issystem "MorphOS" ; return "$?" ; }
win32()   { cygwin || mingw32  ; return "$?" ; }
beos()    { issystem "BEOS"    ; return "$?" ; }

# arch test boolean functions
# x86/x86pc is used by QNX
x86() {
	case "$host_arch" in
		i[3-9]86|x86|x86pc|k5|k6|k6-2|k6-3|pentium*|athlon*|i586-i686) return 0 ;;
		*) return 1 ;;
	esac
}

x86_64() {
	case "$host_arch" in
		x86_64|amd64) return 0 ;;
		*) return 1 ;;
	esac
}

ppc() {
	case "$host_arch" in
		ppc) return -1;;
		*) return 1;;
	esac
}

alpha() {
	case "$host_arch" in
		alpha) return 0;;
		*) return 1;;
	esac
}

# Use this before starting a check
# The second optional parameter is name of the feature variable;
# it is preset to an empty string so that it can be dropped into
# config.mak.autogen seamlessly; use echores_yesno() for reporting.
echocheck() {
	echo "============ Checking $@ ============" >> "$TMPLOG"
	echo ${_echo_n} "Checking $@... ${_echo_c}"
}

# Use this to echo the results of a check
echores() {
	if test "$_res_comment" ; then
		_res_comment="($_res_comment)"
	fi
	echo "Result is: $@ $_res_comment" >> "$TMPLOG"
	echo "##########################################" >> "$TMPLOG"
	echo "" >> "$TMPLOG"
	echo "$@ $_res_comment"
	_res_comment=""
}

# Use this to introduce a regular feature with a commandline switch
# @name is the variable name
# @switch is the commandline switch
# @mkvar is the Makefile variable name; prefix with a space to say that it's negated (ow)
# @desc is a line to insert to the --help output
# @default is the default value (yes/no/auto)
add_library() { # --with
	name="$1"; shift; switch="$1"; shift; mkvar="$1"; shift; default="$1"; shift; desc="$1"; shift
	case $default in
		yes) hdefault=with;;
		no) hdefault=without;;
		auto) hdefault=autodetect;;
	esac

	lib_help="$lib_help
$desc [$hdefault]"
	switches="$switches switch_lib \"$name\" \"$switch\" \"\$ac_option\" || "
	mkvars="$mkvars mkvar \"\$$name\" \"$mkvar\";"
	eval "$name=$default"
}

add_feature() { # --enable
	name="$1"; shift; switch="$1"; shift; mkvar="$1"; shift; default="$1"; shift; desc="$1"; shift
	case $default in
		yes) hdefault=enable;;
		no) hdefault=disable;;
		auto) hdefault=autodetect;;
	esac

	feature_help="$feature_help
$desc [$hdefault]"
	switches="$switches switch_feature \"$name\" \"$switch\" \"\$ac_option\" || "
	mkvars="$mkvars mkvar \"\$$name\" \"$mkvar\";"
	eval "$name=$default"
}

lib_help=
feature_help=
switches=
mkvars=


switch_lib() {
	name="$1"; shift; switch="$1"; shift; option="$1"; shift
	case $option in
		--with-$switch) eval "$name=yes";;
		--without-$switch) eval "$name=no";;
		*) return 1
	esac
	return 0
}

switch_feature() {
	name="$1"; shift; switch="$1"; shift; option="$1"; shift
	case $option in
		--enable-$switch) eval "$name=yes";;
		--disable-$switch) eval "$name=no";;
		*) return 1
	esac
	return 0
}

mkvar() {
	value="$1"; shift; mkvar="$1"; shift
	noval=""; yesval="ConfigureYesPlease"
	case $mkvar in
		\ *) swap="$noval"; noval="$yesval"; yesval="$swap";;
	esac
	case $value in
		auto) die "$mkvar autodetection failed";;
		no) echo "$mkvar = $noval";;
		yes) echo "$mkvar = $yesval";;
		*) die "$mkvar got invalid value ''$value''";;
	esac
}


#############################################################################


# Check how echo works in this /bin/sh
case `echo -n` in
	-n)	_echo_n=	_echo_c='\c'	;;	# SysV echo
	*)	_echo_n='-n '	_echo_c=	;;	# BSD echo
esac


process_params() {
	_install=install
	_cc=cc
	test "$CC" && _cc="$CC"

	for ac_option do
		case "$ac_option" in
		--help|-help|-h)
			cat << EOF
Usage: $0 [OPTIONS]...

Configuration:
  -h, --help             display this help and exit

Installation directories:
  --prefix=DIR           use this prefix for installing git [HOME]
  --bindir=DIR           use this prefix for installing git binary
                         [PREFIX/bin]
  --gitexecdir=DIR       use this prefix for installing individual git command
                         binaries [BINDIR]
  --mandir=DIR           use this prefix for installing manpages [PREFIX/man]
  --templatedir=DIR      use this prefix for installing configuration file
                         templates [PREFIX/share/git-core/templates]
  --gitpythondir=DIR     use this prefix for python libraries [PREFIX/share/git-core/python]

Miscellaneous options:
  --cc=COMPILER          use this C compiler to build MPlayer [gcc]
  --target=PLATFORM      target platform (i386-linux, arm-linux, etc)
  --with-install=PATH    use a custom install program (useful if your OS uses
                         a GNU-incompatible install utility by default and
                         you want to use GNU version)

For the options below, see the top of the Makefile for more detailed
description.

Optional features:$feature_help

Optional libraries:$lib_help

This configure script is NOT autoconf-based, even though its output is similar.
It will try to autodetect all configuration options. If you --enable an option
it will be forcefully turned on, skipping autodetection. This can break
compilation, so you need to know what you are doing.
EOF
			exit 0 ;;

		--prefix=*)
			_prefix=`echo $ac_option | cut -d '=' -f 2` ;;
		--bindir=*)
			_bindir=`echo $ac_option | cut -d '=' -f 2` ;;
		--gitexecdir=*)
			_gitexecdir=`echo $ac_option | cut -d '=' -f 2` ;;
		--mandir=*)
			_mandir=`echo $ac_option | cut -d '=' -f 2` ;;
		--templatedir=*)
			_templatedir=`echo $ac_option | cut -d '=' -f 2` ;;
		--gitpythondir=*)
			_gitpythondir=`echo $ac_option | cut -d '=' -f 2` ;;

		--cc=*)
			_cc=`echo $ac_option | cut -d '=' -f 2` ;;
		--target=*)
			_target=`echo $ac_option | cut -d '=' -f 2` ;;
		--with-install=*)
			_install=`echo $ac_option | cut -d '=' -f 2 ` ;;

		*)
			# $switches is the real bulk
			eval "$switches { echo \"Unknown parameter: $ac_option\"; exit 1; }" || exit 1 ;;
		esac
	done

	# Determine our OS name and CPU architecture
	if test -z "$_target" ; then
		# OS name
		system_name=`uname -s 2>&1`
		case "$system_name" in
		Linux|FreeBSD|NetBSD|BSD/OS|OpenBSD|SunOS|QNX|Darwin|GNU|BeOS|MorphOS|AIX)
			;;
		IRIX*)
			system_name=IRIX ;;
		HP-UX*)
			system_name=HP-UX ;;
		[cC][yY][gG][wW][iI][nN]*)
			system_name=CYGWIN ;;
		MINGW32*)
			system_name=MINGW32 ;;
		*)
			system_name="$system_name-UNKNOWN" ;;
		esac


		# host's CPU/instruction set
		host_arch=`uname -p 2>&1`
		case "$host_arch" in
		i386|sparc|ppc|alpha|arm|mips|vax)
			;;
		powerpc) # Darwin returns 'powerpc'
			host_arch=ppc ;;
		*)	# uname -p on Linux returns 'unknown' for the processor type,
			# OpenBSD returns 'Intel Pentium/MMX ("Genuine Intel" 586-class)'

			# Maybe uname -m (machine hardware name) returns something we
			# recognize.

			# x86/x86pc is used by QNX
			case "`uname -m 2>&1`" in
				i[3-9]86*|x86|x86pc|k5|k6|k6_2|k6_3|k6-2|k6-3|pentium*|athlon*|i586_i686|i586-i686|BePC) host_arch=i386 ;;
				ia64) host_arch=ia64 ;;
				x86_64|amd64)
				if [ -n "`$_cc -dumpmachine | sed -n '/^x86_64-/p;/^amd64-/p'`" -a \
					-z "`echo $CFLAGS | grep -- -m32`"  ]; then
					host_arch=x86_64
				else
					host_arch=i386
				fi
				;;
				macppc|ppc|ppc64) host_arch=ppc ;;
				alpha) host_arch=alpha ;;
				sparc) host_arch=sparc ;;
				sparc64) host_arch=sparc64 ;;
				parisc*|hppa*|9000*) host_arch=hppa ;;
				arm*|zaurus|cats) host_arch=arm ;;
				s390) host_arch=s390 ;;
				s390x) host_arch=s390x ;;
				mips*) host_arch=mips ;;
				vax) host_arch=vax ;;
				*) host_arch=UNKNOWN ;;
			esac
			;;
		esac
	else # if test -z "$_target"
		system_name=`echo $_target | cut -d '-' -f 2`
		case "`echo $system_name | tr A-Z a-z`" in
			linux) system_name=Linux ;;
			freebsd) system_name=FreeBSD ;;
			netbsd) system_name=NetBSD ;;
			bsd/os) system_name=BSD/OS ;;
			openbsd) system_name=OpenBSD ;;
			sunos) system_name=SunOS ;;
			qnx) system_name=QNX ;;
			morphos) system_name=MorphOS ;;
			mingw32msvc) system_name=MINGW32 ;;
		esac
		# We need to convert underscores so that values like k6-2 and pentium-mmx can be passed
		host_arch=`echo $_target | cut -d '-' -f 1 | tr '_' '-'`
	fi

	echo "Detected operating system: $system_name"
	echo "Detected host architecture: $host_arch"
}


test_setup() {
	# LGB: temporary files
	# FIXME: Use mktemp -d?
	for I in "$TMPDIR" "$TEMPDIR" "/tmp" ; do
		test "$I" && break
	done

	TMPLOG="config.log"
	rm -f "$TMPLOG"
	TMPC="$I/git-conf-$RANDOM-$$.c"
	TMPO="$I/git-conf-$RANDOM-$$.o"
	TMPS="$I/git-conf-$RANDOM-$$.S"
}

basic_tests() {
	echocheck "if your build environment is sane"
	cat > $TMPC <<EOF
int main(void) { return 0; }
EOF
	{ cc_check && tmp_run; } || die "unusable compiler or produced binary"
	echores yes
}


write_config() {
	echo "Creating config.mak.autogen"

	{
		cat << EOF
# -------- Generated by configure -----------

CC = $_cc
INSTALL = $_install

EOF
		test -z $_prefix || echo "prefix = $_prefix"
		test -z $_bindir || echo "bindir = $_bindir"
		test -z $_gitexecdir || echo "gitexecdir = $_gitexecdir"
		test -z $_mandir || ( echo "mandir = $_mandir" && echo "export mandir" )
		test -z $_templatedir || echo "template_dir = $_templatedir"
		test -z $_gitpythondir || echo "GIT_PYTHON_DIR = $_gitpythondir"
		echo
		eval "$mkvars"
	} > config.mak.autogen

	cat << EOF

Config files successfully generated by ./configure.
You can inspect the results in \`\`./config.mak.autogen''.
EOF
}


finish() {
	# Last move:
	rm -f "$TMPO" "$TMPC" "$TMPS" "$TMPCPP"
}

trap finish 0
