#!/bin/sh -f

# This script unpacks an A++P++ .tar.gz file
# and runs the compilation and
# checking process, generating a nice log file.

# You may want to do a simple redirection of stdout to get a
# log file, i.e. script_name > log_file.
# This scrip redirects stderr to stdout, so do not worry about
# redirecting stderr yourself.

# Written by Brian Gunney

# To do:
# Write compound command function so that compound commands
# can be broken up and checked individually for exit values.
# Currently, only the last command in a compound command
# issues a recognized error value.

script_name=`basename $0`	# The name of this script.
dir_name=`dirname $0`	# The directory of this script.
#alsoworks dir_name=`echo $script_name | sed -e 's:^\([^/]\):./\1:' -e 's:/[^/]*$::'`



# Define the string list assignment function sla.
if test -r $dir_name/sla.sh; then
  # Usually, this is all that is needed:
  . $dir_name/sla.sh
else
  echo "Cannot find sla.sh"
  exit 1
fi


# Some additional variables required for this whole twisted process.
# It would be nice if everything were better organized so that the
# required path would be more predictable.
PATH=${PATH}:/usr/local/gnu/bin
export PATH


# Set default flags for this script before processing script options.
dist_file=''
action='eval'
banner='echo'
build_dir=test_compile_dir


# This script uses the command line argument processor "sla".
# Sla uses grep and sed.  Not all seds and greps use a compatible
# command line interface.  Sla can use any version compatible with
# GNU sed and GNU grep.  By default, Sla uses the sed and grep
# specified in your PATH, but you can override it by setting the
# shell variables GREP (or SLA_GREP) and SED (or SLA_SED).
# You probably do NOT want to limit portability by setting them in
# this script though.  It is best to set them in your environment
# to keep this script portable.
#
# If you really want to set them in this script, uncomment and use the
# next two lines.
# SLA_GREP=grep
# SLA_SED=sed

# Sla parameters.
# Do not use \| in the sla parameters because blue's grep does not support it.
# In fact, despite sla's flexibility, do not overuse fancy regular expressions
# in case they are not supported on some platforms.
flind='-';	# Flag start with -.
assop='$^';	# Some option arguments may be detached or attached with a =


# Save the command line options before running sla.
command_line_opts="$*"


# Check for help flag.
sla_scan tmp_ "-" "$" 'h' "$@"
if test "$tmp_sla_commands"; then
  cat << EOF
$script_name is a script to check an A++P++ distribution file.
Usage: $script_name [options]
  Options:
  -h	Print this message.
  -s	Shows (cat) this script.
  -n	Do not do anything.  Just list the commands that would be issued.
  -q	Do not output banner information.
  -dist_file <distribution file>
	Specify the distribution file to check.  This is required.
  -config_for <case>
	Configure for the specified case.  This script contains a look-up
	table to determine the configuration flags for the case you specify.
  -check_output <filename>
	Check the output generated by $script_name for success or failure.
For your logging convenience, this script redirects stderr to stdout.
(Do not try to redirect stderr from this script because there is nothing left.)
EOF
exit
fi


# Check for the option to show this script.
sla_scan tmp_ $flind '$' 's' "$@"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"
if test "$tmp_sla_commands"; then
  cat $0
  exit
fi


# Check for option to run in innert mode.
sla_scan tmp_ $flind '$' 'n' "$@"
test "$tmp_sla_commands" && action=echo
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"


# Check for quietness option.
sla_scan tmp_ $flind '$' 'q' "$@"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"
test "$tmp_sla_commands" && banner=:


# Check for option to check output log.
sla_scan tmp_ $flind $assop 'check_output' "$@"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"
test "$tmp_sla_commands" && eval "$tmp_sla_commands"
if test "$check_output"; then
  # Check the output of a run of this script to determine if the run passed or failed.
  # Return a pass/fail value accordingly.
  file_name=$check_output
  # echo grep "^$script_name DONE\$" $file_name
  grep "^$script_name DONE\$" $file_name > /dev/null 2>&1
  exit_value=$?
  if [ $exit_value -eq 0 ]; then
    echo pass
  else
    echo fail
  fi
  exit $exit_value
fi


# Set name of distribution file.
sla_scan tmp_ $flind $assop 'dist_file' "$@"
test "$tmp_sla_commands" && eval "$tmp_sla_commands"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"


# Set name of build directory.
sla_scan tmp_ $flind $assop 'build_dir' "$@"
test "$tmp_sla_commands" && eval "$tmp_sla_commands"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"


# Check for short-hand configuration specifications (config_for).
sla_scan tmp_ $flind $assop 'config[-_]for' "$@"
test "$tmp_sla_commands" && eval "$tmp_sla_commands"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"

# Previous settings
# sun)			configure_for="--with-CC=cc-4.2 --with-CXX=CC-4.2 --enable-PXX" ;;
# sun_ccv4_on_v5)	configure_for="--with-CC=cc-4.2 --with-CXX=CC-4.2 -enable-SHARED_LIBS" ;;

