#!/bin/sh

# usage: ./configure.sh [options]
# options:
# --cflags='flags'		(default "-g")
# --target='target'		(no default)
# --target-file-format='format	(no default)
# --host='host'			(no default)
# --target-gcc='gcc'		(default "gcc", if host and target are same)
# --target-strip='strip'	(default "strip")
# --target-nm='nm'		(default "nm")
# --root='dir'			(default "..")
# --front-end='front-end'
#    one of `x', `nextstep', `dos', `svgalib', `win32', 'sdl'	(no default)
# --syn68k-target='target'
# --sound='sound'

cflags='-g'
root='..'

# save away arguments to be used when creating the `config.status'
arguments=''

while [ $# != 0 ]; do
  arg="$1"; shift

  # append the next argument onto the argument list for `config.status'
  arguments="$arguments '$arg'"

  case "${arg}" in
    # options
    -*=*)
      opt=`echo ${arg} | sed 's:^-*\([^=]*\)=.*$:\1:'`
      val=`echo ${arg} | sed 's:^-*[^=]*=\(.*\)$:\1:'`
      
      ## Change `-' in the option name to `_'.
      optname="${opt}"
      opt="`echo ${opt} | tr - _`"

      case "${opt}" in
        "cflags")
          cflags="${val}"
        ;;
        "root")
          root="${val}"
        ;;
        "target")
          target="${val}"
        ;;
        "target_gcc")
          target_gcc="${val}"
	;;
        "target_strip")
          target_strip="${val}"
        ;;
        "target_nm")
          target_nm="${val}"
        ;;
        "host")
          host="${val}"
        ;;
        "front_end")
	  front_end="${val}"
	;;
	"target_file_format")
	  target_file_format="${val}"
	;;
	"syn68k_target")
	  syn68k_target="${val}"
	  ;;
	"sound")
	  sound="${val}"
	  ;;
	*)
	  echo "unknown option \`${arg}', ignored"
	;;
      esac
    ;;
    *)
      echo "unknown option \`${arg}', ignored"
    ;;
  esac
done

util_dir=${root}/util

if [ "${target}" = "" ]; then
  echo "Fatal error: you must specify a target.  Exiting."
  exit 1
fi

if [ "${front_end}" = "" ]; then
  echo "Fatal error: you must specify a front end.  Exiting."
  exit 1
fi  

if [ "${host}" = "" ]; then
  echo "You did not specify a host.  Taking a guess."
  host=`${root}/util/config.guess`

  if [ "${host}" = "" ]; then
    echo "config.guess failed to determine the host type.  Exiting."
    exit 1
  else
    echo "This appears to be a \`${host}'."
  fi
fi

case "${front_end}" in
  x | nextstep | dos | svgalib | win32 | sdl)
    ;;
  *)
    echo "Fatal error: unknown front end \`${front_end}'.  Exiting."
    exit 1
  ;;
esac

case "${sound}" in
  dummy | djgpp | linux | sdl)
    ;;
  *)
    echo "Fatal error: unknown sound \`${sound}'.  Exiting."
    exit 1
    ;;
esac

# canonicalize the name of the target; this should
# give us the name used for tool configuration
if canonical_target=`${root}/util/config.sub "${target}"` ; then : ; else
  exit $?
fi

# canonicalize the name of the host; this should
# give us the name used for tool configuration
if canonical_host=`${root}/util/config.sub "${host}"` ; then : ; else
  exit $?
fi

if [ "${target_gcc}" = "" ]; then
  if [ "${canonical_target}" = "${canonical_host}" ]; then
    target_gcc=gcc
  else
    echo "Fatal error: target and host differ, target gcc must by specified.  Exiting."
    exit 1
  fi
fi

if [ "${target_nm}" = "" ]; then
  target_nm=nm
fi

if [ "${target_strip}" = "" ]; then
  target_strip=strip
fi

