# Architecture-specific configuration.
# 
# usage: configure
#
# TODO:
#   locate bash on the system (for Cornell Suns it's /usr/local/gnu/bin/bash)
#     if bash cannot be found, use ksh instead.
#   better job of finding egrep
#

# figure out the architecture
PATCH_ARCH=i686-unknown-linux
ARCH=`config/config.guess`
TARGET=`echo ${ARCH} | awk -F'-' '{ print $1 }'`
TYPE=`echo ${ARCH} | awk -F'-' '{ print $2 }'`
OS=`echo ${ARCH} | awk -F'-' '{ print $3 }'`

# quit if we know the architecture won't work
if [ "${OS}" = "cygwin1.3.2" ]; then
  echo "Cygwin 1.3.2 is not supported---upgrade to version 1.3.10"
  exit 1
fi
if [ "${OS}" = "cygwin1.3.3" ]; then
  echo "Cygwin 1.3.3 is not supported---upgrade to version 1.3.10"
  exit 1
fi

# get the root directory of the source tree
# Note: under Cygwin, pwd can return a path name containing a colon.
#  Such path names don't work in make's VPATH, so we convert them
#  to path names without colons using the cygpath command.
if [[ $OS == cygwin* ]]; then
  PWD=`pwd`
  CYCDIR=`cygpath -u "$PWD"`
else
  CYCDIR=`pwd`
fi

# Decide on a built-in command to find commands.  In ksh this is
#  command -v and in bash it is type -p.  The 'which' command is
#  giving me trouble on solaris so I resort to this.
if [[ $BASH = "" ]]; then # ksh
  WHICH='command -v'
else
  WHICH='type -p'
fi

###########################################################################
# functions to find appropriate helper programs
#
TMPFILE=/tmp/cyconfig$$
RES=

# diff_path <arch>
#   given the architecture, outputs a suitable version of diff

function diff_path {
  DIFF="diff"
  # make sure it's GNU diff
  $DIFF --version > $TMPFILE 2>&1
  grep GNU $TMPFILE > /dev/null
  if [ $? != 0 ]; then
    if [ "$TYPE" = "sun" ]; then
      f="/usr/local/gnu/diffutils-2.6/bin/diff"
      if [ -f "$f" ]; then
        DIFF=$f
      else
        echo "Warning: could not find $f"
        echo "  file include/arch/$1.h may be incorrect/incomplete"
      fi
    fi
  fi
  rm -f $TMPFILE
  RES=$DIFF
}

# egrep_path <arch>
#   given the architecture, outputs a suitable version of egrep

function egrep_path {
  EGREP="egrep"
  if [ "$TYPE" = "sun" ]; then
    f="/usr/xpg4/bin/egrep"
    if [ -f "$f" ]; then
      EGREP=$f
    else
      echo "Warning: could not find $f"
      echo "  file include/arch/$1.h may be incorrect/incomplete"
    fi
  fi
  RES=$EGREP
}

# finds a suitable version of cc, along with special flags
#   if it can't find gcc, it uses cc (which, if not symlinked to gcc,
#   will fail)
#
function get_cc {
  CC=gcc
  if [ "$TYPE" = "apple" ]; then
    CC="cc -no-cpp-precomp -Wno-long-double"
  else
    for comp in gcc cc; do
      CC=`$WHICH $comp 2> /dev/null`
      if [ -n "$CC" -a -x "$CC" ]; then
        CC=$comp
        break
      fi
    done
  fi
  if [ -z "$CC" ]; then
    echo "Could not find gcc or cc on this system"
    exit 1
  fi
  if [ "$TARGET" = "i686" ]; then
    CC="$CC -march=i686"
  fi
  RES=$CC
}

# sets up default Cyclone load flags
#
function get_ldflags {
  LDFLAGS=
  if [ "$TYPE" = "sun" ]; then
    LDFLAGS="-lnsl -lsocket -lresolv"
  fi
  RES=$LDFLAGS
}

