#! /bin/sh

#{{{  make sure we have bash
if [ "$BASH_VERSION" = "" ]; then
	BASH=
	# search for "bash" in the PATH environment
	for dir in `printf '%s' "$PATH" | tr ':' '\n'`; do
		if [ -f $dir/bash ] && [ -x $dir/bash ]; then
			BASH=$dir/bash
			break
		fi
	done

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

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


#}}}

# should be in bash when we get here

#
#	occam for all (ofa) project KRoC (Kent Retargetable occam Compiler)
#	KRoC driver script
#	Copyright (C) 1997  D.J. Beckett
#	Modifications copyright (C) 2000-2004  Fred Barnes <frmb@kent.ac.uk>
#
#	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.
#

# If this file has the name "kroc.in" then it is a template for the kroc
# driver program; to generate the actual kroc script, use:
#     ./build --force-configure configure-kroc make-kroc [install-kroc]
# in the KRoC source tree
#

#{{{  set $SED and $progname
SED="@SED@"

progname=$(printf '%s' "$0" | $SED 's/^.*\///')

#}}}
#{{{  setup various variables

CC=@CC@
LD=@LD@
ARCH_LDFLAGS="@KROC_CCSP_LDFLAGS@"
ARCH_ASFLAGS="@KROC_CCSP_ASFLAGS@"

# Only the 'kroc' program need be in the users path
#PATH=$KROC/bin:$PATH

package_version="@VERSION@"

if [ "x@KROC_RMOX@" = "x" ]; then
  dversion='2.0'
else
  dversion='2.0 (RMoX)'
fi
target_canonical="@KROC_CANONICAL_TARGET@"
target_cpu="@KROC_TARGET_CPU@"
target_os="@KROC_TARGET_OS@"
# -kc : cgr-mp CCSP interface
octranopts="-kc @KROC_CCSP_TRANFLAGS@"
ccopts="@KROC_CCSP_CFLAGS@"
deplibs=""
ocllibs=""
ocrtslibs="-lm @KROC_CCSP_LIBS@"
extcflags="@KROC_CCSP_CFLAGS@"
dtraces=0

case "$target_os" in
	cygwin*)
		octranopts="$octranopts -nsymops --cnpfx _"
		;;
	darwin*)
		octranopts="$octranopts -nsymops --cnpfx _"
		;;
	solaris*)
		# solaris stock assembler doesn't eat from stdin (go via tempfile)
		octranopts="$octranopts -es"
		;;
esac

fatal=
defaultlibraries=1

#}}}
#{{{  options to occ21

# Warnings:
# -nwca : No warnings for CHAN OF ANY
# -nwgy : No warnings on GUY construct
# -nwu  : No Unused Name Warnings
# -nwp  : No Unused Parameter Warnings
occ_no_warn_opts="-nwca -nwgy -nwp -nwu"
# -walign : Warn on alignment checks
# -wall   : Enable all warnings
# -wd     : Provide descoped name warnings
# -wo     : Provide overlap check warnings
occ_warn_opts="-walign -wall -wd -wo -wqual"

# Processor class:  -tX argument to occ21 and .kXX temporary file suffix
proc_class='t8'
tsuffix='tce'

#
# -w    : Full Code Insertion
# -y    : Disable Library I/O
# -etc  : Enable ETC code generation.
# -znd  : No Debug Information At All
# -znec : Allow comments anywhere (makes folded source legal in more cases)
# -udo  : User defined operators
# -init : INITIAL declarations
## -s    : run in STOP error mode
##>>  these now handled seperately  <<##
### -revalt : use reversed ALT disable where possible (more efficient)
### -zen  : enhanced ALT enables (more efficient)
### -zep  : ALT pre-enabling sequence (very efficient)
#
# -xin  : Enable extended input

# Default: medium warnings
occwopts=
occopts="-etc -w -y -znd -znec -udo -zncc -init -xin -mobiles -mpt -zrpe @KROC_CCSP_OCCFLAGS@"

case "$target_cpu" in
	i386 | i486 | i586 | i686 | x86_64)
		occopts="$occopts -zcxdiv -zcxrem -zzs"
		;;
	sparc*)
		occopts="$occopts -tbe"
		;;
	powerpc64)
		occopts="$occopts"
		;;
	mips|mipsbe|mipsle)
		occopts="$occopts"
		;;
esac


#}}}
#{{{  extra CC options

# necessary for dynamic procs (makes all synbols appear in the dynamic symbol table)

case "$target_os" in
	darwin*)
		extraccopts=${EXTRACCOPTS:--read_only_relocs suppress}
		;;
	solaris*)
		extraccopts=${EXTRACCOPTS:-}
		;;
	*)
		extraccopts=${EXTRACCOPTS:--Xlinker -E}
		;;
esac


#}}}
#{{{  setup cc, as and ld
cc=${CC:-gcc}
as=${AS:-as}
asflags=""
ld=${LD:-ld}
case "$target_os" in
	darwin*)
		ldopts="-dynamiclib"
		libext=".dylib"
		;;
	*)
		ldopts="-shared"
		libext=".so"
		;;
esac

# Assembler options needed A1 and A2 are used to define alignment.
# Different versions of the gnu assembler require different values:
# try A1=2, A=1 (powers rather than absolutes).
asflags="$asflags --defsym A1=4 --defsym A2=2 -W"

#}}}
#{{{  path temporaries build up from options
opts_libs=""
opts_libpaths=""
opts_incpaths=""
#}}}

