#!/bin/sh
# tag: Tom Lord Tue Dec  4 15:07:58 2001 (scripts/configure-top)
#
# configure -
#
################################################################
# Copyright (C) 2001 Tom Lord
# 
# See the file "COPYING" for further information about
# the copyright and warranty status of this work.
# 

################################################################
# The generic top-level configure file.
# 
# This computes the variables:
# 
# 	srcroot		the root of the source tree
# 	objroot		the root of the build tree
#	srcdir		the source dir (the same as srcroot here)
# 	package		the name of the package (from =plugin/distribution)
#	branchname	the branch name of the package 
#			  ($package sans version and snapshot numbers)
# 	pkgbasename	the basename name of the package 
#			  ($branchname sans branch name)
# 
# It parses $srcroot/PLUGIN/options to get default option values
# and handles command line arguments:
# 
#	--yes option
#	--y option
#	--no option
#	--n option
# 	--with option value
# 	--with-option value
# 	--with option=value
# 	--with-option=value
# 
# and:
# 
#	--version | -V
#	--help | -h
#	--help-options
#	--help-compatability
#	--prefix
#	--config-shell
# 
# It then invokes $srcroot/build-tools/scripts/configure-dirs
# 
# 
set -e

################################################################
# srcdir
# 
# Compute the source directory for this configure script.
# 
# Normally this is inherited from the environment.  See "src/configure".
# 

# If $srcdir is not set from the environment, 
# make it "dirname $0":
# 
# 	./configure 	=> .
#	configure	=> .
#	$dir/configure	=> $dir
# 
if test x$srcdir = x ; then
  srcdir=`dirname $0`
fi

# make "$srcdir" an absolute path
#
here="`pwd`"
cd "$srcdir"
srcdir="`pwd`"
cd "$here"


################################################################
# special options
# 
# Some options are special:
# 
#	--version | -V
#	--help | -h
#	--help-options
#	--help-compatability
# 
# They cause all other options to have no effect and the
# first special option found causes the script to exit.
# 
if test $# -ne 0 ; then

  for opt in "$@" ; do
    case $opt in

      --version|-V)

		printf "Hackerlab configure 0.0\\n"
		printf "Copyright 2001, Tom Lord\\n"
		printf "\\n"
	        printf "This is free software; see the source for copying conditions.\\n"
      		printf "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\\n"
      		printf "PARTICULAR PURPOSE.\\n"
		printf "\\n"
		exit 0
		;;


      --help|-h)

		printf "usage: configure [options]\\n"
		printf "\\n"
		printf " --version | -V		print version information\\n"
		printf " --help | -h		print this message\\n"
		printf " --help-options		print a list of configuration options\\n"
		printf " --help-compatability	print the list of packages with which\\n"
		printf "				this package is purportedly compatible\\n"
		printf "\\n"
		printf " --prefix dir		specify the installation root\\n"
		printf " --prefix=dir\\n"
		printf "\\n"
		printf " --config-shell SHELL   specify a shell for configure scripts\\n"
		printf "\\n"
		printf " --yes option		specify a binary option\\n"
		printf " --y option\\n"
		printf " --no option\\n"
		printf " --n option\\n"
		printf " --with option [yes|y|1|no|n|0]\\n"
		printf " --with-option [yes|y|1|no|n|0]\\n"
		printf " --with option=[yes|y|1|no|n|0]\\n"
		printf " --with-option=[yes|y|1|no|n|0]\\n"
		printf "\\n"
		printf " --with option value	specify a string or package option\\n"
		printf " --with-option value\\n"
		printf " --with option=value\\n"
		printf " --with-option=value\\n"
		printf "\\n"
		exit 0
		;;


	--help-options)

		printf "\\n"
		printf "Available options and default values: \\n"
		printf "\\n"
		if test ! -f "$srcdir/PLUGIN/options" ; then
		  printf " (none)\\n"
		else
 		  str="`cat \"$srcdir/PLUGIN/options\" \
			| grep -E -v \"^[ 	]*(;.*)?\$\" \
			| sed -e \"s/^binary[ 	]*//\" \
			      -e  \"s/^string[ 	]*//\"`"

		  if test -z "$str" ; then
		    str=" (none)"
		  fi
		  printf "%s\\n" "$str"
		fi
		printf "\\n"

		exit 0
		;;


	--help-compatability)

		printf "\\n"
		printf "Compatability List:\\n"
		printf "\\n"
		if test -f "$srcdir/PLUGIN/compatabile" ; then
		  cat "$srcdir/PLUGIN/compatabile"
		else
		  printf " (none)\\n"
		fi
		printf "\\n"
		exit 0
		;;

      --)	break
		;;

      *)	;;
    esac
  done
