#!/bin/sh
#
#   STAR-CCM+
#   Unix platform run script
#
#   Copyright 2000-2010 CD-adapco. All Rights Reserved
#

# If you update this documentation you should also update the windows
# version in bin/win32/starccm/starccm.cpp

usage () {
cat << \EOF

Usage: starccm+ [-server] [<options> ...] [<simfile>]

Where:
  -server                # Starts the STAR-CCM+ server. The default is to start the STAR-CCM+ client.

General options:
  -info                  # Prints information about the simulation file.
  -ini <file>            # Specify an .ini file to provide default starccm+ arguments.
  -loc                   # Prevent the server locator from starting.
  -new                   # Create a new simulation. If a simulation file is named and does not exist, it is created.
  -v, -vv, -vvv          # Verbose mode. Prints environment changes and subcommands. 
  -version               # Print the version information and exit.
  -use-path-env          # Use PATH environment variable to locate starccm+ scripts.
  <simfile>              # Use the supplied simulation file (eg. star.sim).

License options:
  -lite                  # Use Lite Session license (reduced functionality).
  -nosuite               # Do not check out <name>suite licenses for additional nodes.
  -power                 # Use Power Session license option.
  -podkey  <value>       # Specify a PoD license key
  -licpath <path:...>    # Specify a license path that overrides the default license path
  -license <lic1,...>    # Specify which custom licenses to reserve when a simulation is created/restored
  -noreserve             # Specify that no custom licenses will be reserved when a  simulation is created/restored
  -noretry               # Specify that we will not retry required licenses
  
Client options:
  -batch [<file>]        # Run in batch mode (no UI), play the Java macro file if specified.
  -batch-report          # Write a summary report of system usage of a batch run.
  -classpath <cp>        # Specify batch classpath.
  -config <name>         # Use a previously saved machine configuration.
  -save-config <name>    # Save the specified machine configuration.
  -fontsize <size>       # Override default ui font size.
  -host <host>[:port]    # Server host (and optional port) to join existing session.
  -port <port>           # Server port to join existing session.
  -locale <locale>       # Override default locale (en:US, ja, ru:RU).
  -m[acro] <file>        # Runs macro file upon client startup.
  -noexit                # Do not shutdown server after batch file execution.
  -reset                 # Restore default client layout and settings.
  -time                  # Print server elapsed and cpu times on exit.
  -userdir <name>        # Append name to default client settings directory.
  -nbuserdir <name>      # Specify client settings directory.

Visualization options:
  -mesa                  # Force graphics mode to use software rendering library.
  -hardwarebatch         # Force graphics mode to use hardware rendering library in batch.

Server options:
  -collab                # Enable collaboration (allow other users to connect to server).
  -load                  # Load simulation file without waiting for a client to connect.
  -pio                   # use parallel I/O to load simulation file.
  -port <port>           # Specify server port to open.
  -portrange <range>     # Specify the number of ports the server can attempt to bind to.
  -rsh <rsh command>     # Specify the remote shell command to use (default rsh).
  -ldlibpath <path:...>  # Add directories to the server LD_LIBRARY_PATH.

Parallel options:
  -batchsystem <batch system[:"options"]>
  -bs <batch system[:"options"]>
                         # Specify the batch management system under which STAR-CCM+ is being run.
  -hostregexpr <regexpr> # Use a regular expression to modify hostnames.
  -machinefile <file>    # Machine resource file name.
  -mpi <driver>          # Specify MPI driver to use.
  -mpiflags <options>    # MPI driver expert options.
  -mpitest[:<options>]   # Perform MPI tests and exit.
  -np <np>               # Specify the number of parallel processes.
  -on <host[:np][,...]>  # Hosts to run parallel processes on.
  -phelp[:<option>]      # Print additional help for specified option.

EOF

# Obsolete ?
#   -oncpu <CPU1,CPU2,CPU3,...,CPUN>  # Prescribe the CPUs that the processes be bound to. (SGI only)

# Developer options
#   -arch <arch>     # Specifies the architecture (linux, linux-x86_64)
#   -env <env>       # Specifies the compiler build environment (gnu4.3-g, intel11.1)
#   -cout            # cout messages to console rather than send to client 
#   -d <debugger>    # invoke <debugger> (e.g. gdb) by java
#   -deleteOnExit    # Free memory when server is shut down
#   -display <display>     # Set the display for server. Useful when using debuggers.
#   -ide             # run netbean ide version of client (hidden option)
#   -jdebug          # shorthand for 
# -jvmargs "-J-Dsun.awt.disablegrab=true -J-Xdebug -J-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8765"
#   -pidfile         # the serial server will write out a process file (hidden option)
#   -valgrind <feature>:<options>       
#                    # start server under control of valgrind.
#                    # The feature can be either callgrind or memcheck.


if [ $# -gt 0 ]; then
    echo_error "$*"
fi

exit 1
}

echo_error() {
    echo "Error: $1"
    shift
    for line do echo "       $line"; done
}

echo_info() {
    echo "Info: $1"
    shift
    for line do echo "      $line"; done
}

echo_warning() {
    echo "Warning: $1"
    shift
    for line do echo "         $line"; done
}

# Variables set:
# star_args		: passed to executable
# nodestarccmargs	: passed to recursive server script exec
# addto_java_server_cmd	: promoted directly to client's server command

process_arguments() {

    # initialize flags
    parallel=no
    exit_on_error=yes
    mppoptions=

    # process command line arguments
    while [ $# -gt 0 ]; do
    case $1 in

    -arch )
        # cannot set star_arch here because we need to know
        # if the arch was set on the cmd line when we construct
        # the server command for the client.
        [ $# -lt 2 ] && usage
        arch_opt="$2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	addto_java_server_cmd "$1 $2"
        shift
        ;;

    -collab)
        # enable collaboration (different user names can connect to server)
        star_args="$star_args -collab"
        nodestarccmargs="$nodestarccmargs -collab"
	addto_java_server_cmd "$1"
        collab=yes
        ;;

    -deleteOnExit)
        star_args="$star_args $1"
        nodestarccmargs="$nodestarccmargs $1"
	addto_java_server_cmd "$1"
        ;;

    -lite)
        # use Lite Session License (Reduced functionality)
        star_args="$star_args -lite"
        nodestarccmargs="$nodestarccmargs -lite"
	    addto_java_server_cmd "$1"
        lite=yes
        ;;
        
    -licpath)
        # override license path
        star_args="$star_args $1 $2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	    addto_java_server_cmd "$1 $2"
        licpath="$2"
        shift
        ;;
        
    -podkey)
        # set pod key
       	star_args="$star_args $1 $2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	    addto_java_server_cmd "$1 $2"
        podkey="$2"
        shift
        ;;
       
    -license)
        # Custom license to reserve on simulation startup
		star_args="$star_args $1 $2"
		nodestarccmargs="$nodestarccmargs $1 $2"
		addto_java_server_cmd "$1 $2"
		license="$2"
        shift
        ;;
      
   -nophysics)
        # use Mesh Session License (Reduced functionality)
        star_args="$star_args -nophysics"
        nodestarccmargs="$nodestarccmargs -nophysics"
    	addto_java_server_cmd "$1"
        nophysics=yes
        ;;
	
   -nosuite)
        # Do not check out <name>suite licenses for additional nodes
        star_args="$star_args -nosuite"
        nodestarccmargs="$nodestarccmargs -nosuite"
	    addto_java_server_cmd "$1"
        nosuite=yes
        ;;
        
	-noretry)
        # Do not retry custom licenses
        star_args="$star_args -noretry"
        nodestarccmargs="$nodestarccmargs -noretry"
	    addto_java_server_cmd "$1"
        noretry=yes
        ;;
        
	-noreserve)
        # Do not reserve custom licenses
        star_args="$star_args -noreserve"
        nodestarccmargs="$nodestarccmargs -noreserve"
	    addto_java_server_cmd "$1"
        noreserve=yes
        ;;

    -env | -c )
        [ $# -lt 2 ] && usage
        star_env="$2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	    addto_java_server_cmd "-env $2"
        shift
        ;;

    -heavyhead )
        echo_warning "The -heavyhead option is deprecated."
        ;;
    -lighthead )
        echo_error "The -lighthead option is deprecated."
        exit 1
        ;;

    -np)
        [ $# -lt 2 ] && usage
        np=$2
	# -np implies parallel
        parallel=yes
	addto_java_server_cmd "$1 $2"
        setup_parallel_args="$setup_parallel_args $1 $np"
        nodestarccmargs="$nodestarccmargs $1 $2"
        shift
        ;;

    -machinefile)
        [ $# -lt 2 ] && usage
        machinefile=$2
	addto_java_server_cmd "$1 $2"
        setup_parallel_args="$setup_parallel_args $1 $2"
        shift
        ;;

    -mpidriver | -mpidistrib | -mpi)
        [ $# -lt 2 ] && usage
        mpidistrib="$2"
        basempidistrib=`echo $2 | sed 's/:.*//'`
        # double comma is a special character string reserved by ccm+
        mppo=`echo $2 | sed -e 's/.[^:]*://' -e 's/"//g' -e 's/,,/ /g'`
        if [ "$mppo" != "$basempidistrib" ]; then
            [ -n "$mppoptions" ] && mppoptions="$mppoptions $mppo" || mppoptions="$mppo"
        fi
	addto_java_server_cmd "$1 $basempidistrib"
        shift
        ;;

    -mpiflags | -mppflags )
        [ $# -lt 2 ] && usage
        # double comma is a special character string reserved by ccm+
        mppo=`echo "$2" | sed -e 's/"//g' -e 's/,,/ /g'`
        [ -n "$mppoptions" ] && mppoptions="$mppoptions $mppo" || mppoptions="$mppo"
        shift
        ;;    
    
    -batchsystem | -bs )
        # specify the batch management system being used
        [ $# -lt 2 ] && usage
        parallel=yes
        basebatchsystem=`echo $2 | sed 's/:.*//'`
        # double comma is a special character string reserved by ccm+
        batchoptions=`echo $2 | sed -e 's/.[^:]*://' -e 's/"//g' -e 's/,,/ /g'`
        [ "$basebatchsystem" = "$batchoptions" ] && batchoptions=

	addto_java_server_cmd "$1 $basebatchsystem"
	[ -n "$batchoptions" ] && addto_java_server_cmd "-batchsystemoptions \"$batchoptions\""

        case $basebatchsystem in
        pbs|torque|lsf|sge|ll)
            # Batch Queueing System
            batchsystem="$2"
            ;;
        *)
            # Unknown Batch System
            usage "Unknown Batch Management System"
            ;;
        esac

        shift
        ;;

    -batchsystemoptions)
        # specify options specific to the batch system
        [ $# -lt 2 ] && usage
        batchoptions=`echo $2 | sed 's/"//g'`
        # double comma is a special character string reserved
        # by ccm+
        batchoptions=`echo $2 | sed -e 's/.[^:]*://' -e 's/"//g' -e 's/,,/ /g'`
	addto_java_server_cmd "$1 \"$batchoptions\""
        shift
        ;;   

    -benchmarkhelp*)
        echo "Warning unsupported option :  -benchmarkhelp"
        echo 
        main_args="$main_args $1"
        shift
        ;;

    -benchmark*)
        echo "Warning unsupported option :  -benchmark"
        echo 
        # implies benchmark
        benchmark=yes
	# set the client's 'main'
        batch_main="star.common.StarBenchmark"
        # double comma is a special character string reserved by ccm+
        bargs=`echo $1 | sed -e 's/.[^:]*://' -e 's/"//g' -e 's/,,/ /g'`
        [ "$1" = "$bargs" ] && bargs=
        for i in $bargs; do
            bench_args="$bench_args $i"
        done
        ;;    

    -mpitest*)
        # implies MPI test
        mpitest=yes
	# set the client's 'main'
        batch_main="star.common.StarMpiStressTest"
        # double comma is a special character string reserved by ccm+
        targs=`echo $1 | sed -e 's/.[^:]*://' -e 's/"//g' -e 's/,,/ /g'`
        [ "$1" = "$targs" ] && targs=
        for i in $targs; do
            mpitest_args="$mpitest_args $i"
        done
        ;;

    -hostinfo*)
        # implies benchmark
        benchmark=yes
	# set the client's 'main'
        batch_main="star.common.StarBenchmark"
        # instruct benchmark to simply gather system information
        bench_args="$bench_args -hostinfo"
        ;;
        
    -on)
        [ $# -lt 2 ] && usage
        on=$2
        # implies parallel by default
        parallel=yes
        setup_parallel_args="$setup_parallel_args $1 $2"
        nodestarccmargs="$nodestarccmargs $1 $2"
        shift
        ;;

    -oncpu)
        [ $# -lt 2 ] && usage
        oncpu=$2
	addto_java_server_cmd "$1 $2"
        setup_parallel_args="$setup_parallel_args $1 $2"
        shift
        ;;

    -power)
        # use powersuite license feature
        star_args="$star_args -power"
        nodestarccmargs="$nodestarccmargs -power"
	addto_java_server_cmd "$1"
        ;;

    -rsh)
        [ $# -lt 2 ] && usage
        rshcmd=`echo $2 | sed -e 's/,,/ /g' -e 's/"//g'`
        setup_parallel_args="$setup_parallel_args $1 \"$rshcmd\""
        nodestarccmargs="$nodestarccmargs $1 \"$rshcmd\""
	addto_java_server_cmd "$1 \"$rshcmd\""

	rshcmdbase=`echo $rshcmd | sed -e 's/"//g' -e 's/ .*//g'`
        if [ ! `dirname $rshcmdbase` = "." ]; then 
            if [ ! -r "$rshcmdbase" ]; then
                echo_error "Cannot find rsh command : $rshcmdbase"
                exit 1
            fi
        fi
        # do not pass ssh arguments into server at this time
        star_args="$star_args $1 $rshcmdbase"
        shift
        ;;

    -hostregexpr)
        [ $# -lt 2 ] && usage
        hostre="$2"
        setup_parallel_args="$setup_parallel_args $1 \"$2\""
	addto_java_server_cmd "$1 `echo $2 | sed 's,\\\$,\\\\\$,'`"
        shift
        ;;

    -fullysubscribe)
        echo_info "-fullysubscribe is deprecated and has been replaced by -populate pernode" \
                  "The option -fullysubscribe may be removed in the future." 
        populate="pernode"
        setup_parallel_args="$setup_parallel_args -populate $populate"
	addto_java_server_cmd "-populate $populate"
        ;;

    -populate)
        # specify how to populate the hosts with processes
        # given a machine file or batchsystem. The two options are
        #    roundrobin (default)
        #    pernode (fully populate a node before allocating to next node)
        [ $# -lt 2 ] && usage
        populate="$2"
        setup_parallel_args="$setup_parallel_args $1 $2"
	addto_java_server_cmd "$1 $2"
        shift
        ;;

    -pidfile)
        # this is a hidden option which requests the serial server to
        # write out a file listing it's PID and the hostname in it.
        # This file can subsequently be used to ensure the server process
        # has been killed.
        write_pidfile=yes
	addto_java_server_cmd "$1"
        ;;    

    -forcemesa | -mesa)
        forcemesa=yes
        nodestarccmargs="$nodestarccmargs $1"
        ;;

    -hardwarebatch)
        forcehardware=yes
        nodestarccmargs="$nodestarccmargs $1"
        ;;

    -nothreads)
        # do not start session locator thread
        nothreads=yes
        nodestarccmargs="$nodestarccmargs -nothreads"
        star_args="$star_args -nothreads"
	addto_java_server_cmd "$1"
        ;;

    -module)
        # dynamic load a library
        star_args="$star_args $1 $2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	addto_java_server_cmd "$1 $2"
        shift
        ;;

    -jvmargs)
        [ $# -lt 2 ] && usage
        addto_jvmargs "$2"
        shift
        ;;

    -jdebug)
        # short hand to enable java debugging support
        addto_jvmargs "-J-Dsun.awt.disablegrab=true -J-Xdebug -J-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8765"
        shift
        ;;

    -ldlibpath)
        [ $# -lt 2 ] && usage
        ldlibpath="$2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	addto_java_server_cmd "$1 $2"
        shift
        ;;

    -v | -verbose)
        verbose=yes
        setup_parallel_args="$setup_parallel_args -verbose"
        nodestarccmargs="$nodestarccmargs $1"
	addto_java_server_cmd "$1"
        ;;

    -version)
        echo_version
	exit
        ;;

    -pio)
        nodestarccmargs="$nodestarccmargs $1"
	    addto_java_server_cmd "$1"
        star_args="$star_args $1"
        ;;

    -procfile)
        # This is a private option only to be used
        # by recursive calls to starccm+
        [ $# -lt 2 ] && usage
        procfile="$2"
        star_args="$star_args $1 $2"
        nodestarccmargs="$nodestarccmargs $1 $2"
	addto_java_server_cmd "$1 $2"
        shift
        ;;

    -ini)
        [ $# -lt 2 ] && usage
	# picked directly out of args by process_inifile
        shift
        ;;

    -noini)
        nodestarccmargs="$nodestarccmargs $1"
	addto_java_server_cmd "$1"
	;;

    -valgrind*)   
        [ $# -lt 2 ] && usage
	valgrind=`echo $2 | sed 's/ /,,/g'`
        nodestarccmargs="$nodestarccmargs $1 $valgrind"
	# promote directly to client's server command
	addto_java_server_cmd "$1 $valgrind"
        shift
        ;;
      
    -memcheck)
        valgrind='memcheck'
        nodestarccmargs="$nodestarccmargs $1 $2"
	addto_java_server_cmd "-valgrind $valgrind"
        ;;

    -profile)
        valgrind='callgrind'
        nodestarccmargs="$nodestarccmargs $1 $2"
	addto_java_server_cmd "-valgrind $valgrind"
        ;;

    -portrange)
	[ $# -lt 2 ] && usage
	batch_args="$batch_args $1 $2"
	# pass to executable
	star_args="$star_args $1 $2"
	# promote directly to client's server command
	addto_java_server_cmd "$1 $2"
	shift
	;;

    *)
        main_args="$main_args "$1
        nodestarccmargs="$nodestarccmargs $1"
        ;;

    esac

    shift
    done

    # > 1 command line option can add to the mppoptions so
    # they have to be promoted after all command line
    # options have been parsed.
    [ -n "$mppoptions" ] && addto_java_server_cmd "-mppflags \"$mppoptions\""

    # Nothing should be placed here. Try placing
    # any argument validation in the validate_arguments
    # function below.
}