#{{{  various local settings
intree=
use_occ21_revalt=1
use_occ21_zen=1
use_occ21_zep=1
default_errormode_stop=0
showall=0
srcs=
verbose=
makelib=
compile=yes
translate=yes
link=yes
rmoxlink=
outfile=
dorun=yes
showversion=
showlibpath=
showincpath=
showascc=
showcflags=
showcc=
showld=
showas=
showldflags=
showasflags=
showkrocpath=
showautovars=
delete_temp=yes
enable_udc=
skip_link=
debugkroc=0
dumpxml=
usenocc=
nocc="@NOCCHOME@/nocc"
noccopts="--specs-file @NOCCHOME@/nocc.specs.xml"
linkstatic=0


#}}}
#{{{  process command-line arguments
while :
do
	case $# in
	0)
		break
		;;
	esac

	option=$1
	shift

	orig_option=$option     # Save original for error messages

	# Split out the argument for options that take them
	case $option in
	--*=*)
		optarg=$(printf '%s' "$option" | $SED -e 's/^[^=]*=//')
		;;
	# These options have mandatory values.  Since we didn't find an = sign,
	# the value must be in the next argument
	--in-tree | --octran-opts | --oc-opts | --cc-opts | --nocc-opts | --linkcc)
		optarg=$1
		shift
		;;
	esac


	case "$option" in
		#{{{  --in-tree*  build using tools in KRoC source tree
	--in-tree*)
		intree="$optarg"
		;;
		#}}}
		#{{{  -b, --brief  brief warnings
	-b | --brief)
		occopts="$occopts -b"
		;;
		#}}}
		#{{{  -c, --compile  compile only
	-c | --compile)
		link=
		octranopts="$octranopts -c"
		noccopts="$noccopts -c"
		;;
		#}}}
		#{{{  -e, --enable-udc  enable user-defined channel checks
	-e | --enable-udc)
		enable_udc=yes
		# can't use enhanced enabling with UDCs
		use_occ21_zen=0
		;;
		#}}}
		#{{{  -p, --pre-compile  precompile sources
	-p | --pre-compile)
		translate=
		link=
		;;
		#}}}
		#{{{  -n, --dry-run  do dry-run
	-n | --dry-run)
		dorun=
		verbose=yes
		;;
		#}}}
		#{{{  --dryrun  dry-run (obsolete)
	--dryrun)
		dorun=
	        printf '%s: --dryrun is obsolete, please use --dry-run\n' "$progname" 1>&2
		verbose=yes
		;;
		#}}}
		#{{{  --no-checks  disable run-time checks
	--no-checks)
		printf '%s: warning: disabling run-time checks\n' "$progname"
		octranopts="$octranopts -n"
		;;
		#}}}
		#{{{  -io, --inline-io  inline channel I/O
	-io | --inline-io)
		octranopts="$octranopts -ii -io -ia"
		;;
		#}}}
		#{{{  -is, --inline-sched  inline scheduler operations
	-is | --inline-sched)
		octranopts="$octranopts -is"
		;;
		#}}}
		#{{{  -it, --inline-ldtimer  inline timer operations
	-it | --inline-ldtimer)
		octranopts="$octranopts -it"
		;;
		#}}}
		#{{{  -o  output file
	-o)
		outfile=$1
		shift
		;;
		#}}}
		#{{{  -o*  output file
	-o*)
		outfile=$(printf '%s' "$option" | $SED -e 's/^..//')
		;;
		#}}}
		#{{{  -s, --strict  strict compilation mode
	-s | --strict)
		occopts="$occopts -strict"
		;;
		#}}}
		#{{{  --rmox  building for RMoX
	--rmox)
		octranopts="$octranopts -kr --exporttab ."
		;;
		#}}}
		#{{{  --rmox*  building RMoX module of some type
	--rmox*)
		value=$(printf '%s' "$option" | $SED -e 's/^......[-]*//')
		link=
		case $value in
		app | application)
			octranopts="$octranopts -kr --rmoxmode app"
			occopts="$occopts -zdme"
			rmoxlink=app
			;;
		drv | driver)
			octranopts="$octranopts -kr --rmoxmode drv"
			occopts="$occopts -zdme"
			rmoxlink=drv
			;;
		srv | service)
			octranopts="$octranopts -kr --rmoxmode srv"
			occopts="$occopts -zdme"
			rmoxlink=srv
			;;
		fs | filesystem)
			octranopts="$octranopts -kr --rmoxmode fs"
			occopts="$occopts -zdme"
			rmoxlink=fsm
			;;
		net | network)
			octranopts="$octranopts -kr --rmoxmode net"
			occopts="$occopts -zdme"
			rmoxlink=net
			;;
		*)
			printf '%s: unknown RMoX build mode: %s\n' "$progname" "$value" 1>&2
			exit 1
		esac
		;;
		#}}}
		#{{{  --nfw  no wait for globally FORKed processes
	--nfw)
		octranotps="$octranopts --nfw"
		;;
		#}}}
		#{{{  --new  no external wait for blocking syscalls
	--new)
		octranopts="$octranopts --new"
		;;
		#}}}
		#{{{  --octran-opts*  options for the translator
	--octran-opts*)
		octranopts="$octranopts $optarg"
		;;
		#}}}
		#{{{  --oc-opts*  options for the occam compiler
	--oc-opts*)
		occopts="$occopts $optarg"
		;;
		#}}}
		#{{{  --cc-opts*  options for the C compiler
	--cc-opts*)
		ccopts="$ccopts $optarg"
		;;
		#}}}
		#{{{  --linkcc*  compiler (for linking)
	--linkcc*)
		cc="$optarg"
		;;
		#}}}
		#{{{  --nocc-opts*  options for NOCC
	--nocc-opts*)
		noccopts="$noccopts $optarg"
		;;
		#}}}
		#{{{  -nd, --no-dynmem  disable dynamic memory
	-nd | --no-dynmem)
		occopts="$occopts -ndm"
		octranopts="$octranopts -nd"
		;;
		#}}}
		#{{{  -l, --library  building dynamic library
	-l | --library)
		# set library (and non-main) for tranpc, and no vectorspace for compiler
		octranopts="$octranopts -c -l"
		occopts="$occopts -v"
		makelib=yes
		;;
		#}}}
		#{{{  -l*  adding library (arch-specific)
	-l*)
		opts_libs="$opts_libs ${option/-l/-loccam_}"
		;;
		#}}}
		#{{{  -L*  adding path to libraries
	-L*)
		dir=$(printf '%s' $option | $SED -e 's:/$::' -e 's:^..::')
		opts_libpaths="$dir:$opts_libpaths"
		;;
		#}}}
		#{{{  -I*  adding path to includes
	-I*)
		dir=$(printf '%s' "$option" | $SED -e 's:/$::' -e 's:^..::')
		opts_incpaths="$dir:$opts_incpaths"
		;;
		#}}}
		#{{{  -v, --verbose, --v, --verb*  verbose operation
	-v | --verbose | --v | --verb*)
		verbose=yes
		octranopts="$octranopts -v"
		;;
		#}}}
		#{{{  -k, --keep-temp  keep temporary files
	-k | --keep-temp)
		delete_temp=
		octranopts="$octranopts -es"
		;;
		#}}}
		#{{{  -V, --version  show version
	-V | --version)
		showversion=yes
		;;
		#}}}
		#{{{  --libpath  show occam compiler library paths
	--libpath)
		showlibpath=yes
		;;
		#}}}
		#{{{  --incpath  show occam compiler include paths
	--incpath)
		showincpath=yes
		;;
		#}}}
		#{{{  --cclibpath  show C compiler library paths (-L...)
	--cclibpath)
		showlibpath=yes
		showascc=yes
		;;
		#}}}
		#{{{  --ccincpath  show C compiler include paths (-I...)
	--ccincpath)
		showincpath=yes
		showascc=yes
		;;
		#}}}
		#{{{  --cflags  show C compiler flags
	--cflags)
		showcflags=yes
		;;
		#}}}
		#{{{  --cc  show C compiler
	--cc)
		showcc=yes
		;;
		#}}}
		#{{{  --ld  show dynamic linker
	--ld)
		showld=yes
		;;
		#}}}
		#{{{  --ldflags  show dynamic linker flags
	--ldflags)
		showldflags=yes
		;;
		#}}}
		#{{{  --as  show assembler
	--as)
		showas=yes
		;;
		#}}}
		#{{{  --asflags  show assembler flags
	--asflags)
		showasflags=yes
		;;
		#}}}
		#{{{  --rtslibs  show run-time system libraries
	--rtslibs)
		showrtslibs=yes
		;;
		#}}}
		#{{{  --tranflags  show translator flags
	--tranflags)
		showtranflags=yes
		;;
		#}}}
		#{{{  --tran  show path to translator
	--tran)
		showtran=yes
		;;
		#}}}
		#{{{  -h, --help  show help
	-h | --help | --he*)
		fatal=yes
		;;
		#}}}
		#{{{  -w, --warn  enable warnings
	-w | --warn)
		occwopts=$occ_warn_opts
		;;
		#}}}
		#{{{  -nw, --no-warn  disable warnings
	-nw | --no-warn)
		occwopts=$occ_no_warn_opts
		;;
		#}}}
		#{{{  -nowarn  no warnings (obsolete)
	--nowarn)
	        printf '%s: --nowarn is obsolete, please use --no-warn\n' "$progname" 1>&2
		occwopts=$occ_no_warn_opts
		;;
		#}}}
		#{{{  -t2, -t4, -t8, -t9  processor class
	-t2 | -t4 | -t8 | -t9 )
		proc_class=$(printf '%s' $option | $SED -e 's/^.//')
		tsuffix="k$proc_class"
	        printf '%s: Option %s is experimental: setting processor class to %s\n' "$progname" "$option" "$proc_class" 1>&2
		;;
		#}}}
		#{{{  -X1  enable ETC output (dummy)
	-X1 )
	        printf '%s: Already using ETC.  Ignorning.\n' "$progname" 1>&2
		;;
		#}}}
		#{{{  -X2  enable user-defined operators (dummy)
	-X2 )
	        printf '%s: User defined operators already enabled.  Ignoring.\n' "$progname" 1>&2
		;;
		#}}}
		#{{{  -X3  enable INITIAL decls (dummy)
	-X3 )
		printf '%s: INITIAL declarations already enabled.  Ignoring.\n' "$progname" 1>&2
		;;
		#}}}
		#{{{  -X5  enable mobile types (dummy)
	-X5 )
		printf '%s: MOBILE types now enabled by default\n' "$progname" 1>&2
		;;
		#}}}
		#{{{  -X6  enable extended input for unhandled CASE tags
	-X6 )
		printf '%s: enabling extended input for unhandled CASE tags\n' "$progname" 1>&2
		occopts="$occopts -xtag"
		;;
		#}}}
		#{{{  -X7  enable mobile processes (dummy)
	-X7 )
		printf '%s: mobile process types now enabled by default\n' "$progname" 1>&2
		;;
		#}}}
		#{{{  -d  post-mortem debugging
	-d )
		printf '%s: Selecting post-mortem debugging\n' "$progname" 1>&2
		octranopts="$octranopts -dX"
		;;
		#}}}
		#{{{  -dt, --dtraces  enable debugging traces
	-dt | --dtraces)
		printf '%s: Enabling debugging traces\n' "$progname" 1>&2
		dtraces=1
		occopts="$occopts -dtraces"
		octranopts="$octranopts -dt"
		;;
		#}}}
		#{{{  -di  insert debugging
	-di )
		printf '%s: Selecting insert debugging\n' "$progname" 1>&2
		octranopts="$octranopts -di"
		;;
		#}}}
		#{{{  -dm  dynamic memory debugging
	-dm )
		printf '%s: Selecting dynamic memory debugging\n' "$progname" 1>&2
		octranopts="$octranopts -dm"
		;;
		#}}}
		#{{{  -ds  enable memory-usage summary
	-ds )
		printf '%s: Enabling memory usage summary\n' "$progname" 1>&2
		octranopts="$octranopts -ds"
		;;
		#}}}
		#{{{  -O, --optimise  enable optimisations (dummy)
	-O | --optimise )
		printf '%s: Optimisations already enabled\n' "$progname" 1>&2
		;;
		#}}}
		#{{{  -P, --pause  enable scheduler-check at loopend
	-P | --pause )
		printf '%s: Enabling scheduler check at loop-end/back-jump\n' "$progname" 1>&2
		octranopts="$octranopts -p"
		;;
		#}}}
		#{{{  -H  halt error-mode
	-H | --halterror )
		printf '%s: Compiling in HALT error mode\n' "$progname" 1>&2
		octranopts="$octranopts -H"
		;;
		#}}}
		#{{{  -S  stop error-mode
	-S | --stoperror )
		printf '%s: Compiling in STOP error mode\n' "$progname" 1>&2
		octranopts="$octranopts -S"
		;;
		#}}}
		#{{{  --force-tlp  force top-level interface to KYB, SCR, ERR
	--force-tlp )
		octranopts="$octranopts --tlp-kybscrerr"
		;;
		#}}}
		#{{{  --skip-link  skip link into final exec.
	--skip-link )
		printf '%s: skipping final link into executable\n' "$progname" 1>&2
		skip_link=yes
		;;
		#}}}
		#{{{  --no-zen  no enhanced pre-enabling
	--no-zen)
		use_occ21_zen=0
		;;
		#}}}
		#{{{  --use-zen  use enhanced pre-enabling
	--use-zen)
		use_occ21_zen=1
		;;
		#}}}
		#{{{  --no-revalt  no reversed ALT disabling
	--no-revalt)
		use_occ21_revalt=0
		;;
		#}}}
		#{{{  --use-revalt  use reversed ALT disabling
	--use-revalt)
		use_occ21_revalt=1
		;;
		#}}}
		#{{{  --no-zep  no ALT preenabling
	--no-zep)
		use_occ21_zep=0
		;;
		#}}}
		#{{{  --use-zep  use ALT pre-enabling
	--use-zep)
		use_occ21_zep=1
		;;
		#}}}
		#{{{  --ncl  no compiler libraries
	--ncl)
		defaultlibraries=0
		;;
		#}}}
		#{{{  --xml  dump XML
	--xml)
		dumpxml=1
		;;
		#}}}
		#{{{  --nocc  use new occam-pi compiler
	--nocc)
		if [ ! -x $nocc ]; then
			printf '%s: not configured to use NOCC\n' "$progname" 1>&2
			exit 1
		fi
		usenocc=1
		;;
		#}}}
		#{{{  --static  link to static binary
	--static)
		linkstatic=1
		;;
		#}}}
		#{{{  --krocdir  show directory where KRoC data files are kept
	--krocdir)
		showkrocpath=1
		;;
		#}}}
		#{{{  --autovars  show variables autoconf needs
	--autovars)
		showautovars=1
		;;
		#}}}
		#{{{  -z, --all-help  show all options
	-z | --all-help)
		showall=1
		;;
		#}}}
		#{{{  --debugkroc  KRoC debugging enable (not for users)
	--debugkroc)
		debugkroc=1
		;;
		#}}}
		#{{{  --*, -*  unrecognised options
	--* | -*)
		printf '%s: Unrecognized option: "%s"; use --help for usage.\n' "$progname" "$orig_option" 1>&2
		exit 1
		;;
		#}}}
		#{{{  *  source file
	*)      srcs="$srcs $option"
		;;
		#}}}

	esac