fi


################################################################
# Sanity Check
# 
# Don't try to configure a source directory.  Always build in a
# separate directory.
# 
# 

if test -r PLUGIN ; then
  echo "Running configure in a source directory is not recommended" 1>&2
  echo "(source directory detected by existence of ./PLUGIN)"  1>&2
  exit 1
fi


# If "$prefix" is not set from the environment, make
# it "`pwd`/=install".
#
if test x$prefix = x ; then
  prefix=`pwd`/=install
fi

# Set srcroot and objroot
# 
srcroot="$srcdir"
objroot=`pwd`


# Compute the package name
# 
pkgfile="$srcroot/=project/package"
if test ! -f "$pkgfile" ; then
  echo "ERROR: no distribution name file found ($pkgfile)." 1>&2
  exit 1
else

  basere="([a-zA-Z]([a-zA-Z0-9]*(-[a-zA-Z0-9]+)?)*)"
  vsnre="([0-9]+\\.[0-9]+)"
  patchre="(base-0|patch-[0-9]+|version-0|version-fix-[0-9]+)"

  package=`grep -E -e "^[ 	]*($basere)(--$basere)?(--$vsnre(--$patchre)?)?[ 	]*(;.*)?\$" "$pkgfile" | head -1`

  if test "x$package" = x ; then
    echo "ERROR: ill-formed distribution name in =project ($pkgfile)." 1>&2
    cat "$pkgfile" 1>&2
    exit 1
  fi
fi

branchname=`echo "$package" | sed -e "s/--[0-9].*//"`
pkgbasename=`echo "$branchname" | sed -e "s/--.*//"`

# Find the top-level PLUGIN directory, if it exists.
# 
 
if test -d "$srcdir/PLUGIN" ; then
  plugindir="$srcdir/PLUGIN"
else
  plugindir=
fi

# obtain lists of options
# 
# 
if test -z "$plugindir" -o ! -f "$plugindir/options" ; then
  binaryopts=
  stringopts=
  packageopts=
else
  binaryopts=`grep "^binary" "$plugindir/options" | sed -e "s/binary[ 	][ 	]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/"`
  binaryopts=`echo $binaryopts`

  stringopts=`grep "^string" "$plugindir/options" | sed -e "s/string[ 	][ 	]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/"`
  stringopts=`echo $stringopts`

  packageopts=`grep -E "^(required|optional)" "$plugindir/packages" \
	       | sed -e "s/required[ 	][ 	]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/" \
	       | sed -e "s/optional[ 	][ 	]*\([a-zA-Z][-a-zA-Z0-9]*\).*/\1/"`
  packageopts=`echo $packageopts`
fi

# clear out the list of option settings
# 
#
optfile="$objroot/Options"
tmpoptfile="$objroot/,,Options"
rm -f "$optfile" "$tmpoptfile"
touch "$optfile" "$tmpoptfile"


# Command line arguments can override the environment variable "prefix"
#
#	--prefix dir
#	--prefix=dir
#
# the shell used by configure
# 
# 	--config-shell SHELL
#
# and configuration options (see the comment at the top of the file)
#

config_shell=/bin/sh

