#!/bin/sh

if [ $# -eq 0 ]
then
  echo "usage: $0 <compile-or-link-command>"
  exit 1
fi

# INITIALIZATION
OCC="gcc"
OOPTS=""
BASEDIR=$(dirname "$0")
OBIN=$BASEDIR"/opari"
OINC="-I"$BASEDIR
OOINC=${OINC}

#PREC=${OBJECT_MODE:-32}
PFLAG=""

FPP=" "
FTR="tr f F"

COMPONLY=no
USESOMP=no
USESMPI=no
COMP=""
FLIB=""
ULIB=""

#V=yes

# PROCESS COMMAND LINE
# - collect source files for opari instrumentation (OFILES)
# - collect compiler output files so they can correctly renamed (MFILES)
# - make compiler to compile instrumented files (NEWFILE)
# - add opari include directory before first file (OINC)
# - collect special arguments to opari (everything up to "--")
for arg in "$@"
do
  case ${arg} in
  *.c|*.C|*.cc|*.CC|*.cpp|*.CPP|*.cxx|*.CXX|*.f|*.F|*.f90|*.F90)
         BASE=`echo ${arg} | sed -e 's/\.[^\.]*$//'`
         SUF=`echo ${arg} | sed -e 's/.*\./\./' | ${FTR}`
         NEWFILE=${BASE}.mod${SUF}
         OFILES="${OFILES} $arg"
         MFILES="${MFILES} `basename ${BASE}.mod.o`"
         ARGS="${ARGS} ${OINC} ${NEWFILE}"
         OINC=""
         ;;
  --)    OOPTS="${OOPTS} ${COMP} ${ARGS}"
         ARGS=""
         COMP=""
         ;;
  -nosrc) OOPTS="${OOPTS} -nosrc"
         FPP=""
         FTR="cat"
         ;;
  -fopenmp) USESOMP=yes
         ARGS="${ARGS} ${arg}"
         ;;
  -lmpi*) USESMPI=yes
         ULIB="${ULIB} ${arg}"
         ;;
  -l*)   ULIB="${ULIB} ${arg}"
         ;;
  -@)    V=yes
         ;;
  -c)    COMPONLY=yes
         ARGS="${ARGS} ${arg}"
         ;;
  -*64)  PREC=64
         PFLAG=${arg}
         ARGS="${ARGS} ${arg}"
         ;;
  -*32)  PREC=32
         PFLAG=${arg}
         ARGS="${ARGS} ${arg}"
         ;;
  *)     if [ -z "${COMP}" ]
         then
           COMP=${arg}
         else
           ARGS="${ARGS} ${arg}"
         fi
         ;;
  esac
done

# Determine plain compiler name and make sure Fortran can handle C preprocessor
BCOMP=`basename ${COMP}`
case ${BCOMP} in
*f*) COMP="${COMP}${FPP}"
     ;;
esac

#if [ "${PREC}" = "@PREC@" ]
#then
  ELGLIB="-L/opt/ompp/lib"
  HWLIB=""
#else
#  echo "ERROR: ${PREC}bit-mode (${PFLAG}) not supported by this installation of KOJAK"
#  exit 32
#fi

# INSTRUMENTATION
# - run opari on every collected source file
for ofile in ${OFILES}
do
  if [ ${USESOMP} = "yes" ]
  then
    [ -n "${V}" ] && echo "+++ ${OBIN} ${OOPTS} -table opari.tab.c $ofile"
    eval ${OBIN} ${OOPTS} -table opari.tab.c $ofile || exit
  else
    [ -n "${V}" ] && echo "+++ ${OBIN} ${OOPTS} -disable omp -table opari.tab.c $ofile"
    eval ${OBIN} ${OOPTS} -disable omp -table opari.tab.c $ofile || exit
  fi
done

# AUTOMATIC FUNCTION INSTRUMENTATION
IOPT=""

# EXECUTING MODIFIED COMMAND
if [ ${COMPONLY} = "yes" ]
then
  # COMPILATION ONLY
  [ -n "${V}" ] && echo "+++ ${COMP} ${IOPT} ${ARGS}"
  eval ${COMP} ${IOPT} ${ARGS} || exit
else
  # COMPILATION + LINKING
  # - determine whether MPI is used (by checking COMP)
  # - determine whether Fortran is used (by checking COMP)
  # - link the right EPILOG library depending on OpenMP/MPI usage
  case ${BCOMP} in
  mp*) USESMPI=yes
       ;;
  esac
  case ${BCOMP} in
  *f*) FLIB=""
       ;;
  esac

  # Compile opari table file
  [ -n "${V}" ] && echo "+++ ${OCC} ${PFLAG} ${OOINC} -c opari.tab.c"
  eval ${OCC} ${PFLAG} ${OOINC} -c opari.tab.c || exit

  if [ ${USESOMP} = "yes" ]
  then
    if [ ${USESMPI} = "yes" ]
    then
      ELIB="${ELGLIB} ${FLIB} -lompp  ${ULIB} ${HWLIB} "
    else
      ELIB="${ELGLIB} -lompp ${ULIB} ${HWLIB} "
    fi
  else
    if [ ${USESMPI} = "yes" ]
    then
      ELIB="${ELGLIB} ${FLIB} -lompp  ${ULIB} ${HWLIB} "
    else
      ELIB="${ELGLIB} -lompp ${ULIB} ${HWLIB} "
    fi
  fi

  # MODIFIED COMPILING/LINKING STEP
  [ -n "${V}" ] && echo "+++ ${COMP} ${IOPT} ${ARGS} opari.tab.o ${ELIB}"
  eval ${COMP} ${IOPT} ${ARGS} opari.tab.o ${ELIB} || exit
fi

# RENAME COMPILER OUTPUT TO ORIGINAL FILE NAME
for mfile in ${MFILES}
do
  if [ -f ${mfile} ]
  then
    TARGET=`echo ${mfile} | sed -e 's/\.mod//'`
    [ -n "${V}" ] && echo "+++ mv ${mfile} ${TARGET}"
    eval mv ${mfile} ${TARGET}
  fi
done
exit 0
