#!/bin/bash
########################################################################
#                  mcleanb                                             #
# This shell script cleans files of a MCTDH-directory form trailing    #
# blanks. Ignored are executable,object,*.dvi,*.ps,*_bk*, *_md*, and   #
# *~ files. The script uses sed.                                       #
# HDM 12/13                                                            #
########################################################################

#-----------------------------------------------------------------------
#  Definitions :
#-----------------------------------------------------------------------
minus40='----------------------------------------'
minus60=$minus40'--------------------'
minus80=$minus40$minus40
 star40='****************************************'
# set locale, so that date etc will be in uniform format.
export LC_ALL=C
echo "$minus80"
oldpwd=`pwd`
if [ -d /tmpa ] && [ -w /tmpa ] ; then
   tmp="/tmpa"
elif [ -d /tmp ] && [ -w /tmp ] ; then
   tmp="/tmp"
elif [ -d /work/${LOGNAME} ] && [ -w /work/${LOGNAME} ] ; then
   tmp="/work/${LOGNAME}"
elif [ -d /work ] && [ -w /work ] ; then
   tmp="/work"
elif [ -d /worka/${LOGNAME} ] && [ -w /worka/${LOGNAME} ] ; then
   tmp="/worka/${LOGNAME}"
elif [ -d /worka ] && [ -w /worka ] ; then
   tmp="/worka/"
elif [ -d "$HOME" ] && [ -w "$HOME" ] ; then
   tmp="$HOME"
else
   tmp=$oldpwd
fi

# --- Find the argument dir (last argument).
it=1
for i in "$@" ; do
   i1=$i
   if [ -z "${it#-[ei]}" ]; then unset i1  # all options with arguments
   elif [ -z "${i##-*}" ];  then unset i1 ; fi
   it=$i
done
dir=${i1:-$MCTDH_DIR}

if [ -z "$dir" ]; then
   echo " MCTDH_DIR is empty!"
   exit
elif [  -d "$dir" ]; then
   cd $dir
   dir=`pwd`
else
   unset dir
fi
all=0

#-----------------------------------------------------------------------
#  Read the options (if any).
#-----------------------------------------------------------------------

while getopts ":hacspe:i:" opt; do
    case $opt in
    h  ) help=1 ;;
    a  ) all=1  ;;
    c  ) chk=1  ;;
    s  ) show=1 ;;
    e  ) excl=$OPTARG ;;
    i  ) incl=$OPTARG ;;
    p  ) pr=1   ;;
    \? ) echo ' Unkown option!'
         echo $usage
         echo ' -h provides a help text.'
         exit 1 ;;
  esac
done
shift $(($OPTIND - 1))
cd $oldpwd

if [ -n "$show" ];then
   unset all
   unset excl
   unset incl
   unset pr
fi


dir2=$tmp
if [ -n "$2" ] ; then
   echo "Nothing must follow dir1."
   exit
elif [ -n "$1" ] ; then
   dir1="$1"
else
   dir1="$MCTDH_DIR"
fi

if [ -n "${dir1%%/*}" ] ; then
    if [ -d $dir1 ]; then cd $dir1; dir1=`pwd`; cd $oldpwd; fi
fi
if [ -n "${dir2%%/*}" ] ; then
    if [ -d $dir2 ]; then cd $dir2; dir2=`pwd`; cd $oldpwd; fi
fi


if [ "$1" = "-h" ] || [ "$2" = "-h" ] || [ "$3" = "-h" ]; then help=1; fi

if [ -n "$help" ] ; then
   cat <<EOF
Purpose : Clean files of a MCTDH-directory from trailing blanks.
          The files of MCTDH-directory dir1 are cleaned and
          copied back to dir1.
          Ignored are binary, object, *.dvi, *.ps, *~ files (etc).
          I.e., cleaned will be those files, which are on the MCTDH
          package before installation.
