#! /bin/sh

# $Id: configure,v 1.23 2005/07/25 22:36:40 stolpmann Exp $

#--- Options ---
# value -1: off by command line ("forced")
# value 0: off by default
# value 1: on by default
# value 2: on by command line ("forced")
# defaults:

set_defaults () {
    enable_findlib=1
    enable_compatcgi=0
    with_netstring=1
    with_cgi=1
    with_smtp=1
    with_pop=1
    with_nethttpd=1
}
set_defaults

version="1.1"
exec_suffix=""

ehelp_findlib="Enable/disable installation as findlib package"
whelp_netstring="Include/omit netstring library"
whelp_cgi="Include/omit cgi library"
whelp_pop="Include/omit pop library"
whelp_smtp="Include/omit smtp library"
whelp_nethttpd="Include/omit nethttpd library (GPL!)"
ehelp_compatcgi="Enable/disable compatibility for legacy Cgi"

# Which options exist? eoptions for enable/disable, woptions for with/without:
eoptions="findlib compatcgi"
woptions="netstring cgi pop smtp nethttpd"

# Directories to include. The notation +package is allowed.
incdirs=""

# Directory where to install the library:
libdir=`ocamlc -where`/ocamlnet

# Directory where to install data files:
net_db_dir="<library directory>"
net_db_dir_set=0

# Packages to include anyway:
requires="unix"

check_library () {
    # $1: the name of the library (findlib)
    # $2: a typical file in $incdirs
    if [ "$enable_findlib" -gt 0 ]; then
	ocamlfind query "$1" >/dev/null 2>/dev/null
	return
    else
	stdlib=`ocamlc -where`
	for dir in $incdirs; do
	    case "$dir" in
		+*)
		    dir=`echo "$dir" | sed -e "s|^\+|$stdlib/|"` ;;
	    esac
	    if [ -f "$dir/$2" ]; then
		return 0
	    fi 
	done
	return 1   # not found
    fi
}


print_options () {
	for opt in $eoptions; do
		e="o=\$enable_$opt"
		eval "$e"
		uopt=`echo $opt | sed -e 's/_/-/g'`
		if [ $o -gt 0 ]; then
			echo "    -enable-$uopt"
		else
			echo "    -disable-$uopt"
		fi
	done
	for opt in $woptions; do
		e="o=\$with_$opt"
		eval "$e"
		uopt=`echo $opt | sed -e 's/_/-/g'`
		if [ $o -gt 0 ]; then
			echo "    -with-$uopt"
		else
			echo "    -without-$uopt"
		fi
	done
	if [ "$enable_findlib" -le 0 ]; then
	    if [ -n "$incdirs" ]; then
		echo "    -I $incdirs"
	    fi
	    if [ -n "$libdir" ]; then
		echo "    -libdir $libdir"
	    fi
	fi
	echo "    -datadir $net_db_dir"
}


usage () {
	set_defaults
	cat <<_EOF_ >&2
usage: ./configure [ options ]

_EOF_
	for opt in $eoptions; do
		e="help=\$ehelp_$opt"
		eval "$e"
		uopt=`echo $opt | sed -e 's/_/-/g'`
		echo "-enable-$uopt:" >&2
		echo "-disable-$uopt:" >&2
		echo "        $help" >&2
	done
	for opt in $woptions; do
		e="help=\$whelp_$opt"
		eval "$e"
		uopt=`echo $opt | sed -e 's/_/-/g'`
		echo "-with-$uopt:" >&2
		echo "-without-$uopt:" >&2
		echo "        $help" >&2
	done
	cat <<_EOF_ >&2
-I dir
        Add directory to include path (only if -disable-findlib)
-libdir dir
	Install the library into this directory (only if -disable-findlib)
-datadir dir
        Install the run-time data file into this directory

Defaults are:

_EOF_
	print_options >&2
	exit 1
}


check_eopt () {
	for x in $eoptions; do
		if [ "$x" = "$1" ]; then
			return 0
		fi
	done
	echo "Unknown option: $1" >&2
	exit 1
}


check_wopt () {
	for x in $woptions; do
		if [ "$x" = "$1" ]; then
			return 0
		fi
	done
	echo "Unknown option: $1" >&2
	exit 1
}


echo "Welcome to Ocamlnet version $version" >&2

