#! /bin/sh

if [ "$BASH_VERSION" = "" ]; then
	BASH=
	# search for "bash" in the PATH environment
	XIFS="$IFS"
	IFS=':'
	for dir in $PATH; do
		if [ -f $dir/bash ] && [ -x $dir/bash ]; then
			BASH=$dir/bash
			break
		fi
	done

	IFS="$XIFS"

	if [ "$BASH" = "" ]; then
		printf 'could not find bash!\n'
		exit 1
	fi

	exec $BASH "$0" "$@"
fi

#
# should be in a bash environment when we get here!
#

#
#	build -- KRoC/Linux configuration/installation script
#	Copyright (C) 2001-2006 Fred Barnes <frmb@kent.ac.uk>
#	Copyright (C) 2007-2008 University of Kent
#
#	This program is free software; you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation; either version 2 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with this program; if not, write to the Free Software
#	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#


#
#	This is a re-write of what was in version 1.2.x
#


# unset any undesirables
unset KROC
unset INSTALL_DIR
unset DIST_DIR
unset MAKEFLAGS

#{{{  installation directories
kroc_configdir=""
kroc_archbindir=""
kroc_archlibdir=""
kroc_archincdir=""
kroc_mandir=""
kroc_krocdir=""
kroc_kroc_examples=""
kroc_kroc_vtlib=""
kroc_kroc_vtinclude=""
kroc_kroc_doc=""
kroc_kroc_cgtests=""


#}}}
#{{{  source packages
CCSP_SRC=runtime/ccsp
MKOCCDEPS_SRC=tools/mkoccdeps
OCC21_SRC=tools/occ21
ILIBR_SRC=tools/ilibr
TRANX86_SRC=tools/tranx86
KROC_SRC=tools/kroc
KROCIF_SRC=runtime/libkrocif
INMOSLIBS_SRC=modules/inmoslibs/libsrc
BSCLIB_SRC=modules/bsclib/libsrc
BSCLIB_EXAMPLES_SRC=modules/bsclib/examples
COURSE_SRC=modules/course/libsrc
COURSE_EXAMPLES_SRC=modules/course/examples
COURSE_ANSWERS_SRC=modules/course/answers
USEFUL_SRC=modules/useful/libsrc
USEFUL_EXAMPLES_SRC=modules/useful/examples
DYNPROC_SRC=modules/dynproc/libsrc
DYNPROC_EXAMPLES_SRC=modules/dynproc/examples
DEMO_BAR_SRC=demos/bar
DEMO_GAME_SRC=demos/game
DEMO_ROBOTS_SRC=demos/robots
DEMO_TTYGAMES_SRC=demos/ttygames
UDC_SRC=modules/udc/libsrc
UDC_EXAMPLES_SRC=modules/udc/examples
RASTER_SRC=modules/raster/libsrc
RASTER_EXAMPLES_SRC=modules/raster/examples
SDLRASTER_SRC=modules/sdlraster/libsrc
SDLRASTER_EXAMPLES_SRC=modules/sdlraster/examples
OCCSDL_SRC=modules/occSDL/libsrc
OCCSDL_EXAMPLES_SRC=modules/occSDL/examples
OCCGL_SRC=modules/occGL/libsrc
OCCGL_EXAMPLES_SRC=modules/occGL/examples
OCCADE_SRC=modules/occade/libsrc
OCCADE_EXAMPLES_SRC=modules/occade/examples
BUTTON_SRC=modules/button/libsrc
BUTTON_EXAMPLES_SRC=modules/button/examples
PONY_SRC=modules/pony/libsrc
PONY_EXAMPLES_SRC=modules/pony/examples
CIF_SRC=modules/cif/libsrc
CIF_EXAMPLES_SRC=modules/cif/examples
CGTESTS_SRC=tests/cgtests
HERETICC_SRC=tests/hereticc
FMTOUTLIB_SRC=modules/fmtoutlib/libsrc
MOA_SRC=modules/moa/libsrc
MOA_EXAMPLES_SRC=modules/moa/examples
MANPAGE_LIST=""
MANPAGE_SECTIONS=""
DOC_SRC=doc
OCCAMDOC_SRC=tools/occamdoc

ALL_PKGS="$CCSP_SRC $MKOCCDEPS_SRC $OCC21_SRC $ILIBR_SRC $TRANX86_SRC $KROC_SRC $KROCIF_SRC $OCCAMDOC_SRC \
	$DOC_SRC \
	$INMOSLIBS_SRC \
	$BSCLIB_SRC $BSCLIB_EXAMPLES_SRC \
	$COURSE_SRC $COURSE_EXAMPLES_SRC $COURSE_ANSWERS_SRC \
	$USEFUL_SRC $USEFUL_EXAMPLES_SRC \
	$DYNPROC_SRC $DYNPROC_EXAMPLES_SRC \
	$UDC_SRC $UDC_EXAMPLES_SRC \
	$CIF_SRC $CIF_EXAMPLES_SRC \
	$CGTESTS_SRC \
	$DEMO_BAR_SRC $DEMO_GAME_SRC $DEMO_ROBOTS_SRC $DEMO_TTYGAMES_SRC \
	$RASTER_SRC $RASTER_EXAMPLES_SRC \
	$SDLRASTER_SRC $SDLRASTER_EXAMPLES_SRC \
	$PONY_SRC $PONY_EXAMPLES_SRC \
	$OCCSDL_SRC $OCCSDL_EXAMPLES_SRC \
	$OCCGL_SRC $OCCGL_EXAMPLES_SRC \
	$OCCADE_SRC $OCCADE_EXAMPLES_SRC \
	$BUTTON_SRC $BUTTON_EXAMPLES_SRC \
	$FMTOUTLIB_SRC \
	$MOA_SRC $MOA_EXAMPLES_SRC"
FAILABLE_PKGS="\
	$UDC_SRC $UDC_EXAMPLES_SRC \
	$DEMO_ROBOTS_SRC \
	$SDLRASTER_SRC $SDLRASTER_EXAMPLES_SRC \
	$MOA_SRC $MOA_EXAMPLES_SRC \
	$OCCSDL_SRC $OCCSDL_EXAMPLES_SRC \
	$OCCGL_SRC $OCCGL_EXAMPLES_SRC \
	$OCCADE_SRC $OCCADE_EXAMPLES_SRC \
	$BUTTON_SRC $BUTTON_EXAMPLES_SRC \
	$RASTER_SRC $RASTER_EXAMPLES_SRC \
	$CIF_EXAMPLES_SRC"


#}}}
#{{{  release/install settings
DUMPOUT=
DUMPMAIL="kroc-bugs@kent.ac.uk"
VERSION="1.5.0-pre4"
PRERELEASE=1
NEXTPATCH="1.5.0-pre5"
PATCHINFOFILE="update-info-$NEXTPATCH"
PATCHINFOURL="http://www.cs.kent.ac.uk/projects/ofa/kroc/updates/$PATCHINFOFILE"
# things set in typescript_head are: SED, AWK, MAKE, WGET

#}}}
#{{{  various local variables
# 42 means unset or auto-detect
BUILDRECONF=0
ACTIONLIST=
FORCECONFIGURE=
FORCESINGLEBUILD=0
USEPRIORITY=42
USECPUTIMERS=42
USEPTHREADS=42
USECTTD=42
USEPONY=42
USEUDC=42
USEPGROUPS=42
USEMP=42
USER_INSTALL=0
ALL_SETTINGS=0
EXTRA_CCSP_CONFIGURE_OPTS=""
EXTRA_KROC_CONFIGURE_OPTS=""
NOCC_INSTALL=""
BUILD_NUMCPUS=1
MAKE_COMPILEOPTS=""

KROCHOST_ARCH=
KROCHOST_VENDOR=
KROCHOST_OS=
DEFERRED_INSTALL_ERROR=

FAILED_PRECONFIGURES=
FAILED_CONFIGURES=
FAILED_MAKES=
FAILED_INSTALLS=

#}}}

#
#	functions
#

