#!/bin/sh

progname=hpf

print_usage() {
cat <<.
Usage: ${progname} [-help] [-dryrun] [-T|-S|-c] [-o OUT_FILE]
           [-C=CHECK] [-stack STACK_SIZE] [-procRANK EXTENT ...]
           [-temp=TEMP_DIR] [-v] [-w]
           [-compOpts COMP_OPTS] [-linkOpts LINK_OPTS]
           FILE ... [-lLIB_NAME] ...
where
   OUT_FILE     = name of final output file
   CHECK        = run-time check to be performed (stack, ...)
   STACK_SIZE   = words of memory reserved for temporary arrays
   RANK         = default processor arrangement rank
   EXTENT       = default processor arrangement extent
   TEMP_DIR     = directory used for temporary files
   COMP_OPTS    = string added to option list for target compiler
   LINK_OPTS    = string added to option list for linker
   FILE         = input file
   LIB_NAME     = output linked with library libLIB_NAME.a
.
}

HPF_HOME="@HPF_HOME@"

ADLIB="${HPF_HOME}/lib/libadlib.a"
FADLIB="${HPF_HOME}/lib/libadapt.a"

MPILIB="@MPI_LIB_DIR@/libmpi.a"

F90_LIB="@F90_LIB_DIR@/libf90.a"

ADAPT="${HPF_HOME}/bin/adapt"

LIBRARIES="$FADLIB $ADLIB $MPILIB $F90_LIB -lm"

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#                                                                           #
#  Process args to set variables: TRANSLATOR_OPTS, COMPILER_OPTS,           #
#  LINKER_OPTS, FILES, TEMP_DIR, OUTPUT_FILE, and flags:                    #
#  translator_output, assembler_output, object_output, dryrun, verbose      #
#                                                                           #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

TRANSLATOR_OPTS=""
COMPILER_OPTS="-mismatch -w"
LINKER_OPTS=""
FILES=""
TEMP_DIR="."
OUTPUT_FILE=""
while test -n "$1" ; do
  case $1 in
    -help)
      print_usage >& 2
      exit 1
      ;;
    -T)
      if test -z "$assembler_output" -a -z "$object_output" ; then
        translator_output="yes"
      else
	echo "${progname}: -T, -S and -c flags are mutually exclusive"
	exit 1
      fi
      ;;
    -S)
      if test -z "$translator_output" -a -z "$object_output" ; then
        assembler_output="yes"
      else
	echo "${progname}: -T, -S and -c flags are mutually exclusive"
	exit 1
      fi
      ;;
    -c)
      if test -z "$translator_output" -a -z "$assembler_output" ; then
        object_output="yes"
      else
	echo "${progname}: -T, -S and -c flags are mutually exclusive"
	exit 1
      fi
      ;;
    -dryrun)
      dryrun="yes"
      verbose="yes"
      ;;
    -l*)
      FILES="$FILES $1"
      ;;
    -o)
      shift
      OUTPUT_FILE="$1"
      ;;
    -C=*)
      CHECK=`echo $1 | sed 's/-C=//'`
      case $CHECK in
        stack)
	  TRANSLATOR_OPTS="$TRANSLATOR_OPTS -c"
          ;;
        *)
	  echo "${progname}: unrecognised run-time check: $1"
	  exit 1
          ;;
      esac
      ;;
    -stack)
      shift
      STACK_SIZE="$1"
      if test -n "`echo $STACK_SIZE | tr -d [0-9]`" ; then
        echo "${progname}: non-numeric STACK_SIZE: $STACK_SIZE"
        exit 1
      fi
      TRANSLATOR_OPTS="$TRANSLATOR_OPTS -s $STACK_SIZE"
      ;;
    -proc*)
      RANK=`echo $1 | sed 's/-proc//'`
      if test -n "`echo $RANK | tr -d [0-9]`" ; then
        echo "${progname}: non-numeric RANK: $RANK"
        exit 1
      fi
      TRANSLATOR_OPTS="$TRANSLATOR_OPTS -p$RANK"
      while test $RANK -ne 0 ; do
        shift
        EXTENT="$1"
        if test -n "`echo $EXTENT | tr -d [0-9]`" ; then
          echo "${progname}: non-numeric EXTENT: $EXTENT"
          exit 1
        fi
        TRANSLATOR_OPTS="$TRANSLATOR_OPTS $EXTENT"
        RANK=`expr $RANK - 1`
      done
      ;;
    -temp=*)
      COMPILER_OPTS="$COMPILER_OPTS $1"
      LINKER_OPTS="$LINKER_OPTS $1"
      TEMP_DIR=`echo $1 | sed 's/-temp=//'`
      ;;
    -v)
      COMPILER_OPTS="$COMPILER_OPTS $1"
      verbose="yes"
      ;;
    -w)
      TRANSLATOR_OPTS="$TRANSLATOR_OPTS -w"
      #LINKER_OPTS="$LINKER_OPTS $1"
      ;;
    -compOpts)
      shift
      COMPILER_OPTS="$COMPILER_OPTS $1"
      ;;
    -linkOpts)
      shift
      LINKER_OPTS="$LINKER_OPTS $1"
      ;;
    -*)
      print_usage >& 2
      exit 1 ;;
    *.hpf | *.hpf90 | *.h90 | *.f | *.c | *.a | *.o)
      FILES="$FILES $1"
      ;;
    *)
      echo "${progname}: unrecognised file suffix: $1"
      exit 1
      ;;
  esac
  shift