validate_arguments() {
    if [ -n "$machinefile" -a $parallel = no ]; then
        usage "-np <no. processes> must be set for parallel jobs"
        exit 1
    fi

    # -on doesn't mean parallel if only one process is specified
    if [ -n "$on" -a -z "$np" ]; then
        [ -z "`echo $on | grep '[:,]'`" ] && parallel=no
    fi    
}

addto_LD_LIBRARY_PATH() {
    [ -n "$2" ] && verify_readable $1

    case $star_arch in

    win*)
        PATH="$1:$PATH"
        ;;

    *)
        LD_LIBRARY_PATH="$1${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
        ;;

    esac
}


append_LD_LIBRARY_PATH() {
    [ -n "$2" ] && verify_readable $1

    case $star_arch in

    win*)
        PATH="$PATH:$1"
        ;;

    *)
        LD_LIBRARY_PATH="$LD_LIBRARY_PATH${LD_LIBRARY_PATH:+:}$1"
        ;;

    esac
}


addto_LD_PRELOAD() {
    [ -n "$2" ] && verify_readable $1

    LD_PRELOAD="$1${LD_PRELOAD:+:}$LD_PRELOAD"
}

addto_CLASSPATH() {
    [ -n "$2" ] && verify_readable $1

    case $star_arch in

    win*)
        CLASSPATH="`cygpath -di $1`${CLASSPATH:+\;}$CLASSPATH"
        ;;

    *)
        CLASSPATH="$1${CLASSPATH:+:}$CLASSPATH"
        ;;

    esac
}