#{{{  usage ()
usage ()
{
	cat 1>&2 << EOF
Usage: $0 [options] [action] [action] ...
where options are:
  --install-dir=<path>         target installation path [PREFIX]
  --prefix=<path>              equivalent to --install-dir
  --configdir=<path>           install path for configuration file [/etc or home-dir]
  --bindir=<path>              install path for binaries [PREFIX/bin]
  --libdir=<path>              install path for libraries [PREFIX/lib]
  --incdir=<path>              install path for includes [PREFIX/include/kroc]
  --mandir=<path>              install path for manual pages [PREFIX/share/man]
  --krocdir=<path>             install path for kroc-specific files [PREFIX/share/kroc]
  --extra-ccsp-opts=<opts>     extra CCSP configuration options []
  --extra-kroc-opts=<opts>     extra kroc configuration options []
  --nocc-install=<path>        path to NOCC install []
  --reconf                     edit configuration
  -A | --all-settings          show all settings in configuration menu

  --dry-run                    just print what is going to be done, without doing it
  --force-configure            re-configure packages, even they look configured
  --force-single-build         do not attempt to use make speedup on a multiprocessor

  --no-priority                disable process priority
  --no-cputimers               disable CPU timer support (required for accurate timing on variable-frequency hardware)
  --no-pthreads                build without pthreads support
  --no-udc                     build without user defined channels support
  --with-cttd                  build with channel-type type-description support
  --with-mp                    build with multi-processing support
  --with-pony                  build with support for KRoC.net/pony

  -h | --help                  this help text
  -V | --version               print version and exit

and actions are:
  build                        build everything (default if not specified)
  update                       attempt to download source-code update
  preconfigure-<pkg>           pre-configure <pkg> (only needed for ccsp)
  configure-<pkg>              configure <pkg> (see below for list of packages)
  fconfigure-<pkg>             force configure of <pkg>
  make-<pkg>                   make <pkg>
  install-<pkg>                install <pkg>
  clean-<pkg>                  clean <pkg>
  distclean-<pkg>              clean <pkg> (for a distribution)
  clean                        clean all packages
  distclean                    clean all packages (for a distribution)
  examples                     configure and compile example programs
  tests                        build and run test-suite programs
  all                          builds everything: build examples cgtests

choices for <pkg> are:
  ccsp                         CCSP (run-time occam/transputer kernel)
  ccspt                        CCSP with debugging trace support
  mkoccdeps                    occam dependency generator
  occ21                        inmos occam compiler
  ilibr                        inmos librarian
  tranx86                      ETC to i386 translator
  kroc                         kroc script, kmakef and setup files
  krocif                       kroc interface library
  inmoslibs                    inmos libraries
  bsclib                       blocking system call libraries
  course                       UKC course library
  useful                       general utility module
  dynproc                      dynamic occam processes
  udc                          user-defined channels
  manpages                     man-page based documentation
  cgtests                      compiler test suite
  hereticc                     runtime benchmark suite
  cif                          occam-pi/C interface
  raster                       raster graphics support
  sdlraster                    SDLRaster SDL based raster graphics
  occsdl                       SDL bindings module
  occgl                        OpenGL bindings module
  occade                       arcade game development module
  button                       OpenGL buttons module
  pony                         pony (kroc-net) networking infrastructure
  fmtoutlib                    formatted output module
  moa                          MySQL bindings module
  doc                          documentation
  occamdoc                     occam documentation tool
  examples                     all example programs, which are:
    bsclib_examples            blocking system calls example programs
    course_examples            UKC course example programs
    course_answers             UKC course sample answers
    useful_examples            useful example programs
    dynproc_examples           dynamic occam process examples
    udc_examples               user-defined channels examples
    bar_demo                   animated ALT demonstrator
    game_demo                  text-based adventure game
    robots_demo                robots and particle demonstrators
    ttygames_demo              text-based games
    cif_examples               C interface examples
    raster_examples            raster example programs
    sdlraster_examples         SDLRaster example programs
    occsdl_examples            occSDL example programs
    occgl_examples             occGL example programs
    occade_examples            Occade example programs
    button_examples            button example programs
    pony_examples              pony example programs
    moa_examples               moa example programs
EOF
}
#}}}
#{{{  deferred_install_error ()
deferred_install_error ()
{
	DEFERRED_INSTALL_ERROR=1
}
#}}}
#{{{  install_error ()
install_error ()
{
	$TEE -a "$DUMPOUT" << EOF

***********************************************************
*                     INSTALLATION ERROR                  *
***********************************************************

The KRoC installation failed.  Ensure that you have the
relevant development packages for your system installed.
For more information see the KRoC web-page at:

    http://www.cs.kent.ac.uk/projects/ofa/kroc/

If the above link doesn't help, please mail:

    kroc-bugs@kent.ac.uk

with the "typescript" file and a description of your
system (e.g. architecture, distribution, etc.)


EOF
}
#}}}
#{{{  software_missing (name)
software_missing ()
{
	if [ "$1" = "" ]; then
		printf 'software_missing() called incorrectly\n' | tee -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi
	if [ "$1" = "tee" ]; then
		printf '%s: faulty tee, might have problems later on..\n' "$0" | tee -a "$DUMPOUT" 1>&2
	else
		printf '%s: unable to run %s --version.\n' "$0" "$prog" | tee -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi
}
#}}}
#{{{  guess_software ()
guess_software ()
{
	# sort out SED, AWK and WGET variables (take from the environment first if they exist)
	SED=${SED:-}
	AWK=${AWK:-}
	MAKE=${MAKE:-}
	WGET=${WGET:-}
	TEE=${TEE:-}
	CUT=${CUT:-}

	XIFS="$IFS"
	IFS=':'

	PREFIXES="gnu:g:none"

	for pfix in $PREFIXES; do
		if [ "$pfix" = "none" ]; then
			pfix=""
		fi
		for pth in $PATH; do
			this_pth="$pth/$pfix"
			if [ -x "$this_pth""sed" ] && [ "$SED" = "" ]; then
				SED="$this_pth""sed"
			fi
			if [ -x "$this_pth""awk" ] && [ "$AWK" = "" ]; then
				AWK="$this_pth""awk"
			fi
			if [ -x "$this_pth""wget" ] && [ "$WGET" = "" ]; then
				WGET="$this_pth""wget"
			fi
			if [ -x "$this_pth""make" ] && [ "$MAKE" = "" ]; then
				MAKE="$this_pth""make"
			fi
			if [ -x "$this_pth""tee" ] && [ "$TEE" = "" ]; then
				TEE="$this_pth""tee"
			fi
			if [ -x "$this_pth""cut" ] && [ "$CUT" = "" ]; then
				CUT="$this_pth""cut"
			fi
		done
	done

	IFS="$XIFS"
}
#}}}
#{{{  typescript_head ()
typescript_head ()
{
	if [ -f $DUMPOUT ]; then
		mv $DUMPOUT $DUMPOUT.old
	fi
	printf 'Install of KRoC/Linux source distribution @ %s\n' "$(date)" > $DUMPOUT
	printf 'Version %s\n' "$VERSION" >> $DUMPOUT
	printf 'Distribution path: %s\n' "$DIST_DIR" >> $DUMPOUT
	printf 'Installation path: %s\n' "$INSTALL_DIR" >> $DUMPOUT
	printf '    kroc config install:    %s\n' "$kroc_configdir" >> $DUMPOUT
	printf '    arch-binaries install:  %s\n' "$kroc_archbindir" >> $DUMPOUT
	printf '    arch-libraries install: %s\n' "$kroc_archlibdir" >> $DUMPOUT
	printf '    arch-includes install:  %s\n' "$kroc_archincdir" >> $DUMPOUT
	printf '    manpages install:       %s\n' "$kroc_mandir" >> $DUMPOUT
	printf '    kroc-specific install:  %s\n' "$kroc_krocdir" >> $DUMPOUT
	printf '        examples install:      %s\n' "$kroc_kroc_examples" >> $DUMPOUT
	printf '        VT libraries install:  %s\n' "$kroc_kroc_vtlib" >> $DUMPOUT
	printf '        VT includes install:   %s\n' "$kroc_kroc_vtinclude" >> $DUMPOUT
	printf '        documentation install: %s\n' "$kroc_kroc_doc" >> $DUMPOUT
	printf '        cgtests install:       %s\n' "$kroc_kroc_cgtests" >> $DUMPOUT
	printf 'Various software versions:\n' >> "$DUMPOUT"
	XX_PROGRAMS="${CC:-gcc}"
	case `uname` in
		*BSD* | *Darwin*)
			# Non-GNU tee -- which will break horribly if we give
			# it --version.
			;;
		*)
			XX_PROGRAMS="$XX_PROGRAMS ${TEE:-tee}"
			;;
	esac
	case `uname` in
		*SunOS*)
			# Non-GNU as.
			;;
		*)
			XX_PROGRAMS="$XX_PROGRAMS ${AS:-as}"
			;;
	esac
	for prog in $XX_PROGRAMS; do
		printf '        %s\n' "$prog" >> "$DUMPOUT"
		echo | "$prog" --version >> "$DUMPOUT" 2>&1 || echo | "$prog" -v >> "$DUMPOUT" 2>&1 || software_missing "$prog"
	done
	printf '\n' >> "$DUMPOUT"

	# sed, awk and friends have already been guessed earlier  (just check + report here)
	if [ "$SED" = "" ] || [ ! -x "$SED" ]; then
		printf '%s: missing \"sed\"\n' "$0"
		install_error
		exit 1
	elif [ "$AWK" = "" ] || [ ! -x "$AWK" ]; then
		printf '%s: missing \"awk\"\n' "$0"
		install_error
		exit 1
	elif [ "$MAKE" = "" ] || [ ! -x "$MAKE" ]; then
		printf '%s: missing \"make\"\n' "$0"
		install_error
		exit 1
	fi

	printf 'operating system is: %s\n' "$(uname -a)" >> "$DUMPOUT"
	printf 'tee is: %s\n' "$TEE" >> "$DUMPOUT"
	printf 'cut is: %s\n' "$CUT" >> "$DUMPOUT"
	printf 'sed is: %s\n' "$SED" >> "$DUMPOUT"
	printf 'awk is: %s\n' "$AWK" >> "$DUMPOUT"
	printf 'make is: %s\n' "$MAKE" >> "$DUMPOUT"
	if [ "$WGET" != "" ]; then
		printf 'wget is: %s\n' "$WGET" >> "$DUMPOUT"
	fi
}
#}}}
#{{{ check_autoconf (dist-dir, package-src-dir)
# Ensure that the autoconf scripts in a package have been built.
check_autoconf ()
{
	CURRENT_DIR="$(pwd)"
	cd "$1/$2"
	# configure files not present or out of date ?
	if [ -f configure.in ]; then
		CONFIG_IN="configure.in"
	elif [ -f configure.ac ]; then
		CONFIG_IN="configure.ac"
	else
		CONFIG_IN=""
	fi
	if [ "$CONFIG_IN" != "" ]; then
		if [ ! -f Makefile.in ] || [ ! -f configure ] || [ Makefile.in -ot Makefile.am ] || [ configure -ot $CONFIG_IN ]; then
			#{{{  add our aclocal dir to the path, if it exists
			old_aclocal="$ACLOCAL"
			aclocal_dir="$INSTALL_DIR/share/aclocal"
			if [ -d "$aclocal_dir" ] ; then
				ACLOCAL="${ACLOCAL:-aclocal} -I $aclocal_dir"
			fi
			export ACLOCAL
			#}}}

			printf '%s: package in %s needs automake files updating\n' "$0" "$2" | $TEE -a "$DUMPOUT"
			(autoreconf -f -i 2>&1 && touch .success) | $TEE -a "$DUMPOUT"

			#{{{  check for unexpanded macros in configure
			if grep '^OCCAM_OCCBUILD' configure >/dev/null 2>/dev/null; then
				printf 'error: autoreconf in %s was unable to find occbuild.m4\nYou must install the "tools/kroc" subdirectory before building occam code.\n' "$2" | $TEE -a "$DUMPOUT" 1>&2
				rm -f .success configure Makefile.in
			fi
			#}}}

			if [ -f .success ]; then
				rm .success
			else
				printf 'error while autoreconfing in %s\n' "$2" | $TEE -a "$DUMPOUT" 1>&2
				deferred_install_error
				cd "$CURRENT_DIR"
				return 1
			fi

			#{{{  restore original ACLOCAL
			ACLOCAL="$old_aclocal"
			#}}}
		fi
	fi
	cd "$CURRENT_DIR"
}
#}}}
#{{{ preconfigure_pkg (prefix-dir, dist-dir, package-src-dir [, preconf-opt])
preconfigure_pkg ()
{
	if [ "$1" = "" ] || [ "$2" = "" ] || [ "$3" = "" ]; then
		printf 'preconfigure_pkg() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	if [ -r "$2/$3/.builddata" ]; then
		# means this is a directory of sub-packages which get preconfigured together
		source "$2/$3/.builddata"
		for subpkg in $SUBPKGS; do
			# do appropriate test for preconfiguring this sub-package
			if [ -x "$2/$3/$subpkg/preconfigure" ]; then
				preconfigure_pkg "$1" "$2" "$3/$subpkg" "$4"
			fi
		done
	elif [ -f "$2/$3/preconfigure" ]; then
		check_autoconf "$2" "$3"
		CURRENT_DIR="$(pwd)"
		cd "$2/$3"
		if [ "$4" = "" ]; then
			(./preconfigure 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		else
			(./preconfigure $4 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		fi
		if [ -f .success ]; then
			rm .success
		else
			printf 'error while pre-configuring %s\n' $3 | $TEE -a "$DUMPOUT" 1>&2
			deferred_install_error
			return 1
		fi
		cd "$CURRENT_DIR"
	fi
	return 0
}
#}}}
#{{{  configure_pkg (prefix-dir, dist-dir, package-src-dir [, additional configure options])
configure_pkg ()
{
	if [ "$1" = "" ] || [ "$2" = "" ] || [ "$3" = "" ]; then
		printf 'configure_pkg() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	if [ -r "$2/$3/.builddata" ]; then
		# means this is a directory of sub-packages which get configured together
		source "$2/$3/.builddata"
		for subpkg in $SUBPKGS; do
			# do appropriate test for configuring this sub-package
			if [ -f "$2/$3/$subpkg/configure.in" ] || [ -f "$2/$3/$subpkg/configure.ac" ]; then
				configure_pkg "$1" "$2" "$3/$subpkg" "$4"
			fi
		done
	else
		check_autoconf "$2" "$3"
		CURRENT_DIR="$(pwd)"
		cd "$2/$3"
		# already configured ?
		if [ -f Makefile.in ] && [ -f Makefile ] && [ "$FORCECONFIGURE" = "" ]; then
			printf '%s: package in %s looks configured, not re-configuring\n' "$0" $3 | $TEE -a "$DUMPOUT"
		else
			if [ "$4" = "" ]; then
				(./configure --prefix="$1" --bindir="$kroc_archbindir" --datadir="$kroc_krocdir" --mandir="$kroc_mandir" --libdir="$kroc_archlibdir" \
					--includedir="$kroc_archincdir" --sysconfdir="$kroc_configdir" 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
			else
				(./configure --prefix="$1" --bindir="$kroc_archbindir" --datadir="$kroc_krocdir" --mandir="$kroc_mandir" --libdir="$kroc_archlibdir" \
					--includedir="$kroc_archincdir" --sysconfdir="$kroc_configdir" $4 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
			fi
			if [ -f .success ]; then
				rm .success
			else
				printf 'error while configuring in %s\n' "$3" | $TEE -a "$DUMPOUT" 1>&2
				deferred_install_error
				cd "$CURRENT_DIR"
				return 1
			fi
		fi
		cd "$CURRENT_DIR"
	fi
	return 0
}
#}}}
#{{{  make_pkg (dist-dir, package-src-dir [, additional make options])
make_pkg ()
{
	if [ "$1" = "" ] || [ "$2" = "" ]; then
		printf 'make_pkg() called incorrectly\n' 1>&2
		install_error
		exit 1
	fi

	if [ -r "$1/$2/.builddata" ]; then
		# means this is a directory of sub-packages which get made together
		source "$1/$2/.builddata"
		for subpkg in $SUBPKGS; do
			# do appropriate test for making this sub-package
			if [ -r "$1/$2/$subpkg/Makefile" ] || [ -r "$1/$2/$subpkg/GNUmakefile" ]; then
				make_pkg "$1" "$2/$subpkg" "$3"
			fi
		done
	else
		CURRENT_DIR="$(pwd)"
		cd "$1/$2"
		if [ "$3" = "" ]; then
			($MAKE $MAKE_COMPILEOPTS 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		else
			($MAKE $MAKE_COMPILEOPTS $3 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		fi
		if [ -f .success ]; then
			rm .success
		else
			printf 'error while making in %s\n' "$2" | $TEE -a "$DUMPOUT" 1>&2
			deferred_install_error
			cd "$CURRENT_DIR"
			return 1
		fi
		cd "$CURRENT_DIR"
	fi
	return 0
}
#}}}
#{{{  install_pkg (dist-dir, ackage-src-dir [, additional make-install options])
install_pkg ()
{
	if [ "$1" = "" ] || [ "$2" = "" ]; then
		printf 'install_pkg() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	if [ -r "$1/$2/.builddata" ]; then
		# means this is a directory of sub-packages which get installed together
		source "$1/$2/.builddata"
		for subpkg in $SUBPKGS; do
			install_pkg "$1" "$2/$subpkg" "$3"
		done
	else
		CURRENT_DIR="$(pwd)"
		cd "$1/$2"
		if [ "$3" = "" ]; then
			($MAKE install 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		else
			($MAKE install $3 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		fi
		if [ -f .success ]; then
			rm .success
		else
			printf 'error while installing in %s\n' "$2" | $TEE -a "$DUMPOUT" 1>&2
			deferred_install_error
			cd "$CURRENT_DIR"
			return 1
		fi
		cd "$CURRENT_DIR"
	fi

	return 0
}
#}}}
#{{{  clean_pkg (dist-dir, package-src-dir [,additional make options])
clean_pkg ()
{
	if [ "$1" = "" ] || [ "$2" = "" ]; then
		printf 'clean_pkg() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	if [ -r "$1/$2/.builddata" ]; then
		# means this is a directory of sub-packages which get cleaned together
		source "$1/$2/.builddata"
		for subpkg in $CLEANSUBPKGS; do
			clean_pkg "$1" "$2/$subpkg" "$3"
		done
	else
		CURRENT_DIR="$(pwd)"
		cd "$1/$2"
		if [ "$3" = "" ]; then
			($MAKE clean 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		else
			($MAKE clean $3 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		fi
		if [ -f .success ]; then
			rm .success
		else
			printf 'error while cleaning in %s (continuing anyway)\n' "$2" | $TEE -a "$DUMPOUT" 1>&2
		fi
		cd "$CURRENT_DIR"
	fi
	return 0
}
#}}}
#{{{  distclean_pkg (dist-dir, package-src-dir [, additional make options])
distclean_pkg ()
{
	if [ "$1" = "" ] || [ "$2" = "" ]; then
		printf 'distclean_pkg() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	if [ -r "$1/$2/.builddata" ]; then
		# means this is a directory of sub-packages which get distcleaned together
		source "$1/$2/.builddata"
		for subpkg in $CLEANSUBPKGS; do
			distclean_pkg "$1" "$2/$subpkg" "$3"
		done
	else
		CURRENT_DIR="$(pwd)"
		cd "$1/$2"
		if [ "$3" = "" ]; then
			($MAKE distclean 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		else
			($MAKE distclean $3 2>&1 && touch .success) | $TEE -a "$DUMPOUT"
		fi
		if [ -f .success ]; then
			rm .success
		else
			printf 'error while dist-cleaning %s (continuing anyway)\n' "$2" | $TEE -a "$DUMPOUT" 1>&2
		fi
		cd $CURRENT_DIR
	fi
	return 0
}
#}}}
#{{{  prepare_patch (info-file)
prepare_patch ()
{
	if [ "$1" = "" ]; then
		printf 'prepare_patch() called incorrectly\n' 1>&2
		install_error
		exit 1
	fi
	if [ ! -f $1 ]; then
		printf 'prepare_patch(): no such file %s\n' "$1" 1>&2
		install_error
		exit 1
	fi
	FIRSTLINE=$(cat $1 | head -1)
	SECONDLINE=$(cat $1 | head -2 | tail -1)
	# this is a noddy check, but will prevent things going bad if the download messes up
	EXPSNDLINE=$(printf '# KRoC/Linux update (%s %s)' "$VERSION" "$NEXTPATCH")

	if [ "$FIRSTLINE" != "#! /bin/sh" ] && [ "$FIRSTLINE" != "#! /bin/bash" ]; then
		printf '%s: bad patch file %s, removing it.  Assuming latest code version (%s)\n' "$0" "$1" "$VERSION" | $TEE -a "$DUMPOUT"
		rm -f "$1"
		exit 1
	elif [ "$SECONDLINE" != "$EXPSNDLINE" ]; then
		printf '%s: bad patch file %s, removing it.  Assuming latest code version (%s)\n' "$0" "$1" "$VERSION" | $TEE -a "$DUMPOUT"
		rm -f "$1"
		exit 1
	fi
	CURRENT_DIR="$(pwd)"
	cd /tmp
	# shitty way to get the patch script, but it'll work
	printf '%s: preparing patch from %s to %s\n' "$0" "$VERSION" "$NEXTPATCH" | $TEE -a "$DUMPOUT"
	if [ ! -x $1 ]; then
		chmod +x $1
	fi
	printf '%s: extracted patch script to %s, will apply in %s\n' "$0" "$1" "$DIST_DIR" | $TEE -a "$DUMPOUT"
	rm -f $DIST_DIR/.success
	($1 $DIST_DIR 2>&1 && touch $DIST_DIR/.success) | $TEE -a "$DUMPOUT"
	if [ -f $DIST_DIR/.success ]; then
		rm -f $DIST_DIR/.success
		printf '%s: patch script ran successfully.  Use \"%s\" to compile+install changes.\n' "$0" "$0" | $TEE -a "$DUMPOUT"
	else
		printf '%s: patch script failed to run successfully.\n' "$0" | $TEE -a "$DUMPOUT"
	fi
	cd $CURRENT_DIR
}
#}}}
#{{{  setopts_host (host-arch, host-vendor, host-os)
setopts_host ()
{
	if [ "$1" = "" ] || [ "$2" = "" ] || [ "$3" = "" ]; then
		printf 'setopts_host() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	# setup any arch/vendor/os specific options

	case "$3" in
	cygwin)
		if [ $USEPTHREADS -eq 42 ]; then
			printf '  cygwin: enabling pthreads\n'
			USEPTHREADS=1
		fi
		if [ $USEMP -eq 42 ]; then	
			printf '  cygwin: disabling MP support\n'
			USEMP=0
		fi
		if [ $USEUDC -eq 42 ]; then	
			printf '  cygwin: enabling user-defined channel support\n'
			USEUDC=1
		fi
		;;
	darwin* | Darwin*)
		if [ $USEPTHREADS -eq 42 ]; then
			printf '  darwin: enabling pthreads\n'
			USEPTHREADS=1
		fi
		if [ $USEMP -eq 42 ]; then
			printf '  darwin: enabling multi-processor support\n'
			USEMP=1

			# cannot support UDC with MP currently
			if [ $USEUDC -eq 42 ]; then
				printf '  darwin: disabling user-defined channel support\n'
				USEUDC=0
			fi
		fi
		if [ $USEUDC -eq 42 ]; then	
			printf '  darwin: enabling user-defined channel support\n'
			USEUDC=1
		fi
		# tweak some paths to make things go smoothly
		CPATH="/usr/X11R6/include:/sw/include:$CPATH"; export CPATH
		LIBRARY_PATH="/usr/X11R6/lib:/sw/lib:$LIBRARY_PATH"; export LIBRARY_PATH
		PKG_CONFIG_PATH="/sw/lib:$PKG_CONFIG_PATH"; export PKG_CONFIG_PATH
		;;
	solaris*)
		if [ $USEPTHREADS -eq 42 ]; then
			printf '  solaris: enabling pthreads\n'
			USEPTHREADS=1
		fi
		if [ $USEMP -eq 42 ]; then	
			printf '  solaris: disabling multi-processor support\n'
			USEMP=1
		fi
		if [ $USEUDC -eq 42 ]; then	
			printf '  solaris: enabling user-defined channel support\n'
			USEUDC=1
		fi
		;;
	*bsd* | *BSD*)
		if [ $USEPTHREADS -eq 42 ]; then
			printf '  *BSD: enabling pthreads\n'
			USEPTHREADS=2
		fi
		if [ $USEMP -eq 42 ]; then	
			NUMCPUS=$(/sbin/sysctl -n hw.ncpu)
			if [ $NUMCPUS -ge 2 ]; then
				printf '  *BSD: %d logical processors, enabling multi-processor support\n' "$NUMCPUS"
				USEMP=1

				# also, instruct to build with this many
				BUILD_NUMCPUS=$NUMCPUS

				# cannot support UDC with MP currently
				if [ $USEUDC -eq 42 ]; then
					printf '  *BSD: disabling user-defined channel support\n'
					USEUDC=0
				fi
			else
				printf '  *BSD: single CPU system, not enabling multi-processor support\n'
				USEMP=0
			fi
		fi
		if [ $USEUDC -eq 42 ]; then	
			printf '  *BSD: enabling user-defined channel support\n'
			USEUDC=1
		fi
		;;
	linux* | Linux*)
		if [ $USEPTHREADS -eq 42 ]; then
			printf '  linux: enabling pthreads\n'
			USEPTHREADS=1
		fi
		if [ $USEMP -eq 42 ]; then
			# auto-detect, means we check for multiple processors
			if [ ! -f /proc/cpuinfo ]; then
				printf '  linux: no /proc/cpuinfo, not enabling multi-processor support\n'
				USEMP=0
			else
				NUMCPUS=$($AWK 'BEGIN { i=0; } /^processor[ :\t]/ {i++} END {print(i);}' < /proc/cpuinfo)
				if [ $NUMCPUS -ge 2 ]; then
					printf '  linux: %d logical processors, enabling multi-processor support\n' "$NUMCPUS"
					USEMP=1

					# also, instruct to build with this many
					BUILD_NUMCPUS=$NUMCPUS

					# cannot support UDC with MP currently
					if [ $USEUDC -eq 42 ]; then
						printf '  linux: disabling user-defined channel support\n'
						USEUDC=0
					fi
				else
					printf '  linux: single CPU system, not enabling multi-processor support\n'
					USEMP=0
				fi
			fi
		fi
		if [ $USEUDC -eq 42 ]; then
			printf '  linux: enabling user-defined channel support\n'
			USEUDC=1
		fi
		;;
	esac
}
#}}}
#{{{  setopts_build
setopts_build ()
{
	if [ $BUILD_NUMCPUS -le 1 ]; then
		# only 1 CPU anyway
		return 1
	fi
	if [ $FORCESINGLEBUILD -eq 1 ]; then
		# told not to probe this
		return 1
	fi

	# now, check that we have a make which understands how we want to do this! (ask for version)
	rm -f .success
	($MAKE -j$BUILD_NUMCPUS --version 2>&1 && touch .success) > /dev/null
	if [ -f .success ]; then
		rm .success
		printf 'build: using make option -j%d\n' "$BUILD_NUMCPUS" | $TEE -a "$DUMPOUT"
		MAKE_COMPILEOPTS="-j$BUILD_NUMCPUS"
	fi
	return 0
}
#}}}
#{{{  package_status (dist-dir, package-src-dir)
package_status ()
{
	if [ "$1" = "" ] || [ "$2" = "" ]; then
		printf 'package_status() called incorrectly\n' | $TEE -a "$DUMPOUT" 1>&2
		install_error
		exit 1
	fi

	if [ -r "$1/$2/.builddata" ]; then
		# means this is a directory of sub-packages which get their status reported together
		source "$1/$2/.builddata"
		for subpkg in $SUBPKGS; do
			package_status "$1" "$2/$subpkg"
		done
	else
		printf 'package: %-30s' "$2"
		if [ -f $1/$2/configure.in ] || [ -f $1/$2/configure.ac ]; then
			if [ -f $1/$2/config.status ]; then
				printf 'AC* '
			else
				printf 'AC- '
			fi
		else
			printf '    '
		fi
		if [ -f $1/$2/Makefile.am ]; then
			if [ -f $1/$2/Makefile ]; then
				printf 'AM* '
			else
				printf 'AM  '
			fi
		elif [ -f $1/$2/Makefile.in ]; then
			if [ -f $1/$2/Makefile ]; then
				printf 'MK* '
			else
				printf 'MK- '
			fi
		elif [ -f $1/$2/Makefile ]; then
			printf 'MK  '
		else
			printf '    '
		fi
		if [ -f $1/$2/config.guess ] && [ -f $1/$2/config.sub ]; then
			printf '[autofiles] '
		else
			printf '            '
		fi
		TEMPCPKG=$(find $1/$2 -name '*.[ch]' | head -1)
		if [ "$TEMPCPKG" != "" ]; then
			printf 'C '
		else
			printf '  '
		fi
		TEMPOPKG=$(find $1/$2 -name '*.occ' | head -1)
		if [ "$TEMPOPKG" != "" ]; then
			printf 'occam '
		else
			printf '      '
		fi
		printf '\n'
	fi
}
#}}}


#
#	*****************************
#	** REAL SCRIPT STARTS HERE **
#	*****************************
#

if [ -f .install_dir ]; then
	# in transition, may have an old .install_dir
	FAILEDSRC=0
	source .install_dir || FAILEDSRC=1

	if [ $FAILEDSRC -eq 1 ]; then
		INSTALL_DIR=$(cat .install_dir)
		# force the questions to be asked again
		printf '\n*** NOTE ***: found possible old .install_dir, check install paths carefully\n'
		BUILDRECONF=1
	fi
else
	INSTALL_DIR=
fi
DRYRUN=
SKIPMENU=0

#{{{  set distribution directory
if [ "$DIST_DIR" = "" ]; then
	DIST_DIR="$(pwd)"
fi
#}}}

# do this first!
guess_software

#{{{  process command-line arguments
SPECIAL_ACTION=none
while [ $# -ge 1 ]
do
	case X$1 in
	X--help | X-h)
		usage
		exit 0
		;;
	X--version | X-V)
		printf '%s: KRoC/Linux source release version %s\n' "$0" "$VERSION"
		exit 0
		;;
	X--reconf)
		BUILDRECONF=1
		;;
	X--copyright)
		printf '%s: KRoC/Linux Version %s Copyright (C) 1995-2007 KRoC Authors.\n' "$0" "$VERSION"
		if [ -f AUTHORS ]; then
			cat ./AUTHORS
		fi
		exit 0
		;;
	X-A | X--all-settings)
		ALL_SETTINGS=1
		;;
	X--install-dir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --install-dir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		INSTALL_DIR="$1"
		SKIPMENU=1
		;;
	X--install-dir=*)
		INSTALL_DIR=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		SKIPMENU=1
		;;
	X--prefix)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --prefix requires an argument\n' "$0" 1>&2
			exit 1
		fi
		INSTALL_DIR="$1"
		SKIPMENU=1
		;;
	X--prefix=*)
		INSTALL_DIR=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		SKIPMENU=1
		;;
	X--configdir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --configdir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		kroc_configdir="$1"
		;;
	X--configdir=*)
		kroc_configdir=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--bindir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --bindir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		kroc_archbindir="$1"
		;;
	X--bindir=*)
		kroc_archbindir=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--libdir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --libdir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		kroc_archlibdir="$1"
		;;
	X--libdir=*)
		kroc_archlibdir=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--incdir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --incdir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		kroc_archincdir="$1"
		;;
	X--incdir=*)
		kroc_archincdir=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--mandir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --mandir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		kroc_mandir="$1"
		;;
	X--mandir=*)
		kroc_mandir=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--krocdir)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --krocdir requires an argument\n' "$0" 1>&2
			exit 1
		fi
		kroc_krocdir="$1"
		;;
	X--krocdir=*)
		kroc_krocdir=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--extra-ccsp-opts=*)
		EXTRA_CCSP_CONFIGURE_OPTS=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--extra-ccsp-opts)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --extra-ccsp-opts requires an argument\n' "$0" 1>&2
			exit 1
		fi
		EXTRA_CCSP_CONFIGURE_OPTS="$1"
		;;
	X--extra-kroc-opts=*)
		EXTRA_KROC_CONFIGURE_OPTS=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--extra-kroc-opts)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --extra-kroc-opts requires an argument\n' "$0" 1>&2
			exit 1
		fi
		EXTRA_KROC_CONFIGURE_OPTS="$1"
		;;
	X--nocc-install=*)
		NOCC_INSTALL=$(printf '%s\n' "$1" | $SED -e 's/^[^=]*=//')
		;;
	X--nocc-install)
		shift
		if [ "$1" = "" ]; then
			printf '%s: --nocc-install requires an argument\n' "$0" 1>&2
			exit 1
		fi
		NOCC_INSTALL="$1"
		;;
	X--force-configure)
		FORCECONFIGURE=1
		;;
	X--force-single-build)
		FORCESINGLEBUILD=1
		;;
	X--with-priority)
		USEPRIORITY=1
		;;
	X--no-priority)
		USEPRIORITY=0
		;;
	X--with-mp)
		USEMP=1
		;;
	X--no-mp)
		USEMP=0
		;;
	X--with-cputimers)
		USECPUTIMERS=1
		;;
	X--no-cputimers)
		USECPUTIMERS=0
		;;
	X--with-pthreads)
		USEPTHREADS=1
		;;
	X--no-pthreads)
		USEPTHREADS=0
		;;
	X--with-cttd)
		USECTTD=1
		;;
	X--no-cttd)
		USECTTD=0
		;;
	X--with-pony)
		USEPONY=1
		;;
	X--no-pony)
		USEPONY=0
		;;
	X--with-udc)
		USEUDC=1
		;;
	X--no-udc)
		USEUDC=0
		;;
	X--prefix=*)
		INSTALL_DIR=$(printf '%s\n' $1 | $SED -e 's/^[^=]*=//')
		;;
	X--dry-run)
		DRYRUN=1
		;;
	X*)
		# must be an action
		if [ "$ACTIONLIST" = "" ]; then
			ACTIONLIST=$1
		else
			ACTIONLIST="$ACTIONLIST $1"
		fi
		;;
	esac
	shift