# when setting up a new architecture, figures out the default
#   set up genfiles to use
#
function get_def_genfiles {
  mkdir ${CYCDIR}/bin/genfiles/${ARCH}
  case "${OS}" in
    cygwin*)
      DEF_ARCH=i686-unknown-cygwin1.3.10;;
    *)
      DEF_ARCH=i686-unknown-linux
  esac
  echo "Using the genfiles from ${DEF_ARCH}" 
  ${CYCDIR}/bin/genfiles/extract_patch ${PATCH_ARCH} ${DEF_ARCH}
  cp -r ${CYCDIR}/bin/genfiles/${DEF_ARCH}/* ${CYCDIR}/bin/genfiles/${ARCH}
  CVS_files=`find ${CYCDIR}/bin/genfiles/${ARCH} -name CVS`
  if [ -n "$CVS_files" ]; then
    \rm -rf $CVS_files
  fi
  if [ -f "${CYCDIR}/bin/genfiles/${PATCH_ARCH}.patch" ]; then
    \rm -rf ${CYCDIR}/bin/genfiles/${PATCH_ARCH}
  fi
}

###########################################################################
#  incdir="$CYCDIR/include"
#  libdir="$CYCDIR/bin/cyc-lib"
#  bindir=

incdir="/usr/include/cyclone"
libdir="/usr/local/lib/cyclone"
bindir="/usr/local/bin"

# arguments
#
while [ $# != 0 ]; do
  case "$1" in
    -bindir) # set the directory to store the binaries
        shift
        if [ $# = 0 ]; then 
	  echo "-bindir must specify a directory"; exit 1; fi
        bindir=$1
        shift
    ;;
    -libdir) # set the library directory
        shift
        if [ $# = 0 ]; then 
	  echo "-libdir must specify a directory"; exit 1; fi
        libdir=$1
        shift
    ;;
    -incdir) # set the include directory
        shift
        if [ $# = 0 ]; then 
	  echo "-incdir must specify a directory"; exit 1; fi
        incdir=$1
        shift
    ;;
    -prefix) # set directories to prefix/bin prefix/lib/cyclone ...
        shift
        if [ $# = 0 ]; then 
	  echo "-prefix must specify a directory prefix"; exit 1; fi
	prefix=$1
        shift
    ;;
    *) # bad option
        echo "usage: configure [-sh shell] [-incdir dir] [-bindir dir] [-libdir dir] [-prefix pre]";
        exit 1
    ;;
  esac
done

if [ -n "$prefix" ]; then
  bindir="$prefix/bin"
  libdir="$prefix/lib/cyclone"
fi

# function to cleanup if we can't port the arch
function cleanup {
  \rm -f ${CYCDIR}/config/arch/${ARCH}*
  \rm -rf ${CYCDIR}/bin/genfiles/${ARCH}
  exit 1
}

# figure out cc to use
get_cc
CC=$RES

cd config

# see if we have #defines for this architecture
if [ ! -f "arch/${ARCH}" ]; then
  echo "This architecture ($ARCH) is currently unsupported."
  echo "Set it up (y/n)?"
  read resp
  if [ "$resp" = "y" ]; then
    echo | ${CC} -E -dM - > arch/$ARCH
    if [ $? != 0 ]; then
      echo "error creating arch #define file"
      cleanup
    fi
    awk '{ printf("#undef %s\n",$2); }' arch/$ARCH > arch/$ARCH.undef
    if [ $? != 0 ]; then
      echo "error creating arch #undef file"
      cleanup
    fi
    echo "Creating architecture-specific include file"
    egrep_path ${ARCH}
    EGREP=$RES
    export EGREP
    export CC
    if [ -d "${CYCDIR}/bin/genfiles/${ARCH}" ]; then
      echo "Warning: genfiles directory for ${ARCH} exists"
    else
      get_def_genfiles;
    fi
  else
    echo "aborting."
    exit 1
  fi
else
  # make sure all of the needed configuration files are here
  if [ -f "arch/${ARCH}.undef" ]; then
    echo "Supported architecture ${ARCH}"
    cd ../bin/genfiles; ./extract_patch ${PATCH_ARCH} ${ARCH}; cd -
    if [ ! -d "${CYCDIR}/bin/genfiles/${ARCH}" ]; then
      echo "Warning: genfiles directory for ${ARCH} not present"
      get_def_genfiles;
    fi
  else
    echo "Error---missing configuration files for ${ARCH}; rerun configure"
    cleanup
  fi
fi

# set up the installation paths
function chkdir {
  echo -n "  $1=$2"
  if [ ! -d "$2" ]; then
    echo " (will create)"
  else
    echo
  fi
}
echo "Will install into"
chkdir "binaries" $bindir
chkdir "libraries" $libdir
chkdir "include files" $incdir

# figure out all supported architectures by checking for config files
ALL_ARCHS=`cd arch; \ls -1 | grep -v undef | grep -v CVS | awk '{printf("%s ",$1);}'`

# get default load flags
get_ldflags
LD_FLAGS=$RES
diff_path
DIFF=$RES

# write the config Makefile
cd ..

(cat <<EOF
# -*- Makefile -*-
# THIS FILE IS AUTOMATICALLY GENERATED BY configure FROM Makefine.inc.in

# architecture specific defines
CYCDIR=${CYCDIR}
ARCH=${ARCH}
INC_INSTALL=${incdir}
BIN_INSTALL=${bindir}
LIB_INSTALL=${libdir}
ALL_ARCHS=${ALL_ARCHS}
CC=${CC}
LDFLAGS=${LD_FLAGS}
SHELL=${CONFIGSHELL}
DIFF=${DIFF}

EOF
cat Makefile.inc.in) > Makefile.inc