# check that specified file/directory exists and is readable
verify_readable() {
    if [ -r "$1" ]; then
        if [ $verbose ] ; then
            echo "found $1"
        fi
    else
        echo_error "Cannot read \"$1\"."
        
        # ide doesn't care about directories
        if [ "$exit_on_error" = yes ]; then
            echo "Aborting: Installation is missing required files."
            exit
        fi
    fi
}

locate_dev_home() {
    # set dev_home relative to the location of this script, ./../..

    dev_home=`cd \`dirname "$0"\`/../.. && pwd`

    verify_readable "$dev_home"
}

determine_star_env() {

    if [ -z "$star_env" ]; then
        # select a build from the ones in the lib directory.
        if [ -r "$server_home/lib/$star_arch" ]; then

            # release builds, in order of preference
            preferred="gnu4.6 gnu4.5 gnu4.4 gnu4.3 gnu4.2 gnu4.1 intel10.0 intel9.1"
            actual=`cd $server_home/lib/$star_arch && echo *`

            for p in $preferred; do
                for a in $actual; do
                    case $a in

                    system)
                        ;;

                    *)
                        star_env="$a"
                        [ "$star_env" = "$p" ] && break 2
                        ;;

                    esac
                done
            done
        fi
    fi

    if [ -z "$star_env" ]; then
        echo_error "STAR-CCM+ for $star_arch has not been installed in $server_home"\
                   "Installed architectures are: "`cd $server_home/lib/ && echo *-*`
        exit 1
    fi

    # strip off all but optimization extentions
    star_env_opt_base="$star_env"
    for f in -r8; do
        star_env_opt_base=`basename "$star_env_opt_base" $f`
    done

    # strip off remaining optimization extentions
    star_env_base="$star_env_opt_base"
    for f in -g -mf -vt -callgrind; do
        star_env_base=`basename "$star_env_base" $f`
    done
}


