#!/bin/bash
#
# This script generates the dependencies on include files.
# One has to run it under Linux, as it uses gcc.
# Copy the file dependencies to the end of the Makefile.
# The MCTDH package has to be installed and all object files must
# already exist.
#
# HDM 06/01
#-----------------------------------------------------------------------

if [ "$1" = "-h" ] ; then
      minus40='----------------------------------------'
      echo " "
      echo $minus40$minus40
      echo "mkdepend generates a list of dependencies on include files."
      echo "This list is written to the file dependencies."
      echo "The user is prompted if he wishes to update the Makefile."
      echo 'Usage : ./mkdepend (while being in $MCTDH_DIR/install).'
      echo 'Or    : ./mkdepend <compiler>. The default is g77.'
      echo " "
      echo "Note: mkdepend calls gcc and thus should be run under Linux."
      echo "Note: All object files must already exist. (run: compile all)."
      echo $minus40$minus40
      echo " "
      exit
fi

SRCDIR="mctdh gendvr genoper geninwf opfuncs propwf \
        analyse potfit fd_cmplx fd_real vcham oct"

ms=$MCTDH_DIR/source
mi=$ms/include
obj=$MCTDH_DIR/object/i686/gfortran
if [ -n "$1" ]; then obj=$MCTDH_DIR/object/i686/$1 ; fi
if ! [ -d $obj ] ; then obj=$MCTDH_DIR/object/i686/g77 ; fi
if ! [ -d $obj ] ; then obj=$MCTDH_DIR/object/x86_64/gfortran ; fi
if ! [ -d $obj ] ; then echo "No object file. Compile all with gfortran" ; exit ; fi
echo "Object file : $obj"
pwdir=`pwd`
cd $obj
ls *.o > $pwdir/ofiles
cd $pwdir
ofc=`cat ofiles | wc -l`
if [ $ofc -lt 45 ] ; then
   echo "Only $ofc objects in ofiles"
   echo 'Need to "compile all" ? '
   echo "Object file : $obj"
   cat ofiles
   exit
fi

dt=`date`
dt1=`echo "$dt" | tr -s ' ' | cut -d' ' -f2-3 | tr ' ' '_' `
dt1=${dt1}_$$
if [ -f dependencies ] ; then
    mv dependencies dependencies_$dt1
fi
cat /dev/null > clist

# The new gcc 3.2 behaves differently
gcc3=`gcc --version | grep -i gcc | egrep ' (3|4)\.[0-9]'`
if [ -n "$gcc3" ] ; then
   Fo="\.o:"
else
   Fo="\.F\.o:"
fi

# Here the work begins. Run through all source-directories.

for dir in $SRCDIR; do

    if [ $dir = analyse ] ; then
        dir1=$dir
        cd $ms/$dir
        mv template.F template
        mi=$ms/include
        pinc="\$(PATH_INC)"
    elif [ $dir = fd_real ] ; then
        dir1=filter
        mi=$ms/fd_real
        pinc="\$(PATH_FILTER)"
    elif [ $dir = fd_cmplx ] ; then
        dir1=fdc
        mi=$ms/fd_cmplx
        pinc="\$(PATH_FDC)"
    else
        dir1=$dir
        mi=$ms/include
        pinc="\$(PATH_INC)"
    fi
    dd=`echo $dir1 | tr [a-z] [A-Z]`
    ar="\$(AR_$dd)(\$(PATH_$dd)"
    echo "$dir $ar $pinc" | awk '{ printf("%-13s %-35s %-16s\n",$1,$2,$3) }'

#   gcc -MM : Run  only the preprocessor and output a rule suitable for
#             make describing the  dependencies  of  each  object file.
#   The tr command replaces "\" by "%", which is more easy to handle
#   by sed.

    ls $ms/$dir/*.F >/dev/null 2>&1 && \
    gcc -MM -I$mi $ms/$dir/*.F | tr '\\' '%' \
    | sed "/${Fo}.*\.F$/d" \
    | sed "/^[a-z].*${Fo} %$/{
           N
           \?\n *${ms}.*\.F\$?D
           }"\
    | sed "\?^ *${ms}.*\.F?d" \
    | sed "s?$mi?$pinc?" \
    | sed "/${Fo}/s?^\([a-z0-9_]*\)${Fo}.*?$ar/\1\.o\)  : %?"\
      >> $pwdir/clist

    if [ $dir = analyse ] ; then mv template template.F ; cd $pwdir ; fi
done

# The first three seds comand removes program lines that are not followed
#   by include lines.
# The forth sed comand replaces $MCTDH_DIR/source/include by $(PATH_INC).
# The fifth sed comand replaces e.g. "einpbas.F.o" by
#  "$(AR_GENDVR)($(PATH_GENDVR)/einpbas.o) : %".
# The "%" ist later replaced by "\".

echo "clist -> dependencies"
echo "#  MCTDH dependencies created by mkdepend. $dt" > dependencies

# 1) Write lines that contain .inc to dependencies and translate % -> \
# 2) Ignore lines that contain /*/source/* (but not .inc)
# 3) If main program (fgrep finds the file among the ofiles) then
#    replace path (e.g. "$(AR_GENDVR)($(PATH_GENDVR)") by "$(PATH_MAIN)".
#    Otherwise just copy to dependencies while translating % -> \

while read LINE
  do
    if [ -z "${LINE##*.inc*}"  ] ; then
      echo "     $LINE" | tr '%' '\\' >> dependencies
    elif [ -z "${LINE##/*/source/*}" ] ; then
      :
    else
      prog=${LINE##\$(AR_*)(\$(PATH_*)/}
      prog=${prog%%.o)*}
      pprog=`fgrep ${prog}8 ofiles`
      if [ -n "$pprog" ] ; then
         pprog="\$(PATH_MAIN)/$prog\$(VER).o  : \\"
         echo $pprog >> dependencies
      else
         echo $LINE | tr '%' '\\' >> dependencies
      fi
    fi
  done < clist
echo ' ' >> dependencies

rm -f ofiles
rm -f clist


#  Append dependencies to Makefile, if desired.

echo -n "Shall I update the Makefile? Type y or n : "
read ans
if [ "$ans" = y ] || [ "$ans" = yes ] || [ "$ans" = Y ] ; then
    sed '/#  MCTDH dependencies created/,$d' Makefile > Makefile.new
    mv Makefile Makefile_$dt1
    cat dependencies >> Makefile.new
    mv Makefile.new Makefile
    echo "Makefile updated. Old Makefile saved to Makefile_$dt1"
fi

exit