while test $# -ne 0 ; do
  case "$1" in
  --)			shift
  			break
			;;
			
  --prefix=*)		prefix="`printf '%s\n' \"$1\" | sed -e 's/^--prefix=//'`"
    			shift
			;;
			
  --prefix)		shift
			if test $# -eq 0 ; then
       			  echo ERROR: --prefix requires an argument 1>&2
       			  exit 1
    			fi
			prefix="$1"
			shift
			;;

  --config-shell)	shift
			if test $# -eq 0 ; then
       			  echo ERROR: --config-shell requires an argument 1>&2
       			  exit 1
    			fi
			config_shell="$1"
			shift
			;;

  --yes | -y | -n | --no) 
			# Compute the implicit value for the option.
			# Either 0 or 1.
			#
		        if test $1 = --yes -o $1 = -y ; then
			  value=1
			else
			  value=0
			fi

			shift

			# Get the raw option name
			#
			if test $# -eq 0 ; then
			  echo ERROR: --yes and --no require an argument 1>&2
			  exit 1
			fi

			rawopt="$1"
			shift


			# Search the list of valid binary option names
			# for a matching option and remove it from
			# that list if found.
			# 
			leftover=
			thisopt=
			if test ! -z "$binaryopts" ; then
			  for opt in $binaryopts ; do
			    if test "$opt" = "$rawopt" ; then
			      thisopt="$opt"
			    else
			      leftover="$leftover $opt"
			    fi
			  done
			fi
			binaryopts="$leftover"

			# If we didn't find a matching option, that's an error.
			#
			if test -z "$thisopt" ; then
			  echo "ERROR: unrecognized option for --yes or --no ($1)" 1>&2
			  exit 1
			fi

			# Record the value:
			#
			echo "binary $thisopt=$value" >> "$tmpoptfile"

			;;


  --with-*|--with)	
			# Just to be fancy, we permit:
			# 
			# 	--with var value
			# 	--with var=value
			# 	--with-var value
			# 	--with-var=value
			# 
			# What we don't permit is:
			# 
    			# 	--with-var
			# 
			# as a way to set a binary option to "yes", because that
			# leads to horrible ambiguities.
			# 

			# Compute the raw option name.
			# 
			# Either var or var=value.
			# 
			case $1 in 
			  --with)	shift
					if [ $# = 0 ] ; then
					  echo ERROR: --with requires an option and value 1>&2
			  		  exit 1
					fi
					rawopt="$1"
					erroruse="--with $rawopt"
					shift
					;;

			  --with-*)	rawopt="`printf '%s\n' \"$1\" | sed -e 's/^--with-//'`"
					erroruse="--with-$rawopt"
				        shift
					;;
			esac

			# invariant:
			# 
			# $rawopt	either the option name or option=value
			# $erroruse	either --with $rawopt or --with-$rawopt
			# 
			# If the value is a separate argument, it is $1.
			# 


			# Is rawopt foo=bar just foo?
			# 
			case "$rawopt" in

			  *=*)		withopt="`printf '%s\n' \"$rawopt\" | sed -e 's/=.*//'`"
					withval="`printf '%s\n' \"$rawopt\" | sed -e 's/^[^=]*=//'`"
					;;

			  *)		withopt="$rawopt"
					if [ $# = 0 ] ; then
					  echo "ERROR: $erroruse requires an argument" 1>&2
					  exit 1
					fi
					withval="$1"
					shift
					;;
			esac

			# invariant
			# 
			# $withopt	-- the option name
			# $withval	-- the raw option value
			# 


			# search for a matching binary option:
			#
			# Remove it from the list of binary options,
			# if it is found.
			# 
			leftover=
			thisopt=
			if test ! -z "$binaryopts" ; then
			  for opt in $binaryopts ; do
			    if test "$opt" = "$withopt" ; then
			      thisopt=$opt
			    else
			      leftover="$leftover $opt"
			    fi
			  done
			fi
			binaryopts="$leftover"

			# Is it a binary option?
			#
			if test ! -z "$thisopt" ; then

			  # Yes, binary option.  
			  # 

			  # Is the value provided recognizable as a binary value?
			  # Convert it to 0 or 1.
			  # 
			  case "$withval" in
			    yes|y|1)	withval=1
				        ;;
			    no|n|0)	withval=0
				        ;;
			    *)		echo "ERROR: unrecognized value for binary option ($withopt $withval)" 1>&2
				        exit 1
					;;
			  esac

			  # Valid binary option.
			  # Store it.
			  # 
			  echo "binary $thisopt=$withval" >> "$tmpoptfile"


			else
			  # Not a binary option.
			  # 
			  # Search for a matching string option:
			  # 
			  leftover=
			  thisopt=
			  if test ! -z "$stringopts" ; then
			    for opt in $stringopts ; do
			      if test "$opt" = "$withopt" ; then
			        thisopt=$opt
			      else
			        leftover="$leftover $opt"
			      fi
			    done
			  fi
			  stringopts="$leftover"

			  # Is it a string option?
			  # 
			  if test ! -z "$thisopt" ; then
			    # Yes, a string option.
			    # Store it.
			    # 
			    echo "string $thisopt=$withval" >> "$tmpoptfile"
			  else
			    # Not a string option.
			    # 
			    # Search for a matching package option:
			    # 
			    leftover=
			    thisopt=
			    if test ! -z "$packageopts" ; then
			      for opt in $packageopts ; do
			        if test "$opt" = "$withopt" ; then
			          thisopt=$opt
			        else
			          leftover="$leftover $opt"
			        fi
			      done
			    fi
			    packageopts="$leftover"
			    
			    # Is it a package option?
			    # 
			    if test -z "$thisopt" ; then
			      # No, its an unrecognized option.
			      # 
			      echo "ERROR: unrecognized argument ($erroruse)" 1>&2
			      exit 1
			    else
			      # Yes, its a package option.
			      # 
			      # Pass it as a hint to the package finder script
			      #
			      echo "PACKAGE HANDLERS NOT DONE YET" 1>&2
			      exit 1
			    fi
			  fi
			fi
			;;

    *)			printf "configure: unrecognized option (%s)\\n" "$1" 1>&2
			printf "try --help\\n" 1>&2
			exit 1
			;;


  esac