done


#}}}
#{{{  if we're doing something unusual, do it instead of the normal build
if [ "$SPECIAL_ACTION" != "none" ]; then
	$SPECIAL_ACTION
	exit 0
fi
#}}}

if [ "$INSTALL_DIR" = "" ]; then
	if [ "$USER" = "root" ] || [ "$UID" = "0" ]; then
		# if running as root, use /usr/local by default
		INSTALL_DIR="/usr/local"
	else
		# use install/ in the source path by default
		INSTALL_DIR="$(pwd)/install"
	fi
fi
#{{{  set the various kroc_... directories (pre-config)
if [ "$kroc_configdir" = "" ]; then
	if [ "$USER" = "root" ] || [ "$UID" = "0" ]; then
		# use /etc/ as the configuration directory
		kroc_configdir="/etc"
	elif [ "$HOME" != "" ] && [ ! -w "$HOME" ]; then
		# home-directory that we can't write to, use installation directory
		kroc_configdir="$INSTALL_DIR"
	elif [ "$HOME" != "" ]; then
		# use the user's home-directory
		kroc_configdir="$HOME"
		USER_INSTALL=1
	else
		# use the installation tree
		kroc_configdir="$INSTALL_DIR"
	fi
fi
if [ "$kroc_configdir" = "$HOME" ] && [ -w "$HOME" ]; then
	USER_INSTALL=1