while [ "$#" -gt 0 ]; do
	case "$1" in
		-enable-*)
			opt=`echo "$1" | sed -e 's/-enable-//' -e 's/-/_/g'`
			check_eopt "$opt"
			eval "enable_$opt=2"
			shift
			;;
		-disable-*)
			opt=`echo "$1" | sed -e 's/-disable-//' -e 's/-/_/g'`
			check_eopt "$opt"
			eval "enable_$opt=-1"
			shift
			;;
		-with-*)
			opt=`echo "$1" | sed -e 's/-with-//' -e 's/-/_/g'`
			check_wopt "$opt"
			eval "with_$opt=2"
			shift
			;;
		-without-*)
			opt=`echo "$1" | sed -e 's/-without-//' -e 's/-/_/g'`
			check_wopt "$opt"
			eval "with_$opt=-1"
			shift
			;;
		-I|-include|-incdir)
		        incdirs="$incdirs $2"
			shift; shift
			;;
		-libdir)
		        libdir="$2"
			shift; shift
			;;
	        -datadir)
		        net_db_dir="$2"
			net_db_dir_set=1
			shift; shift
			;;
		-version)
			echo "$version"
			exit 0
			;;
		*)
			usage
	esac
done

######################################################################
# Check ocamlfind

if [ "$enable_findlib" -gt 0 ]; then
    printf "%s" "Checking for findlib... "
    if ocamlfind query stdlib >/dev/null 2>/dev/null; then
	echo "found"
	if [ "$net_db_dir_set" -eq 0 ]; then
	    net_db_dir=`ocamlfind printconf destdir`/netstring
	    net_db_dir_set=1
	fi
    else
	echo "not found"
	enable_findlib=0
	if [ "$enable_findlib" -eq 2 ]; then
	    echo "Sorry, findlib cannot be found."
	    echo "Make sure that ocamlfind is in your PATH, or download findlib"
	    echo "from www.ocaml-programming.de"
	    exit 1
	fi
    fi
fi

if [ "$net_db_dir_set" -eq 0 ]; then
    net_db_dir="$libdir"
    net_db_dir_set=1
fi


######################################################################
# Check that options are sane

# Option dependencies:
# -with-cgi needs -with-netstring
# -with-pop needs -with-netstring
# -with-smtp needs -with-netstring
# -with-nethttpd needs -with-cgi (and -with-netstring)

need_cgi=`expr $with_cgi '>' 0`
need_pop=`expr $with_pop '>' 0`
need_smtp=`expr $with_smtp '>' 0`
need_netstring=`expr $with_netstring '>' 0`
need_nethttpd=`expr $with_nethttpd '>' 0`

if [ $need_nethttpd -gt 0 ]; then need_cgi=1; fi
if [ $need_cgi -gt 0 ]; then need_netstring=1; fi
if [ $need_pop -gt 0 ]; then need_netstring=1; fi
if [ $need_smtp -gt 0 ]; then need_netstring=1; fi

# Forced negative dependencies:
# -without-netstring implies -without-cgi, -without-pop, -without-smtp
# -without-cgi implies -without-nethttpd

if [ $with_netstring -eq -1 ]; then 
    need_netstring=0; need_cgi=0; need_pop=0; need_smtp=0; need_nethttpd=0
fi

if [ $with_cgi -eq -1 ]; then
    need_cgi=0; need_nethttpd=0
fi

# Map need_* back to with_*, check for incompatibilities:

for component in netstring pop cgi smtp nethttpd; do
    eval "need_it=\$need_$component"
    eval "with_it=\$with_$component"
    
    if [ $need_it -gt 0 ]; then
	case $with_it in
	    -1)  echo "Options incompatible with '-without-$component'";
	         exit 1;;
	    0)   eval "with_$component=1" ;;
	    1)   : ;;
	    2)   : ;;
	esac
    else
	case $with_it in
	    -1)  : ;;
	    0)   : ;;
	    1)   eval "with_$component=0" ;;
	    2)   echo "Options incompatible with '-with-$component'";
	         exit 1;;
	esac
    fi
done


######################################################################
# Does ocamlopt support multi-threading?

printf "%s" "Checking multi-threading support... "
mt_type=vm
mt_switch="-vmthread"
mkdir -p tmp
cat <<_EOF_ >tmp/t.ml
let _ = Mutex.create();;
_EOF_
if ocamlopt -thread -o tmp/t threads.cmxa tmp/t.ml 2>/dev/null; then
    if tmp/t 2>/dev/null; then
	mt_type=posix
	mt_switch="-thread"
    fi
fi
echo $mt_type

######################################################################
# Do we need pcre?

need_pcre=0
if [ "$with_netstring" -gt 0 ]; then
    need_pcre=1
    requires="$requires pcre"
fi

######################################################################
# Do we need equeue?

need_equeue=0
if [ "$with_nethttpd" -gt 0 ]; then
    need_equeue=1
    requires="$requires equeue"
fi

