#!/bin/sh
#
CPLUSPLUS="g++"
CC_OPTIONS=" -DSTDC_HEADERS=1 -DRETSIGTYPE=void -DHAVE_ALLOCA_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DTIMEVAL_HAS_USEC=1 -DHAVE_POPEN=1 -DHAVE_RUSAGE=1 -I. -I./t -O2 -Wall -Wno-unused -Wuninitialized"
BINDIR=/mnt/finsun/wrk/pjanhune/tela-1.12
INCLUDEDIR=/mnt/finsun/wrk/pjanhune/tela-1.12
VERSION="1.12"
WHEN_COMPILED="g++ on SunOS finsun 4.1.3_U1 12 sun4m, Tue Nov 15 15:44:32 EET 1994"
STD_CT_OBJECTS="std.o files.o plotmtv.o la.o fft.o dld.o fileio.o numerics.o    "
LIBRARIES="-lreadline -ltermcap /usr/local/lib/libdf.a  /mnt/finsun/fmi/geo/pjanhune/fftpack/libfftpack.a -llapack -lblas -L/usr/local/lang/SC2.0.1patch /usr/local/lang/SC2.0.1patch/values-Xs.o -lM77 -lF77 -lansi -static -lm "

# --This is a Bourne shell script, but it is not complete yet.
# --The Makefile inserts a few lines at the beginning, thus creating
# --'telakka' from this 'telakka.in'.
# --Specifically, the variables CPLUSPLUS, CC_OPTIONS, VERSION, WHEN_COMPILED,
# --STD_CT_OBJECTS, BINDIR, INCLUDEDIR and LIBRARIES must be defined.
#

nm_options=""