fi
if [ "$kroc_archbindir" = "" ]; then
	kroc_archbindir="/bin"
fi
if [ "$kroc_archlibdir" = "" ]; then
	kroc_archlibdir="/lib"
fi
if [ "$kroc_archincdir" = "" ]; then
	kroc_archincdir="/include/kroc"
fi
if [ "$kroc_mandir" = "" ]; then
	kroc_mandir="/share/man"
fi
if [ "$kroc_krocdir" = "" ]; then
	kroc_krocdir="/share/kroc"
fi

#}}}
#{{{  make some decisions about default features, _except_ POSIX threads, UDC and MP support
if [ $USEPRIORITY -eq 42 ]; then
	USEPRIORITY=1
fi
if [ $USECTTD -eq 42 ]; then
	USECTTD=0
fi
if [ $USEPONY -eq 42 ]; then
	USEPONY=0
fi
if [ $USEPGROUPS -eq 42 ]; then
	USEPGROUPS=0
fi


#}}}
#{{{  remember certain settings -- may need to know if they changed
preset_INSTALL_DIR="$INSTALL_DIR"
preset_archbindir="$kroc_archbindir"
preset_archlibdir="$kroc_archlibdir"
preset_archincdir="$kroc_archincdir"
preset_mandir="$kroc_mandir"
preset_krocdir="$kroc_krocdir"
preset_configdir="$kroc_configdir"
preset_USEPRIORITY=$USEPRIORITY
preset_USECPUTIMERS=$USECPUTIMERS
preset_USEUDC=$USEUDC
preset_USECTTD=$USECTTD
preset_USEPONY=$USEPONY
preset_USEPTHREADS=$USEPTHREADS
preset_USEMP=$USEMP
preset_USEPGROUPS=$USEPGROUPS
preset_EXTRA_CCSP_CONFIGURE_OPTS="$EXTRA_CCSP_CONFIGURE_OPTS"
preset_EXTRA_KROC_CONFIGURE_OPTS="$EXTRA_KROC_CONFIGURE_OPTS"
preset_NOCC_INSTALL="$NOCC_INSTALL"


