#! /bin/sh
## 
## Time-stamp: <1998-03-01 15:14:55 szi>
## 
#H Run Scheme - a wrapper to the command line interfaces of different
#H Scheme systems.
#H 
## The command line options of this script are based on Guile's
## command line options.
##
#H Usage: run-scheme [options] <file> [args]
#H 
#H Scheme options:
#H   -s, --script <file>        load <file> and exit
#H   -e, --eval   <expression>  evaluate <expression> and exit
#H   --                         stop scanning arguments
#H   The above switches stop argument processing.
#H 
#H       --use-slib             enable Jaffer's Scheme library
#H       --use-scheme-type      define the following functions:
#H                                scheme-implementation-type,
#H                                scheme-implementation-version,
#H                                scheme-implementation-executable
#H 
#H Wrapper options:
#H   -p, --prefer <system>      prefered system: guile, scm
#H   -q, --quiet                do not print found Scheme system
#H 
#H   -h, --help                 show this help
#H   -v, --version              display version of this wrapper
## 
#V Version: 0.0.1
## 
## Copyright (c) 1998 Sascha Ziemann
## 
## Send comments to szi@aibon.ping.de
##

#set -v
#set -x
#DEBUG=1


# tools we need

ECHO="echo"
GREP="grep"
SED="sed"
TEST="test"
WHICH="which"

# defaults

SEARCH_ORDER="guile scm"
SCHEME_SYS="none"
SCHEME_EXE="/bin/false"
SCHEME_VER="unknown"
USE_SLIB="false"
USE_TYPE="false"
PREFERED="none"
QUIET="false"
ACTION="none"

# search functions

search_guile() {
    SCHEME_SYS="guile"
    SCHEME_EXE=$($WHICH $SCHEME_SYS)
    if $TEST -x $SCHEME_EXE ; then
        SCHEME_VER=$($SCHEME_EXE -c "(display (version))")
    else
	SCHEME_SYS="none"
    fi
}

search_scm() {
    SCHEME_SYS="scm"
    SCHEME_EXE=$($WHICH $SCHEME_SYS)
    if $TEST -x $SCHEME_EXE ; then
        SCHEME_VER=$($SCHEME_EXE -c "(display (scheme-implementation-version))")
    else
	SCHEME_SYS="none"
    fi
}

# search_siod() {
#     SCHEME_SYS="siod"
#     if SCHEME_EXE=$($WHICH $SCHEME_SYS) && $TEST -x $SCHEME_EXE ; then
# 	SCHEME_VER=$($SCHEME_EXE < /dev/null | $GREP SIOD | $SED -e 's/^.*Version //' | $SED -e 's/ [0-9][0-9]*\-[A-Z][A-Z][A-Z]-[0-9][0-9]$//')
#     else
# 	SCHEME_SYS="none"
#     fi
# }

# other tools

display_help() {
    $GREP ^\#H $0 | sed -e 's/^\#..//'
}

display_version() {
    echo -n "$0: "
    $GREP ^\#V $0 | sed -e 's/^\#..//'
}

# read arguments

prev=
stop=

while test $# -gt 0
do
    arg="$1"

    case "$arg" in
	--help | -h)
	    display_help
	    exit 0
	    ;;
	--version | -v)
	    display_version
	    exit 0
	    ;;
	--prefered | -p)
	    prev="PREFERED"
	    ;;
	--quiet | -q)
	    QUIET="true"
	    ;;
	--script | -s)
	    if test "$ACTION" = "none" ; then
		ACTION="script"
		prev="SCRIPT"
		stop=true
	    else
		echo "Fatal Error: Can not perform two actions!"
		exit 1
	    fi
	    ;;
	--eval | -e)
	    if test "$ACTION" = "none" ; then
		ACTION="eval"
		prev="EVAL"
		stop=true
	    else
		echo "Fatal Error: Can not perform two actions!"
		exit 1
	    fi
	    ;;
	--use-slib)
	    USE_SLIB="true"
	    ;;
	--use-scheme-type)
	    USE_TYPE="true"
	    ;;
	--)
	    shift
	    break;
	    ;;
	*)	
	    if test -z "$prev" ; then
		break;
	    else
		eval "$prev=\$arg"
		prev=
		if test "$stop" = "true" ; then
		    shift
		    break;
		fi
	    fi
	    ;;
    esac

    shift
