#! /bin/sh
#
# This file contains support shell routines and steps common to all
# runtests scripts.
#
# Find MPIRUN
#
# Some people don't include "." in their path (! in case an ls trojan horse,
# I guess - if someone does that to you, you have bigger problems).  This
# code tests to see if you have a path to mpirun; if not, it tries ./mpirun.
#
# One particular problem is having multiple mpiruns in the path.  An
# absolute path for mpirun will fix many problems
FindMPIRUN () {
    if [ -z "$MPICH_USE_LIB_MPIRUN" -a ! -x "$mpirun" ] ; then
        IFS="${IFS= 	}"; saveifs="$IFS"; IFS="${IFS}:"
        for dir in $PATH ; do 
            if [ -x $dir/mpirun ] ; then
	        if [ -n "${MPICH_VERSION}" ] ; then
		    # Test that we've found the correct mpirun
		    if strings $dir/mpirun | grep "MPIRUN for MPICH" > /dev/null ; then
		        :
		    else
		        # echo "$dir/mpirun isn't for MPICH"
		        continue
		    fi
	        fi
                mpirun="mpirun"
                break
             fi
        done
        IFS="$saveifs"
    fi
    if [ -z "$mpirun" -a -x "./mpirun" ] ; then
        mpirun=./mpirun
    fi
    #
    if [ -z "$mpirun" ] ; then
        echo "No mpirun in path.  Testing can not proceed."
        exit 1
    fi
}

# MakeExe program-name
MakeExe() {
    if [ -s $STOPFILE ] ; then 
        echo "Found stopfile; exiting"
	exit 0
    fi
    if [ ! -x $1 ] ; then
	$MAKE $1
        if [ ! -x $1 ] ; then 
	    echo "Could not build executable $1; aborting tests"
	    exit 1
        fi
    fi
}

# CleanExe program-name
CleanExe() {
    if [ $makeeach = 1 ] ; then
	/bin/rm -f $1 $1.o
    fi
}

# Output marker
OutTime() {
    if [ $quiet = 0 ] ; then
	if [ -z "$hostname" ] ; then
	    hostname=`hostname`
	fi
	d=`date`
	echo "$hostname : $d"
    fi
}

# Do an "on the fly" check for problems.
# Checkout testname difffile 
# difffile may be empty, in which case stdout is used.
CheckOutput() {
    bfile=$1
    difffile=$2
    if [ ! -s ${bfile}.out ] ; then
        echo "No output file ${bfile}.out!"
    else
	fileok="no"
	cmpfile=""	
	for stdfile in $srcdir/${bfile}.std $srcdir/${bfile}.std2 \
			${bfile}.stdo ; do
	    if [ -z "$cmpfile" -a -s "$stdfile" ] ; then
		cmpfile=$stdfile
	    fi
	    if test -s $stdfile && diff -b ${bfile}.out $stdfile > /dev/null ; then
		fileok=yes
		break;
	    fi
	done
	if [ $fileok = "no" ] ; then
	    if [ -n "$difffile" ] ; then
   	        if [ -n "$cmpfile" ] ; then
                    echo "Differences in ${bfile}.out" >> ${difffile}
	            diff -b ${bfile}.out $cmpfile >> ${difffile}
	        else
                    echo "Cannot find a file to compare against for test ${bfile}.out"
	        fi
	    else
   	        if [ -n "$cmpfile" ] ; then
                    echo "Differences in ${bfile}.out"
	            diff -b ${bfile}.out $cmpfile
	        else
                    echo "Cannot find a file to compare against for test ${bfile}.out"
	        fi
            fi
	    nodiff=0
	fi
    fi
}

# Runtest pgm-name np marker-test args outfiles
RunTest() {
    OutTime
    testfiles="$testfiles $1.out"
    /bin/rm -f $1.out
    MakeExe $1
    mname=$3
    if [ -z "$mname" ] ; then mname="*** $1 ***" ; fi
    echo "$mname" >> $1.out
    echo "$mname"
    mvarg=""
    if [ -n "$5" ] ; then rm -f $5 ; 
	if [ "$device" != "ch_p4mpd" ] ; then
            if [ -n "$MPIRUNMVBACK" ] ; then mvarg="$MPIRUNMVBACK \"$5\"" ;
fi 
	fi
    fi
    # The eval is necessary to ensure that the mvarg value is properly
    # tokenized.
    eval $mpirun $args -np $2 $mvarg $1 $4 </dev/null >> $1.out 2>&1
    if [ -n "$5" ] ; then 
        for file in $5 ; do 
            if [ -s $file ] ; then 
                cat $file >> $1.out ; rm -f $file 
            fi
        done
    fi
    echo "$mname" >> $1.out
    if [ ! -s $srcdir/$1.std -a ! -s $1.stdo ] ; then
        # We don't need a special file if the output is just "No Errors"
        cat >>$1.stdo <<EOF
$mname
 No Errors
$mname
EOF
    fi
    if [ "$CheckOutputWhileRunning" = "yes" -o "$check_at_once" = 1 ] ; then
        CheckOutput $1
    fi
    CleanExe $1
}

#
# Check the output of the programs against the "standard" output.  The 
# possible files are:
#   $srcdir/file.std
#   $srcdir/file.std2
#   file.stdo     
# The last one is an automatically generated file for those programs
# that simply produce a " No errors" output.
CheckAllOutput ()
{
    difffile=$1
    /bin/rm -f ${difffile}
    nodiff=1
    for file in $testfiles ; do
	bfile=`basename $file .out`
	CheckOutput $bfile ${difffile}
    done
    if [ -s ${difffile} ] ; then
        cat ${difffile}
    elif [ $nodiff = 1 ] ; then
        echo "-- No differences found; test successful"
    fi
}