#}}}
if [ ! -f .install_dir ] || [ $BUILDRECONF -eq 1 ]; then

	WRITEANDEXIT=0

	if [ $SKIPMENU -eq 0 ] || [ $BUILDRECONF -eq 1 ]; then
		#{{{  no defaults set, show menu -- or reconfiguring
		#{{{  ANSI colour setup
		case "X$TERM" in
		"Xxterm" | "Xvt100" | "Xvt220" | "Xlinux")
			ANSION1=$(printf '\033[1m')
			ANSIOFF1=$(printf '\033[0m')
			ANSION2=$(printf '\033[1;34m')
			ANSIOFF2=$(printf '\033[0m')
			ANSION3=$(printf '\033[1m')
			ANSIOFF3=$(printf '\033[0m')
			;;
		*)
			ANSION1=""
			ANSIOFF1=""
			ANSION2=""
			ANSIOFF2=""
			ANSION3=""
			ANSIOFF3=""
			;;
		esac
		#}}}
		printf '\nKRoC %s installation configuration\n'
		printf -- '---------------------------------------------------------------------------\n\n'
		while [ : ]; do
			#{{{  display menu
			EXTRAMENUSETTINGS=""
			printf '\n'
			printf 'KRoC installation directories:\n\n'
			printf ' %s1%s.  install base: %s%s%s\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$INSTALL_DIR" "$ANSIOFF1"
			printf ' %s2%s.  architecture-specific binaries: %s%s%s  (%s%s)\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$kroc_archbindir" "$ANSIOFF1" "$INSTALL_DIR" "$kroc_archbindir"
			printf ' %s3%s.  architecture-specific libraries: %s%s%s  (%s%s)\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$kroc_archlibdir" "$ANSIOFF1" "$INSTALL_DIR" "$kroc_archlibdir"
			printf ' %s4%s.  architecture-specific includes: %s%s%s  (%s%s)\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$kroc_archincdir" "$ANSIOFF1" "$INSTALL_DIR" "$kroc_archincdir"
			printf ' %s5%s.  manual pages: %s%s%s  (%s%s)\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$kroc_mandir" "$ANSIOFF1" "$INSTALL_DIR" "$kroc_mandir"
			printf ' %s6%s.  kroc specific files: %s%s%s  (%s%s)\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$kroc_krocdir" "$ANSIOFF1" "$INSTALL_DIR" "$kroc_krocdir"
			printf ' %s7%s.  kroc configuration: %s%s%s\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$kroc_configdir" "$ANSIOFF1"
			printf '\n'
			printf 'Features:\n\n'
			printf ' %sA%s.  process priority: ' "$ANSION2" "$ANSIOFF2"; if [ $USEPRIORITY -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			printf ' %sB%s.  CPU timers: ' "$ANSION2" "$ANSIOFF2"; if [ $USECPUTIMERS -eq 42 ]; then printf '%sauto-detect%s' "$ANSION3" "$ANSIOFF3"; 
					elif [ $USECPUTIMERS -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			printf ' %sC%s.  user-defined channels: ' "$ANSION2" "$ANSIOFF2"; if [ $USEUDC -eq 42 ]; then printf '%sauto-detect%s' "$ANSION3" "$ANSIOFF3";
					elif [ $USEUDC -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			printf ' %sD%s.  channel-type descriptors: ' "$ANSION2" "$ANSIOFF2"; if [ $USECTTD -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			printf ' %sE%s.  blocking syscalls use POSIX threads: ' "$ANSION2" "$ANSIOFF2"; if [ $USEPTHREADS -eq 42 ]; then printf '%sauto-detect%s' "$ANSION3" "$ANSIOFF3"
					elif [ $USEPTHREADS -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			if [ $ALL_SETTINGS -eq 1 ]; then
				printf ' %sF%s.  support for PONY: ' "$ANSION2" "$ANSIOFF2"; if [ $USEPONY -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
				printf ' %sG%s.  support for process groups: ' "$ANSION2" "$ANSIOFF2"; if [ $USEPGROUPS -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			fi
			printf ' %sH%s.  support for multi-processor machines: ' "$ANSION2" "$ANSIOFF2"; if [ $USEMP -eq 42 ]; then printf '%sauto-detect%s' "$ANSION3" "$ANSIOFF3"
					elif [ $USEMP -eq 1 ]; then printf '%senabled%s' "$ANSION1" "$ANSIOFF1"; else printf 'disabled'; fi; printf '\n'
			if [ $ALL_SETTINGS -eq 1 ]; then
				printf ' %sI%s.  path to NOCC install: %s%s%s\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$NOCC_INSTALL" "$ANSIOFF1"
				printf ' %sXC%s. extra CCSP configuration options: %s%s%s\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$EXTRA_CCSP_CONFIGURE_OPTS" "$ANSIOFF1"
				printf ' %sXK%s. extra kroc configuration options: %s%s%s\n' "$ANSION2" "$ANSIOFF2" "$ANSION1" "$EXTRA_KROC_CONFIGURE_OPTS" "$ANSIOFF1"
				EXTRAMENUSETTINGS=", F-XK"
			fi

			printf '\n1-7 to change path, A-E%s to toggle/set feature, Ctrl-C to abort,' "$EXTRAMENUSETTINGS"
			printf '\n    ! to write config and exit, return to confirm and install: '
			#}}}
			#{{{  read reply and process
			read REPLY || REPLY="abort"
			if [ "$REPLY" = "abort" ]; then
				printf '\naborting KRoC install.\n'
				exit 1
			elif [ "$REPLY" = "!" ]; then
				WRITEANDEXIT=1
				break		# from while
			elif [ "$REPLY" = "" ]; then
				break		# from while
			elif [ "$REPLY" = "1" ]; then
				printf '\ninstall base: '
				read INSTALL_DIR
				if [ "$INSTALL_DIR" = "" ]; then
					printf 'warning: install base will be the root directory\n'
				fi
			elif [ "$REPLY" = "2" ]; then
				printf '\narchitecture-specific binaries: '
				read kroc_archbindir
			elif [ "$REPLY" = "3" ]; then
				printf '\narchitecture-specific libraries: '
				read kroc_archlibdir
			elif [ "$REPLY" = "4" ]; then
				printf '\narchitecture-specific include files: '
				read kroc_archincdir
			elif [ "$REPLY" = "5" ]; then
				printf '\nmanual pages: '
				read kroc_mandir
			elif [ "$REPLY" = "6" ]; then
				printf '\nkroc-specific files: '
				read kroc_krocdir
			elif [ "$REPLY" = "7" ]; then
				printf '\nkroc configuration: '
				read kroc_configdir
			elif [ "$REPLY" = "A" ] || [ "$REPLY" = "a" ]; then
				USEPRIORITY=$((1 - USEPRIORITY))
			elif [ "$REPLY" = "B" ] || [ "$REPLY" = "b" ]; then
				USECPUTIMERS=$((1 - USECPUTIMERS))
			elif [ "$REPLY" = "C" ] || [ "$REPLY" = "c" ]; then
				if [ $USEUDC -eq 42 ]; then
					USEUDC=1
				elif [ $USEUDC -eq 1 ]; then
					USEUDC=0
				else
					USEUDC=42
				fi
			elif [ "$REPLY" = "D" ] || [ "$REPLY" = "d" ]; then
				USECTTD=$((1 - USECTTD))
			elif [ "$REPLY" = "E" ] || [ "$REPLY" = "e" ]; then
				if [ $USEPTHREADS -eq 42 ]; then
					USEPTHREADS=1
				elif [ $USEPTHREADS -eq 1 ]; then
					USEPTHREADS=0
				else
					USEPTHREADS=42
				fi
			elif [ "$REPLY" = "F" ] || [ "$REPLY" = "f" ] && [ $ALL_SETTINGS -eq 1 ]; then
				USEPONY=$((1 - USEPONY))
			elif [ "$REPLY" = "G" ] || [ "$REPLY" = "g" ] && [ $ALL_SETTINGS -eq 1 ]; then
				USEPGROUPS=$((1 - USEPGROUPS))
			elif [ "$REPLY" = "H" ] || [ "$REPLY" = "h" ]; then
				if [ $USEMP -eq 42 ]; then
					USEMP=1
				elif [ $USEMP -eq 1 ]; then
					USEMP=0
				else
					USEMP=42
				fi
			elif [ "$REPLY" = "I" ] || [ "$REPLY" = "i" ] && [ $ALL_SETTINGS -eq 1 ]; then
				printf '\nlocation of NOCC install (-- to clear): '
				read tmp_NOCC_INSTALL
				if [ "$tmp_NOCC_INSTALL" = "--" ]; then
					NOCC_INSTALL=""
				elif [ "$tmp_NOCC_INSTALL" ]; then
					NOCC_INSTALL="$tmp_NOCC_INSTALL"
				fi
			elif [ "$REPLY" = "XC" ] || [ "$REPLY" = "xc" ] && [ $ALL_SETTINGS -eq 1 ]; then
				printf '\nextra CCSP options (-- to clear): '
				read tmp_EXTRA_CCSP_CONFIGURE_OPTS
				if [ "$tmp_EXTRA_CCSP_CONFIGURE_OPTS" = "--" ]; then
					EXTRA_CCSP_CONFIGURE_OPTS=""
				elif [ "$tmp_EXTRA_CCSP_CONFIGURE_OPTS" ]; then
					EXTRA_CCSP_CONFIGURE_OPTS="$tmp_EXTRA_CCSP_CONFIGURE_OPTS"
				fi
			elif [ "$REPLY" = "XK" ] || [ "$REPLY" = "xk" ] && [ $ALL_SETTINGS -eq 1 ]; then
				printf '\nextra kroc options (-- to clear): '
				read tmp_EXTRA_KROC_CONFIGURE_OPTS
				if [ "$tmp_EXTRA_KROC_CONFIGURE_OPTS" = "--" ]; then
					EXTRA_KROC_CONFIGURE_OPTS=""
				elif [ "$tmp_EXTRA_KROC_CONFIGURE_OPTS" ]; then
					EXTRA_KROC_CONFIGURE_OPTS="$tmp_EXTRA_KROC_CONFIGURE_OPTS"
				fi
			else
				printf '\nunrecognised option: %s\n' "$REPLY"
			fi
			#}}}
		done

		#}}}
	fi
	#{{{  write out to .install_dir file something that can be sourced
	printf 'writing configuration to .install_dir\n'

	printf '\n# KRoC .install_dir file\n# this is an autogenerated file, edit at your own risk!\n#\n' > .install_dir
	printf 'INSTALL_DIR="%s"\n' "$INSTALL_DIR" >> .install_dir
	printf 'kroc_configdir="%s"\n' "$kroc_configdir" >> .install_dir
	printf 'kroc_archbindir="%s"\n' "$kroc_archbindir" >> .install_dir
	printf 'kroc_archlibdir="%s"\n' "$kroc_archlibdir" >> .install_dir
	printf 'kroc_archincdir="%s"\n' "$kroc_archincdir" >> .install_dir
	printf 'kroc_mandir="%s"\n' "$kroc_mandir" >> .install_dir
	printf 'kroc_krocdir="%s"\n' "$kroc_krocdir" >> .install_dir
	printf 'USEPTHREADS=%d\n' "$USEPTHREADS" >> .install_dir
	printf 'USEMP=%d\n' "$USEMP" >> .install_dir
	printf 'USEUDC=%d\n' "$USEUDC" >> .install_dir
	printf 'USEPRIORITY=%d\n' "$USEPRIORITY" >> .install_dir
	printf 'USECPUTIMERS=%d\n' "$USECPUTIMERS" >> .install_dir
	printf 'USECTTD=%d\n' "$USECTTD" >> .install_dir
	printf 'USEPONY=%d\n' "$USEPONY" >> .install_dir
	printf 'USEPGROUPS=%d\n' "$USEPGROUPS" >> .install_dir
	printf 'EXTRA_CCSP_CONFIGURE_OPTS=%s\n' "$EXTRA_CCSP_CONFIGURE_OPTS" >> .install_dir
	printf 'EXTRA_KROC_CONFIGURE_OPTS=%s\n' "$EXTRA_KROC_CONFIGURE_OPTS" >> .install_dir
	printf 'NOCC_INSTALL=%s\n' "$NOCC_INSTALL" >> .install_dir

	printf '\n\n' >> .install_dir

	if [ $WRITEANDEXIT -eq 1 ]; then
		exit 0
	fi

	#}}}
fi
#{{{  finalise kroc_... directories for real paths based on INSTALL_DIR
kroc_archbindir="$INSTALL_DIR$kroc_archbindir"
kroc_archlibdir="$INSTALL_DIR$kroc_archlibdir"
kroc_archincdir="$INSTALL_DIR$kroc_archincdir"
kroc_mandir="$INSTALL_DIR$kroc_mandir"
kroc_krocdir="$INSTALL_DIR$kroc_krocdir"
kroc_kroc_examples="${INSTALL_DIR}/lib/kroc/examples"
kroc_kroc_vtlib="$kroc_krocdir/vtlib"
kroc_kroc_vtinclude="$kroc_krocdir/vtinclude"
kroc_kroc_doc="$kroc_krocdir/doc"
kroc_kroc_cgtests="$kroc_kroc_examples/cgtests"

#}}}
#{{{  pre-release messages
if [ "$PRERELEASE" = "1" ]; then
	cat << EOF

*****************************************************
**                      NOTE!                      **
**  this is a pre-release version of KRoC/Linux    **
**  and may contain bugs.  Known bugs are listed   **
**  in the BUGS file included in the distribution  **
**                                                 **
**  please report new bugs / suspicious behaviour  **
**  to:  kroc-bugs@kent.ac.uk                      **
**                                                 **
*****************************************************
EOF
	printf 'sleeping for 1 second..\n'
	sleep 1
elif [ "$PRERELEASE" = "2" ]; then
	cat << EOF

*********************************************************
**                         NOTE!                       **
**  this is a final-prerelease version of KRoC/Linux   **
**  and should not contain bugs in "stable" features.  **
**                                                     **
**  known bugs are listed in the included BUGS file.   **
**                                                     **
**  please report new-bugs and suspicious behaviour    **
**  to:  kroc-bugs@kent.ac.uk                          **
**                                                     **
*********************************************************
EOF
	printf 'sleeping for 1 second..\n'
	sleep 1
fi


#}}}
#{{{  if any important configure options changed, force reconfiguration of packages
if [ "$INSTALL_DIR" != "$preset_INSTALL_DIR" ]; then
	FORCECONFIGURE=1
fi
if [ "$kroc_archbindir" != "$preset_archbindir" ]; then
	FORCECONFIGURE=1
fi
if [ "$kroc_archlibdir" != "$preset_archlibdir" ]; then
	FORCECONFIGURE=1
fi
if [ "$kroc_archincdir" != "$preset_archincdir" ]; then
	FORCECONFIGURE=1
fi
if [ "$kroc_mandir" != "$preset_mandir" ]; then
	FORCECONFIGURE=1
fi
if [ "$kroc_configdir" != "$preset_configdir" ]; then
	FORCECONFIGURE=1
fi
if [ "$USEPRIORITY" != "$preset_USEPRIORITY" ]; then
	FORCECONFIGURE=1
fi
if [ "$USECPUTIMERS" != "$preset_USECPUTIMERS" ]; then
	FORCECONFIGURE=1
fi
if [ "$USEUDC" != "$preset_USEUDC" ]; then
	FORCECONFIGURE=1
fi
if [ "$USECTTD" != "$preset_USECTTD" ]; then
	FORCECONFIGURE=1
fi
if [ "$USEPONY" != "$preset_USEPONY" ]; then
	FORCECONFIGURE=1
fi
if [ "$USEPTHREADS" != "$preset_USEPTHREADS" ]; then
	FORCECONFIGURE=1
fi
if [ "$USEMP" != "$preset_USEMP" ]; then
	FORCECONFIGURE=1
fi
if [ "$USEPGROUPS" != "$preset_USEPGROUPS" ]; then
	FORCECONFIGURE=1
fi
if [ "$EXTRA_CCSP_CONFIGURE_OPTS" != "$preset_EXTRA_CCSP_CONFIGURE_OPTS" ]; then
	FORCECONFIGURE=1
fi
if [ "$EXTRA_KROC_CONFIGURE_OPTS" != "$preset_EXTRA_KROC_CONFIGURE_OPTS" ]; then
	FORCECONFIGURE=1
fi
if [ "$NOCC_INSTALL" != "$preset_NOCC_INSTALL" ]; then
	FORCECONFIGURE=1
fi


#}}}

printf 'Installing KRoC/Linux in %s\n' "$INSTALL_DIR"
printf '   configuration: %s\n' "$kroc_configdir"
printf '   architecture-specific binaries: %s\n' "$kroc_archbindir"
printf '   architecture-specific libraries: %s\n' "$kroc_archlibdir"
printf '   architecture-specific includes: %s\n' "$kroc_archincdir"
printf '   manual pages: %s\n' "$kroc_mandir"
printf '   kroc-specific files: %s\n' "$kroc_krocdir"
printf '   examples: %s\n' "$kroc_kroc_examples"
printf '   virtual-transputer libraries: %s\n' "$kroc_kroc_vtlib"
printf '   virtual-transputer includes: %s\n' "$kroc_kroc_vtinclude"
printf '   kroc documentation: %s\n' "$kroc_kroc_doc"
printf '   compiler test suite: %s\n' "$kroc_kroc_cgtests"
printf '\n'

#{{{  set up environment
# This should be the same as kroc-setup.sh.
PATH="$kroc_archbindir:$PATH"
LD_LIBRARY_PATH="$kroc_archlibdir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"; export LD_LIBRARY_PATH
#}}}
#{{{  sort out the ACTIONLIST
SHOWBANNER=0

if [ "$ACTIONLIST" = "" ] || [ "$ACTIONLIST" = "build" ] || [ "$ACTIONLIST" = "all" ]; then
	# place install process in ACTIONLIST
	if [ "$ACTIONLIST" = "all" ]; then
		FULLINSTALL=1
	else
		FULLINSTALL=
	fi
	SHOWBANNER=1
	ACTIONLIST="preconfigure-ccsp \
		configure-ccsp make-ccsp install-ccsp \
		bsyscalls-support cputimers-support dynproc-support \
		configure-mkoccdeps make-mkoccdeps install-mkoccdeps \
		configure-occ21 make-occ21 install-occ21 \
		configure-ilibr make-ilibr install-ilibr \
		configure-kroc make-kroc install-kroc \
		configure-tranx86 make-tranx86 install-tranx86 \
		configure-krocif make-krocif install-krocif \
		configure-inmoslibs make-inmoslibs install-inmoslibs \
		configure-bsclib make-bsclib install-bsclib \
		configure-course make-course install-course \
		configure-useful make-useful install-useful \
		configure-cif make-cif install-cif \
		configure-occsdl make-occsdl install-occsdl \
		configure-raster make-raster install-raster \
		configure-sdlraster make-sdlraster install-sdlraster \
		configure-occgl make-occgl install-occgl \
		configure-occade make-occade install-occade \
		configure-button make-button install-button \
		configure-fmtoutlib make-fmtoutlib install-fmtoutlib \
		configure-moa make-moa install-moa"
	if [ "$USEUDC" -eq 1 ]; then
		# conditional on the "--with-udc" flag
		ACTIONLIST="$ACTIONLIST \
			configure-udc make-udc install-udc"
	fi
	if [ "$USEPONY" -eq 1 ]; then
		# conditional on the "--with-pony" flag
		ACTIONLIST="$ACTIONLIST \
			configure-pony make-pony install-pony"
	fi
	ACTIONLIST="$ACTIONLIST \
		configure-occamdoc make-occamdoc install-occamdoc \
		configure-dynproc make-dynproc install-dynproc"
else
	FULLINSTALL=
fi

EXAMPLEINSTALL=
TESTSINSTALL=
APIINSTALL=

# some transformations
EXAMPLE_ACTIONS="building-examples bsyscalls-support cputimers-support dynproc-support \
		configure-bsclib_examples make-bsclib_examples install-bsclib_examples \
		configure-course_examples make-course_examples install-course_examples \
		configure-course_answers make-course_answers install-course_answers \
		configure-useful_examples make-useful_examples install-useful_examples \
		configure-dynproc_examples make-dynproc_examples install-dynproc_examples \
		configure-cif_examples make-cif_examples install-cif_examples \
		configure-bar_demo make-bar_demo install-bar_demo \
		configure-game_demo make-game_demo install-game_demo \
		configure-robots_demo make-robots_demo install-robots_demo \
		configure-ttygames_demo make-ttygames_demo install-ttygames_demo \
		configure-raster_examples make-raster_examples install-raster_examples \
		configure-sdlraster_examples make-sdlraster_examples install-sdlraster_examples \
		configure-occsdl_examples make-occsdl_examples install-occsdl_examples \
		configure-occgl_examples make-occgl_examples install-occgl_examples \
		configure-occade_examples make-occade_examples install-occade_examples \
		configure-button_examples make-button_examples install-button_examples \
		configure-moa_examples make-moa_examples install-moa_examples"
if [ "$USEUDC" -eq 1 ]; then
	EXAMPLE_ACTIONS="$EXAMPLE_ACTIONS \
		configure-udc_examples make-udc_examples install-udc_examples"
fi
if [ "$USEPONY" -eq 1 ]; then
	EXAMPLE_ACTIONS="$EXAMPLE_ACTIONS \
		configure-pony_examples make-pony_examples"
fi
TESTS_ACTIONS="building-tests \
		bsyscalls-support cputimers-support dynproc-support \
		configure-cgtests make-cgtests install-cgtests \
		configure-hereticc make-hereticc install-hereticc"
DOC_ACTIONS="building-api \
		install-manpages \
		configure-occamdoc make-occamdoc install-occamdoc \
		configure-doc make-doc install-doc \
		extract-api"

if [ "$FULLINSTALL" = "1" ]; then
	ACTIONLIST="$ACTIONLIST examples buildtests doc"
fi
NEWACTIONLIST=

for action in $ACTIONLIST; do
	case X$action in
	Xexamples)
		NEWACTIONLIST="$NEWACTIONLIST $EXAMPLE_ACTIONS"
		;;
	Xbuildtests)
		NEWACTIONLIST="$NEWACTIONLIST $TESTS_ACTIONS"
		;;
	Xtests)
		NEWACTIONLIST="$NEWACTIONLIST $TESTS_ACTIONS run-tests"
		;;
	Xdoc)
		NEWACTIONLIST="$NEWACTIONLIST $DOC_ACTIONS"
		;;
	Xccspt)
		NEWACTIONLIST="$NEWACTIONLIST preconfigure-ccsp configure-ccspt make-ccspt install-ccspt"
		;;
	Xccsp)
		NEWACTIONLIST="$NEWACTIONLIST preconfigure-ccsp configure-ccsp make-ccsp install-ccsp"
		;;
	Xmkoccdeps)
		NEWACTIONLIST="$NEWACTIONLIST configure-mkoccdeps make-mkoccdeps install-mkoccdeps"
		;;
	Xocc21)
		NEWACTIONLIST="$NEWACTIONLIST configure-occ21 make-occ21 install-occ21"
		;;
	Xilibr)
		NEWACTIONLIST="$NEWACTIONLIST configure-ilibr make-ilibr install-ilibr"
		;;
	Xtranx86)
		NEWACTIONLIST="$NEWACTIONLIST bsyscalls-support cputimers-support dynproc-support configure-tranx86 make-tranx86 install-tranx86"
		;;
	Xkroc)
		NEWACTIONLIST="$NEWACTIONLIST bsyscalls-support cputimers-support dynproc-support configure-kroc make-kroc install-kroc"
		;;
	Xkrocif)
		NEWACTIONLIST="$NEWACTIONLIST bsyscalls-support cputimers-support dynproc-support preconfigure-krocif configure-krocif make-krocif install-krocif"
		;;
	X*)
		FOUND=0

		for x in inmoslibs bsclib course course_answers useful dynproc udc manpages cgtests hereticc cif raster sdlraster occsdl occgl occade button pony fmtoutlib moa occamdoc; do
			if [ "X$x" = "X$action" ]; then
				NEWACTION="bsyscalls-support cputimers-support dynproc-support configure-$action make-$action install-$action"
				FOUND=1
			fi
		done

		for x in bsclib course course useful dynproc udc bar game cif raster sdlraster occsdl occgl occade button pony moa; do
			if [ "X${x}_examples" = "X$action" ]; then
				NEWACTION="bsyscalls-support cputimers-support dynproc-support configure-$action make-$action install-$action"
				FOUND=1
			fi
		done

		if [ $FOUND -eq 1 ]; then
			NEWACTIONLIST="$NEWACTIONLIST $NEWACTION"
		elif [ "$NEWACTIONLIST" = "" ]; then
			NEWACTIONLIST="$action"
		else
			NEWACTIONLIST="$NEWACTIONLIST $action"
		fi
		;;
	esac