done


#}}}
#{{{  directory configuration
kroc_archbindir="@KROC_ARCHBINDIR@"
kroc_archlibdir="@KROC_ARCHLIBDIR@"
kroc_archincdir="@KROC_ARCHINCDIR@"
kroc_mandir="@KROC_MANDIR@"
kroc_krocdir="@KROC_KROCDIR@"
#}}}
#{{{  path-dependant options

if [ "$intree" = "" ]; then
	occ21="$kroc_archbindir/occ21"
	octran="$kroc_archbindir/tranx86"
else
	occ21="$intree/tools/occ21/occ21"
	octran="$intree/tools/tranx86/tranx86"
fi

if [ $dtraces -eq 1 ]; then
	ocrts="-lkrocif -lccsptrace"
else
	ocrts="-lkrocif -lccsp"
fi


#}}}
#{{{  build colon-separated search path for libraries
if [ "$intree" = "" ]; then
  ocspath="$kroc_krocdir/@KROC_TARGET_PREFIX@vtlib:$kroc_krocdir/@KROC_TARGET_PREFIX@vtinclude"
else
  ocspath="$intree/modules/inmoslibs/libsrc/forall"
fi
if [ "X$OCSEARCH" != "X" ]; then
  ocspath="$OCSEARCH:$ocspath"
