#! /bin/sh
#
#   Checks the latest PETSc patch number at the ftp site
#   If needed, brings over the patch tar file and applies it
#   For all arches available on the current machine updates any 
#      libraries that all already built (ignores arches that have no
#      libraries built yet) after the user for permission
#   Reminds the user to run petscupdate on all other systems for
#      libraries that have already been built.
#
#  Uses the PETSc sh script urlget
#
#--------------------------------------------------------------
#
#  Locate the PETSc directory
#
if [ "$PETSC_DIR" != "" ]; then
  if [ -d $PETSC_DIR ]; then
    if [ ! -f $PETSC_DIR/include/petscversion.h ]; then
      echo "Though the directory " $PETSC_DIR " indicated by the"
      echo "PETSC_DIR environmental variable exists it does not"
      echo "have the include/petscversion.h file" 
      exit
    fi
  else
    echo "The environmental variable PETSC_DIR points to a nonexistent"
    echo "directory: " $PETSC_DIR
    exit
  fi
else
  if [ -f include/petscversion.h ]; then
    PETSC_DIR=`pwd`
  else
    echo "Cannot determine the PETSc installation directory"
    echo "Either run petscupdate from the PETSc installation directory"
    echo "or set the environmental variable PETSC_DIR and run petscupdate again"
    exit
  fi
fi
#
#  Get installed PETSc version
#
VERSION_MAJOR=`grep PETSC_VERSION_MAJOR $PETSC_DIR/include/petscversion.h | sed -e "s/#define PETSC_VERSION_MAJOR[ ]*//g"`
VERSION_MINOR=`grep PETSC_VERSION_MINOR $PETSC_DIR/include/petscversion.h | sed -e "s/#define PETSC_VERSION_MINOR[ ]*//g"`
VERSION_SUBMINOR=`grep PETSC_VERSION_SUBMINOR $PETSC_DIR/include/petscversion.h | sed -e "s/#define PETSC_VERSION_SUBMINOR[ ]*//g"`
PATCH_LEVEL=`grep PETSC_PATCH_LEVEL $PETSC_DIR/include/petscversion.h | sed -e "s/#define PETSC_PATCH_LEVEL[ ]*//g"`
VERSION=$VERSION_MAJOR.$VERSION_MINOR.$VERSION_SUBMINOR
#
#  Check if urlget works
#
URLGET=$PETSC_DIR/bin/urlget
$URLGET -v > /dev/null 2>&1
if [ $? -ne 0 ]; then
  echo "Unable to access web to download the patches"
  exit 127
fi
cd $PETSC_DIR
#
#  Get the current release PETSc version
#
file=`$URLGET http://www-unix.mcs.anl.gov/petsc/petsc-current/include/petscversion.h`
_MAJOR=`grep PETSC_VERSION_MAJOR $file | sed -e "s/#define PETSC_VERSION_MAJOR[ ]*//g"`
_MINOR=`grep PETSC_VERSION_MINOR $file | sed -e "s/#define PETSC_VERSION_MINOR[ ]*//g"`
_SUBMINOR=`grep PETSC_VERSION_SUBMINOR $file | sed -e "s/#define PETSC_VERSION_SUBMINOR[ ]*//g"`
rm -f $file
if [ $VERSION_MAJOR -lt $_MAJOR -o $VERSION_MINOR -lt $_MINOR -o $VERSION_SUBMINOR -lt $_SUBMINOR ]; then
  echo "*********************************************************************"
  echo "    There is a newer release of PETSc then your installation       "
  echo "          $_MAJOR.$_MINOR.$_SUBMINOR  vs  $VERSION "
  echo "        We recommend upgrading to the latest version "
  echo "*********************************************************************"
fi
#
#  Get the current PETSc patch level for the users PETSc version
#
file=`$URLGET http://www-unix.mcs.anl.gov/petsc/petsc-patches.html`
PATCH=`grep "petsc-patches-$VERSION." $file | head -1 | sed -e "s?[-:/ A-Za-z0-9<>\"=.]*petsc-patches-$VERSION.\([0-9]*\).tar.gz[-:/ A-Za-z0-9<>\"=.]*?\1?g"`
rm -f $file
if [ $PATCH -ne $PATCH_LEVEL ]; then
#
#  Bring over the patch tar file
#
  file=`$URLGET ftp://info.mcs.anl.gov/pub/petsc/patches/petsc-patches-$VERSION.$PATCH.tar.gz`
  tar xf $file
  touch include/petscversion.h 
  echo "Updating PETSc directory $PETSC_DIR source and docs files, PETSc version $VERSION to patch $PATCH from $PATCH_LEVEL" 
  rm -f $file
else
  echo "Your source code and docs of patch level $PATCH_LEVEL of PETSc version $VERSION are up to date"
fi
#
#  Get list of directories that may need recompiling
#
file=`$URLGET ftp://info.mcs.anl.gov/pub/petsc/patches/petsc-patches-$VERSION.$PATCH.dirs`
dirs=`cat $file`
rm -f $file
#
#  Check if the libraries are already built
#
arch=`$PETSC_DIR/bin/petscarch`
ls lib/lib*/$arch*/libpetsc.a lib/lib*/$PETSC_ARCH/libpetsc.a > .tmp 2>&1
archs=`grep -v "No such" .tmp | sed -e "s?lib/lib[gO_c+omplex]*/\([_a-zA-Z0-9]*\)/libpetsc.a?\1?g"  | sort | uniq`
rm -f .tmp
for arch in $archs
do
  opts=`ls lib/lib*/$arch/libpetsc.a | sed -e "s?lib/lib\([gO_c+omplex]*\)/$arch/libpetsc.a?\1?g"`
  for opt in $opts
  do
#   
#      Check if libraries are out of date
#
    flag=`ls -tl lib/lib$opt/$arch/libpetsc.a include/petscversion.h | head -1 | grep include`
    if [ "$flag" = "" ]; then
      break;
    fi
#
#      Rebuild libraries
#
    echo "Update $arch $opt library (return for yes, n for no)?"
    read update
    if [ "$update" = "" ]; then
      echo "Updating $arch $opt library"
      for dir in $dirs
      do
        pushd $dir > /dev/null 2>&1; make BOPT=$opt PETSC_ARCH=$arch ACTION=libfast tree
        popd > /dev/null 2>&1
      done
      make BOPT=$opt PETSC_ARCH=$arch shared > /dev/null 2>&1
    fi
  done
done
#
#  Remind the user to run petscupdate on any other arches that have libraries built
#
ls lib/lib*/*/libpetsc.a > .tmp 2>&1
archs=`grep -v "No such" .tmp | sed -e "s?lib/lib[gO_c+omplex]*/\([_a-zA-Z0-9]*\)/libpetsc.a?\1?g"  | sort  | uniq`
rm -f .tmp
for arch in $archs
do
  flag=`ls -tl lib/lib*/$arch/libpetsc.a include/petscversion.h | tail -1 | grep include`
  if [ "$flag" = "" ]; then
    echo "You may want to run petscupdate on the PETSC_ARCH $arch to update the libraries"
  fi
done