done
ACTIONLIST=$NEWACTIONLIST

# the first action must always be "setbuildtarget" (since this decides final settings), and then "setbuildoptions"
ACTIONLIST="setbuildtarget setbuildoptions $ACTIONLIST"


#}}}

DUMPOUT=$DIST_DIR/typescript

# start installation
typescript_head

HAVE_BSYSCALLS_SUPPORT=
HAVE_CPUTIMERS_SUPPORT=
HAVE_DYNPROC_SUPPORT=

# run through ACTIONLIST and do whatever!
for action in $ACTIONLIST; do
	case X$action in
		#{{{  setbuildtarget: guesses the host system type and sets KROCHOST_ARCH, KROCHOST_VENDOR and KROCHOST_OS
	Xsetbuildtarget)
		check_autoconf "$DIST_DIR" "$CCSP_SRC"
		if [ ! -x $DIST_DIR/$CCSP_SRC/config.guess ]; then
			printf '%s: missing config.guess in CCSP source tree!\n' "$0"  1>&2
			# this is pretty bad..
			install_error
			exit 1
		else
			printf 'guessing host system type... '
			KROCHOSTSTR=$($DIST_DIR/$CCSP_SRC/config.guess || printf 'unknown-unknown-unknown\n')

			KROCHOST_ARCH=$(printf '%s' "$KROCHOSTSTR" | $CUT -d - -f -1)
			KROCHOST_VENDOR=$(printf '%s' "$KROCHOSTSTR" | $CUT -d - -f 2-2)
			KROCHOST_OS=$(printf '%s' "$KROCHOSTSTR" | $CUT -d - -f 3-)

			printf '%s\n' "$KROCHOSTSTR"

			# then set any build-specific options
			setopts_host "$KROCHOST_ARCH" "$KROCHOST_VENDOR" "$KROCHOST_OS"
		fi
		# frmb: removed scheduler-structure support, there is a better way to do this..
		;;
		#}}}
		#{{{  setbuildoptions: if this is a multiprocessor build (decided by setbuildtarget), set BUILD_NUMCPUS in MAKE_COMPILEOPTS
	Xsetbuildoptions)
		setopts_build
		;;
		#}}}
		#{{{  update: does a source update from the distribution site
	Xupdate)
		if [ "$WGET" = "" ]; then
			printf '%s: cannot update, no wget\n' "$0" | $TEE -a "$DUMPOUT"
		else
			CURRENT_DIR=$(pwd)
			cd /tmp
			if [ ! -f "$PATCHINFOFILE" ]; then
				FAILED=
				printf '%s: trying to wget %s\n' "$0" "$PATCHINFOURL" | $TEE -a "$DUMPOUT"
				$WGET -q "$PATCHINFOURL" || FAILED=1
				if [ "$FAILED" = "1" ]; then
					rm -f "$PATCHINFOFILE"
					cd "$CURRENT_DIR"
					printf '%s: unable to get %s, assuming latest version (%s)\n' "$0" "$PATCHINFOURL" "$VERSION" | $TEE -a "$DUMPOUT"
				else
					cd "$CURRENT_DIR"
					prepare_patch /tmp/"$PATCHINFOFILE" && exit 0
				fi
			else
				# file already here
				cd $CURRENT_DIR
				printf '%s: file /tmp/%s already exists, using it\n' "$0" "$PATCHINFOFILE" | $TEE -a "$DUMPOUT"
				prepare_patch /tmp/"$PATCHINFOFILE" && exit 0
			fi
		fi
		;;
		#}}}
		#{{{  status: shows individual package status
	Xstatus)
		printf 'installation directory: %s\n' "$INSTALL_DIR"
		printf 'distribution directory: %s\n' "$DIST_DIR"
		printf 'sed: %s\n' "$SED"
		printf 'awk: %s\n' "$AWK"
		printf 'make: %s\n' "$MAKE"
		printf 'wget: %s\n' "$WGET"
		for PKG in $ALL_PKGS; do
			package_status $DIST_DIR $PKG
		done
		;;
		#}}}
		#{{{  autoupdate: updates autoconf/automake files
	Xautoupdate)
		printf 'distribution directory: %s\n' "$DIST_DIR"
		printf 'auto-file update, path to default files [/usr/share/automake]: '
		read REPLY
		if [ "$REPLY" = "" ]; then
			AUTOPATH=/usr/share/automake
		else
			AUTOPATH="$REPLY"
		fi
		if [ ! -r $AUTOPATH/config.guess ]; then
			printf 'that directory does not appear to contain config.guess, aborting.\n'
			exit 1
		fi
		AUTOFILES="config.guess config.sub depcomp missing mkinstalldirs install-sh"
		for PKG in $ALL_PKGS; do
			PKGSTAT=$(package_status $DIST_DIR $PKG | grep autofiles)
			if [ "$PKGSTAT" != "" ]; then
				printf 'updating autofiles in %-24s: ' "$DIST_DIR" "$PKG"
				for file in $AUTOFILES; do
					if [ -f $DIST_DIR/$PKG/$file ]; then
						cp $AUTOPATH/$file $DIST_DIR/$PKG/$file
						printf '%s ' "$file"
					fi
				done
				printf '\n'
			fi
		done
		;;
		#}}}
		#{{{  building-examples: set example build
	Xbuilding-examples)
		EXAMPLEINSTALL=1
		;;
		#}}}
		#{{{  building-tests: set tests build
	Xbuilding-tests)
		TESTSINSTALL=1
		;;
		#}}}
		#{{{  building-api: set API build
	Xbuilding-api)
		APIINSTALL=1
		;;
		#}}}
		#{{{  bsyscalls-support: attempts to determine whether or not support for blocking system calls is present
	Xbsyscalls-support)
		nm "$kroc_archlibdir/libkroc.so" 2> /dev/null | grep "scheduler_can_do_bsyscalls" 1> /dev/null && HAVE_BSYSCALLS_SUPPORT=1
		grep "^#define BLOCKING_SYSCALLS 1" "$kroc_archincdir/ccsp_config.h" 1> /dev/null && HAVE_BSYSCALLS_SUPPORT=1
		printf "%s: checking for blocking system calls support... " $0 | $TEE -a "$DUMPOUT"
		if [ "$HAVE_BSYSCALLS_SUPPORT" != "" ]; then
			printf "yes\n" | $TEE -a "$DUMPOUT"
		else
			printf "no\n" | $TEE -a "$DUMPOUT"
		fi
		;;
		#}}}
		#{{{  cputimers-support: attempts to determine whether or not support for CPU timers is present
	Xcputimers-support)
		nm "$kroc_archlibdir/libkroc.so" 2> /dev/null | grep "scheduler_can_do_cputimers" 1> /dev/null && HAVE_CPUTIMERS_SUPPORT=1
		grep "^#define ENABLE_CPU_TIMERS 1" "$kroc_archincdir/ccsp_config.h" 1> /dev/null && HAVE_CPUTIMERS_SUPPORT=1
		printf "%s: checking for cpu-timers support... " $0 | $TEE -a "$DUMPOUT"
		if [ "$HAVE_CPUTIMERS_SUPPORT" != "" ]; then
			printf "yes\n" | $TEE -a "$DUMPOUT"
		else
			printf "no\n" | $TEE -a "$DUMPOUT"
		fi
		;;
		#}}}
		#{{{  dynproc_support: attempts to determine whether or not support for dynamic processes is present
	Xdynproc-support)
		nm "$kroc_archlibdir/libkroc.so" 2> /dev/null | grep "scheduler_can_do_dynproc" 1> /dev/null && HAVE_DYNPROC_SUPPORT=1
		grep "^#define DYNAMIC_PROCS 1" "$kroc_archincdir/ccsp_config.h" 1> /dev/null && HAVE_DYNPROC_SUPPORT=1
		printf "%s: checking for dynamic process support... " $0 | $TEE -a "$DUMPOUT"
		if [ "$HAVE_DYNPROC_SUPPORT" != "" ]; then
			printf "yes\n" | $TEE -a "$DUMPOUT"
		else
			printf "no\n" | $TEE -a "$DUMPOUT"
		fi
		;;
		#}}}
		#{{{  clean: clean all packages
	Xclean)
		# clean all packages
		for PKG in $ALL_PKGS; do
			clean_pkg $DIST_DIR $PKG
		done
		;;
		#}}}
		#{{{  distclean: clean for distribution
	Xdistclean)
		# clean for distribution
		for PKG in $ALL_PKGS; do
			distclean_pkg $DIST_DIR $PKG
		done
		rm -f .install_dir
		for sec in $MANPAGE_SECTIONS; do
			if [ -d $DIST_DIR/doc/man$sec ]; then
				printf 'cleaning up local man-pages (section %d)..\n' "$sec" | $TEE -a "$DUMPOUT"
				rm -rf $DIST_DIR/doc/man$sec
			fi
		done
		printf 'cleaning up any index.bt files..\n' | $TEE -a "$DUMPOUT"
		find $DIST_DIR/doc -name index.bt | xargs rm -f
		printf 'cleaning up any index.db files..\n' | $TEE -a "$DUMPOUT"
		find $DIST_DIR/doc -name index.db | xargs rm -f

		# better remove symbolic-links created by ccsp pre-configure (!)
		if [ -L $DIST_DIR/$CCSP_SRC/arch/arch ] || [ -L $DIST_DIR/$CCSP_SRC/include/arch ]; then
			printf 'cleaning up ccsp pre-configure symbolic links\n' | $TEE -a "$DUMPOUT"
			test -L $DIST_DIR/$CCSP_SRC/arch/arch/mpsched.S && rm -f $DIST_DIR/$CCSP_SRC/arch/arch/mpsched.S
			test -L $DIST_DIR/$CCSP_SRC/arch/arch/schedvars.S && rm -f $DIST_DIR/$CCSP_SRC/arch/arch/schedvars.S
			test -L $DIST_DIR/$CCSP_SRC/arch/arch && rm -f $DIST_DIR/$CCSP_SRC/arch/arch
			test -L $DIST_DIR/$CCSP_SRC/include/arch && rm -f $DIST_DIR/$CCSP_SRC/include/arch
		fi
		if [ -L $DIST_DIR/$CCSP_SRC/include/config.h ]; then
			printf 'cleaning up ccsp configure symbolic links\n' | $TEE -a "$DUMPOUT"
			test -L $DIST_DIR/$CCSP_SRC/include/config.h && rm -f $DIST_DIR/$CCSP_SRC/include/config.h
		fi
		if [ -L $DIST_DIR/$KROCIF_SRC/jumpstubs.S ]; then
			printf 'cleaning up KRoC interface preconfigure symbolic links\n' | $TEE -a "$DUMPOUT"
			test -L $DIST_DIR/$KROCIF_SRC/jumpstubs.S && rm -f $DIST_DIR/$KROCIF_SRC/jumpstubs.S
		fi
		# better clean-up any tilde temp. files
		find $DIST_DIR/ -name '*~' | xargs rm -f
		;;
		#}}}
		#{{{  install-manpages: put the manual pages in $INSTALL_DIR/doc/man1, and point MANPATH at $INSTALL_DIR/doc
	Xinstall-manpages)
		# put the manual pages in $kroc_mandir/man[1..8], and point MANPATH at it
		for msec in $MANPAGE_SECTIONS; do
			install -d -v "$kroc_mandir/man$msec" | $TEE -a "$DUMPOUT"
		done
		for manpage in $MANPAGE_LIST; do
			case X$manpage in
				X*.1)
					msec=1
					;;
				X*.3)
					msec=3
					;;
			esac
			install -m 0644 -v "$DIST_DIR/doc/$manpage" "$kroc_mandir/man$msec" | $TEE -a "$DUMPOUT"
		done
		# if "mandb" exists, run it to create the manpage index
		MANDB=$(type mandb 2>&1 | $SED -e 's/^'mandb' is hashed (\([^)]*\))/\1/g' -e 's/^'mandb' is //g' -e '/not found/d')
		if [ "$MANDB" = "" ]; then
			printf '%s: could not find mandb, will not build manpage index\n' "$0" | $TEE -a "$DUMPOUT"
		else
			printf 'building manpage index..\n'
			mandb "$kroc_mandir" 2>&1 | $TEE -a "$DUMPOUT"
		fi
		;;
		#}}}
		#{{{  extract-api: extract inline documentation from modules
	Xextract-api)
		docsrc="$(find modules/*/libsrc -name '*.occ' -or -name '*.inc')"
		(occamdoc -v -f html -d "$kroc_kroc_doc/api" $docsrc && touch .success) 2>&1 | $TEE -a "$DUMPOUT"
		if [ -f .success ]; then
			rm .success
		else
			printf 'error while running occamdoc\n' | $TEE -a "$DUMPOUT" 1>&2
			exit 1
		fi
		;;
		#}}}
		#{{{  run-tests: run tests
	Xrun-tests)
		all_ok=1

		pushd "$CGTESTS_SRC"
		./run-tests -v || all_ok=0
		popd

		pushd "$HERETICC_SRC"
		./hereticc -n1 -r1 || all_ok=0
		popd

		if [ "$all_ok" == 0 ]; then
			exit 1
		fi
		;;
		#}}}
	X*-*)
		what=$(printf '%s\n' $action | $SED -e 's/-.*$//')
		pkg=$(printf '%s\n'  $action | $SED -e 's/^[^-]*-//')
		ABORT_ACTION=
		CONF_SPECOPTS=
		PRECONF_SPECOPTS=
		# turn pkg into PKG_SRC
		case X$pkg in
			#{{{  ccsp: run-time kernel
		Xccsp)
			PKG_SRC=$CCSP_SRC

			if [ $USEPRIORITY -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-process-priority"
			elif [ $USEPRIORITY -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-process-priority"
			fi

			if [ $USECPUTIMERS -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-cpu-timers"
			elif [ $USECPUTIMERS -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-cpu-timers"
			fi

			if [ $USEPTHREADS -eq 1 ] || [ $USEPTHREADS -eq 2 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-pthreads"
			elif [ $USEPTHREADS -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-pthreads"
			fi

			if [ $USEMP -eq 1 ] || [ $USEMP -eq 42 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-mp"
			elif [ $USEMP -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-mp"
			fi

			if [ $USEPGROUPS -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-pgroups"
			elif [ $USEPGROUPS -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-pgroups"
			fi

			if [ $USEUDC -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-udc"
			elif [ $USEUDC -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-udc"
			fi

			if [ "$EXTRA_CCSP_CONFIGURE_OPTS" ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS $EXTRA_CCSP_CONFIGURE_OPTS"
			fi
			;;
			#}}}
			#{{{  ccspt: run-time kernel with debugging trace support
		Xccspt)
			PKG_SRC=$CCSP_SRC

			if [ $USEPRIORITY -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-process-priority"
			elif [ $USEPRIORITY -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-process-priority"
			fi

			if [ $USECPUTIMERS -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-cpu-timers"
			elif [ $USECPUTIMERS -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-cpu-timers"
			fi

			if [ $USEPTHREADS -eq 1 ] || [ $USEPTHREADS -eq 2 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-pthreads"
			elif [ $USEPTHREADS -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-pthreads"
			fi

			if [ $USEMP -eq 1 ] || [ $USEMP -eq 42 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-mp"
			elif [ $USEMP -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-mp"
			fi

			if [ $USEPGROUPS -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-pgroups"
			elif [ $USEPGROUPS -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-pgroups"
			fi

			if [ $USEUDC -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-udc"
			elif [ $USEUDC -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-udc"
			fi

			if [ "$EXTRA_CCSP_CONFIGURE_OPTS" ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS $EXTRA_CCSP_CONFIGURE_OPTS"
			fi
			CONF_SPECOPTS="$CONF_SPECOPTS --enable-dtraces"

			;;
			#}}}
			#{{{  mkoccdeps: occam dependency generator
		Xmkoccdeps)
			PKG_SRC=$MKOCCDEPS_SRC
			;;
			#}}}
			#{{{  occ21: occam-pi compiler
		Xocc21)
			PKG_SRC=$OCC21_SRC
			if [ $USEPRIORITY -eq 0 ]; then
				CONF_SPECOPTS="--disable-process-priority"
			fi
			;;
			#}}}
			#{{{  cgtests: compiler test suite
		Xcgtests)
			PKG_SRC=$CGTESTS_SRC
			CONF_SPECOPTS="--with-kroc"
			;;
			#}}}
			#{{{  hereticc: runtime benchmark suite
		Xhereticc)
			PKG_SRC=$HERETICC_SRC
			;;
			#}}}
			#{{{  ilibr: inmos librarian
		Xilibr)
			PKG_SRC=$ILIBR_SRC
			;;
			#}}}
			#{{{  tranx86: native code translator
		Xtranx86)
			PKG_SRC=$TRANX86_SRC
			if [ $USEPRIORITY -eq 0 ]; then
				CONF_SPECOPTS="--disable-process-priority"
			fi
			if [ $USEMP -eq 1 ] || [ $USEMP -eq 42 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-mp"
			elif [ $USEMP -eq 0 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --disable-mp"
			fi

			;;
			#}}}
			#{{{  kroc: wrapper script
		Xkroc)
			if [ $USER_INSTALL -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-user-install"
			fi
			if [ $USEPTHREADS -eq 1 ] || [ $USEPTHREADS -eq 2 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-pthreads"
			fi
			if [ $USEMP -eq 1 ] || [ $USEMP -eq 42 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-mp"
			fi
			if [ $USECTTD -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-cttd"
			fi
			if [ $USEPONY -eq 1 ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --enable-pony"
			fi
			if [ "$EXTRA_KROC_CONFIGURE_OPTS" ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS $EXTRA_KROC_CONFIGURE_OPTS"
			fi
			if [ "$NOCC_INSTALL" ]; then
				CONF_SPECOPTS="$CONF_SPECOPTS --with-nocc=$NOCC_INSTALL"
			fi
			PKG_SRC=$KROC_SRC
			;;
			#}}}
			#{{{  krocif: kroc interface library
		Xkrocif)
			PKG_SRC=$KROCIF_SRC
			;;
			#}}}
			#{{{  inmoslibs: inmos libraries
		Xinmoslibs)
			PKG_SRC=$INMOSLIBS_SRC
			;;
			#}}}
			#{{{  bsclib_examples: blocking sys-call examples
		Xbsclib_examples)
			if [ "$HAVE_BSYSCALLS_SUPPORT" = "1" ]; then
				PKG_SRC=$BSCLIB_EXAMPLES_SRC
			else
				ABORT_ACTION=1
			fi
			;;
			#}}}
			#{{{  course_examples: course examples
		Xcourse_examples)
			PKG_SRC=$COURSE_EXAMPLES_SRC
			;;
			#}}}
			#{{{  course_answers: course model answers
		Xcourse_answers)
			PKG_SRC=$COURSE_ANSWERS_SRC
			;;
			#}}}
			#{{{  useful_examples: useful example programs
		Xuseful_examples)
			PKG_SRC=$USEFUL_EXAMPLES_SRC
			;;
			#}}}
			#{{{  dynproc_examples: dynamic loadable process examples
		Xdynproc_examples)
			if [ "$HAVE_DYNPROC_SUPPORT" = "1" ]; then
				PKG_SRC=$DYNPROC_EXAMPLES_SRC
			else
				ABORT_ACTION=1
			fi
			;;
			#}}}
			#{{{  udc_examples: user-defined channel examples
		Xudc_examples)
			PKG_SRC=$UDC_EXAMPLES_SRC
			if [ "$HAVE_BSYSCALLS_SUPPORT" != "1" ]; then
				# better make sure we don't try and build things requiring bsyscalls..
				CONF_SPECOPTS="--disable-bsyscalls"
			fi
			;;
			#}}}
			#{{{  cif_examples: C-interface examples
		Xcif_examples)
			PKG_SRC=$CIF_EXAMPLES_SRC
			;;
			#}}}
			#{{{  raster_examples: raster example programs
		Xraster_examples)
			PKG_SRC=$RASTER_EXAMPLES_SRC
			;;
			#}}}
			#{{{  sdlraster_examples: SDLRaster example programs
		Xsdlraster_examples)
			PKG_SRC=$SDLRASTER_EXAMPLES_SRC
			;;
			#}}}
			#{{{  occsdl_examples: occSDL example programs
		Xoccsdl_examples)
			PKG_SRC=$OCCSDL_EXAMPLES_SRC
			;;
			#}}}
			#{{{  occgl_examples: occGL example programs
		Xoccgl_examples)
			PKG_SRC=$OCCGL_EXAMPLES_SRC
			;;
			#}}}
			#{{{  occade_examples: Occade example programs
		Xoccade_examples)
			PKG_SRC=$OCCADE_EXAMPLES_SRC
			;;
			#}}}
			#{{{  button_examples: button example programs
		Xbutton_examples)
			PKG_SRC=$BUTTON_EXAMPLES_SRC
			;;
			#}}}
			#{{{  pony_examples: kroc-net/pony example programs
		Xpony_examples)
			PKG_SRC=$PONY_EXAMPLES_SRC
			;;
			#}}}
			#{{{  moa_examples: moa example programs
		Xmoa_examples)
			PKG_SRC=$MOA_EXAMPLES_SRC
			;;
			#}}}
			#{{{  bar_demo: the "better-bar" demonstrator
		Xbar_demo)
			PKG_SRC=$DEMO_BAR_SRC
			;;
			#}}}
			#{{{  game_demo: the "occam-pi adventure game" demonstrator
		Xgame_demo)
			PKG_SRC=$DEMO_GAME_SRC
			;;
			#}}}
			#{{{  robots_demo: the "robots" demonstrator
		Xrobots_demo)
			PKG_SRC=$DEMO_ROBOTS_SRC
			;;
			#}}}
			#{{{  ttygames_demo: the tty-games demonstrators
		Xttygames_demo)
			PKG_SRC=$DEMO_TTYGAMES_SRC
			;;
			#}}}
			#{{{  bsclib: blocking system-calls library
		Xbsclib)
			if [ "$HAVE_BSYSCALLS_SUPPORT" = "1" ]; then
				PKG_SRC=$BSCLIB_SRC
			else
				ABORT_ACTION=1
			fi
			;;
			#}}}
			#{{{  course: course library
		Xcourse)
			PKG_SRC=$COURSE_SRC
			;;
			#}}}
			#{{{  useful: general utility library
		Xuseful)
			PKG_SRC=$USEFUL_SRC
			;;
			#}}}
			#{{{  dynproc: dynamic loadable processes
		Xdynproc)
			if [ "$HAVE_DYNPROC_SUPPORT" = "1" ]; then
				PKG_SRC=$DYNPROC_SRC
			else
				ABORT_ACTION=1
			fi
			;;
			#}}}
			#{{{  udc: user-defined channels
		Xudc)
			PKG_SRC=$UDC_SRC
			;;
			#}}}
			#{{{  cif: C-interface
		Xcif)
			PKG_SRC=$CIF_SRC
			;;
			#}}}
			#{{{  raster: raster-based graphics
		Xraster)
			PKG_SRC=$RASTER_SRC
			;;
			#}}}
			#{{{  sdlraster: raster-based graphics with SDL
		Xsdlraster)
			PKG_SRC=$SDLRASTER_SRC
			;;
			#}}}
			#{{{  occsdl: SDL bindings
		Xoccsdl)
			PKG_SRC=$OCCSDL_SRC
			;;
			#}}}
			#{{{  occgl: OpenGL bindings
		Xoccgl)
			PKG_SRC=$OCCGL_SRC
			;;
			#}}}
			#{{{  occade: arcade games development
		Xoccade)
			PKG_SRC=$OCCADE_SRC
			;;
			#}}}
			#{{{  button: OpenGL buttons library
		Xbutton)
			PKG_SRC=$BUTTON_SRC
			;;
			#}}}
			#{{{  pony: kroc-net/pony network infrastructure
		Xpony)
			PKG_SRC=$PONY_SRC
			;;
			#}}}
			#{{{  fmtoutlib: formatted output library
		Xfmtoutlib)
			PKG_SRC=$FMTOUTLIB_SRC
			;;
			#}}}
			#{{{  moa: MySQL bindings
		Xmoa)
			PKG_SRC=$MOA_SRC
			;;
			#}}}
			#{{{  doc: documentation
		Xdoc)
			PKG_SRC=$DOC_SRC
			;;
			#}}}
			#{{{  occamdoc: occamdoc tool
		Xoccamdoc)
			PKG_SRC=$OCCAMDOC_SRC
			;;
			#}}}
		X*)
			(printf 'error: unknown package %s\n' "$pkg" | $TEE -a "$DUMPOUT") 1>&2
			install_error
			exit 1
			;;
		esac
		if [ "$ABORT_ACTION" != "" ]; then
			continue		# to "for .. in .." loop
		fi
		# all default actions
		printf '%s: performing action %s on %s (in %s/%s)\n' "$0" "$what" "$pkg" "$DIST_DIR" "$PKG_SRC" | $TEE -a "$DUMPOUT"
		if [ "$DRYRUN" = "" ]; then
			# actually do it
			case X$what in
				#{{{  preconfigure: pre-configure package
			Xpreconfigure)
				if [ "$PRECONF_SPECOPTS" = "" ]; then
					preconfigure_pkg "$INSTALL_DIR" "$DIST_DIR" "$PKG_SRC"
				else
					preconfigure_pkg "$INSTALL_DIR" "$DIST_DIR" "$PKG_SRC" "$PRECONF_SPECOPTS"
				fi
				;;
				#}}}
				#{{{  configure: configure package
			Xconfigure)
				if [ "$CONF_SPECOPTS" = "" ]; then
					configure_pkg "$INSTALL_DIR" "$DIST_DIR" "$PKG_SRC"
				else
					configure_pkg "$INSTALL_DIR" "$DIST_DIR" "$PKG_SRC" "$CONF_SPECOPTS"
				fi
				;;
				#}}}
				#{{{  fconfigure: configure package (forced)
			Xfconfigure)
				SAVED_FORCECONFIGURE=$FORCECONFIGURE
				FORCECONFIGURE=1
				if [ "$CONF_SPECOPTS" = "" ]; then
					configure_pkg "$INSTALL_DIR" "$DIST_DIR" "$PKG_SRC"
				else
					configure_pkg "$INSTALL_DIR" "$DIST_DIR" "$PKG_SRC" "$CONF_SPECOPTS"
				fi
				FORCECONFIGURE=$SAVED_FORCECONFIGURE
				;;
				#}}}
				#{{{  make: compile package
			Xmake)
				# maybe need to skip a make, if failed to configure
				LCL_DO_MAKE=1
				for pp in $FAILED_CONFIGURES; do
					if [ "$pp" = "$pkg" ]; then
						printf '%s: skip make on %s (failed to configure)\n' "$0" "$pkg" | $TEE -a "$DUMPOUT"
						FAILED_MAKES="$FAILED_MAKES $pkg"
						LCL_DO_MAKE=0
					fi
				done
				if [ $LCL_DO_MAKE -eq 1 ]; then
					make_pkg $DIST_DIR $PKG_SRC
				fi
				;;
				#}}}
				#{{{  install: install package
			Xinstall)
				LCL_DO_INSTALL=1
				for pp in $FAILED_MAKES; do
					if [ "$pp" = "$pkg" ]; then
						printf '%s: skip install on %s (failed to make)\n' "$0" "$pkg" | $TEE -a "$DUMPOUT"
						FAILED_INSTALLS="$FAILED_INSTALLS $pkg"
						LCL_DO_INSTALL=0
					fi
				done
				if [ $LCL_DO_INSTALL -eq 1 ]; then
					install_pkg "$DIST_DIR" "$PKG_SRC"
				fi
				;;
				#}}}
				#{{{  clean: clean package
			Xclean)
				clean_pkg "$DIST_DIR" "$PKG_SRC"
				;;
				#}}}
				#{{{  distclean: clean package for distribution
			Xdistclean)
				distclean_pkg "$DIST_DIR" "$PKG_SRC"
				;;
				#}}}
			esac

			# check for failure and failable packages
			if [ "$DEFERRED_INSTALL_ERROR" != "" ]; then
				for pp in $FAILABLE_PKGS; do
					if [ "$pp" = "$PKG_SRC" ]; then
						# allowed to fail this one
						DEFERRED_INSTALL_ERROR=""

						case X$what in
						Xpreconfigure)
							FAILED_PRECONFIGURES="$FAILED_PRECONFIGURES $pkg"
							;;
						Xconfigure)
							FAILED_CONFIGURES="$FAILED_CONFIGURES $pkg"
							;;
						Xmake)
							FAILED_MAKES="$FAILED_MAKES $pkg"
							;;
						Xinstall)
							FAILED_INSTALLS="$FAILED_INSTALLS $pkg"
							;;
						esac

						break
					fi
				done
			fi
			if [ "$DEFERRED_INSTALL_ERROR" != "" ]; then
				install_error
				exit 1
			fi
		fi
		;;
	X*)
		(printf 'error: unknown action %s.  use --help for help.\n' "$action" | $TEE -a "$DUMPOUT") 1>&2
		exit 1
		;;
	esac