case "$config_for" in
  sun)			configure_for="" ;;
  sun_kcc)		configure_for="--with-CC=cc --with-CXX=KCC" ;;
  sun_gnu)		configure_for="--with-CC=gcc --with-CXX=g++" ;;
  sun_ccv5)		configure_for="--with-CC=cc-5.0 --with-CXX=CC-5.0" ;;
  sun_ccv4_on_v5)	configure_for="--with-CC=cc-4.2 --with-CXX=CC-4.2" ;;
  sun_insure)		configure_for="--with-CC=insure --with-CXX=insure" ;;
  tera)			configure_for="" ;;
  tera_kcc)		configure_for="--with-CC=cc --with-CXX=KCC" ;;
  tera_gnu)		configure_for="--with-CC=gcc --with-CXX=g++" ;;
  riptide)		configure_for="--with-CC=cc --with-CXX=CC" ;;
  *)
    echo "Error: configuration shorthand $config_for is not defined in $script_name."
    echo "       See the script for which shorthand is defined."
    exit 1
    ;;
esac


# Check for more short-hand configuration specification (config_opt)
sla_scan tmp_ $flind $assop 'config_opt' "$@"
test "$tmp_sla_commands" && eval "$tmp_sla_commands"
test "$tmp_new_arg_command" && eval "$tmp_new_arg_command"
case "$config_opt" in
  FastCompile)	set -- "$@" --enable-CXX_OPT= --enable-C_OPT= ;;
  Debug)	set -- "$@" --enable-INTERNALDEBUG --enable-CXX_OPT= --enable-C_OPT= --enable-C_DEBUG=-g --enable-CXX_DEBUG=-g ;;
esac


# Done processing options for this script.



# To support an graceful exit upon error,
# define the die function similar to Perl.
# Make it gaudy.
die () {
    echo "ERROR_MESSAGE_FROM $script_name (at `date`):"
    if [ $?2 ]; then echo "Error $2"; fi
    if [ $?1 ]; then exit $1; fi
    exit 99
}



# Check to be sure we have all the required variables set correctly.
if [ "$dist_file" = "" ]; then
    die 1 "Error: the distribution file is unset.  Use '-dist_file ...'"
fi



# Prefer make over gmake because we want to test vendor make.
MAKE=make
# The following is a very kludgey fix to a difficult problem.
# The KCC compiler returns error if not all symbols
# are resolved when building the shared A++P++ libraries.
# There is a way to ignore the unresolved symbol
# error, but none of the syntax gotten from the
# manual worked.
# GNU make somehow ignores the error, but tera's
# native make exits.  So when using KCC on tera,
# use GNU make.  BTNG.
hostname | grep '^tc' &&	\
  echo $configure_for | grep -e '--with-CXX=KCC' &&	\
  MAKE=gmake



# Determine A++P++ directory from the distribution file name.
ap_dir=`basename $dist_file | sed -e 's/.tar.gz$//' -e 's:^.*/::'`


# Set build directory if it is not yet set.
if [ -n "$build_dir" ]; then
  # Build is separate directory.
  configure=../$ap_dir/configure
else
  # Build in source directory.
  build_dir=$ap_dir
  configure=./configure
fi



# Define a function to run a command ($1) gaudily.
# If unsuccessful, die with commentary ($2)
# Run command up to specifed number of tries ($3).
# Stderr is redirected to stdout.
export banner action
gaudy_run () {
    COM="$1"
    TRIES=${3:-1}
    BEGTIME=`date +%H:%M:%S`
    $banner
    $banner "======================================================================"
    $banner "STARTING \"$COM\" at $BEGTIME"
    $banner "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
    $action $COM 2>&1
    if [ $? = 0 ]; then
      $banner "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
      $banner "FINISHED $2: $BEGTIME to `date +%H:%M:%S`"
      $banner "======================================================================"
      $banner
      return
    fi
    die 1 "$2"
}


#########################################################################
#########################################################################


# Write out header
$banner "executing:		$0"
$banner "from:			`pwd`"
$banner "on:			`uname -a`"
$banner "pid:			$$"
$banner "at:			`date`"
$banner "by:			`whoami`"
$banner "configure options are:	'$configure_for $*'"
$banner "command line options:	'$command_line_opts'"

# Write out the script
gaudy_run "cat $0"			"showing THIS script ($0)"
gaudy_run "set"				"showing current environment"

# Run the commands
gaudy_run "rm -rf $ap_dir"		"removing ap directory"
gaudy_run "gzip -dc $dist_file | tar xf -"	\
					"extracting distribution"
gaudy_run "pwd; ls -al"			"listing after unpacking"
if [ ! "$build_dir" = "$ap_dir" ]; then
  gaudy_run "rm -rf $build_dir; mkdir $build_dir"	\
					"making build directory $build_dir"
fi
gaudy_run "cd $build_dir; pwd; PWD=\`pwd\`; export PWD; ls -al"	"entering build directory $build_dir"
# Note: PWD must be explicitly set.  Configure uses it.  sh does not set it.

# DQ: Comment out to test scripts with ROSE
gaudy_run "$configure --prefix=$PWD $configure_for $*"	\
					"configuring"
# DQ: Comment out to test scripts with ROSE
gaudy_run "$MAKE"			"make-ing"
gaudy_run "$MAKE check"			"make-ing check" 3

# DQ: Comment out make install until it works properly within ROSE
# gaudy_run "$MAKE install"		"make-ing install"

# Write out trailer
$banner
$banner "============================================================="
$banner "$script_name DONE"
$banner "============================================================="