case ${canonical_target} in
  m68k-next-ns* | m68k-next-bsd* | m68k-next-mach* | m68k-next-nextstep*)
    target_os='next'
    target_syn68k='next'
    target_arch='m68k'
    target_file_format='mach-o'
    objc='yes'
  ;;
  i[3456]86-next-ns* | i[3456]86-next-bsd* | i[3456]86-next-mach* \
	| i[3456]86-next-nextstep*)
    target_os='next'
    target_syn68k='next'
    target_arch='i386'
    target_file_format='mach-o'
    objc='yes'
  ;;
  i[3456]86-msdos-go32 | i[3456]86-go32-bsd | i[3456]86-unknown-msdos)
    target_os='msdos'
    target_syn68k='msdos'
    target_file_format='coff'
    target_arch='i386'
  ;;

# NOTE: Historically we've used mingw32 but called it cygwin.  The reason
# we use mingw32 is because it has a license compatible with Executor.
# However, since internally we've called it cygwin, I'm hesitant to change
# cygwin to mingw32 everywhere right now (20031217).

  i[3456]86-pc-mingw32)
    target_os='cygwin32'
    target_syn68k='mingw32'
    echo target os set to cygwin32 which is a misnomer.  this really is mingw32
    target_file_format='pe'
    target_arch='i386'
  ;;
  i[3456]86-pc-cygwin32)
    target_os='cygwin32'
    target_syn68k='cygwin32'
    target_file_format='pe'
    target_arch='i386'
  ;;
  alpha-unknown-linux)
    target_os='linux'
    target_syn68k='linux'
    target_file_format='elf'
    target_arch='alpha'
  ;;
  powerpc-unknown-linux)
    target_os='linux'
    target_syn68k='linux'
    target_file_format='elf'
    target_arch='powerpc'
  ;;
  i[3456]86-unknown-linux)
    target_os='linux'
    target_syn68k='linux'
    target_arch='i386'
    if [ x"${target_file_format}" = x"" ]; then
      # default linux file format; this may change
      target_file_format='a.out'
    fi
  ;;

  *)
    echo "Fatal error: unknown target \`${canonical_target}'.  Exiting."
    exit 1
  ;;
esac

case ${canonical_host} in
  m68k-next-ns* | m68k-next-bsd* | m68k-next-mach* \
   | m68k-next-nextstep*)
    host_os='next'
    host_arch='m68k'
    objc='yes'
  ;;
  i[3456]86-next-ns* | i[3456]86-next-bsd* | i[3456]86-next-mach* \
   | i[3456]86-next-nextstep*)
    host_os='next'
    host_arch='i386'
    objc='yes'
  ;;
  i[3456]86-msdos-go32 | i[3456]86-go32-bsd | i[3456]86-unknown-msdos)
    host_os='msdos'
    host_arch='i386'
  ;;
  alpha-unknown-linux)
    host_os='linux'
    host_arch='alpha'
  ;;
  powerpc-unknown-linux)
    host_os='linux'
    host_arch='powerpc'
  ;;
  i[3456]86-unknown-linux)
    host_os='linux'
    host_arch='i386'
  ;;

  *)
    echo "Fatal error: unknown host \`${canonical_host}'.  Exiting."
    exit 1
  ;;
esac

# check for the target directories
target_arch_dir=${root}/src/config/arch/${target_arch}
if [ ! -d ${target_arch_dir} ]; then
  echo "Fatal error: target arch directory \`${target_arch_dir}' not found.  Exiting."
  exit 1
fi

target_os_dir=${root}/src/config/os/${target_os}
if [ ! -d ${target_os_dir} ]; then
  echo "Fatal error: target os directory \`${target_os_dir}' not found.  Exiting."
  exit 1
fi

if [ -r ${root}/src/config/os/${target_os}/${target_os}.make ]; then

  if [ -r ${root}/src/config/os/${target_os}/${target_os}.sh ]; then
    ${root}/src/config/os/${target_os}/${target_os}.sh		\
     "${target_gcc}"						\
     "${cflags}"						\
     ${root}/src/config/os/${target_os}/${target_os}.make	\
     __config__.target_os.make
    
    if [ $? != "0" ]; then
      echo "Fatal error: target os configuration failed.  Exiting."
      exit 1
    fi
    target_os_make=__config__.target_os.make
  else
    target_os_make=${root}/src/config/os/${target_os}/${target_os}.make
  fi
else
  target_os_make="/dev/null"
fi

