#!/bin/bash
####################################################################
#                  MCL                                             #
# MCTDH Code List. Lists the number of routines and files of       #
# an MCTDH directory.                                              #
#                                                                  #
# HDM 02/01                                                        #
####################################################################

minus40='----------------------------------------'
# set locale, so that date etc will be in uniform format.
export LC_ALL=C

mctdh=$MCTDH_DIR
if [ "$1" = "-p" ] ; then
   print=1
   shift 1
elif [ "$1" = "-l" ] ; then
   if [ -n "$2" ] ; then cd $2 ; shift 1 ;fi
   mdir=`pwd`
   shift 1
   unset mctdh

fi
if [ "$1" = "-h" ] || [ "$2" = "-h" ] ||  [ "$3" = "-h" ] ; then
   echo "$minus40$minus40"
   echo "MCTDH Code List."
   echo "Purpose: List the number of code-lines, subroutines, etc."
   echo "Usage  : mcl [-h] [-p] [-l | -l dir] ."
   echo '-h     : print this help text.'
   echo '-p     : write filenames to $MCTDH_DIR/allfiles.'
   echo '-l     : List the current directory rather than $MCTDH_DIR.'
   echo '-l dir : List the directory "dir" rather than $MCTDH_DIR.'
   echo "$minus40$minus40"
   exit
elif [ "$1" = "-l" ] ; then
   if [ -n "$2" ] ; then cd $2 ; fi
   mdir=`pwd`
   unset mctdh
elif [ "$1" = "-p" ] ; then
   print=1
fi

# Trying o find a MCTDH directory.
 while [ -z "$mctdh" ] ; do
    ls | tr '\n' ' ' | fgrep -w bin | fgrep -w elk_inputs | \
        fgrep -w inputs | fgrep -w source | fgrep -w install | \
        fgrep -w doc | fgrep -w operators | fgrep -w pinputs > /dev/null
    if [ $? = 0 ] ; then
       mctdh=$mdir
    else
       cd ../
       mdir=`pwd`
       length=`echo "$mdir" | wc -c`
       if [ $length -le 3 ] ; then
          echo "This does not seem to be a MCTDH directory!"
          exit 1
       fi
    fi
 done

#--  set awk1 to awk or nawk if gawk is not available ---#
if [ -z "$awk1" ] ; then
   exist=`which gawk | cut -d' ' -f1 | fgrep '/bin'`
   if [ -n "$exist" ] ; then
      awk1=gawk
   fi
fi
if [ -z "$awk1" ] ; then
   exist=`which nawk | cut -d' ' -f1 | fgrep '/bin'`
   if [ -n "$exist" ] ; then
      awk1=nawk
   fi
fi
if [ -z "$awk1" ] ; then
   exist=`which awk | cut -d' ' -f1 | fgrep '/bin'`
   if [ -n "$exist" ] ; then
      awk1=awk
   fi
fi

function sub_count()
{
# This function is taken from mutil (S.Wefing).
# first argument describes what is counted
   what=$1
   shift

# the other argments are the names of the files ...
# ... count them
   let fc=0
   for f in $@; do
      let fc+=1
   done
   if test $fc -eq 0; then
      return
   fi
   count[0]=$fc

# ... count their lines and their bytes
   let i=1
   for c in `cat $*|wc -lc`; do
      count[$i]=$c
      let i+=1
   done

# convert bytes to kilo bytes
   count[2]=$((count[2]/1024))

# print results
   echo "$what" ! ${count[0]} ! ${count[1]} ! ${count[2])} | \
   $awk1 -F"!" '{ printf("%-28s  %8s  %18s  %18s \n",$1,$2,$3,$4) }'

# add to total count
   total[0]=$((total[0]+count[0]))
   total[1]=$((total[1]+count[1]))
   total[2]=$((total[2]+count[2]))

   return

}

#-----------------------------------------------------------------------------
#     Actual script starts here.
#-----------------------------------------------------------------------------

cd $mctdh
blk12='            '
minus10='       --------'
minus20='--------------------'
star40='****************************************'