setup_star() {
    # reset library path to alleviate problems running an mpi
    # program through the java RunTime.exec() method.
     

    # if this script is launching a serial server process or a parallel
    # server process (not mpirun) then add any additional paths to LD_LIBRARY_PATH
    if [ "$mode" = "server" -o "$mode" = "executable" ]; then
        if [ -n "$node" -o "$parallel" = "no" -a -n "$ldlibpath" ]; then
            addto_LD_LIBRARY_PATH $ldlibpath
        fi
    fi

    [ -z "$dev_home" ] && locate_dev_home

    server_home="$dev_home/star"

    # put server home into the environment
    STAR_HOME="$server_home"
    export STAR_HOME

    # determine arch if not over-ridden in options 
    if [ -z "$arch_opt" ]; then
        arch_opts=`cd $server_home/lib && echo *-*`
        star_arch=`$server_home/bin/maparch $arch_opts`
    else
        star_arch="$arch_opt"
    fi

    determine_star_env

    server_lib_dir="$server_home/lib/$star_arch/$star_env/lib"

    if [ "$mode" = server -o "$mode" = executable ] ; then
        addto_LD_LIBRARY_PATH "$server_lib_dir" verify
    fi

    script_name="starccm+"
    if [ -z "$USE_PATH" ]; then
        # logic on choosing the script path
        # 1. If we type starccm+ from the <install_path>/star/bin directory
        #    we probably want to run from the same <install_path> on a remote
        #    machine so we expand the script path to be an absolute path
        # 2. If we type an absolute path and the absolute path does not
        #    correspond to the PATH env then we expand the script path to the
        #    same absolute path
        # 3. If we type an absolute path and it does correspond to the PATH
        #    env then we cannot establish if the path got resolved through PATH
        #    or if the user typed an absolute path. In this case we cannot be
        #    sure what the script path should be. We use the absolute path and
        #    give the user the choice to use the -use-path-env option on the CL
        # 4. If the path if relative to $HOME then we do not expand the script
        #    path to the absolute path because if we do an rsh the relative path
        #    will be ok and $HOME may be mounted in different locations on 
        #    different machines.
        # 5. If another relative path is given then we just expand the script path
        #    to the absolute path
        if [ -n "$HOME" ]; then
            relativetohome=`echo $server_home/bin/$script_name | sed "s,$HOME,\\.,"`
        else
            relativetohome=
        fi
        if [ "$relativetohome" = "$0" ]; then
            script_name="$0"
        else
            script_name="$server_home/bin/$script_name"
        fi
        unset relativetohome
    fi
}

