#!/bin/sh

# Get configuration
PATH=$PATH:`dirname $0`
eval `tau-config`

# Define variables 
makefile_specified=no
options_specified=no

# depending on the options, we might invoke the regular compiler, TAU_COMPILER, or both
invoke_without_tau=no
invoke_with_tau=yes


usage()
{
    cmd=`basename $0`
    echo ""
    echo " $cmd - C++ compiler wrapper for TAU"
    echo ""
    echo " Usage: $cmd [-tau:help] [-tau:<options>] [-tau:makefile <tau_stub_makefile>] "
    echo "             [-tau:verbose] [-tau:keepfiles] [-tau:show] ..."
    echo ""
    echo " Options:"
    echo "   -tau:help            Show this help message"
    echo "   -tau:verbose         Enable verbose mode"
    echo "   -tau:keepfiles       Keep intermediate files"
    echo "   -tau:show            Do not invoke, just show what would be done"
    echo "   -tau:<options>       Specify comma separated list of TAU options"
    echo "                        <MPI,PTHREAD,OPENMP,PROFILE,"
    echo "                         CALLPATH,TRACE,VAMPIRTRACE,EPILOG>"
    echo " "
    echo " Notes:"
    echo "   If the -tau:makefile option is not used, the TAU_MAKEFILE"
    echo "   environment variable will be checked, if it is not specified,"
    echo "   then the -tau:<options> will be checked against available"
    echo "   bindings."
    echo ""
    echo " Example usage:"
    echo ""
    echo "   $cmd foo.cc -o foo"
    echo "   $cmd -tau:MPI,OPENMP,TRACE foo.cc -o foo"
    echo "   $cmd -tau:verbose -tau:PTHREAD foo.cc -o foo"
    echo ""
    exit 1
}

TAUARGS=
NON_TAUARGS=
EATNEXT=false
next_arg_makefile=false
next_arg_options=false
verbose=false
binding_options=
opt_keepfiles=false

for arg in "$@" ; do
  # Thanks to Bernd Mohr for the following that handles quotes and spaces (see configure for explanation)
  modarg=`echo "x$arg" | sed -e 's/^x//' -e 's/"/\\\"/g' -e s,\',%@%\',g -e 's/%@%/\\\/g' -e 's/ /\\\ /g' -e 's#(#\\\(#g' -e 's#)#\\\)#g'`
  if [ $EATNEXT = true ] ; then
      # these arguments should only go to the non-tau invocation
      NON_TAUARGS="$NON_TAUARGS $modarg"
      EATNEXT=false
  elif [ $next_arg_makefile = true ] ; then
      MAKEFILE=$arg
      next_arg_makefile=false
  elif [ $next_arg_options = true ] ; then
      TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS $arg"
      next_arg_options=false
  else
      case $arg in 
	  -tau:makefile)
	      makefile_specified=yes
	      next_arg_makefile=true
	      ;;
	  -tau:options)
	      options_specified=yes
	      next_arg_options=true
	      ;;
	  -tau:verbose)
	      verbose=true
	      ;;
	  -tau:keepfiles)
	      opt_keepfiles=true
	      ;;
	  -tau:show)
	      invoke_without_tau=yes
	      invoke_with_tau=no
	      NON_TAUARGS="$NON_TAUARGS $modarg"
              SHOW=show
	      ;;
	  -tau:help)
	      usage
	      ;;
	  -tau:*)
	      binding_options="$binding_options `echo $arg | sed -e 's/-tau://' -e 's/,/ /g'`"
	      ;;
	  -E)
	      invoke_without_tau=yes
	      invoke_with_tau=no
	      NON_TAUARGS="$NON_TAUARGS $modarg"
	      ;;
	  -MD | -MMD)
              # if either of these are specified, we invoke the regular compiler
              # and TAU_COMPILER, unless -E or another disabling option is specified
	      invoke_without_tau=yes
	      NON_TAUARGS="$NON_TAUARGS $modarg"
	      ;;
	  -MF | -MT | -MQ)
              # these arguments should only go to the non-tau invocation
	      NON_TAUARGS="$NON_TAUARGS $modarg"
	      # we must eat the next argument as well and use it for the non-tau invocation only
	      EATNEXT=true
	      ;;
	  -MF* | -MT* | -MQ* | -MP | -MG)
              # these arguments should only go to the non-tau invocation
	      NON_TAUARGS="$NON_TAUARGS $modarg"
	      ;;
	  -M | -MM | -V | -v | --version | -print-prog-name=ld | -print-search-dirs | -dumpversion)
              # if any of these are specified, we invoke the regular compiler only
	      invoke_without_tau=yes
	      invoke_with_tau=no
	      NON_TAUARGS="$NON_TAUARGS $modarg"
	      ;;
	  *)
	      TAUARGS="$TAUARGS $modarg"
	      NON_TAUARGS="$NON_TAUARGS $modarg"
	      ;;
      esac
  fi
