#!/bin/sh

# If an outside makefile has specified -w, our wrapper will generate extra/incorrect 
# output unless we remove the flags
MAKEFLAGS=
MFLAGS=

# 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 - Fortran compiler wrapper for TAU"
    echo ""
    echo " Usage: $cmd [options] ..."
    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 ""
    echo "   -tau:pdtinst         Use PDT instrumentation"
    echo "   -tau:compinst        Use compiler instrumentation"
    echo "   -tau:headerinst      Instrument headers"
    echo ""
    echo "   -tau:<options>       Specify comma separated list of TAU options"
    echo "                        e.g. <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.f90 -o foo"
    echo "   $cmd -tau:MPI,OPENMP,TRACE foo.f90 -o foo"
    echo "   $cmd -tau:verbose -tau:PTHREAD foo.f90 -o foo"
    echo ""
    exit 1
}

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

if [ $# -eq 0 ]; then
  usage
fi

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)
	      command_options="$command_options -optKeepFiles"
	      ;;
	  -tau:pdtinst)
	      binding_options="$binding_options pdt"
	      command_options="$command_options -optPDTInst"
	      ;;
	  -tau:compinst)
	      command_options="$command_options -optCompInst"
	      ;;
	  -tau:headerinst)
	      command_options="$command_options -optHeaderInst"
	      ;;
	  -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" >&2
	    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


# SiCortex Pathscale/Opari workarounds
if [ "$SICORTEX" = "yes" ] ; then
    TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optOpariOpts=-nodecl"
else
    # default only for non-sicortex platforms
    TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS -optCompInst"
fi


TAUCOMPILER_OPTIONS="$TAUCOMPILER_OPTIONS $command_options"

if [ $invoke_without_tau = yes ] ; then
cat <<EOF > /tmp/makefile.tau.$USER.$$
include $MAKEFILE
all:
	@\$(TAU_F90) \$(TAU_MPI_INCLUDE) $NON_TAUARGS || exit 0
show:
	@echo \$(TAU_F90) \$(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_F90) $TAUARGS || exit 0

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

exit $x