setup_dars() {
    if [ "$userfortrancompiler" ]; then
        libdir=`$server_home/bin/map_dars -f $userfortrancompiler -arch $star_arch`
        mechdir=`$server_home/bin/map_darsmech -f $userfortrancompiler -arch $star_arch`
    else
        libdir=`$server_home/bin/map_dars -arch $star_arch`
        mechdir=`$server_home/bin/map_darsmech -arch $star_arch`
    fi
    case $libdir in
       *linux-x86*)
         libredkindir=`$server_home/bin/map_dars -f "absoft_9.0" -arch $star_arch`;;
    esac
    #setup fortran libraries
    if [ -d "$libredkindir" ]; then
        addto_LD_LIBRARY_PATH "$libredkindir"
    fi

    if [ "$libdir" ]; then
        addto_LD_LIBRARY_PATH "$libdir"
        #hard coded fo hpux-hppa
        case $libdir in

        *hpux-hppa*)
            addto_LD_PRELOAD "$libdir/libF90.sl"
            ;;

        esac
    fi
    if [ -d "$mechdir" ]; then
        addto_LD_LIBRARY_PATH "$mechdir"
    fi

}

setup_fortran() {
    if [ "$userfortrancompiler" ]; then
        libdir=`$server_home/bin/map_fortran -f $userfortrancompiler -arch $star_arch`
    else
        libdir=`$server_home/bin/map_fortran -arch $star_arch`
    fi
    case $libdir in
       *linux-x86*)
         libredkindir=`$server_home/bin/map_fortran -f "absoft_9.0" -arch $star_arch`;;
    esac
    #setup fortran libraries
    if [ -d "$libredkindir" ]; then
        addto_LD_LIBRARY_PATH "$libredkindir"
    fi

    if [ "$libdir" ]; then
        addto_LD_LIBRARY_PATH "$libdir"
        #hard coded fo hpux-hppa
        case $libdir in

        *hpux-hppa*)
            addto_LD_PRELOAD "$libdir/libF90.sl"
            ;;

        esac
    fi
}

setup_hdf5() {
    hdf5_dir=`$dev_home/star/bin/map_hdf5 -arch $star_arch`
    if [  "$hdf5_dir" != 'na' ] ; then
        addto_LD_LIBRARY_PATH "$hdf5_dir" verify
    fi
    unset hdf5_dir
}

setup_mkl() {
    mkllibpath=`$dev_home/star/bin/map_mkl -mkllibpath`
    if [ "$mkllibpath" != "na" ] ; then
        addto_LD_LIBRARY_PATH "$mkllibpath" verify
    fi
}

setup_vtk() {
    m=
    [ "$mode" = 'client' ] && m="-client"
    vtk_dir=`$dev_home/star/bin/map_vtk -arch $star_arch $m`

    addto_LD_LIBRARY_PATH "$vtk_dir" verify

    #jdk7 does not add the correct path for libjawt.so
    JDKHOME=`$server_home/bin/mapjdk $star_arch`
    case $star_arch in
        
        linux-x86_64*)
            addto_LD_LIBRARY_PATH "$JDKHOME/jre/lib/amd64" verify
            ;;
        
        linux-x86*)
            addto_LD_LIBRARY_PATH "$JDKHOME/jre/lib/i386" verify
            ;;
        
        *)
            ;;
        
    esac



    if [ "$forcemesa" -o "$batch" = 'yes' ] && [ -z "$forcehardware" ] || uses_MangledMesa; then
        if [ "$mode" = 'client' ] ; then
            addto_LD_LIBRARY_PATH "$vtk_dir/mesa" verify
            MESA_GLX_ALPHA_BITS=8
	    export MESA_GLX_ALPHA_BIT
	    MESA_GLX_DEPTH_BITS=24
            export MESA_GLX_DEPTH_BITS
        fi
    fi

    unset vtk_dir
}

setup_cad() {
    parasolid_is_supported=`$dev_home/star/bin/map_parasolid -arch $star_arch -parasolid`
    if [ "$parasolid_is_supported" = 'parasolid' ] ; then
        parasolid_lib_dir=`$dev_home/star/bin/map_parasolid -arch $star_arch`
        addto_LD_LIBRARY_PATH "$parasolid_lib_dir"
	P_SCHEMA=`$dev_home/star/bin/map_parasolid -arch $star_arch -schema`
        export P_SCHEMA
    elif [  "$parasolid_is_supported" = 'emulated' ] ; then
        # CAD is in emulation mode.   Still set P_SCHEMA variable but don't
        # set LD_LIBRARY_PATH
        echo "Warning: Parasolid is not fully supported on $star_arch"
	P_SCHEMA=`$dev_home/star/bin/map_parasolid -arch $star_arch -schema`
        export P_SCHEMA
    elif [  "$parasolid_is_supported" = 'na' ] ; then
        echo "Warning: Parasolid is not available on $star_arch"
    elif [ "$parasolid_is_supported" = 'Error' ] ; then
        exit 1
    fi

    # Ensure import_cad script is in PATH
    PATH="$server_home/bin:$PATH"
    export PATH

    unset parasolid_lib_dir
    unset parasolid_is_supported
}

setup_scmatnshell() {
    # Ensure starcast.shell and map_scmat script is in PATH
    PATH="$server_home/bin:$PATH"
    export PATH
}