fi

ocsearch=
if [ "$intree" = "" ]; then
  oclibpath="-L$kroc_archlibdir"
  cincludepath="-I$kroc_archincdir"
else
  oclibpath="@KROC_CCSP_LIBPATH@ -L$intree/modules/inmoslibs/libsrc/forall"
  cincludepath="@KROC_CCSP_CINCPATH@"
fi

#}}}
#{{{  use "ocspath" to add entries to "oclibpath", "ocsearch" and "cincludepath"
# ocspath is a COLON-SEPARATED list now, better process slightly differently


XIFS="$IFS"
IFS=':'

for dir in $ocspath; do
	dir=$(printf '%s' "$dir" | $SED -e 's:/$::')
	ocsearch="$ocsearch:$dir"
done

IFS="$XIFS"

#}}}
#{{{  add given command-line entries to "oclibpath", "ocsearch" and "cincludepath"

for lname in $opts_libs; do
	ocllibs="$ocllibs $lname"
done

XIFS="$IFS"
IFS=':'

for dir in $opts_libpaths; do
	oclibpath="-L$dir $oclibpath"
	ocsearch="$dir:$ocsearch"
done

for dir in $opts_incpaths; do
	cincludepath="-I$dir $cincludepath"
	ocsearch="$dir:$ocsearch"