done

# No other arguments are permitted.
# 
if [ $# != 0 ] ; then
  echo "ERROR: unrecognized arguments" 1>&2
  echo "        " "$*" 1>&2
  exit 1
fi

# Provide default values for options not specified on 
# the command line.
# 

# Default binary option values:
# 
if test ! -z "$binaryopts" ; then
  for opt in $binaryopts ; do
    default=`grep "^binary[ 	][ 	]*$opt[ 	]" "$plugindir/options" \
             | sed -e "s/binary[ 	][ 	]*[a-zA-Z][-a-zA-Z0-9]*[ 	][ 	]*\([^ 	][^ 	]*\)/\1/"`

    # Is the default value recognizable?
    # Convert it to 0 or 1.
    # 
    case "$default" in
      0|1)	;;

      yes|y)	default=1
    		;;

      no|n)	default=0
		;;

      *)	echo "ERROR: Bad default value for $opt ($default) in $plugindir/options" 1>&2
	        exit
		;;
    esac

    echo "binary $opt=$default" >> "$tmpoptfile"
  done
fi


# Default string option values:
# 
if test ! -z "$stringopts" ; then

  for opt in $stringopts ; do
    default=`grep "^string[ 	][ 	]*$opt[ 	]" "$plugindir/options" \
	     | sed -e "s/string[ 	][ 	]*[a-zA-Z][-a-zA-Z0-9]*[ 	][ 	]*\(.*\)/\1/"`
    echo "string $opt=$default" >> "$tmpoptfile"
  done

fi

# Default package option values:
# 
if test ! -z "$packageopts" ; then

  for opt in $packageopts ; do
    default=`grep "^string[ 	][ 	]*$opt[ 	]" "$plugindir/options" \
	    | sed -e "s/string[ 	][ 	]*[a-zA-Z][-a-zA-Z0-9]*[ 	][ 	]*\(.*\)/\1/"`
    echo "PACKAGE HANDLERS NOT DONE YET" 1>&2
    exit 1
  done
