#!/bin/bash
####################################################################
#                  MCG                                             #
# MCTDH Code Grep. Finds strings or regex in MCTDHFortran files.   #
# Uses egrep                                                       #
#                                                                  #
# HDM 02/01                                                        #
####################################################################

purp="Purpose: Search for a string or a regex within the MCTDH Fortran files."
usage="Usage  : mcg [ -a -b -i -w -c -h ] regex [dir]."
help1='-h   : print this help text.'
help2='-i   : Let egrep work case insensitive (see man egrep "-i").'
help3='-w   : Search for a word (see man egrep "-w").'
help4='-c   : Search additionally through the C-files.'
help9='-u   : Do not modify the regex-input. (unmodified, see below).'
hlp5a='-a n : Print n lines after  the match. (See man egrep "-A").'
hlp5b='-b n : Print n lines before the match. (See man egrep "-B").'
hlp5c='-e p : Exclude files the names of which match pattern p.'
hlp5d='       e.g. "-e '"'(vcham|analyse)'"' " will ignore all files'
hlp5e='       from directories vcham and analyse.'
help6='--   : End of options. This allows to search for e.g "-4".'
help7='If dir is given, then the search is started relative'
help8=' to $MCTDH_DIR/source/dir.'
txt='NB: To make the input simpler (no quoting, no backslash), there apply'
tx1='    the following transformation rules:'
tx2='    { -> \( ;  } -> \) ;  * -> \* ; . -> \. ;   -> * ;   -> .*'
tf2='    { -> \( ;  } -> \) ;  * -> \* ; . -> \. ;   -> * ;   -> .*'
tx3='    Furthermore, a final "=" is replaced by " *=" '
tx4='    These transformations are switched off by the option -u'
tx5="Example:  mcg b.c{d}fg=   is equivalent to: "
tf5="Example:  mcg b.c{d}fg=   is equivalent to: "
tx6="  mcg -u 'b\.c\(d\)*f.*g *='"
minus40='----------------------------------------'
tyt='NB: If you are working on a german (french) keyboard, set the environment'
ty1='    variable: "export MCTDH_KB=german" (french) and run "mcg -h" again.'
eopt='-n'

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

while getopts ":a:b:e:hiwcu" opt; do
    case $opt in
    h  ) echo "$minus40$minus40"
         echo "MCTDH Code Grep"
         echo "$purp"
         echo "$usage"
         echo "  $help1"
         echo "  $help2"
         echo "  $help3"
         echo "  $help4"
         if [ "$MCTDH_KB" = german ] ; then echo "  $help9" ; fi
         echo "  $hlp5a"
         echo "  $hlp5b"
         echo "  $hlp5c"
         echo "  $hlp5d"
         echo "  $hlp5e"
         echo "  $help6"
         echo ' '
         echo "$help7$help8"
         echo ' '
       if [ "$MCTDH_KB" = german ] ; then
         echo "$txt"
         echo "$tx1"
         echo "$tx2"
         echo "$tx3"
         echo "$tx4"
         echo "$tx5$tx6"
       elif [ "$MCTDH_KB" = french ] ; then
         echo "$txt"
         echo "$tx1"
         echo "$tf2"
         echo "$tx3"
         echo "$tx4"
         echo "$tf5$tx6"
       else
         echo "$tyt"
         echo "$ty1"
       fi
         echo "$minus40$minus40"
         exit ;;
    e  ) excl="$OPTARG" ;;
    i  ) eopt=${eopt}i ;;
    w  ) eopt=${eopt}w ;;
    u  ) unmodified=1  ;;
    a  ) eopt="$eopt -A $OPTARG" ;;
    b  ) eopt="$eopt -B $OPTARG" ;;
    c  ) ccode=1 ;;
    \?) echo -e "\nERROR: option $OPTARG unknown!"
        exit 1 ;;

  esac
done
shift $(($OPTIND - 1))

if [ -z "$unmodified" ] && [ "$MCTDH_KB" = german ] ; then
# Transform the input regular expression.
   reg=` echo "$1" | sed -e  's/(/\\\(/g'   -e  's/)/\\\)/g' \
                         -e  's/{/\\\(/g'   -e  's/}/\\\)/g' \
                         -e  's/\*/\\\*/g'  -e  's/|/\\\|/g' \
                         -e  's/\./\\\./g'   \
                         -e  's/\+/\\\+/g'  -e  's/\?/\\\?/g' \
                         -e  's//\*/g'     -e  's//\.\*/g' `

   regex=` echo "$reg" | sed -e 's/\\\\(/\\\(/g' -e 's/\\\\)/\\\)/g' `

   reg=${regex%=}
   if [ "$reg" != "$regex" ] ; then regex=${reg}' *=' ; fi
   echo "Searching for : $regex"

elif [ -z "$unmodified" ] && [ "$MCTDH_KB" = french ] ; then
   reg=` echo "$1" | sed -e  's/(/\\\(/g'   -e  's/)/\\\)/g' \
                         -e  's/{/\\\(/g'   -e  's/}/\\\)/g' \
                         -e  's/\*/\\\*/g'  -e  's/|/\\\|/g' \
                         -e  's/\./\\\./g'   \
                         -e  's/\+/\\\+/g'  -e  's/\?/\\\?/g' \
                         -e  's//\*/g'     -e  's//\.\*/g' `

   regex=` echo "$reg" | sed -e 's/\\\\(/\\\(/g' -e 's/\\\\)/\\\)/g' `

   reg=${regex%=}
   if [ "$reg" != "$regex" ] ; then regex=${reg}' *=' ; fi
   echo "Searching for : $regex"
else
   regex=$1
fi

ms=$MCTDH_DIR/source
dir="$2"
if [ -n "$dir" ] ; then
    ms=$ms/$dir
fi
cd $ms

    ffiles=`find . -name "*.[Ff]" -type f -print`
    f90files=`find . -name "*.[Ff]90" -type f -print`
    ffiles=`echo -e "$ffiles\n$f90files" | egrep -v 'source/.*\.(new|old)/'`
if [ -n "$ccode" ] ; then
    cfiles=`find . -name "*.[Cc]" -type f -print`
fi
if [ "$dir" = "include" ] ; then
    egrep $eopt -- "$regex" *.inc
    exit
else
    ifiles=`find . -name "*.inc"  -type f -print`
fi

if [ -z "$excl" ]; then
   all=`echo -e "$ffiles \n$cfiles \n$ifiles" `
else
   all=`echo -e "$ffiles \n$cfiles \n$ifiles" | egrep -v "$excl" `
fi

egrep $eopt -- "$regex" $all | sed -e 's!./!!' -e 's!:! !2' | tr -s ' ' | \
awk '{ printf("%-28s %s %s %s %s %s %s %s %s %s %s %s %s\n",\
$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13) }'

exit