done

IFS="$XIFS"

#}}}


#{{{  set extra flags from options

if [ $use_occ21_revalt -eq 1 ]; then
	occopts="$occopts -revalt"
fi
if [ $use_occ21_zen -eq 1 ]; then
	occopts="$occopts -zen"
fi
if [ $use_occ21_zep -eq 1 ]; then
	occopts="$occopts -zep"
fi

#}}}
#{{{  add current directory as first in search paths
oclibpath="-L. $oclibpath"
ocsearch=".:$ocsearch"
cincludepath="-I. $cincludepath"
procopts="-$proc_class"
occopts="$procopts $occopts"

#}}}
#{{{  add flags for user-defined channels if enabled

if [ $enable_udc ]; then
	# enable MOBILE size-field
	occopts="$occopts -msf"
else
	# disallow PLACE'd channels and don't generate external channel checks
	occopts="$occopts -npc"
	octranopts="$octranopts -nec"
fi

#}}}
#{{{  show library paths and exit if requested

if [ $showlibpath ]; then
	if [ $showascc ]; then
		printf '%s\n' "$oclibpath"
	else
		printf '%s\n' "$ocsearch" | $SED -e 's:^ ::g' -e 's: $::g' -e 's/ /:/g' -e 's/::/:/g'
	fi
	exit 0
fi

#}}}
#{{{  show include paths and exit if requested

if [ $showincpath ]; then
	if [ $showascc ]; then
		printf '%s\n' "$cincludepath"
	else
		printf '%s \n' "$ocsearch" | $SED -e 's:^ ::' -e 's: $::' -e 's/ /:/g' -e 's/::/:/g'
	fi
	exit 0
fi

#}}}


if [ $showcflags ]; then
	printf '%s\n' "$extcflags"
	exit 0
fi
if [ $showcc ]; then
	printf '%s\n' "$CC"
	exit 0
fi
if [ $showrtslibs ]; then
	printf '%s\n' "$ocrtslibs"
	exit 0
fi
if [ $showtranflags ]; then
	printf '%s\n' "$octranopts"
	exit 0
fi
if [ $showtran ]; then
	printf '%s\n' "$octran"
	exit 0
fi
if [ $showld ]; then
	printf '%s\n' "$ld"
	exit 0
fi
if [ $showldflags ]; then
	printf '%s\n' "$ARCH_LDFLAGS"
	exit 0
fi
if [ $showas ]; then
	printf '%s\n' "$as"
	exit 0
fi
if [ $showasflags ]; then
	printf '%s\n' "$ARCH_ASFLAGS"
	exit 0
fi
if [ $showkrocpath ]; then
	printf '%s\n' "$kroc_krocdir"
	exit 0
fi
if [ $showautovars ]; then
	printf 'KROC_CCSP_CFLAGS="%s";\n' "@KROC_CCSP_CFLAGS@"
	printf 'KROC_CCSP_CINCPATH="%s";\n' "@KROC_CCSP_CINCPATH@"
	printf 'KROC_CCSP_OCCFLAGS="%s";\n' "@KROC_CCSP_OCCFLAGS@"
	printf 'KROC_CCSP_TRANFLAGS="%s";\n' "@KROC_CCSP_TRANFLAGS@"
	printf 'KROC_CCSP_ASFLAGS="%s";\n' "@KROC_CCSP_ASFLAGS@"
	printf 'KROC_CCSP_LDFLAGS="%s";\n' "@KROC_CCSP_LDFLAGS@"
	printf 'KROC_CCSP_LIBPATH="%s";\n' "@KROC_CCSP_LIBPATH@"
	printf 'KROC_CCSP_LIBS="%s";\n' "@KROC_CCSP_LIBS@"

	printf 'KROC_CCSP_ENABLE_PTHREADS="%s";\n' "@KROC_CCSP_ENABLE_PTHREADS@"
	printf 'KROC_CCSP_ENABLE_MP="%s";\n' "@KROC_CCSP_ENABLE_MP@"
	printf 'KROC_CCSP_ENABLE_CTTD="%s";\n' "@KROC_CCSP_ENABLE_CTTD@"
	printf 'KROC_CCSP_ENABLE_PONY="%s";\n' "@KROC_CCSP_ENABLE_PONY@"
	printf 'KROC_CCSP_ENABLE_DYNPROC="%s";\n' "@KROC_CCSP_ENABLE_DYNPROC@"
	printf 'KROC_CCSP_ENABLE_SSE2="%s";\n' "@KROC_CCSP_ENABLE_SSE2@"
	printf 'KROC_CCSP_ENABLE_CPUTIMERS="%s";\n' "@KROC_CCSP_ENABLE_CPUTIMERS@"

	printf 'KROC_RMOX="%s";\n' "@KROC_RMOX@"

	exit 0