done


cat >> "$DUMPOUT" << EOF

##  BUILD ENDS

EOF

# final message(s) before exiting

if [ $SHOWBANNER -eq 1 ]; then
	$TEE -a "$DUMPOUT" << EOF

***********************************************************
*                          READ ME!                       *
***********************************************************

The KRoC distribution should now be installed.  Remember to source
the relevant file:

  $INSTALL_DIR/bin/kroc-setup.sh   for sh/ksh/bash/zsh
  $INSTALL_DIR/bin/kroc-setup.csh  for csh/tcsh

EOF

	if [ "$FAILED_CONFIGURES" = "" ]; then
		$TEE -a "$DUMPOUT" << EOF
This installation does not attempt to be perfect, but it should work
for the most part.
EOF
	else
		$TEE -a "$DUMPOUT" << EOF
However, please note that the following packages failed to build and
have not been installed:

EOF
		for pkg in $FAILED_MAKES; do
			printf '  - %s\n' "$pkg" | $TEE -a "$DUMPOUT"
		done
		$TEE -a "$DUMPOUT" << EOF

For more detail on why these packages could not be built, please check
the typescript file.
EOF
	fi

	$TEE -a "$DUMPOUT" << EOF

You can navigate through the distribution via the README files.  It
is recommended that you read the docs/essentially-kroc.txt file.