######################################################################
# Check that pcre is available:

if [ "$need_pcre" -gt 0 ]; then
    printf "%s" "Checking for PCRE... "
    if check_library pcre pcre.cmi; then
	echo "found"
    else
	echo "not found"
	echo "Sorry, installation is not possible without PCRE."
	echo "Get the PCRE library from:"
	echo "http://miss.wu-wien.ac.at/~mottl/ocaml_sources/"
	exit 1
    fi
fi

######################################################################
# Check that equeue is available:

if [ "$need_equeue" -gt 0 ]; then
    printf "%s" "Checking for Equeue... "
    if check_library equeue equeue.cmi; then
	echo "found"
    else
	echo "not found"
	echo "Sorry, installation is not possible without Equeue."
	echo "Get the Equeue library from:"
	echo "http://www.ocaml-programming.de/packages/"
	exit 1
    fi
fi

######################################################################
# Check cygwin

#printf "%s" "Checking for cygwin... "
#u=`uname`
#case "$u" in
#	CYGWIN*)
#		echo "found"
#		exec_suffix=".exe"
#		;;
#	*)
#		echo "not found"
#		;;
#esac

######################################################################
# Summary

echo
echo "Effective options:"
print_options
echo

pkglist=""
for opt in $woptions; do
	e="o=\$with_$opt"
	eval "$e"
	if [ $o -gt 0 ]; then
		uopt=`echo "$opt" | sed -e 's/_/-/g'`
		pkglist="$pkglist $uopt"
	fi
done

if [ -z "$pkglist" ]; then
    echo "Sorry, it is necessary that you want at least one package to be"
    echo "built."
    exit 1
fi

#echo "Packages: $pkglist"

######################################################################
# Write META

disable_compatcgi="#"   # commented out
if [ $enable_compatcgi -gt 0 ]; then
    disable_compatcgi=""
fi

for pkg in $pkglist; do
	echo "Writing $pkg/META"
	sed -e "s/@VERSION@/$version/g" \
	    -e "s/@DISABLE_COMPATCGI@/$disable_compatcgi/g" \
	    $pkg/META.in >$pkg/META
done

######################################################################
# Write Makefile.conf

includes=""
if [ -n "$incdirs" ]; then
    for d in $incdirs; do
	includes="$includes -I $d"
     done
fi

instmethod="conventional"
useocamlfind=""
pp_options="NON_FINDLIB"
if [ "$enable_findlib" -gt 0 ]; then
    instmethod="findlib"
    useocamlfind='$(OCAMLFIND)'
    includes="$includes -package \"\$(REQUIRES)\""
    pp_options="FINDLIB"
fi

nstr_parts="core"
if [ "$enable_compatcgi" -gt 0 ]; then
    nstr_parts="$nstr_parts compatcgi"
fi

echo "Writing Makefile.conf"
cat <<_EOF_ >Makefile.conf
# The Ocamlnet version
VERSION = $version

# The packages to build in the right order:
PKGLIST = $pkglist

# The parts of the netstring package to build:
NETSTRING_PARTS = $nstr_parts

# Whether the OS needs an .exe suffix for executables:
EXEC_SUFFIX = $exec_suffix

# Required packages (findlib):
REQUIRES = $requires

# Included directories (-I dir, or -I +pkg, or -package pkg):
INCLUDES = $includes

# Additional options only for ocamlc:
OCAMLC_OPTIONS =

# Additional options only for ocamlopt:
OCAMLOPT_OPTIONS =

# Where ocamlnet is to be installed (non-findlib):
LIBDIR = $libdir

# Where the ocamlnet lookup tables are to be installed (both findlib
# and non-findlib):
NET_DB_DIR = $net_db_dir

# Method of installation:
INSTMETHOD = $instmethod

# Method of compilation:
# Either "" (non-findlib), or "\$(OCAMLFIND)"
USE_OCAMLFIND = $useocamlfind
PP_OPTIONS = \$(PP_OPTIONS_${pp_options})

# Compiler switch to enable multi-threading:
THREAD = $mt_switch

_EOF_

if [ "$mt_type" != "posix" ]; then
    cat <<_EOF_ >>Makefile.conf
# Disable multi-threading for ocamlopt:
OBJ_MT_NAT_SWITCH = 

_EOF_
fi

######################################################################
# Finish

echo
echo "Please check Makefile.conf."
echo
echo "You can now compile Ocamlnet by invoking"
echo "   make all"
echo "for the bytecode compiler, and optionally by invoking"
echo "   make opt"
echo "for the native-code compiler (if supported on your architecture)."
echo "Finally, a"
echo "   make install"
echo "will install the package(s)."