done

# check prefered

if test "$PREFERED" != "none" ; then
    case $PREFERED in
	guile) search_guile ;;
	scm) search_scm ;;
#	siod) search_siod ;;
	*) echo "Error: Unknown Scheme system: \"$PREFERED\"" ;;
    esac
fi

# check rest

if test "$SCHEME_SYS" = "none" ; then
    for s in $SEARCH_ORDER ; do
	if test "$PREFERED" != "$s" ; then
	    search_$s
	    if test "$SCHEME_SYS" != "none" ; then
		break
	    fi
	fi
    done
fi

# report

if test "$QUIET" = "false" ; then
    if test "$SCHEME_SYS" = "none" ; then
	echo "Can not find any known Scheme system!"
    else
	echo "Using \"$SCHEME_SYS\" version \"$SCHEME_VER\":"
    fi
fi

# perform action

case "$SCHEME_SYS" in
    guile)
	if test "$USE_SLIB" = "true" ; then
	    SLIB="(use-modules (ice-9 slib))"
	else
	    SLIB=
	fi
	if test "$USE_TYPE" = "true" ; then
	    VARS="(define (scheme-implementation-type) 'Guile) (define scheme-implementation-version version) (define (scheme-implementation-executable) \"$SCHEME_EXE\")"
	else
	    VARS=
	fi
	case "$ACTION" in
	    script)
		scm=`$ECHO $VARS $SLIB | $SED -e 's/\"/\\\"/g'`
		if test -n "$scm" ; then
		    cmd="$SCHEME_EXE -c \"$scm\" -s $SCRIPT -- $*"
		else
		    cmd="$SCHEME_EXE -s $SCRIPT -- $*"
		fi
		if test -n "$DEBUG" ; then
		    echo "$cmd"
		fi
		eval "$cmd"
		;;
	    eval)
		scm=`$ECHO $VARS $SLIB $EVAL | $SED -e 's/\"/\\\"/g'`
		cmd="$SCHEME_EXE -c \"$scm\" -- $*"
		if test -n "$DEBUG" ; then
		    echo "$cmd"
		fi
		eval "$cmd"
		;;
	    *)
		echo "Fatal Error: Unknown action: $ACTION!"
		exit 1
		;;
	esac
	;;
    scm)
	if test "$USE_TYPE" = "true" ; then
	    VARS="(define (scheme-implementation-executable) \"$SCHEME_EXE\")"
	else
	    VARS=
	fi
	case "$ACTION" in
	    script)
		scm=`$ECHO $VARS | $SED -e 's/\"/\\\"/g'`
		if test -n "$scm" ; then
		    cmd="$SCHEME_EXE -e \"$scm\" -l $SCRIPT -- $*"
		else
		    cmd="$SCHEME_EXE -l $SCRIPT -- $*"
		fi
		if test -n "$DEBUG" ; then
		    echo "$cmd"
		fi
		eval "$cmd"
		;;
	    eval)
		scm=`$ECHO $VARS $EVAL | $SED -e 's/\"/\\\"/g'`
		cmd="$SCHEME_EXE -e \"$scm\" -- $*"
		if test -n "$DEBUG" ; then
		    echo "$cmd"
		fi
		eval "$cmd"
		;;
	    *)
		echo "Fatal Error: Unknown action: $ACTION!"
		exit 1
		;;
	esac
	;;
#     siod)
# 	case "$ACTION" in
# 	    script)
# 		echo "don't know"
# 		;;
# 	    eval)
# 		echo "don't know"
# 		;;
# 	    *)
# 		echo "Fatal Error: Unknown action: $ACTION!"
# 		exit 1
# 		;;
# 	esac
# 	;;
    *)
	echo "Fatal Error: Unknown Scheme system $SCHEME_SYS!"
	exit 1
	;;
esac

		
    
    