fi

if [ $makelib ]; then
	if [ "X$link" = "X" ]; then
		printf '%s: -c and -l are mutually exclusive (dropping -c)\n' "$progname" 1>&2
		link=yes
	fi
fi


if [ "X${fatal}" != "X" -o "X$srcs" = "X" -o "X$showversion" != "X" ]; then

	exec 1>&2
	printf 'KRoC version %s targeting %s (driver V%s)\n' "$package_version" "$target_canonical" "$dversion"

	if [ $verbose ]; then
		showversion=yes
	fi
	if [ $showversion ]; then
		cat $kroc_krocdir/doc/txt/AUTHORS
		exit 0
	fi

	exec 1>&2
	printf 'Usage: %s [options] [occam sources/pre-compiled sources]\n' "$progname"
	cat << EOF
Options:
  -b,  --brief           Give brief occ21 error messages
  -c,  --compile         Compile source to objects, do not link
  -s,  --strict          Strict checking mode
EOF
	if [ $default_errormode_stop -eq 1 ]; then
		printf '  -H,  --halterror       Compile in HALT error mode\n'
	else
		printf '  -S,  --stoperror       Compile in STOP error mode\n'
	fi
	cat << EOF
  -d                     Enable post-mortem debugging
  -di                    Enable insert debugging
  -e                     Enable user-defined channels
  -h,  --help            Print this message and exit
  -IDIRECTORY            Search DIRECTORY for occam libs & includes, C headers
  -k,  --keep-temp       Keep temporary files
  -V,  --version         Print version
  -l,  --library         Generate .so shared library (for dynamically loaded processes)
  -lNAME                 Link with native library libNAME.a / libNAME.so
  -LDIRECTORY            Search DIRECTORY for native libraries
  -n,  --dry-run         Do not run any commands; just print them.
       --oc-opts=opts    Use these occam compiler ($occ21) options
       --oc-opts opts      \"\"
       --cc-opts=opts    Use these C compiler ($cc) options
       --cc-opts opts      \"\"
  -nw, --no-warn         Give no warnings from $occ21
  -nd, --no-dynmem       Disable dynamic memory support
  -oFILE, -o FILE        Place output in file FILE
  -p,  --pre-compile     Pre-compile occam source to .tce files
  -P   --pause           Event/schedule check at loop-ends and backward jumps
  -io, --inline-io       Inline input/output kernel calls
  -is, --inline-sched    Inline parts of the scheduler
  -it, --inline-ldtimer  Inline load-timer instruction
  -v,  --verbose         Show commands run during compilation
  -w,  --warn            Additional warnings from $occ21
  -z,  --all-help        Show additional options
       --nfw             Do not wait for globally FORKed processes
       --new             Do not wait for blocking syscalls
  -X6                    Extended input for unhandled CASE inputs (experimental)
EOF
	if [ $showall -eq 1 ]; then
	cat << EOF
Exclusive options:
  --cc                   Print compiler for use with external C code
  --cflags               Print compiler flags for use with external C code
  --tran                 Print translator for .etc binaries
  --tranflags            Print translator flags
  --libpath              Print path to occam libraries
  --incpath              Print path to occam include files
  --cclibpath            Print path to occam libraries in CC -L.. form
  --ccincpath            Print path to occam include files in CC -I.. form
  --ld                   Print path to dynamic linker (for generating shared libraries)
  --ldflags              Print linker flags to be used when building shared libraries
  --krocdir              Print path to kroc data files
  --autovars             Print variables for autoconf
Additional options:
  -dm                    Enable dynamic memory debugging
  -ds                    Enable memory usage summary
  -dt                    Enable debugging traces
  -t2, -t4, -t8, -t9     Set processor compilation class (default $proc_class)
  -O   --optimise        Enable optimisations [now default]
       --rmox            Compile for RMoX
       --force-tlp       Force top-level PROC interface to (CHAN BYTE kyb?, scr!, err!)
  --ncl                  Do not link in default compiler libraries
  --xml                  Generate XML tree
  --nocc                 Use NOCC compiler (experimental)
  --linkcc <prog>        Use <prog> to link instead of $cc
  --static               Link to static binary
EOF
	if [ $use_occ21_revalt -eq 1 ]; then
		printf '       --no-revalt       Do not use reversed ALT disabling sequence (default enabled)\n'
	else
		printf '       --use-revalt      Use reversed ALT disabling sequence (default disabled)\n'
	fi
	if [ $use_occ21_zen -eq 1 ]; then
		printf '       --no-zen          Do not use enhanced ALT enabling (default enabled)\n'
	else
		printf '       --use-zen         Use enhanced ALT enabling (default disabled)\n'
	fi
	if [ $use_occ21_zep -eq 1 ]; then
		printf '       --no-zep          Do not use ALT pre-enabling (default enabled)\n'
	else
		printf '       --use-zep         Use ALT pre-enabling (default disabled)\n'
	fi
	if [ $default_errormode_stop -eq 1 ]; then
		printf '  -S,  --stoperror       Compile in STOP error mode (default)\n'
	else
		printf '  -H,  --halterror       Compile in HALT error mode (default)\n'
	fi
	fi
	exit 0
fi