if [ -r ${root}/src/config/arch/${target_arch}/${target_arch}.make ]; then
   target_arch_make=${root}/src/config/arch/${target_arch}/${target_arch}.make
else
  target_arch_make="/dev/null"
fi

if [ -r ${root}/src/config/front-ends/${front_end}/${front_end}.sh ]; then
  # generate the front end makefile front the front end template
  # make file `${front_end}.make'
  
  # there must be a front-end makefile fragment
  ${root}/src/config/front-ends/${front_end}/${front_end}.sh	\
   "${target_gcc}"							\
   "${cflags}"								\
   ${root}/src/config/front-ends/${front_end}/${front_end}.make		\
   __config__.front_end.make
  
  if [ $? != "0" ]; then
    echo "Fatal error: front end configuration failed.  Exiting"
    exit 1
  fi
  
  front_end_make=__config__.front_end.make
else
  # there must be a front-end makefile fragment
  front_end_make=${root}/src/config/front-ends/${front_end}/${front_end}.make
fi

# there must be a front-end config header
front_end_config_h=${root}/src/config/front-ends/${front_end}/${front_end}.h

if [ -r ${root}/src/config/sound/${sound}/${sound}.make ]; then
  if [ -r ${root}/src/config/sound/${sound}/${sound}.sh ]; then
    ${root}/src/config/sound/${sound}/${sound}.sh			\
     "${target_gcc}"							\
     "${cflags}"							\
     ${root}/src/config/sound/${sound}/${sound}.make			\
     __config__.sound.make
    
    if [ $? != "0" ]; then
      echo "Fatal error: target os configuration failed.  Exiting."
      exit 1
    fi
    sound_make=__config__.sound.make
  else
    sound_make=${root}/src/config/sound/${sound}/${sound}.make
  fi
else
  sound_make="/dev/null"
fi

executor_make=${root}/src/executor.make

# link `front-end-config.h' to the front end config header
rm -f front-end-config.h
ln -s ${front_end_config_h} front-end-config.h

# arch determines syn68k usage
rm -f target-arch-config.h
if [ -r ${root}/src/config/arch/${target_arch}/${target_arch}.h ]; then
  target_arch_h=${root}/src/config/arch/${target_arch}/${target_arch}.h

  ln -s ${target_arch_h} target-arch-config.h

  cat > ./test.c.sed << __EOF__
#include <stdio.h>	
#include "@target_arch_h@"

int main ()
{
  printf (
#if defined (SYN68K)
	  "yes"
#else
	  ""
#endif /* SYN68K */
	  );
}
__EOF__

  sed -e "s:@target_arch_h@:${target_arch_h}:" \
    < ./test.c.sed > ./test.c

  gcc -I${root}/src/include -o ./test ./test.c
  if [ x"`./test`" = x"" ]; then
    syn68k=''
  else
    syn68k='yes'
  fi

  rm -f ./test.c.sed ./test.c ./test
else
  # create an empty `target-arch-config.h'
  touch target-arch-config.h
  
  target_conf_h=""
  syn68k=''
fi

rm -f target-os-config.h
if [ -r ${root}/src/config/os/${target_os}/${target_os}.h ]; then
  target_os_h=${root}/src/config/os/${target_os}/${target_os}.h

  ln -s ${target_os_h} target-os-config.h
else
  # create an empty `target-os-config.h'
  touch target-os-config.h
  target_os_h=""
fi

rm -f host-arch-config.h
if [ -r ${root}/src/config/arch/${host_arch}/${host_arch}.h ]; then
  host_arch_h=${root}/src/config/arch/${host_arch}/${host_arch}.h

  ln -s ${host_arch_h} host-arch-config.h
else
  # create an empty `host-arch-config.h'
  touch host-arch-config.h
  host_arch_h=""
fi

rm -f host-os-config.h
if [ -r ${root}/src/config/os/${host_os}/${host_os}.h ]; then
  host_os_h=${root}/src/config/os/${host_os}/${host_os}.h

  ln -s ${host_os_h} host-os-config.h
else
  # create an empty `host-os-config.h'
  touch host-os-config.h
  host_os_h=""
fi

rm -f sound-config.h
if [ -r ${root}/src/config/sound/${sound}/${sound}-sound.h ]; then
  sound_h=${root}/src/config/sound/${sound}/${sound}-sound.h

  ln -s ${sound_h} sound-config.h