CTPP="$BINDIR/ctpp"
compileOnly=false
outputFileSpecified=false
outputFile=tela
echo=":"
VerboseMode=false
ccargs=""
tmpfiles=""
for o in $STD_CT_OBJECTS
do
	case ".$o" in
		./*) ccargs="$ccargs $o"
			 ;;
		.*) ccargs="$ccargs ${BINDIR}/$o"
			;;
	esac
done

cleanup() {	# remove temporary files
	for i in $tmpfiles
	do
		if [ -f $i ]
		then
			/bin/rm $i
		fi	
	done
	exit 1
}

trap 'cleanup' 1 2 3 9 15

usage() {
	echo 'Usage: telakka [-c] [-h] [-n] [-o file] [-v] [-V]'
	echo '       [--compile-only] [--help] [--nostandard]'
	echo '       [--output file] [--verbose] [--version]'
	echo '       [CFLAGS] [files]'
	echo 'is the TeLa Kernel Konstruction Accessory.'
	echo 'It compiles files and links them with appropriate libraries'
	echo 'to produce a new Tela executable kernel.'
	echo 'Options:'
	echo '-h, --help          display this message'
	echo '-c, --compile-only  compile only, do not link (see cc (1))'
	echo '-n, --nostandard    do not link "standard" libraries'
	echo '-o file, --output   specify output file; default "tela"'
	echo '-v, --verbose       verbose mode'
	echo '-V, --version       print version and exit'
	echo 'CFLAGS    any additional options for the C++ compiler'
	echo 'files     files ending with .ct, .o or .a.'
	exit
}


#
# Parse telakka's own options. Gather all other args in $scriptargs.
# Put all other args that start with '-' to $ccoptions, unless it
# starts with -l or -L (they are still put to $scriptargs also).
# ------------------------------------------------------------------
scriptargs=""
ccoptions=""
while [ $# -gt 0 ]
do
	i=$1
    case ".$i" in
		.-h|.-help|.--help)
			usage
			;;
		.-c|.--compile-only)
			compileOnly=true
			;;
		.-n|.--nostandard)
			ccargs=""
			;;
		.-v|.--verbose)
			echo="echo"
			VerboseMode=true
			;;
		.-V|.--version)
			echo "telakka the TeLa Kernel Konstruction Accessory, Version $VERSION."
			echo "For use with tela $VERSION compiled using $WHEN_COMPILED."
			exit
			;;
		.-o|.--output)
            if [ ".$2" = "." ] ; then
                echo "telakka: -o or --output option without filename"
                exit 1
            else
                outputFile=$2;
				outputFileSpecified=true
				shift
            fi
            ;;
		# did not recognize option, append to $scriptargs
		# also append to $ccoptions if appropriate
		.-l*|.-L*)	# -l, -L opts are not ccoptions but are treated as filenames
			scriptargs="$scriptargs $i"
			;;
		.-*)	# other thus far unrecognized opts are ccoptions
			scriptargs="$scriptargs $i"
			ccoptions="$ccoptions $i"
			;;
        .*)		# non-options are probably filenames
			scriptargs="$scriptargs $i"
            ;;
    esac
	shift
done

#
# Compile all .ct files
# ---------------------
for f in $scriptargs
do
	case "$f"
	in
	*.ct)
		base=`basename $f .ct`
		dir=`dirname $f`
		currdir=`pwd`;
		cd $dir
		$echo $CTPP ${base}.ct
		tmpfiles="$tmpfiles ${base}-.c"
		if $CTPP ${base}.ct; then :; else cleanup; fi
		cfile=${base}$$.c
		mv ${base}-.c $cfile
		tmpfiles="$tmpfiles $cfile"
		$echo $CPLUSPLUS -c -I${INCLUDEDIR} ${CC_OPTIONS} $ccoptions $cfile
		if $CPLUSPLUS -c -I${INCLUDEDIR} ${CC_OPTIONS} $ccoptions $cfile; then :; else cleanup; fi
		rm $cfile
		if [ "$outputFileSpecified" = "true" -a "$compileOnly" = "true" ]; then
			mv ${base}$$.o $currdir/$outputFile
		else
			mv ${base}$$.o $currdir/${base}.o
		fi
		cd $currdir
		;;
	*)	;;
	esac
done

if [ "$compileOnly" = "true" ]; then exit; fi

#
# Gather everything into $ccargs, except that .ct -> .o
# Also compute $surely_ctobjects.
# -----------------------------------------------------
surely_ctobjects=""
for f in $scriptargs
do
	case "$f"
	in
	*.ct)
		basef=`basename $f .ct`
		ccargs="$ccargs ${basef}.o"
		surely_ctobjects="$surely_ctobjects $basef"
		;;
	*)
		ccargs="$ccargs $f"
		;;
	esac
done

#
# Create and compile temporary static.C
# -------------------------------------
#   We must use nm to find out whether a given object file
#   contains the symbol fninfo_objfilename or not.
ctobjects=""
staticC=${TMPDIR:=/tmp}/static$$.C
tmpfiles="$tmpfiles $staticC"
echo '#include "ctinfo.H"' >$staticC
echo 'extern "C" {' >>$staticC
for obj in $ccargs
do
	case "$obj"
	in
	*.o)
		bareobj=`basename $obj .o`
		# Determine if $bareobj.o has been compiled from a .ct file or not.
		# Algorithm: 1) if it is in list $surely_ctobjects, it is.
		# 2) otherwise use nm to find out.
		# The nm test is slow, therefore we try to avoid it.
		isctobject=false
		for surely_ctobject in $surely_ctobjects
		do
			if [ "$bareobj" = "$surely_ctobject" ]; then
				isctobject=true
				break
			fi
		done
		if [ "$isctobject" = "false" ]; then
			if nm $nm_options $obj | grep fninfo_$bareobj >/dev/null; then
				isctobject=true
				if [ "$VerboseMode" = "true" ]; then echo "$obj is C-tela file"; fi
			else
				if [ "$VerboseMode" = "true" ]; then echo "$obj is not C-tela file"; fi
			fi
		fi
		if [ "$isctobject" = "true" ]; then
			echo "extern TCFunctionInfo fninfo_${bareobj}[];" >>$staticC;
			ctobjects="$ctobjects $bareobj"
		fi
		;;
	*) ;;
	esac
done
echo "}" >>$staticC
echo '#define INSTALL(name) Install(fninfo_##name,(const unsigned char*)#name)' >>$staticC
echo 'void InstallStatic() {' >>$staticC
for obj in $ctobjects
do
	echo "INSTALL(${obj});" >>$staticC
done
echo '}' >>$staticC
tmpfiles="$tmpfiles $TMPDIR/static$$.o"
(cd $TMPDIR; $CPLUSPLUS -c -I${INCLUDEDIR} ${CC_OPTIONS} $ccoptions static$$.C)
rm $staticC

#
# Finally link everything together
# --------------------------------
$echo $CPLUSPLUS -o $outputFile $BINDIR/libtela.a $TMPDIR/static$$.o $ccargs $LIBRARIES
$CPLUSPLUS -o $outputFile $BINDIR/libtela.a $TMPDIR/static$$.o $ccargs $LIBRARIES

rm $TMPDIR/static$$.o

