#! /bin/bash
#
# (C) Copyright IBM Corp. 2001, 2002, 2003
#
# $Id: runrvm,v 1.19 2004/05/28 21:20:21 augart-oss Exp $
#
# Invoke the Jikes RVM virtual machine that "jbuild" created.
# See also: $RVM_ROOT/rvm/bin/jconfigure -help

# This file, 'runrvm', is the old (as of Sept. 2002) 'rvm' script,
# except the variables are specified using parameters instead of
# environment variables.  'rvm' passes parameters to 'runrvm', using
# values defined by environment variables.

# 'runrvm' must be an executable program; 
# the Eclipse Jikes RVM Launcher Plugin expects this.

# @author Jeffrey Palm
# @date 25 Jun 2002
#
# @author Derek Lieber
# @date 04 Feb 2000
#
# @modified Peter Sweeney
# @date 15 Jan 2001 
#    eliminate dependence on option order.
#
# @modified Steven Augart
# @date 2003 Jun 01
#    Converted from "ksh" to Bash
#

# Sanity checks
# What is our name?
# Bash internal shorthand that works like the "basename" command.
ME="${0##*/}"

function usage() {
    local exitstatus=${1-"1"};
    shift;
    # If exit status is non-zero, redirect to stderr.
    (( $1 != 0 )) && exec >&2
    [ "$*" ] && echo "$@"
    echo "Usage: $ME <home> <rvm_root> <rvm_build> [<options>...]";
    exit $exitstatus;
}

function croak_nonusage () {
    # Display the error message.  If it's a multi-line error message, indent
    # the second and subsequent lines by a few spaces.  
    # Try to auto-wrap the message if we have GNU Fold.

    local gnufold="/usr/bin/fold --width=65 --spaces"
    $gnufold < /dev/null &> /dev/null || gnufold=cat

    echo "${ME}: $*" | $gnufold | sed -e '2,$s/^/     /' >&2
    trap '' EXIT
    exit 1
}


# Just to be sure we're being run properly.
(( $# < 3 )) && usage 1 "Too few arguments.  This program is designed to be run indirectly by the 'rvm' command."
    

## These have already been err-checked for us by "rvm".
home="$1";      shift;  # Used to be $HOME
rvm_root="$1";  shift;  # Used to be $RVM_ROOT
rvm_build="$1"; shift;  # Used to be $RVM_BUILD


# TODO: This portion of the runrvm program should be consolidated with
# the originally-identical part of the gdbrvm program.

## If you change anything below this point, you probably want to 
## change gdbrvm as well.

# Load up where the RVM bootimage, booter, and runtime support files reside:
env="$rvm_build/environment.target"
[[ -f $env ]] || croak_nonusage "There is no file named \"$env\"; have you set RVM_BUILD to a Jikes RVM build directory that was initialized by \"jconfigure\"?"
[[ -r $env ]] || croak_nonusage "The file \"$env\" doesn't allow me to read it; some sort of permissions problem?"
. $env
unset env

# The arguments we'll invoke $rvm_build/JikesRVM.  We
# will put these before any user-specified arguments, so that any flags
# that the user may have explicitly specified will override our defaults.

declare -a sys_args
sys_args=("-X:i=$rvm_build/RVM.image" \
		"-X:vmClasses=$rvm_build/RVM.classes/jksvm.jar:$rvm_build/RVM.classes/rvmrt.jar" \
		"-Duser.timezone=$(date +%Z)"				\
		"-Drvm.root=$rvm_root"					\
		"-Drvm.build=$rvm_build"				\
		"-Djava.home=$rvm_root"					\
		"-Dgnu.classpath.home.url=file:${rvm_build}"		\
		"-Dgnu.classpath.vm.shortname=JikesRVM"			\
		"-Duser.home=$home" "-Duser.dir=$(pwd)"			\
		"-Duser.name=$(whoami)"					\
		"-Dos.name=$(uname -s)" "-Dos.version=$(uname -r)"	\
		"-Dos.arch=$(uname -m)"					\
 )

## This implementation is dependent upon subsequent uses of -cp and -classpath
## overriding previous uses.  This allows us to maintain the semantics that
## the CLASSPATH envar is overridden by any user-specified arguments.
declare -a classpath_args

if [[ ${CLASSPATH-UNSET} = UNSET ]]; then
    classpath_arg=();
else
    classpath_arg=('-classpath' "${CLASSPATH}");
fi

## The arguments the user specified.  These must come last.   If the
## user explicitly specified a -classpath argument, it will override
## ${classpath_arg[@]}
#
# Note: Writing it like this commented-out line below will break!  Must not
# incorporate the assignment into the declare, at least under Bash 2.05b.
#
#declare -a user_args=("$@")
#
declare -a user_args
user_args=("$@")



# Now execute the VM
prog="$rvm_build/JikesRVM"
[[ -f $prog ]] || croak_nonusage "Cannot find a file named \"$prog\"; have you set RVM_BUILD to a Jikes RVM build directory that contains a successfully-completed build?"
[[ -x $prog ]] || croak_nonusage "Cannot execute the file named \"$prog\"; some sort of permissions problem.  Something weird is happening.  Maybe somebody with a highly restrictive \"umask\" compiled Jikes RVM?"

## "shopt -s execfail" is needed so that we can print a better error
## message if we fail to execute the JikesRVM executable.  Otherwise,
## in case of a file format incompatibility (trying to exec an AIX
## binary on Linux, for example) we get the potentially misleading message:
##
## /home/augart/JikesRVM/Clean//rvm/bin/runrvm: /home/augart/JikesRVM/Clean//Build.AIX.EABBCM/JikesRVM: cannot execute binary file
## /home/augart/JikesRVM/Clean//rvm/bin/runrvm: /home/augart/JikesRVM/Clean//Build.AIX.EABBCM/JikesRVM: Success
## Now we can at least append a message saying "FAIL" after the
## misleading message.
shopt -s execfail

declare -r syswrap="${rvm_build}/libsyswrap.so"
if [[ -f ${syswrap} ]]; then
    ## Turn on libsyswrap, which is to say, make sure that we will properly
    ## intercept the select() call.
    LD_PRELOAD="${syswrap}" exec "$prog" "${sys_args[@]}" "${classpath_arg[@]}" "${user_args[@]}"
else
    exec "$prog" "${sys_args[@]}" "${classpath_arg[@]}" "${user_args[@]}"
fi
declare -r -i status=$?
echo >&2  "$ME: Failed to execute $prog; can't run Jikes RVM"
exit $status