done

if test -n "$translator_output" ; then
  test
elif test -n "$assembler_output" ; then
  COMPILER_OPTS="$COMPILER_OPTS -S"
else
  COMPILER_OPTS="$COMPILER_OPTS -c"
fi

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#                                                                           #
#  Call the translator and compiler                                         #
#                                                                           #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

for file in $FILES ; do
  case $file in
    *.hpf | *.hpf90 | *.h90)

      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      #                                                                     #
      #  Initialise translator output file name: `TRANSLATED_FILE'          #
      #                                                                     #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

      if test -n "$translator_output" ; then

        if test -n "$OUTPUT_FILE" ; then
          TRANSLATED_FILE="$OUTPUT_FILE"
        else
          TRANSLATED_FILE="`basename $file | sed 's/\.[^\.]*$//'`.f"
        fi

        # Remove file if it already exists
        if test -f "$TRANSLATED_FILE" ; then
          if test -n "$verbose" ; then
            echo rm "$TRANSLATED_FILE"
          fi
          if test -z "$dryrun" ; then
            rm "$TRANSLATED_FILE"
          fi
        fi

      else

        # Generate name for temporary file
        TEMP_BASE=${TEMP_DIR}/${progname}_$$
        TRANSLATED_FILE=${TEMP_BASE}.f

        # Change name if file already exists
        while test -f "$TRANSLATED_FILE" ; do
          TEMP_BASE=${TEMP_BASE}_
          TRANSLATED_FILE=${TEMP_BASE}.f
        done
      fi

      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      #                                                                     #
      #  Call the translator                                                #
      #                                                                     #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

      if test -n "$verbose" ; then
        echo ${ADAPT} $TRANSLATOR_OPTS -o $TRANSLATED_FILE $file
      fi
      if test -z "$dryrun" ; then
        if ${ADAPT} $TRANSLATOR_OPTS -o $TRANSLATED_FILE $file ; then
          test
        else
          # Remove incomplete translated file and abort driver
          if test -f "$TRANSLATED_FILE" ; then
            if test -n "$verbose" ; then
              echo rm $TRANSLATED_FILE
            fi
            rm $TRANSLATED_FILE
          fi

          exit 1
        fi
      fi

      if test -n "$translator_output" ; then continue ; fi

      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      #                                                                     #
      #  Initialise compiler output file name: `COMPILED_FILE'              #
      #                                                                     #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

      if test -n "$assembler_output" ; then
        if test -n "$OUTPUT_FILE" ; then
          COMPILED_FILE="$OUTPUT_FILE"
        else
          # f90 outputs C ``assembler''...
          COMPILED_FILE="`basename $file | sed 's/\.[^\.]*$//'`.c"
        fi
      elif test -n "$object_output" ; then
        if test -n "$OUTPUT_FILE" ; then
          COMPILED_FILE="$OUTPUT_FILE"
        else
          COMPILED_FILE="`basename $file | sed 's/\.[^\.]*$//'`.o"
        fi
      else
        COMPILED_FILE="`basename $file | sed 's/\.[^\.]*$//'`.o"
        LINKER_FILES="$LINKER_FILES $COMPILED_FILE"
      fi

      # Remove file if it already exists
      if test -f "$COMPILED_FILE" ; then
        if test -n "$verbose" ; then
          echo rm "$COMPILED_FILE"
        fi
        if test -z "$dryrun" ; then
          rm "$COMPILED_FILE"
        fi
      fi

      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      #                                                                     #
      #  Call the compiler                                                  #
      #                                                                     #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

      if test -n "$verbose" ; then
        echo f90 $COMPILER_OPTS -o $COMPILED_FILE $TRANSLATED_FILE
      fi
      if test -z "$dryrun" ; then
        if f90 $COMPILER_OPTS -o $COMPILED_FILE $TRANSLATED_FILE ; then
          test
        else
          # Abort driver.  This shouldn't really happen.
          echo "${progname}: errors in generated code."\
               "See temporary file $TRANSLATED_FILE"
          exit 1
        fi
      fi

      if test -n "$verbose" ; then
        echo rm $TRANSLATED_FILE
      fi
      if test -z "$dryrun" ; then
        rm $TRANSLATED_FILE
      fi

      ;;

    *.c | *.f)
      # Files passed directly to the `f90' compiler

      if test -n "$translator_output" ; then
        continue 
      fi

      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      #                                                                     #
      #  Initialise compiler output file name: `COMPILED_FILE'              #
      #                                                                     #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

      if test -n "$object_output" ; then
        if test -n "$OUTPUT_FILE" ; then
          COMPILED_FILE="$OUTPUT_FILE"
        else
          COMPILED_FILE="`basename $file | sed 's/\.[^\.]*$//'`.o"
        fi
      else
        COMPILED_FILE="`basename $file | sed 's/\.[^\.]*$//'`.o"
        LINKER_FILES="$LINKER_FILES $COMPILED_FILE"
      fi

      # Remove file if it already exists
      if test -f "$COMPILED_FILE" ; then
        if test -n "$verbose" ; then
          echo rm "$COMPILED_FILE"
        fi
        if test -z "$dryrun" ; then
          rm "$COMPILED_FILE"
        fi
      fi

      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      #                                                                     #
      #  Call the compiler                                                  #
      #                                                                     #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

      if test -n "$verbose" ; then
        echo f90 $COMPILER_OPTS -o $COMPILED_FILE $file
      fi
      if test -z "$dryrun" ; then
        if f90 $COMPILER_OPTS -o $COMPILED_FILE $file ; then
          test
        else
          # Abort driver.
          exit 1
        fi
      fi

      ;;
    *.a | *.o)
      # Files passed directly to the linker

      if test -n "$translator_output" -o -n "$assembler_output" -o \
              -n "$object_output" ; then
        continue 
      fi

      LINKER_FILES="$LINKER_FILES $file"
      ;;
    -l*)
      # Library files passed directly to the linker

      if test -n "$translator_output" -o -n "$assembler_output" -o \
              -n "$object_output" ; then
        continue 
      fi

      LINKER_FILES="$LINKER_FILES $file"
      ;;
  esac
done

if test -n "$translator_output" -o -n "$assembler_output" -o \
        -n "$object_output" ; then
  exit 
fi

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#                                                                           #
#  Call the linker                                                          #
#                                                                           #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if test -n "$OUTPUT_FILE" ; then
  LINKER_OPTS="$LINKER_OPTS -o $OUTPUT_FILE"
fi

if test -n "$verbose" ; then
  echo c++ $LINKER_OPTS $LINKER_FILES $LIBRARIES
fi
if test -z "$dryrun" ; then
  c++ $LINKER_OPTS $LINKER_FILES $LIBRARIES
fi

