#! /bin/sh
#
# mkoctfile -- create a .oct file suitable for dynamic linking by
# Octave.

# Exit immediately on any error.

set -e

# Default values for these variables are filled in when Octave is
# compiled. 

: ${CPPFLAGS=%CPPFLAGS%}
: ${INCFLAGS=%INCFLAGS%}
: ${F77=%F77%}
: ${FFLAGS=%FFLAGS%}
: ${FPICFLAG=%FPICFLAG%}
: ${CC=%CC%}
: ${CFLAGS=%CFLAGS%}
: ${CPICFLAG=%CPICFLAG%}
: ${CXX=%CXX%}
: ${CXXFLAGS=%CXXFLAGS%}
: ${CXXPICFLAG=%CXXPICFLAG%}
: ${XTRA_CFLAGS=%XTRA_CFLAGS%}
: ${XTRA_CXXFLAGS=%XTRA_CXXFLAGS%}

: ${SH_LD=%SH_LD%}
: ${SH_LDFLAGS=%SH_LDFLAGS%}

: ${ALL_FFLAGS="$FFLAGS"}

: ${ALL_CFLAGS="$INCFLAGS $XTRA_CFLAGS $CFLAGS"}

: ${ALL_CXXFLAGS="$INCFLAGS $XTRA_CXXFLAGS $CXXFLAGS"}

# Local variables.

usage_msg="usage: mkoctfile [options] file ..."

cfiles=
ccfiles=
f77files=
objfiles=
octfiles=
octfile=
incflags=
ldflags=
dbg=:
strip=false

if [ $# -eq 0 ]; then
  echo $usage_msg
  exit 1;
fi

while [ $# -gt 0 ]; do
  file=
  case "$1" in
    *.c)
      file=$1
      cfiles="$cfiles $file"
    ;;
    *.cc | *.C | *.cpp)
      file=$1
      ccfiles="$ccfiles $file"
    ;;
    *.f | *.F)
      file=$1
      f77files="$f77files $file"
    ;;
    *.o)
      file=$1
      objfiles="$objfiles $file"
    ;;
    -d | --debug | -v | --verbose)
      dbg=echo
    ;;
    -h | -? | --help)
      echo $usage_msg
      cat << EOF

Options:

  -h, -? --help           Print this message.
  -IDIR                   Add -IDIR to compile commands.
  -lLIB                   Add library LIB to link command.
  -LDIR                   Add -LDIR to link command.
  -o FILE, --output FILE  Output file name.  Default extension is .oct.
  -s, --strip             Strip output file.
  -v, --verbose           Echo commands as they are executed.

  FILE                    Compile or link FILE.  Recognized file types are:

			    .c    C source
			    .cc   C++ source
			    .C    C++ source
			    .cpp  C++ source
			    .f    Fortran source
			    .F    Fortran source
			    .o    object file

EOF
      exit 0
    ;;
    -I*)
      incflags="$incflags $1";;
    ;;
    -[lL]*)
      ldflags="$ldflags $1";;
    ;;
    -o | --output)
      shift
      if [ $# -gt 0 ]; then
        octfile=`echo $1 | sed 's,\.[^.]*$,,'`.oct
      else
        echo "mkoctfile: output file name missing"
      fi
    ;;
    -s | --strip)
      strip=true
    ;;
    *)
      echo "mkoctfile: unrecognized argument $1"
      exit 1
    ;;
  esac
  if [ -n "$file" ]; then
    if [ -z "$octfile" ]; then
      octfile=`echo $file | sed 's,\.[^.]*$,,'`.oct
    fi
  fi
  shift
done

# Compile Fortran, C, and C++ files.  Add the name of each object file
# that is produced to the overall list of object files.

if [ -n "$f77files" ]; then
  for f in $f77files; do
    case $f in
      *.f)
        b=`echo $f | sed 's,\.f$,,'`
      ;;
      *.F)
        b=`echo $f | sed 's,\.F$,,'`
      ;;
    esac
    o=$b.o
    objfiles="$objfiles $o"
    $dbg $F77 -c $FPICFLAG $ALL_FFLAGS $f -o $o
    eval $F77 -c $FPICFLAG $ALL_FFLAGS $f -o $o
  done
fi

if [ -n "$cfiles" ]; then
  for f in $cfiles; do
    b=`echo $f | sed 's,\.c$,,'`
    o=$b.o
    objfiles="$objfiles $o"
    $dbg $CC -c $CPPFLAGS $CPICFLAG $ALL_CFLAGS $incflags $f -o $o
    eval $CC -c $CPPFLAGS $CPICFLAG $ALL_CFLAGS $incflags $f -o $o
  done
fi

if [ -n "$ccfiles" ]; then
  for f in $ccfiles; do
    case $f in
      *.cc)
        b=`echo $f | sed 's,\.cc$,,'`
      ;;
      *.C)
        b=`echo $f | sed 's,\.C$,,'`
      ;;
      *.cpp)
        b=`echo $f | sed 's,\.cpp$,,'`
      ;;
    esac
    o=$b.o
    objfiles="$objfiles $o"
    $dbg $CXX -c $CPPFLAGS $CXXPICFLAG $ALL_CXXFLAGS $incflags $f -o $o
    eval $CXX -c $CPPFLAGS $CXXPICFLAG $ALL_CXXFLAGS $incflags $f -o $o
  done
fi

# Link all the object files.

$dbg $SH_LD $SH_LDFLAGS -o $octfile $objfiles $ldflags
eval $SH_LD $SH_LDFLAGS -o $octfile $objfiles $ldflags

# Maybe strip it.

if $strip; then
  $dbg strip $octfile
  eval strip $octfile
fi

exit 0