To build the example programs, run:
    $0 examples

To build the compiler test-suite, run:
    $0 cgtests

To clean the source tree, run:
    $0 clean    ..or..    $0 distclean

Enjoy,

Fred.  (kroc-bugs@kent.ac.uk)

EOF
fi

if [ "$EXAMPLEINSTALL" != "" ]; then
	printf 'Available example programs have been installed into:\n' | $TEE -a "$DUMPOUT"
	printf '    %s\n' "$kroc_kroc_examples" | $TEE -a "$DUMPOUT"

	if [ "$USEPONY" -eq 1 ]; then
		printf 'pony/kroc-net example programs have been left in:\n' | $TEE -a "$DUMPOUT"
		printf '    %s\n' "$PONY_EXAMPLES_SRC"
	fi
fi

if [ "$TESTSINSTALL" != "" ]; then
	printf 'The compiler test-suite has been installed into:\n' | $TEE -a "$DUMPOUT"
	printf '    %s\n' "$kroc_kroc_cgtests" | $TEE -a "$DUMPOUT"
fi

if [ "$APIINSTALL" != "" ]; then
	printf 'The API documentation can be found here:\n' | $TEE -a "$DUMPOUT"
	printf '    %s/api/index.html\n' "$kroc_kroc_doc" | $TEE -a "$DUMPOUT"
fi