fi

# Add the standard config variables to $optfile
#
printf "\\n" >> "$optfile"
printf "string std--package=%s\\n" "$package" >> "$optfile"
printf "string std--prefix=%s\\n" "$prefix" >> "$optfile"
printf "string std--srcroot=%s\\n" "$srcroot" >> "$optfile"
printf "string std--objroot=%s\\n" "$objroot" >> "$optfile"
# 
# Don't put `srcdir' in the Options file.
# 
# printf "string std--srcdir=%s\\n" "$srcdir" >> "$optfile"
# 

# Put the list of names under which this package is advertised
# via the `conf-info' program in $optfile
# 
rm -f ,,advertised-as

if test ! -f "$srcroot/PLUGIN/advertised-as" ; then

  printf "%s\\n" "$package" >> ,,advertised-as

  if test "$branchname" != "$package" ; then
    printf "%s\\n" "$branchname" >> ,,advertised-as
  fi

  if test "$pkgbasename" != "$branchname" ; then
    printf "%s\\n" "$pkgbasename" >> ,,advertised-as
  fi

else

  grep -E -v "^[ 	]*(;.*)?\$" "$srcroot/PLUGIN/advertised-as" \
    | sed -e "s/[ 	]*//g" \
	  -e "s/;.*//" \
  > ,,advertised-as

  printf "%s\\n" "$package" >> ,,advertised-as

fi

printf "string std--advertised-as=" >> "$optfile"
for a in `sort -u ,,advertised-as` ; do
  printf "%s " "$a" >> $optfile
done
printf "\\n" >> "$optfile"
rm -f ,,advertised-as


printf "\\n" >> "$optfile"
printf "\\n" >> "$optfile"

if test -f "$srcroot/PLUGIN/auto" ; then

  auto_conf="$config_shell $srcroot/build-tools/scripts/auto"

  export auto_conf
  export srcroot
  export objroot
  export srcdir
  export prefix
  export config_shell

  # This (setting CC) is a temporary hack.  A more systematic way 
  # to handle non-standard names for the standard tools known to 
  # make is in the works:
  # 

  cc_setting="`cat \"$optfile\" \"$tmpoptfile\" | grep -E -e '^string cc=' | tail -n 1 | sed -e 's/string cc=//'`"
  if test -z "$cc_setting" ; then
    CC=cc
  else
    CC="$cc_setting"
  fi
  export CC

  "$config_shell" "$srcroot/PLUGIN/auto" >> "$optfile"
  printf "\\n" >> "$optfile"
  printf "\\n" >> "$optfile"
fi


cat "$tmpoptfile" >> "$optfile"

rm "$tmpoptfile"



# Build config-include/config-options.h
# 
rm -rf config-include
mkdir config-include
cat > config-include/config-options.h << EOF

#ifndef INCLUDE__CONFIG_OPTIONS_H
#define INCLUDE__CONFIG_OPTIONS_H

EOF

grep "^binary" "$optfile" | sed -e "s/^binary[ 	]*/#define cfg__/" -e "s/-/_/g" -e "s/=/ /" >> config-include/config-options.h

printf "\\n#define CFG__BINARY_OPTIONS() \\\\\\n" >> config-include/config-options.h

grep "^binary" "$optfile" | sed -e "s/^binary[ 	]*/ CFG__BINARY_OPTION(cfg__/" -e "s/-/_/g" -e "s/=/, /" -e "s/\$/) \\\\/" >> config-include/config-options.h

printf "\\n\\n"  >> config-include/config-options.h

grep "^string" "$optfile" \
  | sed -e "s/^[a-z]*[ 	]*//" \
	-e h \
	-e "s/[^=]*=//" \
	-e "s/\"/\\\\\"/g" \
	-e "s/\\\\/\\\\\\\\/g" \
	-e "s/.*/\"&\"/" \
	-e x \
	-e "s/=.*/ /" \
	-e "s/^/#define cfg__/" \
	-e "s/-/_/"g \
	-e G \
	-e "s/\\n//" \
  >> config-include/config-options.h