setup_expat() {
    expat_dir=`$dev_home/star/bin/map_expat -arch $star_arch`
    if [  "$expat_dir" != 'na' ] ; then
        addto_LD_LIBRARY_PATH "$expat_dir" verify
    fi
}

setup_medina() {   
    medina_catalog_dir=`$dev_home/star/bin/map_medina -catalog`
    #set environment variable for location of Medina catalog file
    if [ "$medina_catalog_dir" ]; then
        MEDINA_CATALOG_FILE="$medina_catalog_dir/dscat.ds"
	export MEDINA_CATALOG_FILE
    fi
} 

setup_lgs() {
    lgs_is_supported=`$dev_home/star/bin/map_lgs -arch $star_arch`
    # add LGS to path if supported
    if [ "$lgs_is_supported" != "na" ] ; then
        lgs_lib_dir=`$dev_home/star/bin/map_lgs -arch $star_arch`
        addto_LD_LIBRARY_PATH "$lgs_lib_dir"
    fi
}

setup_lpsolve() {
    lpsolve_is_supported=`$dev_home/star/bin/map_lpsolve -arch $star_arch`
    # add LP_SOLVE to path if supported
    if [ "$lpsolve_is_supported" != "na" ] ; then
        lpsolve_lib_dir=`$dev_home/star/bin/map_lpsolve -arch $star_arch`
        addto_LD_LIBRARY_PATH "$lpsolve_lib_dir"
    fi
}

setup_gtlink() {
    # add gtlink lib to path if supported
    gtlinkdir=`$dev_home/star/bin/map_gtlink -arch $star_arch`
    [ -n "$gtlinkdir" ] && addto_LD_LIBRARY_PATH "$gtlinkdir"
}

setup_wave() {
    # add wave lib to path if supported
    wavedir=`$dev_home/star/bin/map_wave -arch $star_arch`
    [ -n "$wavedir" ] && addto_LD_LIBRARY_PATH "$wavedir"
}

setup_cdlmd() {
	# set LM_PROJECT for pod sever
    if [ "$podkey" ]; then
        LM_PROJECT="$podkey"
		export LM_PROJECT
    fi
	# set CDLMD_LICENSE_FILE for pod server
    if [ "$licpath" ]; then
        CDLMD_LICENSE_FILE="$licpath"
		export CDLMD_LICENSE_FILE
		STARNOFLEXLMRC=true
		export STARNOFLEXLMRC		
    fi
}

setup_vtune() {
    if [ ! `basename "$star_env_opt_base" -vt` = "$star_env_opt_base" ]; then

        if [ -z "$VTUNE_HOME" ]; then
            VTUNE_HOME="/opt"
        fi

        case $star_arch in

        linux-x86_64*)
            addto_LD_LIBRARY_PATH "$VTUNE_HOME/intel/vtune_amplifier_xe_2011/lib64/runtime"
            ;;

        linux-x86*)
            addto_LD_LIBRARY_PATH "$VTUNE_HOME/intel/vtune_amplifier_xe_2011/lib32/runtime"
            ;;

        *)
            echo_warning "Vtune support is not complete on : $star_arch"
            ;;

        esac
    fi
}

setup_valgrind() {

    if [ $parallel = 'yes' -a -z "$node" ]; then
        case $basempidistrib in
	mpich)
            if [ -n "$mppoptions" ]; then
                mppoptions=`echo $mppoptions | sed 's/-p4norem//g'`
                mppoptions="$mppoptions -p4norem"
            else
                mppoptions="-p4norem"
            fi
        
	    echo_info 'MPICH has problems starting up under Valgrind. Worker processes have to be started'\
		      'manually by copying and pasting the command written to the shell by MPICH'
	    ;;

	hp2|hp2_2_7|hp2_3_0|hp2_3_1|platform)
	    ;;

	*)
            echo_error 'valgrind can only be invoked with the MPICH, HP MPI, or Platform MPI driver'\
                       "MPI distrib currently used : $basempidistrib"
	    exit 1
	esac
    fi    

    valgrindversion=`valgrind --version | sed 's,valgrind-,,;s,\..*,,'`
    echo_info "Valgrind version $valgrindversion detected"

    # the $valgrind var can two different formats:
    #   <tool><:options> - specify the tool and pass in options after colon 
    #   <options>        - specify all options. A supported tool must be specified
    #                      in the options using --tool=<tool>

    valgrindfeature=`echo $valgrind | sed 's/:.*//'`
    if [ "$valgrindfeature" = "$valgrind" ]; then
        # either passed in tool with no options of complete option set
        valgrindopts=`echo $valgrind | sed 's/,,/ /g;s/--tool=[^ \t]*//g'`
        if [ "$valgrindopts" = "$valgrind" ]; then
            # no --tool option found so must have simply specified tool with no options
            valgrindfeature="$valgrind"
            valgrindopts=
        else
            # specified --tool in options
            valgrindfeature=`echo $valgrind | sed 's/,,/ /g;s/.*--tool=\([^ \t]*\).*/\1/g'`
        fi
    else
        # must have passed in tool with options
        valgrindopts=`echo $valgrind | sed 's/.[^:]*://;s/"//g;s/,,/ /g'`
    fi

    echo "Valgrind feature : $valgrindfeature"
    echo "Valgrind options : $valgrindopts"

    case $valgrindfeature in
    memcheck)
        if [ -z "$valgrindopts" ]; then
           # default memcheck options
           valgrindopts="--num-callers=30 --db-attach=yes $gdboption --leak-check=yes"
        fi
        if [ "$valgrindversion" -gt 2 ]; then
            debugger="valgrind --tool=$valgrindfeature $valgrindopts"
        else
            debugger="valgrind --skin=$valgrindfeature $valgrindopts"
        fi
        # leak checking is pointless if we don't delete anything
        star_args="$star_args -deleteOnExit"
        ;;

    # batch / startest mode: dont attach debugger, print suppressions and leak check (adds -deleteOnExit)
    memcheck_batch| memcheck_test)
        suppressfile=$STARBIN/../config/valgrind-suppress
        [ -f $suppressfile ] && suppress="--gen-suppressions=all --suppressions=$suppressfile"

        valgrindopts="$valgrindopts --num-callers=30 --db-attach=no --leak-check=yes --track-origins=yes $suppress"
        if [ "$valgrindversion" -gt 2 ]; then
            debugger="valgrind --tool=memcheck $valgrindopts"
        else
            debugger="valgrind --skin=memcheck $valgrindopts"
        fi
        # leak checking is pointless if we don't delete anything
        star_args="$star_args -deleteOnExit"
	;;

    callgrind)
        if [ -z "$valgrindopts" ]; then
            valgrindopts="--dump-instr=yes"
        fi    
        if [ "$valgrindversion" -gt 2 ]; then
            debugger="valgrind --tool=$valgrindfeature $valgrindopts"
        else
            echo_error '"-valgrind callgrind" is not supported in valgrind versions 2.x'
        fi
        ;;

    exp-ptrcheck)
        if [ "$valgrindversion" -gt 2 ]; then
            debugger="valgrind --tool=$valgrindfeature $valgrindoptions"
        else
            echo_error '"-valgrind exp-ptrcheck" is not supported in valgrind versions 2.x'
        fi
        ;; 

    *)
        echo_error '-valgrind command line option must be passed either "memcheck", "callgrind" or "exp-ptrcheck"'\
                   'to specify which valgrind feature you wish to use'
        exit
        ;;
    esac

    # check for --db-attach
    valgrinddbattach=`echo "$valgrindopts" | sed 's/,,/ /g;s/db-attach=no//g'` 

    if [ "$valgrinddbattach" = "$valgrindopts" ]; then
        valgrindxterm=yes
    else
        valgrindxterm=no
    fi
}