else
  # create an empty `sound-config.h'
  touch sound-config.h
  sound_h=""
fi

if [ x"${syn68k}" = x"yes" ]; then
#  syn68k_define='-DSYN68K'
  syn68k_define=''
  syn68k_lib='libsyn68k.a'
  if [ x$syn68k_target = x"" ]; then
    syn68k_target="${target_arch}-${target_syn68k}-${target_file_format}"
  fi
else
  syn68k_define=''
  syn68k_lib=''
  syn68k_target=''
fi

cat > ./test.c << __EOF__
int foo;
__EOF__

${target_gcc} -c test.c
symbol=`${target_nm} test.o | awk '/foo/ { print $3; }'`
case ${symbol} in
  _foo)
	symbol_prefix='_'
	;;
  foo)
       symbol_prefix=''
       ;;
  *)
     echo "Error: unknown asm symbol \`${symbol}', exiting."
     exit 1
esac

rm -f ./test.c ./test.o

if ${target_gcc} --version | egrep -q 'egcs-2\.91'; then
  egcs_dcconvert_workaround=-fno-omit-frame-pointer
else
  egcs_dcconvert_workaround=
fi

${util_dir}/subst.pl				\
 @target_arch_make@:${target_arch_make} 	\
 @target_os_make@:${target_os_make} 		\
 @front_end_make@:${front_end_make}		\
 @sound_make@:${sound_make}			\
 @executor_make@:${executor_make} < ${root}/src/config/Makefile.in > ./tmp-Makefile.in

sed -e "s:@symbol_prefix@:${symbol_prefix}:g

        s:@target@:${target}:g
        s:@canonical_target@:${canonical_target}:g
        s:@target_arch@:${target_arch}:g
        s:@target_os@:${target_os}:g
        s:@target_gcc@:${target_gcc}:g
        s:@target_strip@:${target_strip}:g
	s:@target_file_format@:${target_file_format}:g

        s:@host@:${host}:g
        s:@canonical_host@:${canonical_host}:g
        s:@host_arch@:${host_arch}:g
        s:@host_os@:${host_os}:g

        s:@front_end@:${front_end}:g
	s:@sound@:${sound}:g
        s:@front_end_make@:${front_end_make}:g
        s:@root@:${root}:g
        s:@syn68k_define@:${syn68k_define}:g
        s:@syn68k_lib@:${syn68k_lib}:g
        s:@syn68k_target@:${syn68k_target}:g
        s:@cflags@:${cflags}:g
	s:@egcs_dcconvert_workaround@:${egcs_dcconvert_workaround}:g
        s:@arch@:${target_arch}:g" < ./tmp-Makefile.in > ./Makefile
rm -f ./tmp-Makefile.in

if [ x"${syn68k}" = x"yes" ]; then
  sed -e "/^ifnosyn68k$/,/^end ifnosyn68k$/d" \
      -e "/^ifsyn68k$/d" \
      -e "/^end ifsyn68k$/d" < ./Makefile > ./tmp-Makefile
else
  sed -e "/^ifsyn68k$/,/^end ifsyn68k$/d" \
      -e "/^ifnosyn68k$/d" \
      -e "/^end ifnosyn68k$/d" < ./Makefile > ./tmp-Makefile
fi
rm -f ./Makefile
mv ./tmp-Makefile ./Makefile

if [ x"${objc}" = x"yes" ]; then
  sed -e "/^ifobjc$/d" \
      -e "/^end ifobjc$/d" < ./Makefile > ./tmp-Makefile
else
  sed -e "/^ifobjc$/,/^end ifobjc$/d" < ./Makefile > ./tmp-Makefile
fi
rm -f ./Makefile
mv ./tmp-Makefile ./Makefile

# cleanup
rm -f __config__.*

# create a config.status
mv config.status config.status.running
rm -rf config.status.running

echo '#!/bin/sh'                             > config.status
echo                                        >> config.status
echo "${root}/util/configure.sh $arguments" >> config.status

chmod +x config.status

echo "Executor is now configured for \`${target_arch}-${target_os}/${front_end}'."