#{{{ parse_pragmas
# Search an ETC file for #PRAGMA COMMENT ..." directives.
parse_pragmas () {
	local tcefile="$1" libs lib opt add opts

	# For .USELIB directives, add the library to the list if it's not
	# already been used.
	libs=$($octran -C "$tcefile" | awk '/^\.USELIB / { ORS=" "; print $2 }')
	for lib in $libs; do
		opt="-loccam_$lib"

		add=1
		for used in $deplibs; do
			if [ "$used" = "$opt" ] ; then
				add=0
			fi
		done
		if [ "$add" = "1" ] ; then
			if [ "$verbose" ] ; then
				printf '%s: Using library %s\n' "$progname" "$lib" 1>&2
			fi
			deplibs="$deplibs $opt"
		fi
	done

	# For .LDFLAGS directives, add the flags to the CC options.
	opts=$($octran -C "$tcefile" | awk '/^\.LDFLAGS / { ORS=" "; for (i = 2; i <= NF; i++) { print $i } }')
	if [ "$verbose" -a "$opts" != "" ] ; then
		printf '%s: Using extra linker options %s\n' "$progname" "$opts" 1>&2
	fi
	extraccopts="$extraccopts $opts"
}
#}}}

objs=
tmp_objs=
efile=
for src in $srcs; do
	origsrc=$src
	suffix=$(printf '%s' "$src" | $SED -e 's/^.*\.\(.*\)$/\1/')

	# Handle file. (no suffix)
	if [ "X$suffix" = "X"  ]; then
		nsrc="${src}occ"
		if [ -r $nsrc ]; then
			printf '%s: Assuming you meant to compile %s\n' "$progname" "$nsrc" 1>&2
			src=$nsrc
			suffix=occ
		else
			printf '%s: Ignoring %s (no %s found)\n' "$progname" "$src" "$nsrc" 1>&2
			continue
		fi
	elif [ "$suffix" = "$src" ]; then		# Handle file (no . at all)
		if [ -r "$src.occ" ]; then
			printf '%s: Assuming you meant to compile %s.occ\n' "$progname" "$src" 1>&2
			suffix=occ
		else
			printf '%s: Ignoring %s (no %s.occ found)\n' "$progname" "$src" "$src" 1>&2
			continue
		fi
	fi

	dir=$(printf '%s' "$src" | $SED -e 's%[^/][^/]*$%%')
	if [ "X$dir" = "X$src" ]; then
		dir=
	else
		src=$(printf '%s' "$src" | $SED -e 's%^.*/%%')
	fi

	base=$(printf '%s' "$src" | $SED -e 's/\.[^\.]*$//')

	# Pick output name, either from -o name if given or basename of name
	if [ "X$link" != "X" -a "X$efile" = "X" ]; then
		if [ "X$outfile" = "X" ]; then
			efile=$base
		else
			efile=$outfile
			outfile=
		fi
	elif [ "X$link" = "X" -a "X$rmoxlink" != "X" -a "X$efile" = "X" ]; then
		if [ "X$outfile" = "X" ]; then
			efile="$base.$rmoxlink"
		else
			efile=$outfile
			outfile=
		fi
	fi

	# if the file does not exist, abort
	if [ ! -f $dir$base.$suffix ]; then
		printf '%s: cannot find file %s\n' "$progname" "$dir$base.$suffix" 1>&2
		exit 1
	fi

	if [ $debugkroc -eq 1 ]; then
		printf '    origsrc = %s\n' "$origsrc"
		printf '    src = %s\n' "$src"
		printf '    dir = %s\n' "$dir"
		printf '    base = %s\n' "$base"
		printf '    suffix = %s\n' "$suffix"
		printf '    efile = %s\n' "$efile"
		printf '    outfile = %s\n' "$outfile"
	fi


	# Using pre-compiled file?   FIXME: Handle this better
	if [ $suffix = "etc" ] || [ $suffix = "kt2" ] || [ $suffix = "kt4" ] || [ $suffix = "kt8" ] || [ $suffix = "kt9" ]; then
		compile=
		tfile="$dir$base.$suffix"
		tcefile="$dir$base.tce"

		if [ ! -r $tfile ]; then
			printf '%s: Cannot find pre-compiled file %s\n' "$progname" "$tfile" 1>&2
			exit 1;
		fi
		if [ ! -r $tcefile ]; then
			printf '%s: Cannot find pre-compiled TCE file %s\n' "$progname" "$tcefile" 1>&2
			exit 1;
		fi
	fi

	if [ $suffix != "occ" ] && [ $suffix != "co" ] && [ $suffix != "mcsp" ] && [ "X$compile" != "X" ]; then
		objs="$objs $origsrc"

		if [ "$suffix" = "o" ] ; then
			# Look for a corresponding .tce/.etc file.
			for tcesuffix in .tce .etc; do
				tcefile="$base$tcesuffix"
				if [ -e "$tcefile" ] ; then
					parse_pragmas "$tcefile"
				fi
			done
		fi

		continue
	fi

	if [ $suffix = "co" ]; then
		src="$dir$base.co"
	elif [ $suffix = "mcsp" ]; then
		src="$dir$base.mcsp"
	else
		src="$dir$base.occ"
	fi


	if [ ! -r $src ]; then
		printf '%s: Cannot find occam source file %s\n' "$progname" "$src" 1>&2
		exit 1
	fi

	if [ $link ]; then
		if [ $efile = $src ]; then
			efile="$efile.out";
			printf '%s: Compiling %s to %s\n' "$progname" "$src" "$efile" 1>&2
		fi
	fi

	tmpfiles=

	# .ktX files and TCO (and ETC) files
	if [ $compile ]; then
		if [ $usenocc ]; then
			tcefile="$base.etc"
			tsuffix="etc"
		else
			tcefile="$base.tce"
		fi
		if [ "X$translate" != "X" -a "X$outfile" != "X" ]; then
			tfile=$outfile
		else
			tfile="$base.$tsuffix"
		fi
		tmpfiles="$tmpfiles $tcefile $tfile"
	fi

	# Native assembler file
	sfile="$base.s"
	tmpfiles="$tmpfiles $sfile"

	# Native object file
	if [ "X$link" != "X" -a "X$outfile" != "X" ]; then
		ofile=$outfile
	else
		ofile="$base.o"
	fi
	tmpfiles="$tmpfiles $ofile"

	if [ $delete_temp ]; then
		trap "rm -f $tmpfiles" 1 2 3 9 15
	fi

	ISEARCH=$ocsearch; export ISEARCH
	if [ $verbose ]; then
		printf '%s: Search path for native libraries:\n' "$progname" 1>&2
		printf '  %s\n' "$oclibpath" | $SED -e 's:-L::g' 1>&2
		printf '%s: Search path for occam libraries and includes:\n' "$progname" 1>&2
		printf '  %s\n' "$ocsearch" 1>&2
	fi


	if [ $compile ]; then
		if [ $dorun ]; then
			rm -f $tfile #$tcefile
		fi

		if [ $usenocc ]; then
			cmd="$nocc $noccopts $src -o $tfile"
		else
			cmd="$occ21 $occopts $occwopts $src -o $tfile"
			if [ $dumpxml ]; then
				xmlfile=$base.xml
				cmd="$cmd -ztx -xf $xmlfile"
			fi
		fi

		if [ $verbose ]; then
			printf '%s\n' "$cmd" 1>&2
		fi
		if [ $dorun ]; then
			$cmd
			if [ $? -ne 0 ]; then
				if [ $usenocc ]; then
					printf '%s: %s failed to compile %s to %s\n' "$progname" "$nocc" "$src" "$tfile" 1>&2
				else
					printf '%s: %s failed to compile %s to %s\n' "$progname" "$occ21" "$src" "$tfile" 1>&2
				fi
				exit 1;
			fi
			if [ $link ]; then
				if [ $delete_temp ]; then
					tmp_objs="$tmp_objs $tfile $tcefile"
				fi
			fi
		fi
	fi


	if [ $translate ]; then
		if [ $dorun ]; then
			rm -f $ofile
		fi

		cmd="$octran $octranopts $tfile" # $sfile"
		if [ $verbose ]; then
			printf '%s\n' "$cmd" 1>&2
		fi
		if [ $dorun ]; then
			$cmd
			if [ $? -ne 0 ]; then
				printf '%s: %s failed to translate %s to %s\n' "$progname" "$octran" "$tfile" "$ofile" 1>&2
				exit 1;
			fi
		fi

		# don't assemble anymore -- tranx86 dumps .o files