check_installation() {
    longName="$server_home/lib/java/platform/modules/locale/org-netbeans-core-windows_star.jar"
    [ -r "$longName" ] && return

    echo 'Aborting: the STAR-CCM+ installation is corrupted.'
    echo
    echo 'The file:'
    echo "  $longName"
    echo 'does not exist.'

    case $star_arch in

    hpux-*)
        longPattern="$server_home/lib/java/platform/modules/locale/org-netbeans-core-win*"
        actualName=`echo $longPattern`

        if [ "$actualName" != "$longPattern" ]; then
            echo 'Its name has been truncated to:'
            echo "  $actualName"
        fi
        echo
        echo 'The probable cause is that HPUX tar was used to unpack the distribution.'
        echo 'HPUX tar has a known defect that truncates long filenames.'
        echo
        echo 'See the STAR-CCM+ installation instructions for using a different tar command.'
        ;;

    esac

    exit
}

setup_java() {
    JDK_HOME=`$server_home/bin/mapjdk $star_arch`

    if  [ ! -r "$JDK_HOME" ]; then
        star_os_chip=`$server_home/bin/getarch -noversion`
        star_install_home=`cd $server_home/../.. && pwd`
        java_install_version=`$server_home/bin/getjdk -version`
        echo_error "Java SDK is not installed at $star_install_home/jdk/$star_os_chip/$java_install_version"\
                   "Refer to user documentation for more details"
        exit 1
    fi
    verify_readable "$JDK_HOME"
    verify_readable "$JDK_HOME/bin/java"

    export JDK_HOME

    # echo upgrade message if java 1.6 is found
    JDK_VERSION=`$JDK_HOME/bin/java -version 2>&1 | sed 's/.*"\(.*\)".*/\1/;q'`

    case $JDK_VERSION in

    1.4* | 1.5* )
        echo_error "java version $JDK_VERSION is no longer supported by STAR-CCM+.  Please upgrade to java 1.6"
        exit
        ;;

    esac

    check_installation
}


is_64bit() {

    case $star_arch in

    *-x86-*)
        return 1
        ;;

    esac

    return 0
}

uses_MangledMesa() {

    case $star_arch in

    hpux*)
        return 0
        ;;

    esac

    return 1
}


# set system-specific environments
setup_system() {
    case $star_arch in

    linux-x86*)
        # refer to issue http://192.168.119.114/browse/CCMP-1043
        LIBXCB_ALLOW_SLOPPY_LOCK=1
	export LIBXCB_ALLOW_SLOPPY_LOCK
        ;;

    linux-ia64*)
        ;;

    sunos-*)
        java_data_model=-d64
        ;;
        
    aix-*)
        append_LD_LIBRARY_PATH '/usr/lib'
        ulimit -m `ulimit -mH`
        ;;

    hpux-*)
        # enable 64 bits java runtime
        java_data_model=-d64
        # HP uses remsh by default
        if [ -z "$rshcmd" ]; then
            rshcmd="remsh"
	    # pass on hp-ux rsh specialization to setup_parallel
	    setup_parallel_args="$setup_parallel_args -rsh $rshcmd"
        fi
        ;;

    win*)
        ;;

    *)
        echo_error "$0: $star_arch system not supported"
        exit 1
        ;;

    esac

    # set the default remote shell command if not set already
#    if [ -z "$rshcmd" ]; then
#        rshcmd=`which rsh`
#    fi

    # add compiler libs, 32-bit or 64-bit
    compiler_libs="$dev_home/star/lib/$star_arch/system/$star_env_base"

    is_64bit && compiler_libs="$compiler_libs-64"
    addto_LD_LIBRARY_PATH "$compiler_libs"

    case $star_arch in

    sunos-*)
        # For parasolids libpskernel.so v.19, which is built on sunos
        # 5.10, we are including libm.so.2 in lib/sunos-sparc-5.8/cadimport to
        # support 5.8 and 5.9 which have only libm.so.1.      
        # 3 runtime rules to remember:
        # 1. Always load star-ccm+ LD_LIBRARY_PATH first
        # 2. On sunos5.10, need to load the system libm.so.2.  Make sure
        #    /usr/lib/64 is prepended before star/lib/sunos-sparc-5.8/cadimport
        # 3. Always append cadimport libraries last
        cadimport_sys_libs="$dev_home/star/lib/$star_arch/cadimport/$star_env_base-64"
        append_LD_LIBRARY_PATH '/usr/lib/64'
        append_LD_LIBRARY_PATH "$cadimport_sys_libs"
        unset cadimport_sys_libs
        ;;

    esac

    unset compiler_libs    

    # limit creation of core files if not debug build..
    case $star_env in

    *-g|*-mf*)
        MUDFLAP_OPTIONS='-verbose-violations -viol-segv'
        export MUDFLAP_OPTION
        [ $verbose ] && echo "setenv MUDFLAP_OPTIONS $MUDFLAP_OPTIONS" 
        ;;

    *)
        ulimit -c 0
        ;;

    esac
}