Usage   : mcleanb [ -a -s -e -i -p -h ] [dir1].
 -h     : print this help text.
 -a     : Clean all files except object/, bin/.+/ and obsolete/ ones.
 -c     : Check files for trailing blanks. Files listed, no other action taken.
 -s     : Show all files which are excluded by default but would be
          cleaned by -a. No other options allowed when -s is set.
 -e pat : Exclude file the names of which match pattern pat.
 -i pat : Include only file the names of which match pattern pat.
 -p     : Print file list (and do nothing else).
 If dir1 is not given, \$MCTDH_DIR=$MCTDH_DIR is assumed.
 The pattern pat is an egrep regular expression.

EXAMPLES:
mcleanb                 : Clean all files (except binary, object etc) of \$MCTDH_DIR .
mcleanb -i /potfit/     : Clean only files from the potfit directory of \$MCTDH_DIR .
mcleanb -c ../mctdh84.3 : Check which files of the MCTDH-directory '../mctdh84.3' are not clean.

EOF
   if [ -z "$chk" ]; then
      echo '  Clean Directory: '$dir1
   else
      echo '  Check Directory: '$dir1
   fi
   echo "$minus80"
   exit
fi


if [ ! -d $dir1 ]; then
   echo " The directory dir1 = $dir1 does not exist!"
   exit
fi
cd $dir1
dir1=`pwd`

echo ' Working Directory: '$dir1
echo ' '

if [ ! -d $dir1 ] ; then
   echo "There is no directory $dir1"
   exit
fi
if [ ! -d $dir2 ] && [ -z "$pr$chk$show" ]; then
   echo "There is no directory $dir2"
   exit
fi


#-----------------------------------------------------------------------
#  Exclude list.
#-----------------------------------------------------------------------

EXCLUDE='(/obsolete/|/\.svn/|mctdhall|.*_bk[0-9].*|.*_md[0-9].*|\./bin/binary/|\./object/|.*\.pyc|.*\.pdf|.*\.ps|.*\.dvi|.*\.aux|/install/Makefile_.*|\./doc/.*\.log$|\./doc/guide/guide\.i.*|\./doc/guide/guide\.l.*|\./doc/guide/guide\.blg|\./doc/guide/guide\.toc|.*\.swp$|.*~$|\./source/SUBR|\./source/SFILES|\./install/save-.*|\./install/dependencies|#.*#|\./install/MCTDH_client|MCTDH_IFORT_.*|\./install/MCTDH_IFORT.*|\./source/.*\.F.personal|\./source/.*\.F.original|\./source/include/.*\.inc\.original|\./source/include/.*\.inc\.private|\./source/.*\.F\.new|\./source/.*\.F\.save|Makefile\.new|Makefile\.save|Makefile\.original|include/.*\.inc\.old|include/.*\.inc\.new|include/.*\.inc\.bak|\.nfs.*|/AdvancedUser/|/yaccflex/|cleaned_.*)'

EXEX='(/obsolete/|/\.svn/|\./bin/binary/|\./object/|.*\.swp$|.*~$|#.*#|.*_bk[0-9].*|.*_md[0-9].*|/yaccflex/)'
EXIN='(/vcham_inputs/.*|/doc/vcham/example/.*|/doc/examples/.*|/doc/filter/.*)'

#-----------------------------------------------------------------------
#  Generate the flists.
#-----------------------------------------------------------------------

cd $dir1
if [ -n "$show" ]; then
   echo '######  SHOW EXCLUDED FILES ########'
   echo 'These files will be included when setting -a'
   set -f  # Do not expand shell wildcards
   flist1=`find . -type f -print | egrep -v "$EXEX" |\
           egrep -v "$EXIN" | egrep  "$EXCLUDE" `
   set +f
   n1=`echo "$flist1" | wc -l `
   n1=`echo $n1 `
   echo " ---  There are $n1 excluded files.  ---"
   echo "$flist1" | sort
   echo '-----------------------------------------------------------------'
   exit
fi