#		if [ $dorun ]; then
#			rm -f $ofile
#		fi

#		cmd="$as $asflags $sfile -o $ofile"
#		if [ $verbose ]; then
#			echo $cmd 1>&2
#		fi
#		if [ $dorun ]; then
#			$cmd
#			if [ $? -ne 0 ]; then
#				echo "$progname: $as failed to assemble $sfile to $ofile ($?)" 1>&2
#				exit 1;
#			fi
#		fi
		objs="$objs $ofile"
		tmp_objs="$tmp_objs $ofile"

		if [ $dorun ]; then
			if [ $delete_temp ]; then
				rm -f $sfile
			fi
		fi
	fi

	parse_pragmas "$tcefile"

done

#{{{  add deplibs to ocllibs
# We have to add the libraries in reverse order to get the link order right on
# platforms that care about that (such as Cygwin).
for lib in $deplibs; do
	ocllibs="$lib $ocllibs"
done
#}}}

if [ $defaultlibraries -eq 1 ]; then
	ocllibs="$ocllibs -loccam_forall"
fi

if [ "X$link" = "X" ] && [ "X$rmoxlink" = "X" ]; then
	exit 0
fi

if [ "X$efile" = "X" ]; then
	printf '%s: No output executable file name found (and no -oname)\n' "$progname" 1>&2
	exit 1
fi

if [ $dorun ]; then
	rm -f $efile
fi

if [ $makelib ]; then
	efile=$efile$libext
	cmd="$cc $ccopts $oclibpath $ocrtslibs $ocllibs $ocrts $extraccopts $ARCH_LDFLAGS $ldopts -o $efile $objs"
elif [ $skip_link ]; then
	test
elif [ "X$rmoxlink" != "X" ]; then
	cmd="$ld -o $efile -r $objs"
else
	if [ $linkstatic -eq 1 ]; then
		# need to add in pthread library if we're using that
		USEPTHREAD=0
		printf '%s\n' "$extcflags" | grep KROC_USES_PTHREADS > /dev/null && USEPTHREAD=1

		if [ $USEPTHREAD -eq 1 ]; then
			cmd="$cc $ccopts $objs $oclibpath $cincludepath $ocllibs $ocrts $ocrtslibs $extraccopts -static -o $efile -lpthread"
		else
			cmd="$cc $ccopts $objs $oclibpath $cincludepath $ocllibs $ocrts $ocrtslibs $extraccopts -static -o $efile"
		fi
	else
		cmd="$cc $ccopts $objs $oclibpath $cincludepath $ocllibs $ocrts $ocrtslibs $extraccopts -o $efile"
	fi
fi
if [ $verbose ]; then
	printf '%s\n' "$cmd"  1>&2
fi
if [ $dorun ]; then
	$cmd
	if [ $? -ne 0 ]; then
		printf '%s: %s failed to link %s\n' "$progname" "$cc" "$efile" 1>&2
		exit 1;
	else
		if [ "$rmoxlink" = "app" ]; then
			chmod +x $efile
		fi
	fi
fi
if [ $delete_temp ]; then
	if [ "X$tmp_objs" != "X" ]; then
		rm -f $tmp_objs
	fi
fi

exit 0