# Generate lists of Fortran, C, include, html and tex files.

 ffil77=`find ./source -name "*.[Ff]" -print | fgrep -v obsolete`
 ffil90=`find ./source -name "*.[Ff]90" -print | fgrep -v obsolete`
 ffiles=`echo -e "$ffil77\n$ffil90"`
 stop1=$?
 cfiles=`find ./source -name "*.[Cc]" -print`
 ifiles=`find ./source -name "*.inc"  -print`
 hfiles=`find ./doc    -name "*.html" -print`
 tfiles=`find ./doc    -name "*.tex"  -print`
 stop2=$?
 sfiles=`egrep -l '#!.*/bin' ./{bin,install}/*  2>/dev/null \
      | egrep -v '(.*~|save-.*|.*_bk.*|.*_md.*|.*\.orig|.*\.old|.*\.1|.*\.svn)' `
 pfiles=`ls ./*inputs/*.inp`
 ofiles=`ls ./operators/{*.op,*.srf}`

if [ $stop1 -gt 0 ] || [ $stop2 -gt 0 ] ; then
   echo ' '
   echo "This is not a MCTDH directory!"
   echo "$mctdh"
   echo $minus40$minus20
   exit
fi

# initialize array for total counts
 total[0]=0
 total[1]=0
 total[2]=0

 echo "$star40$star40"
 echo " "
 echo "MCTDH_DIR = $mctdh"
 echo " "

 echo  "PROGRAM CODE" ! files ! lines ! kbytes | \
 $awk1 -F"!" '{ printf("%-28s  %8s  %18s  %18s \n",$1,$2,$3,$4) }'

 echo "$minus20  $minus10     $minus10      $minus10"

 sub_count "Fortran code" "$ffiles"
 sub_count "Fortran include" "$ifiles"
 sub_count "C code" "$cfiles"
 echo ' '
 sub_count "Shell scripts" "$sfiles"
 sub_count "Input files" "$pfiles"
 sub_count "Operator files" "$ofiles"
 echo ' '
 sub_count "HTML documentation" "$hfiles"
 sub_count "TeX  documentation" "$tfiles"
 echo "$minus20  $minus10     $minus10      $minus10"

if [ -n "$print" ] ; then
   date > allfiles
   echo "$ffiles" | sort >> allfiles
   echo "$ifiles" | sort >> allfiles
   echo "$cfiles" | sort >> allfiles
   echo "$sfiles" | sort >> allfiles
   echo "$pfiles" | sort >> allfiles
   echo "$ofiles" | sort >> allfiles
   echo "$hfiles" | sort >> allfiles
   echo "$tfiles" | sort >> allfiles
fi

# print total counts
 echo  "TOTAL" ! ${total[0]} ! ${total[1]} ! ${total[2]} | \
 $awk1 -F"!" '{ printf("%-28s  %8s  %18s  %18s \n",$1,$2,$3,$4) }'
 echo " "
 echo "$minus40$minus40"

 nmbp=`egrep -i '(^      program |^program )'  $ffiles | wc -l `

 nmbs=`egrep -i "^      subroutine "  $ffiles | wc -l `

 nmbf=`egrep -i "^     ( comp.*| dou.*| real\*8 | integer | )function" \
         $ffiles | wc -l `

 nmbc=`egrep -i "^\*  C-routine " $cfiles | wc -l `

 nmba=$(($nmbp+$nmbs+$nmbf+$nmbc))

 echo " "
 echo "Number of Fortran programs    : "$nmbp
 echo "Number of Fortran subroutines : "$nmbs
 echo "Number of Fortran functions   : "$nmbf
 echo "Number of C routines          : "$nmbc
 echo "                                ----- "
 echo "TOTAL                         : "$nmba
 echo " "
 echo "$minus40$minus40"
 bindir=`find $mctdh/bin/binary/* -type d `
 if [ -n "$bindir" ]; then binmem=`du -cs $bindir | cut -f1`; fi
 for ibin in $binmem ; do : ; done  # find the last item
 binmem=${ibin:-0}
 objmem=0
 if [ -d $mctdh/object ]; then objmem=`du -s $mctdh/object | cut -f1`; fi
 allmem=`du -s $mctdh | cut -f1`
 restmem=$(($allmem-$binmem-$objmem))
 am=$(($allmem/1024))
 ak=$(($allmem%1024))
 allmem=${am}M' '${ak}K
 am=$(($binmem/1024))
 ak=$(($binmem%1024))
 binmem=${am}M' '${ak}K
 am=$(($objmem/1024))
 ak=$(($objmem%1024))
 objmem=${am}M' '${ak}K
 am=$(($restmem/1024))
 ak=$(($restmem%1024))
 restmem=${am}M' '${ak}K
 echo "Memory consumption:  MCTDH_DIR   object-files   binary-files      rest"
 echo -e " \t\t     $allmem \t  $objmem \t   $binmem  \t $restmem"
 echo "$star40$star40"
 echo " "

exit