done


if [ "x$NON_TAUARGS" = x ] ; then
    invoke_without_tau=yes
    invoke_with_tau=no
fi

# Find the makefile to use
if [ $makefile_specified = no ] ; then
    if [ "x$binding_options" != "x" ] ; then
	MAKEFILE=`tau-config --makefile $binding_options`
	if [ $verbose = true ] ; then 
	    echo "Matching bindings:"
	    tau-config --makefile --list-matching $binding_options
	    echo ""
	fi
	
    elif [ "x$TAU_MAKEFILE" != "x" ] ; then
	if [ ! -r $MAKEFILE ] ; then
	    echo "ERROR: environment variable TAU_MAKEFILE is set but the file is not readable"
	    exit 1
        fi
	MAKEFILE=$TAU_MAKEFILE
    elif [ "x$DEFAULT_MAKEFILE" != "x" ] ; then
	MAKEFILE=$DEFAULT_MAKEFILE
    else
	MAKEFILE=`tau-config --makefile`
    fi
fi

if [ "x$MAKEFILE" = "x" ] ; then
    echo "ERROR: unable to locate stub makefile" >&2
    exit 1
fi

if [ ! -r $MAKEFILE ] ; then
    echo "ERROR: unable to read stub makefile '$MAKEFILE'" >&2
    exit 1
fi

if [ $verbose = true ] ; then 
    echo "Using: $MAKEFILE"
fi


# if no tau_compiler options were set, use $TAU_OPTIONS
if [ $options_specified = no ] ; then
    TAUCOMPILER_OPTIONS=$TAU_OPTIONS
fi

# unless verbose is specified, use -optQuiet
if [ $verbose = true ] ; then
    TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optVerbose"
else
    TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optQuiet"
fi

TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optCompInst"

# Pathscale/Opari workaround
if [ "$SICORTEX" = "yes" ] ; then
    TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optOpariOpts=-nodecl"
fi

if [ $opt_keepfiles = true ] ; then
    TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optKeepFiles"
fi

if [ $invoke_without_tau = yes ] ; then
cat <<EOF > /tmp/makefile.tau.$USER.$$
include $MAKEFILE
all:
	@\$(TAU_RUN_CXX) \$(TAU_MPI_INCLUDE) $NON_TAUARGS || exit 0
show:
	@echo \$(TAU_RUN_CXX) \$(TAU_MPI_FLIBS) \$(TAU_LIBS) \$(TAU_LDFLAGS) \$(TAU_CXXLIBS)
EOF
make -s -f /tmp/makefile.tau.$USER.$$ $SHOW
/bin/rm -f /tmp/makefile.tau.$USER.$$
fi


if [ $invoke_with_tau = yes ] ; then
cat <<EOF > /tmp/makefile.tau.$USER.$$
include $MAKEFILE
all:
	@\$(TAU_COMPILER) $TAUCOMPILER_OPTIONS \$(TAU_RUN_CXX) $TAUARGS || exit 0

EOF
make -s -f /tmp/makefile.tau.$USER.$$ 
x=$?
/bin/rm -f /tmp/makefile.tau.$USER.$$
fi 

exit $x