export_ldpreload() {
    export LD_PRELOAD
    [ $verbose ] && echo "setenv LD_PRELOAD $LD_PRELOAD"
}

export_libpath() {
    # export shared library path
    case $star_arch in

    aix-*)
        # AIX uses LIBPATH instead of LD_LIBRARY_PATH
        LIBPATH="$LD_LIBRARY_PATH"
        export LIBPATH
        [ $verbose ] && echo "setenv LIBPATH $LIBPATH"
        ;;

    hpux-hppa*)
        export LD_PRELOAD
        # HPUX uses SHLIB_PATH instead of LD_LIBRARY_PATH
	SHLIB_PATH="$LD_LIBRARY_PATH"
        export SHLIB_PATH
        [ $verbose ] && echo "setenv SHLIB_PATH $SHLIB_PATH"
        ;;

    win*)
        export PATH
        if [ $verbose ] ; then 
          echo "setenv PATH $PATH"
        fi
        ;;

    *)
        export LD_LIBRARY_PATH
        if [ $verbose ] ; then
          echo "setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH"
        fi
        ;;

    esac

    # uncomment this to see debug loaded info
    #LD_DEBUG=libs
    #LD_DEBUG_OUTPUT=lddebug
    #export LD_DEBUG
    #export LD_DEBUG_OUTPUT
    if [ -n "$verbose" -a -n "$LD_DEBUG" ] ; then
      echo "setenv LD_DEBUG $LD_DEBUG"
    fi
}


# call all methods that set the environment necessary for 
# "star like" applications ie. starccm+ & startest
setup_environment() {
    setup_star
    setup_system
    setup_vtk
    setup_dars
    setup_fortran 
    setup_cdlmd
    setup_scmatnshell

    case $mode in

    client)
	setup_java
	;;

    server | executable)
        setup_cad
	setup_hdf5
	setup_expat
        setup_medina
        setup_lgs
        setup_lpsolve
        setup_gtlink
        setup_wave
        setup_vtune
        setup_mkl

        [ "$parallel" = 'yes' ] && . "$STARBIN/setup_parallel"
	;;

    esac

    export_libpath
}


addto_java_server_cmd() {
    java_server_cmd="$java_server_cmd $*"
}

setup_client() {
    # server args are added to server command as the args are processed
    # any additional args are added here

    [ "$USE_PATH"      ] && addto_java_server_cmd "-use-path-env"
    [ "$on" -a "$parallel" = 'yes' ] && addto_java_server_cmd "-on $on"

    addto_java_server_cmd "-server "
    startest_server_args="$java_server_cmd"
    java_server_cmd="-Dstar.serverCmd=$script_name $java_server_cmd"

    [ "$verbose" ] && echo "Server command : $java_server_cmd"

    # determine userdir
    [ -f "$dev_home/star/RELEASE_NOTES" ] || `cd $dev_home/star && ./bin/version.sh`
    . $dev_home/star/RELEASE_NOTES
    [ -z "$nb_userdir" ] && nb_userdir="$HOME/.star-$release_number"

    if [ -n "$userdir" ]; then
        nb_userdir="$nb_userdir-$userdir"
    fi


    # accommodate multiple users sharing the same home directory
    [ -d "$nb_userdir" -a ! -w "$nb_userdir" ] && nb_userdir="$nb_userdir-$USER"

    help_cmd="-Dstar.helpCmd=$server_lib_dir/wwhelp"
    benchmarkReport_cmd="-Dbirt.home=$dev_home/birt/2.3.1/ReportEngine"

    rsh_cmd=
    # remove double quotes and replace gaps with unicode. Unfortunately unicode doesn't seem to
    # be interpreted but that doesn't matter because this environment variable is never used on unix
    # because the rsh command used always defers to the one in the server command.
    [ "$rshcmd" ] && rsh_cmd="-Dstar.rshCmd=`echo $rshcmd | sed -e 's/ /\\\\\\\u0020/g' -e 's/\"//'g`"

    platform_dir="-Dstar.platformDir=$dev_home/star/lib/java/platform"

    # enable 64bits java runtime / data model
    [ -n "$java_data_model" ] && netbeans_args="$netbeans_args -J$java_data_model"
# java JPDA debug args appended - jbs
    netbeans_args="$netbeans_args\
 --jdkhome $JDK_HOME \
 --laf Metal\
 -J-Dnetbeans.security.nocheck=true\
 -J-Dnetbeans.logger.console=false\
 -J$help_cmd\
 -J$benchmarkReport_cmd\
 -J$platform_dir\
 -J-Dorg.netbeans.core.TimeableEventQueue.report=120000\
 -J-Dorg.netbeans.core.TimeableEventQueue.waitcursor=240000"

    # add rsh command arg to netbeans args
    [ "$rsh_cmd" ] && netbeans_args="$netbeans_args -J$rsh_cmd"

}

# print and then execute a command
echo_command() {
   [ $verbose ] && echo "$@"
   "$@"
}

error_handler() {
    RETVAL=$@
    [ $RETVAL -ne 0 ] && exit 1
}

addto_jvmargs() {
    [ -n "$2" ] && verify_readable $1

    jvm_args=$1${jvm_args:+\ }$jvm_args
}

addto_nbargs() {
    [ -n "$2" ] && verify_readable $1

    nb_args=-J$1${nb_args:+\ }$nb_args
}
