#! /bin/sh

######################################################################
#                             CAUTION                                #
# When editing this file be aware that it is the focus of /bin/sh    #
# portability problems.  Be very, very careful!  Problems with this  #
# file could cause test cases to succeed when they should fail!      #
######################################################################

# Common function definitions.
. ../common/command-names

# Try to find an echo command that allows us to suppress the newline
# at the end of the line, and also to use C-style escape codes.  We 
# have our own, as a last resort.

## First, find out how to echo without appending a newline,
## and so on.  We end up with five variables:-
#
# echocmd       The name by which we invoke the "echo" command.
# ac_e		Leading argument for enabling escape codes.
# ac_n		Leading argument for echo to suppress newline.
# ac_c          Arg for suppressing newline (may need -e, we test for that.)
# ac_t          (don't know -- I stole this code from Autoconf...)
#
# FreeBSD echo (or at least some version of it) does not support both the
# -n and the -e option AT THE SAME TIME.  This information from 
# Malcolm Boff <Malcolm_Boff@compuserve.com> on 1997/11/01. 
# He suggested that we use printf(1) but we can't do that because
# many systems just don't support it.
#
# According to Marty Leisner <leisner@sdsp.mc.xerox.com>, SunOS 4.1.4
# has the -n option but not the -e option.
#
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
#
for echocmd in echo /bin/echo /usr/bin/echo /usr/5bin/echo ../../testutils/ekko
do
# Unless we're using the builtin, check that the command exists as a file.
if test -f $echocmd || test "$echocmd" = "echo"
then
  # The second echo here ensures that the parenthesised command 
  # succeeds and the output ends with a newline.
  if ($echocmd "testing\c"; echo 1,2,3) | grep c >/dev/null
    then
    # Trailing \c option does not work without -e (it produces a literal c).
    if ($echocmd -e "testing\c"; echo 1,2,3) | grep c >/dev/null
    then
      # \c does not work even with -e.
      if ($echocmd -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null
      then
  	  # -n option not known (and \c not known)
  	  # I don't know what purpose setting ac_c to this value
  	  # has, but Autoconf does it...
  	  ac_n= ac_c='
' ac_t='	'
      else
  	  # -n option works even though -e does not.
  	  # This is unfortunate since the test scripts assume
  	  # in places tha ability to expand escape codes.  
  	  # Send message to STDERR because I want to investigate.
  	  #
  	  # According to Marty Leisner <leisner@sdsp.mc.xerox.com>,
  	  # SunOS 4.1.4 is one such "unusual" system.

  	  # echo Unusual system\; PLEASE inform '<jay@gnu.org>'. >&2
  	  ac_n=-n ac_c= ac_t=
      fi
    else
      # \c does work with -e.
      # Hence we do not need to use -n.
      ac_n= ac_c='\c' ec_t= 
      # Break out of the loop, we have a workable solution.
      break
    fi
  else
    ac_n= ac_c='\c' ac_t=
    # Break out of the loop, we have a workable solution.
    break
  fi
fi
done

# If "echo -e" generates an error, don't do that.  Hey, at least
# /dev/null works!
if ($echocmd -e) >/dev/null 2>&1
then
  if ($echocmd -e) | sed s/-e/xe/ | grep xe >/dev/null
  then
    # Fallback position: use our own replacement which supports -e.
    echocmd="../../testutils/ekko"
    ac_e='-e'
  else
    ac_e='-e'
  fi
fi

# echo "ac_n="$ac_n
# echo "ac_e="$ac_e
# echo "ac_t="$ac_t
# echo "ac_c="$ac_c
# echo "echocmd=" $echocmd


# Function for echoing without a newline, with escape chars enabled.
echo_nonl () {
if test -z "$*"
then
    # this works around an apparent bug in Bash where 
    # "$@$x" expands to something starting with char 0177 (DEL).
    true
else
    ${echocmd} ${ac_n} ${ac_e} "$@$ac_c" ;
fi
}


expect_fail=false

# Call fail when a test failed.
fail () { 
name=`basename $0`
if ${expect_fail:-false}
then
	echo XFAIL $name $* 
	# but don't exit...
else
	echo FAIL $name $* ; exit 2; 
fi ;
}


# Call success when a test succeeded.
success () { 
name=`basename $0`

remove got.stdout           got.stderr 
remove expected.stdout expected.stderr 
remove command.log last.command

echo 
echo "All Tests in `/bin/pwd`/$name are now completed on tools in '$dir'"

if ${expect_fail:-false}
then
	echo XPASS $name: $* ; exit 0; 
else
	echo PASS $name:  $* ; exit 0; 
fi ;
}

# Call miscarry wen a test could not be completed.
miscarry () { 
echo `basename $0`: "Test could not be completed: " "$@"
exit 1 ; 
}


remove () { 
    if test -z "$*"
    then
	# no files listed, nothing to do.
	true 
    else
	rm -rf "$@" || miscarry "Could not remove $@"
    fi
}

rename () { mv "$1" "$2" || miscarry "Could not rename $1 to $2" ; }

##############
docommand () {
# $1 is the label.  
# $2 is the command to execute.
# $3 is the return value to expect
# $4 is what to expect on stdout
# $5 is what to expect on stderr.
#
# If --silent is specified before the label, no output is notmally made.
#
remove last.command expected.stdout expected.stderr got.stdout got.stderr
label="$1"
case $1 in
--silent) silent=true ; shift ; label="$1" ;;
       *) silent=false  ;;
esac
eval "$silent" || echo_nonl "${label}"...

shift

echo_nonl $4 > expected.stderr
echo $1 > last.command

echo $1 >> command.log
eval "$1" >got.stdout 2>got.stderr
rv=$?

if test "$2" != "IGNORE"
then
    test $rv -eq $2 || fail "$label: $1: Expected return value $2, got return value $rv"
fi

if test "$3" != "IGNORE"
then
    echo_nonl "$3" > expected.stdout
    # diff can fail if the file does not end in newline.
    echo        >>expected.stdout
    echo        >>     got.stdout
    diff expected.stdout got.stdout || fail $label: stdout format error with $1
fi

if test "$4" != "IGNORE"
then
    echo_nonl "$4" > expected.stderr
    # diff can fail if the file does not end in newline.
    echo        >>expected.stderr
    echo        >>     got.stderr
    diff expected.stderr got.stderr || fail $label: stderr format error with $1
fi

remove last.command expected.stdout expected.stderr got.stdout got.stderr
eval "$silent" || echo "passed "
true ;
}

#######################
do_output () {
# $1 is the label.
# $2 is the command to execute.
# $3 is the return value to expect
# $4 is a file containing what to expect on stdout.
# $5 is what to expect on stderr.
remove last.command expected.stdout expected.stderr got.stdout got.stderr
label="$1"
echo_nonl "$label..."
shift

echo_nonl $4 > expected.stderr
echo $1 > last.command

echo $1 >> command.log
$1 >got.stdout 2>got.stderr
rv=$?

if test "$2" != "IGNORE"
then
    test $rv -eq $2 || fail "$label: $1: Expected return value $2, got return value $rv"
fi

if test "$3" != "IGNORE"
then
    diff $3 got.stdout || fail $label: stdout format error with $1
fi

if test "$4" != "IGNORE"
then
    echo_nonl $4 > expected.stderr
    # diff can fail if the file does not end in newline.
    echo        >>expected.stderr
    echo        >>     got.stderr
    diff expected.stderr got.stderr || fail $label: stderr format error with $1
fi

remove last.command expected.stdout expected.stderr got.stdout got.stderr
echo "passed "
true ;
}
