#!/bin/bash
#
# set up build process for FGSL
#
# FIXME: 
#  add debug switch with appropriate flags
#  add compiler case constructs to properly treat bits and debug
#-------------------------------------------------------------------------------
usage() {
    echo "configure can take the following switches:"
    echo "          --prefix <dirname>"
    echo "          --f90 <f90_compiler>"
    echo "          --cc  <c_compiler>"
    echo "          --gsl <path_to_gsl>"
    echo "          --bits [32|64] (AIX only)"
    echo "          --help "
}    
#
# Default settings
#
gsl_root="/usr /usr/local"
prefix=""
bits=""
#
# Process argument list
#
while [ ! -z "$1" ] ; do
    case $1 in
	--prefix ) 
	    prefix=$2
	    shift
	    ;;
	--f90 )
	    f90_comp="$2"
	    shift
	    ;;
	--cc )
	    c_comp="$2"
	    shift
	    ;;
	--gsl )
	    gsl_root="$2 $gsl_root"
	    shift
	    ;;
	--bits )
	    bits="$2"
	    shift
	    ;;
	--help )
	    usage
	    exit 0
	    ;;
	* )
	    usage
	    exit 1
	    ;;
    esac
    shift
done
#
# differentiate by OS
#
os=$(uname -s)
case $os in
    Linux) 
	f90_comp=${f90_comp:-"g95 ifort gfortran f95"}
	c_comp=${c_comp:-"gcc icc"}
	arflags="-crsv"
	bits_32=""
	bits_64=""
	;;
    AIX)
	f90_comp=${f90_comp:-"xlf_r g95"}
	c_comp=${c_comp:-"xlc_r gcc"}
	arflags="-crsv -Xany"
	bits_32="-q32"
	bits_64="-q64"
	;;
    *)
	f90_comp=${f90_comp:-"g95"}
	c_comp=${c_comp:-"gcc"}
	arflags="-crsv"
	bits_32=""
	bits_64=""
	;;
esac
#
# Check required functionality
#
dir=d.s$$
mkdir $dir
cd $dir
f90=""
for xx in $f90_comp; do
    if [ ! -x $(which $xx 2> /dev/null) ] ; then
	continue
    fi
    cat > t.f90 <<EOF
program foo
  use, intrinsic :: iso_c_binding
  implicit none
  integer(c_int) :: ic
  integer(c_size_t) :: is
  character(c_char) :: cc
  real(c_float) :: rc
  real(c_double) :: dc
  type(c_ptr) :: ptr
  type(c_funptr) :: fptr
end program
EOF
    $xx -c t.f90 > /dev/null 2>&1
    if [ $? == 0 ] ; then
	f90=$xx
	echo "  Using $(which $f90) as Fortran compiler"
	break
    else
	echo "  Compiler $xx does not support ISO_C_BINDING"
    fi
done
cd ..
rm -rf $dir
cc=""
for xx in $c_comp; do
    if [ -x $(which $xx 2> /dev/null) ] ; then
	cc=$xx
	echo "  Using $(which $cc) as C compiler"
	break
    fi
done
if [ "$bits" != "" ] ; then
    case $bits in
	32 | 64 )
	    ;;
	*)  echo "--bits can only have the values 32 or 64. Aborting"
	    exit 1;
	    ;;
    esac
fi
#
# numeric models
#
rm -f checktypes.exe
$cc -o checktypes.exe ./checktypes.c > /dev/null 2>&1
if [ -x ./checktypes.exe ] ; then
    int=$(./checktypes.exe | grep int)
    flt=$(./checktypes.exe | grep flt)
else
    echo " Could not determine numeric model. Aborting ..."
    exit 1
fi
rm -f checktypes.exe
case $int in
    int_2_4_4_4)
	rm -f integer.finc
	ln -s interface/integer_ilp32.finc integer.finc
	;;
    int_2_4_8_8)
	rm -f integer.finc
	ln -s interface/integer_ilp64.finc integer.finc
	;;
    *)  
	echo "Unsupported numerical integer model. Aborting ..."
	exit 1
	;;
esac
case $flt in
    flt_4_8)
	;;
    *)  
	echo "Unsupported numerical floating point model. Aborting ..."
	exit 1
	;;
esac
#
# differentiate by compiler
#
case $f90 in
    g95|gfortran)
	FFLAGS="$FFLAGS"
	FPP=-cpp
	;;
# NAG. FIXME: other compilers of same name need differentiator
    f95)
	FFLAGS="$FFLAGS -ieee=full -f2003"
	FPP=-fpp
	;;
    sunf95)
	FFLAGS="$FFLAGS"
	FPP=-fpp
	;;
    ifort)
	FPP=-fpp
	;;
    xlf_r|xlf90_r)
	;;
    *) 
	echo "Unsupported Fortran compiler. Aborting ..."
	exit 1
	;;
esac
gsl=""
lib="lib"
for xx in $gsl_root; do
#    echo "Trying $xx"
    if [ -d $xx/include/gsl ] ; then
	gsl_lib=""
	if [ -s $xx/lib/libgsl.a -a -s $xx/lib/libgslcblas.a ] ; then
	    gsl=$xx
	    gsl_lib="-L$xx/lib -lgsl -lgslcblas"
	fi
	if [ -s $xx/lib64/libgsl.a -a -s $xx/lib64/libgslcblas.a ] ; then
	    gsl=$xx
	    gsl_lib="-L$xx/lib64 -lgsl -lgslcblas"
	    lib=lib64
	fi
	if [ "$gsl_lib" != "" ] ; then
	    echo "  Using GSL library located in $gsl/$lib"
	    break
	else
	    echo "  No valid GSL installation found in $xx. Aborting ..."
	    exit 1
	fi
    fi
done
if [ "$prefix" == "" ] ; then
    prefix=$gsl
fi
echo "  Installation target path is $prefix."
rm -rf $dir

#
# Write configuration for make
#
rm -f make.inc
if [ "$f90" == "" -o "$gsl" == "" -o "$cc" == "" ] ; then
    echo "Configuration unsuccessful. make.inc not written."
    exit 1
else
    echo F90 = $f90 >> make.inc
    echo CC = $cc >> make.inc
    echo GSL_LIB = $gsl_lib >> make.inc
    echo GSL_INC = -I$gsl/include >> make.inc
    echo LDFLAGS = $LDFLAGS >> make.inc
    echo FFLAGS = $FFLAGS >> make.inc
    echo CFLAGS = $CFLAGS >> make.inc
    echo PREFIX = $prefix >> make.inc
    echo ARFLAGS = $arflags >> make.inc
    echo FPP = $FPP >> make.inc
    echo LIB = $lib >> make.inc
    echo "Configuration successful. Now run make to build,"
    echo "or make test to run test suite. Enjoy!"
fi
