#!/bin/sh -f

# What I wouldn't do for rc...
# Well... it's better than m4shgmake.

CONFIG="$ROOT/config.mk"
CONFSTR='# Generated by "make config"'

# ==================== The Messy Part ====================

#XXX Ignores lines ending in \
parseconfig() {
	cat <<'!' | sed "s/CONFSTR/$CONFSTR/"
	/^CONFSTR/ {exit}
	/^( *#|	)/ {next}
	function fixup() {
		sub(/ #.*/, "")
		sub(/^ */, "")
		gsub(/'/, "'\"'\"'")
		sub(/[	 ]*\+?=[	 ]*/, "='")
		sub(/[	]*$/, "'")
		var = $0
		val = $0
		sub(/\+?=.*/, "", var)
		sub(/^[^=]+=/, "", val)
	}
	/\+=/ && !/^	/ {
		fixup()
		if(!set[var]) {
			print var"=''"
			append[var]++
		}
		print var"=\"$" var " \"" val
		print var"_orig=\"$" var "\""
		next
	}
	/=/ && !/^	/ {
		fixup()
		delete append[var]
		set[var]++

		print var"="val
		print var"_orig=\"$" var "\""
	}
	END{
		for(v in set)
			print v "_append=''"
		for(v in append)
			print v "_append=true"
	}
!
}

findinc() {
	var="$1"; file="$2"; shift 2
	for d in "$@"; do
		if [ -d "$d" -a -f "$d/$file" ]; then
			eval "$var=\"-I$d\""
			break; fi; done
}
soext=.so
aext=.a
findlib() {
	var="$1"; lib="$2"; shift 2
	for d in "$@"; do
		if [ -d "$d" -a -f "$d/$lib.so" -o -f "$d/lib$lib.a" ]; then
			_libdir="$d"; _libname="$lib"
			eval "$var=\"-L$d -l$lib\""
			break; fi; done
}

expand() {
	_expand="$@"; _expand_old=''
	while [ "$_expand" != "$_expand_old" ]; do
		_expand_old="$_expand"
		eval "_expand=\"$_expand\""; done
	echo -n "$_expand"
}

cfg() {
	CFG="$CFG
$@"
}

equals() {
	if [ -z "$append" ]; then
		echo -n "=";
	else
		echo -n "+="; fi
}

prompt() {
	var=$1; shift
	eval "def=\$$var; orig=\$${var}_orig; append=\$${var}_append"

	unset val
	if [ -z "$def" -o -n "$force" ]; then
		echo "$@"
		echo -n "$var[$def]$(equals) "
		read val
		echo
	fi

	if [ -z "$val" ]; then
		val="$def"; fi
	if [ "$(expand $val)" != "$(expand "$orig")" ]; then
		cfg "$var$(equals)$val"; fi
}

# The messy sed... Turns $(VAR) into ${VAR}, but not $$(VAR) into $${VAR}
eval "$(sed 's/\([^$]\)\$(\([A-Za-z_]*\))/\1${\2}/g' <"$CONFIG" | awk "`parseconfig`")"
CFG="$(sed -n "/^$CONFSTR/q; p" "$CONFIG"; echo "$CONFSTR")"

# ==================== The Fun Part ====================

cat <<!
Configuring for the wmii build.

You'll be prompted for a number of settings which wmii needs to build,
install, and run properly. In most cases, the defaults will be sufficient,
in which case, you may simply press return to accept them.

!

# Guess...
AWKPATH=$(which awk 2>/dev/null)

prompt AWKPATH "Full path to your system's 'awk' program"
prompt PLAN9 "Path of a Plan 9 Port or 9base installation"

force=1
prompt PREFIX Installation prefix

echo
echo "Compilation details (if you don't understand these, just leave the defaults)"
echo
prompt CC C object compiler
prompt LD 'Linker (this should normally not be "ld")'

set -- $CC
if $1 -v 2>&1 | grep 'gcc version' >/dev/null; then
	echo -n You appear to be using gcc. Is this correct? '[yes] '
	while :; do
		read resp
		case "$resp" in
		[Yy][Ee][Ss]|'')
			cfg 'include $(ROOT)/mk/gcc.mk'
			break;;
		[Nn][Oo])
			cfg 'CFLAGS=""'
			# Not perfect. Botches system cflags, but we
			# need to ditch the gcc ones.
			break;;
		*)
			echo -n 'Please answer yes or no: '
		esac
	done
	echo
fi

prompt INCPATH Search path for include files
prompt LIBS Libraries to be linked with every executable

prompt CFLAGS Flags for the C compiler
prompt LDFLAGS Flags for the linker
case $(uname -s) in
	[Dd]arwin) cfg 'STATIC=""';;
	*) prompt STATIC Extra linker flags to produce a static executable;;
esac
unset force

# Make some guesses

# Extract the -L paths from ldflags.
ldlibs="$(awk 'BEGIN{
		for(i=1; i <= ARGC; i++)
			if(ARGV[i] ~ /-L/)
				print ":" substr(ARGV[i], 3)
	}' $LDFLAGS)"
# Turn include paths into ../lib paths.
inclibs="$(expand "$INCPATH"|sed 's,/include:,/lib:,g; s,/include$,/lib,')"
# Lace them all together, and expand them.
libs="$(expand "$LIBDIR:$ldlibs:$inclibs:/usr/local/lib:/opt/local/lib")"

LIBIXP=${LIBIXP%/libixp.a}
INCPATH="$INCPATH:/usr/local/include:/opt/local/include"
incpath="$(expand "$INCPATH")"

oifs="$IFS"; IFS=:
findinc INCX11 X11/Xlib.h $incpath \
	/usr/X11R6/include /usr/x11/include /usr/x11/include /usr/X11/include \
	/usr/openwin/include /opt/x11/include /opt/X11/include
findinc INCICONV iconv.h $incpath

findlib LIBX11 X11 $libs \
	/usr/X11R6/lib /usr/X11/lib /usr/openwin/lib /usr/x11/lib \
	/opt/X11 /opt/x11 /usr/local/lib /opt/local/lib
findlib LIBICONV iconv $libs

if [ -d "$ROOT/libixp" ]; then
	_libdir="$ROOT/lib"; else
	soext=.a findlib LIBIXP ixp "$ROOT/lib" $libs; fi
LIBIXP="$_libdir/libixp.a"
IFS="$oifs"

# Back to prompting
echo Library paths...
prompt INCX11 Compiler flags to find X11 includes
prompt LIBX11 Linker flags to link against libX11

# Find out if the system libc includes iconv...
#   GNU systems tend to make /usr/lib/libc.so or /lib/libc.so
# linker scripts rather than libraries, so I can't parse them.
# As a kludge, I ask ldd what actual libc.so /bin/sh links to,
# which is pretty reliable.  It's very unlikely that anyone will
# actually be prompted for this.
#   I suppose the auto*hell way would be to just compile
# something against libc. Perhaps another day.
if nm -D $(ldd /bin/sh | awk '$1 ~ /^libc\.so/ {print $3}') |
	awk -ve=1 '$2 == "T" && $3 == "iconv" {e=0; exit}; END {exit e}'
then
	echo
	echo "Your system's libc appears to include iconv."
	echo
else
	prompt LIBICONV Linker flags to link agains libiconv \
		'(may be left blank if iconv is part of your system libc)'
fi
prompt INCICONV Compiler flags to find iconv.h
prompt LIBIXP Path to libixp.a

echo Writing config.mk
echo "$CFG
" >config.mk
echo Done.