printf "\\n#define CFG__STRING_OPTIONS() \\\\\\n" >> config-include/config-options.h

grep "^string" "$optfile" \
  | sed -e "s/^[a-z]*[ 	]*//" \
	-e h \
	-e "s/[^=]*=//" \
	-e "s/\"/\\\\\"/g" \
	-e "s/\\\\/\\\\\\\\/g" \
	-e "s/.*/\"&\"/" \
	-e "s/\$/) \\\\/" \
	-e x \
	-e "s/=.*/ /" \
	-e "s/^/ CFG__STRING_OPTION(cfg__/" \
	-e "s/-/_/"g \
	-e "s/\$/, /" \
	-e G \
	-e "s/\\n//" \
  >> config-include/config-options.h

printf "\\n\\n"  >> config-include/config-options.h

if test -f "$srcroot/PLUGIN/compatible" ; then

  printf "\\n\\n#define CFG__COMPATIBLE_RELEASES() \\\\\n" >> config-include/config-options.h

  grep -E -v "^[ 	]*(;.*)?\$" "$srcroot/PLUGIN/compatible" \
    | sed -e "s/[ 	]*//g" \
	  -e "s/;.*//" \
	  -e "s/\\\\/\\\\\\\\/g" \
	  -e "s/\"/\\\\\"/g" \
	  -e "s/^/\"/" \
	  -e "s/\$/\"/" \
	  -e "s/^/  CFG__COMPATIBLE_RELEASE(/" \
	  -e "s/\$/) \\\\/" \
  >> config-include/config-options.h

  printf "\\n\\n" >> config-include/config-options.h

fi

cat >> config-include/config-options.h << EOF

#endif 

EOF

# Build Makefile-config.mk
# 
rm -f Makefile-config.mk
cat > Makefile-config.mk << EOF

ifndef makefile-config-mk
makefile-config-mk	:= 1

EOF

grep "^binary" "$optfile" | sed -e "s/^binary[ 	]*/cfg__/" -e "s/-/_/g" -e "s/=/ := /" >> Makefile-config.mk

grep "^string" "$optfile" \
  | sed -e "s/^[a-z]*[ 	]*//" \
	-e h \
	-e "s/[^=]*=//" \
	-e "s/\\\$/\$\$/g" \
	-e "s/[\\\\#]/\\\\&/g" \
	-e x \
	-e "s/=.*/ := \$(subst x,,x)/" \
	-e "s/^/cfg__/" \
	-e "s/-/_/g" \
	-e G \
	-e "s/\\n//" \
  >> Makefile-config.mk

cat >> Makefile-config.mk << EOF

endif 

EOF

# Report the configuration values to the user:
# 
printf "\\n"
printf "Standard Configuration Settings: \\n"
printf "\\n"
cat  "$optfile" | grep "^[a-z]*[ 	]*std--" | sed -e "s/^[a-z]*[ 	]*std--/    /" -e "s/=/ = /"
printf "\\n"
printf "\\n"
printf "Configuration Options: \\n"
printf "\\n"
cat  "$optfile" | grep -v "^[a-z]*[ 	]*std--" | grep "^binary*[ 	]*" | sed -e "s/binary[ 	]*/    /" -e "s/=/ = /" -e "s/0\$/no/" -e "s/1\$/yes/" 
printf "\\n"
cat  "$optfile" | grep -v "^[a-z]*[ 	]*std--" | grep "^string*[ 	]*" | sed -e "s/string[ 	]*/    /" -e "s/=/ = /"
printf "\\n"
printf "\\n"
printf "Shell Used by Configure Scripts: \\n"
printf "\\n"
printf "    %s\\n" "$config_shell"
printf "\\n"
printf "\\n"



export auto_conf
export srcroot
export objroot
export srcdir
export prefix
export config_shell

"$config_shell" $srcdir/build-tools/scripts/configure-dirs