if [ $all = 0 ]; then
   flist=`find . -type f -print `
   set -f  # Do not expand shell wildcards
   flist1=`echo "$flist" | egrep -v "$EXCLUDE" `
   flist2=`echo "$flist" | egrep  "$EXIN" |\
           egrep -v '(/obsolete/|/\.svn/|.*\.swp$|.*~$|#.*#)'`
   set +f
   flist=`echo "$flist1"; echo "$flist2" `
   flist=`echo "$flist" | sort -u `
elif [ $all = 1 ];then
   flist=`find . -type f -print `
   set -f
   flist1=`echo "$flist" | egrep -v "$EXEX" `
   flist2=`echo "$flist" | egrep  "$EXIN" |\
           egrep -v '(/obsolete/|/\.svn/|.*\.swp$|.*~$|#.*#)'`
   set +f
   flist=`echo "$flist1"; echo "$flist2" `
   flist=`echo "$flist" | sort -u `
fi

if [ -n "$excl" ]; then
   flist=`echo "$flist" | egrep -v "$excl" `
fi

if [ -n "$incl" ]; then
   flist=`echo "$flist" | egrep  "$incl" `
fi


count0=0
count1=0
n1=`echo "$flist" | wc -l `
n1=`echo $n1 `
if [ $n1 -lt 9 ]; then echo "$flist" ; fi
echo " There are $n1 files on:   $dir1"

if [ -n "$pr" ]; then
   echo "$flist"
   echo "$minus80"
   echo "There are $n1 files on $dir1"
   exit
fi

echo " y: The files will be cleaned and re-written to original position."
echo " c: Checking only, list unclean files."
echo " n: Do nothing, exit."

while [ "$answ" != y ] && [ "$answ" != c ] && [ "$answ" != n ]; do
   echo -n ' OK? Type (y|c|n): '
   read answ
done

if [ -n "$chk" ] || [ "$answ" = c ]; then
   cleanedlist="cleaned_$$"
   echo "List of unclean files. "`date` > $cleanedlist
   for j in $flist ; do
      i=${j#./}
      if [ `grep -c ' $' $dir1/$i` = '0' ]; then
         count0=$((count0+1))
      else
         count1=$((count1+1))
         echo "$i" >> $cleanedlist
      fi
   done
   echo  $minus80
   echo "Number of   clean files: $count0"
   echo "Number of unclean files: $count1"
   if [ $count1 -lt 9 ]; then
      if [ $count1 -gt 0 ]; then
         cat $cleanedlist
      fi
      /bin/rm -f $cleanedlist
   else
      echo "The file names of the cleaned files are listed on:"
      echo "`pwd`/$cleanedlist"
   fi
   echo "$star40$star40"
   exit
fi

if [ "$answ" = y ]; then

   tt="ttt_${LOGNAME}_$$"
   cleanedlist="cleaned_$$"
   echo "List of cleaned files. "`date` > $cleanedlist
   for j in $flist ; do
      i=${j#./}
      if [ `grep -c ' $' $dir1/$i` = '0' ]; then
         count0=$((count0+1))
      else
         count1=$((count1+1))
         sed '1,$s/  *$//' $dir1/$i > $dir2/$tt
         chmod --reference="$dir1/$i" $dir2/$tt
         cp -f  $dir2/$tt  $dir1/$i
         chmod --reference="$dir2/$tt" $dir1/$i
         rm -f $dir2/$tt
         echo "$i" >> $cleanedlist
      fi
   done
else
   echo "No cleaning performed. Use the -c option to check what would have been done."
fi

echo  $minus80
echo "Number of   clean files: $count0"
echo "Number of unclean files: $count1"
if [ $count1 -lt 9 ]; then
   if [ $count1 -gt 0 ]; then
      cat $cleanedlist
   fi
   /bin/rm -f $cleanedlist
else
   echo "The file names of the cleaned files are listed on:"
   echo "`pwd`/$cleanedlist"
fi
echo "$star40$star40"

exit
