# -*- mode: makefile -*-
#

chk_petscdir:
	@mypwd=`pwd`; cd ${PETSC_DIR} 2>&1 > /dev/null; true_PETSC_DIR=`pwd`; cd $${mypwd} 2>&1 >/dev/null; \
        newpwd=`echo $${mypwd} | sed "s+$${true_PETSC_DIR}+DUMMY+g"`;\
        haspetsc=`echo $${mypwd} | sed "s+petsc-+DUMMY+g"`;\
        if [ $${mypwd} = $${newpwd} -a $${haspetsc} != $${mypwd} ]; then \
          printf ${PETSC_TEXT_HILIGHT}"*********************W-a-r-n-i-n-g*************************\n" ; \
          echo "Your PETSC_DIR may not match the directory you are in";\
          echo "PETSC_DIR " $${true_PETSC_DIR} "Current directory" $${mypwd};\
          echo "Ignore this if you are running make check             ";\
          printf "******************************************************"${PETSC_TEXT_NORMAL}"\n" ; \
        fi

chk_in_petscdir:
	@if [ ! -f include/petscversion.h ]; then \
	  printf ${PETSC_TEXT_HILIGHT}"*********************** ERROR **********************************************\n" ; \
	  echo " This target should be invoked in top level PETSc source dir!"; \
	  printf "****************************************************************************"${PETSC_TEXT_NORMAL}"\n" ;  false; fi

chk_upgrade:
	-@PETSC_DIR=${PETSC_DIR} ${PYTHON} ${PETSC_DIR}/lib/petsc/bin/petscnagupgrade.py

chk_loc:
	@if [ ${LOC}foo = foo ] ; then \
	  printf ${PETSC_TEXT_HILIGHT}"*********************** ERROR **********************************************\n" ; \
	  echo " Please specify LOC variable for eg: make allmanpages LOC=/sandbox/petsc "; \
	  printf "****************************************************************************"${PETSC_TEXT_NORMAL}"\n" ;  false; fi
	@${MKDIR} ${LOC}/docs/manualpages

chk_c2html:
	@if [ ${C2HTML}foo = foo ] ; then \
          printf ${PETSC_TEXT_HILIGHT}"*********************** ERROR ************************\n" ; \
          echo "Require c2html for html docs. Please reconfigure with --download-c2html=1"; \
          printf "******************************************************"${PETSC_TEXT_NORMAL}"\n" ;false; fi

chklib_dir:
	@if [ ! -d "${INSTALL_LIB_DIR}" ]; then \
	  echo Making directory ${INSTALL_LIB_DIR} for library; ${MKDIR} ${INSTALL_LIB_DIR} ; fi

chkopts:
	-@echo "Warning: chkopts target is deprecated and can be removed from user makefiles"

gnumake:
	+@echo "make gnumake is deprecated, use make libs"
	+@make libs

${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/files:
	@touch -t 197102020000 ${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/files

${PETSC_DIR}/${PETSC_ARCH}/tests/testfiles:
	@${MKDIR} -p ${PETSC_DIR}/${PETSC_ARCH}/tests && touch -t 197102020000 ${PETSC_DIR}/${PETSC_ARCH}/tests/testfiles

libs: ${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/files ${PETSC_DIR}/${PETSC_ARCH}/tests/testfiles
	+@cd ${PETSC_DIR} && MAKEFLAGS="-j$(MAKE_NP) -l$(MAKE_LOAD) $(MAKEFLAGS)" ${OMAKE_PRINTDIR} -f gmakefile ${MAKE_PAR_OUT_FLG} V=${V} libs

# Does nothing; needed for some rules that require actions.
foo:

# Removes garbage files
clean-legacy:
	@-${RM} ${CLEANFILES} ${TESTS} *.o *.lo *~ \
               ex[0-9] ex[0-9][0-9] ex[0-9][0-9][0-9] \
               ex[0-9]f ex[0-9][0-9]f ex[0-9][0-9][0-9]f \
               ex[0-9]k ex[0-9][0-9]k ex[0-9][0-9][0-9]k \
               ex[0-9]f90 ex[0-9][0-9]f90 ex[0-9][0-9][0-9]f90 \
               ex[0-9]cu ex[0-9][0-9]cu ex[0-9][0-9][0-9]cu \
               ex[0-9].exe ex[0-9][0-9].exe ex[0-9][0-9][0-9].exe \
               ex[0-9]f.exe ex[0-9][0-9]f.exe ex[0-9][0-9][0-9]f.exe \
               ex[0-9]f90.exe ex[0-9][0-9]f90.exe ex[0-9][0-9][0-9]f90.exe \
               ex[0-9]cu.exe ex[0-9][0-9]cu.exe ex[0-9][0-9][0-9]cu.exe \
               ex[0-9]hip ex[0-9][0-9]hip ex[0-9][0-9][0-9]hip \
               ex[0-9]hip.exe ex[0-9][0-9]hip.exe ex[0-9][0-9][0-9]hip.exe \
               ex[0-9]sycl ex[0-9][0-9]sycl ex[0-9][0-9][0-9]sycl \
               ex[0-9]sycl.exe ex[0-9][0-9]sycl.exe ex[0-9][0-9][0-9]sycl.exe \
              PI* *.ln l.outa* mputil.mp_* core core.* *.tmp *.map gmon.out *.gcov.html \
              trashz \#*\# *.mex* *.stolen *.trace Log.* *.stolen \
              output/*~ .mpirtmp mon.out *.aus *.mon.* p4pg ins10*.c \
               *.cp_ *.cp__ *.c*.c \
               *.dep *.proj ctoatmp PETScArena* *.L *.anl *.mod .mpi* *.d \
              *.class *.ouit *.ad.* g_* silly.cmp *.tmp.* *.ilk *.pdb *.inst.c *.rej *.gcda *.gcno
	@-${RM} -rf ${CLEANDIRS} *.dSYM AD_cache SunWS_cache

clean:: clean-legacy

#
#  Checks if directory requires particular package or language
# The makefile may contain
#    #requirespackage  'PETSC_HAVE_XXX'
#    #requiresfunction 'PETSC_XXX'
#    #requiresdefine   'PETSC_XXX'
#    #requireslanguage  CONLY (or CPP)
#    #requiresscalar    real (or complex)
#    #requiresprecision double (or single)
#
tree: ${ACTION}
	-@for dir in ${DIRS} ftn-auto ftn-custom f90-custom; do \
            if [ -d $$dir ]; then \
	      r=`grep -E '#(requirespackage|requiresfunction|requiresdefine)' $$dir/makefile | cut -d \' -f2`; \
              if [ "$$?" = 0 ]; then \
                flg=0; \
                for PKGFLG in $$r; do \
                  grep -w "#define $${PKGFLG}" ${PETSC_DIR}/${PETSC_ARCH}/include/petscconf.h > /dev/null; \
                  if [ "$$?" = 1 ]; then flg=1; break; fi; \
                done; \
                if [ "$$flg" = 1 ]; then continue; fi; \
              fi; \
              r=`grep -w requireslanguage $$dir/makefile`; \
              if [ "$$?" = 0 ]; then \
                echo $$r | grep -w ${PETSC_LANGUAGE} > /dev/null; \
                if [ "$$?" = 1 ]; then \
                  continue; \
                fi; \
              fi; \
              r=`grep -w requiresscalar $$dir/makefile`; \
              if [ "$$?" = 0 ]; then \
                echo $$r |  grep -w ${PETSC_SCALAR} > /dev/null; \
                if [ "$$?" = 1 ]; then \
                  continue; \
                fi; \
              fi; \
              r=`grep -w requiresprecision $$dir/makefile`; \
              if [ "$$?" = 0 ]; then \
                echo $$r |  grep -w ${PETSC_PRECISION} > /dev/null; \
                if [ "$$?" = 1 ]; then \
                  continue; \
                fi; \
              fi; \
            else \
              continue; \
            fi; \
            (cd $$dir ; \
            ${OMAKE} tree ACTION=${ACTION}  PETSC_ARCH=${PETSC_ARCH} LOC=${LOC} DATAFILESPATH=${DATAFILESPATH} BASE_DIR=${BASE_DIR}});\
	  done

printdot:
	-@if [ ${PRINT_PROGRESS}foo = dotfoo ] ; then printf "."; fi;

# Performs the specified action throughout the directory tree
tree_basic: ${ACTION}
	-@for dir in ${DIRS} ftn-custom ; do if [ -d $$dir ]; then \
	(cd $$dir ; \
	${OMAKE}  tree_basic ACTION=${ACTION}  \
	PETSC_ARCH=${PETSC_ARCH}  LOC=${LOC}) ;fi; \
	done

# Skips all tutorial and test directories and their children
tree_src: ${ACTION}
	-@for dir in ${DIRS} ftn-custom ; do DIR=`basename $$dir`; if [[ -d $$dir && $$DIR != "tests" && $$DIR != "tutorials" && $$DIR != "doc" ]]; then \
	(cd $$dir ; \
	${OMAKE}  tree_src ACTION=${ACTION}  \
	PETSC_ARCH=${PETSC_ARCH}  LOC=${LOC}) ;fi; \
	done

#This target goes through all the source directories that contains a makefile
alltree_src: ${ACTION}
	-@DIRS=`ls | sed -e s'?tutorials??'g -e s'?tests??g'  -e s'?docs??'g -e s'?include??'g`; \
	for dir in $$DIRS foo ; do if [ -f $$dir/makefile ]; then \
	(cd $$dir ;  \
	${OMAKE}  alltree_src ACTION=${ACTION}  \
	PETSC_ARCH=${PETSC_ARCH} LOC=${LOC} ) ;fi; \
	done

#This target goes through all the dirs that contains a makefile
alltree_makefile: ${ACTION}
	-@DIRS=`ls`; \
	for dir in $$DIRS foo ; do if [ -f $$dir/makefile ]; then \
	(cd $$dir ;  \
	${OMAKE}  alltree_makefile ACTION=${ACTION}  \
	PETSC_ARCH=${PETSC_ARCH} LOC=${LOC} ) ;fi; \
	done

# This target goes through all dirs specified by DIRS,EDIRS, and
# excludes dirs specified by $XDIRS
alltree: ${ACTION}
	@-if [ "${DIRS} ${EDIRS}" != " " ]; then \
	NDIRS="${DIRS} ${EDIRS}" ;\
	if [ "${XDIRS}" != "" ]; then \
	for XDIR in ${XDIRS} qwertyuiop ; do \
	NDIRS=`echo $$NDIRS | sed s/$$XDIR//g`; \
	done; fi ; \
	for dir in $$NDIRS foo ; do if [ -d $$dir ]; then \
	(cd $$dir ;\
	${OMAKE}  alltree ACTION="${ACTION}"  \
	PETSC_ARCH=${PETSC_ARCH} LOC=${LOC} ; ) fi; \
	done ; fi

getmpilinklibs:
	-@echo  ${MPI_LIB}

getmpiincludedirs:
	-@echo  ${MPI_INCLUDE}

# -----------------------------------------------------------------
getmpiexec:
	-@echo  ${MPIEXEC}

getccompiler:
	-@echo ${CC}

getfortrancompiler:
	-@echo ${FC}

getcxxcompiler:
	-@echo ${CXX}

getlinklibs:
	-@echo  ${C_SH_LIB_PATH} ${PETSC_TS_LIB}

getincludedirs:
	-@echo  ${PETSC_CC_INCLUDES}

getcflags:
	-@echo ${CC_FLAGS}

getcxxflags:
	-@echo ${CXX_FLAGS}

getfortranflags:
	-@echo ${FC_FLAGS}

getblaslapacklibs:
	-@echo ${BLASLAPACK_LIB}

getautoconfargs:
	-@echo CC='"${CC}"' CXX='"${CXX}"'  FC='"${FC}"' CFLAGS='"${CC_FLAGS}"' CXXFLAGS='"${CXX_FLAGS}"' FCFLAGS='"${FC_FLAGS}"' LIBS='"${C_SH_LIB_PATH} ${PETSC_TS_LIB}"'



# --------------------------------------------------------------------
#
# All remaining actions are intended for PETSc developers only.
# PETSc users should not generally need to use these commands.
#
#

.SUFFIXES: .F  .F90 .f90 ${SUFFIXES} .PETSc .C .cc .cpp .cxx .r .rm .so .html .ad .m .tex .make  .fig .svg .eps .pdf .jpg .png .dvi .ps .F95 .f95 .fiat .cu .hip.cpp .kokkos.cxx .raja.cxx *.sycl.cxx

#
#

.c.tex .F.tex:
	${LGRIND} -d ${LGRIND_DIR}/lgrindef -i $< > $*.tex

.make.tex:
	${LGRIND} -lmake -d ${LGRIND_DIR}/lgrindef -i $< > $*.tex

.fig.pdf:
	fig2dev -L pdf $< $*.pdf
.fig.eps:
	fig2dev -L eps $< $*.eps
.fig.jpg:
	fig2dev -L jpeg $< $*.jpg
.pdf.jpg:
	convert $< $*.jpg
.eps.pdf:
	epstopdf $< -o=$*.pdf
.ps.pdf:
	ps2pdf $< $*.pdf
.dvi.ps:
	dvips -o $*.ps $<
.svg.png:
	inkscape --export-png=$*.png $<
.svg.pdf:
	inkscape --export-pdf=$*.pdf $<
# Need to define PYTHON
.fiat.h:
	@if [ "${ELEMENT}" != "" ]; then \
	  if [ "${ORDER}" != "" ]; then \
	    python $< $*.h --element_family=${ELEMENT} --element_order=${ORDER}; \
	  else \
	    python $< $*.h --element_family=${ELEMENT}; \
	  fi; \
	else \
	  if [ "${ORDER}" != "" ]; then \
	    python $< $*.h --element_order=${ORDER}; \
	  else \
	    python $< $*.h; \
	  fi; \
	fi

.c.o:
	-+@mypwd=`pwd`; newpwd=`echo $${mypwd} | sed "s+/tutorials+DUMMY+g"`;\
        if [ $${mypwd} != $${newpwd} ]; then \
	  ${OMAKE}  PETSC_ARCH=${PETSC_ARCH}  chk_petscdir;\
        fi
	${PETSC_COMPILE_SINGLE} `pwd`/$<

.cpp.o .cxx.o .cc.o .C.o:
	-+@mypwd=`pwd`; newpwd=`echo $${mypwd} | sed "s+/tutorials+DUMMY+g"`;\
        if [ $${mypwd} != $${newpwd} ]; then \
	  ${OMAKE}  PETSC_ARCH=${PETSC_ARCH}  chk_petscdir;\
        fi
	${PETSC_CXXCOMPILE_SINGLE} `pwd`/$<
#
#   Compiles CUDA code
.cu.o:
	${PETSC_CUCOMPILE_SINGLE} `pwd`/$<

.hip.cpp.o:
	${PETSC_HIPCOMPILE_SINGLE} `pwd`/$<

.kokkos.cxx.o:
	${PETSC_KOKKOSCOMPILE_SINGLE} `pwd`/$<

.sycl.cxx.o:
	${PETSC_SYCLCOMPILE_SINGLE} `pwd`/$<

.raja.cxx.o:
	${PETSC_RAJACOMPILE_SINGLE} `pwd`/$<

.F.o .F90.o .F95.o:
	${PETSC_FCOMPILE_SINGLE} `pwd`/$<

.f.o .f90.o .f95.o:
	${FC} -c ${FC_FLAGS} ${FFLAGS} -o $@ $<
#
#  These rules are for compiling the test examples.
#
.cpp.rm .cxx.rm .cc.rm .C.rm .F.rm .F90.rm .f.rm .c.rm .cu.rm:
	-@${RM} $* *.o $*.mon.* gmon.out mon.out
	-@${RM} *.exe *.ilk *.pdb *.tds
.cu.PETSc .hip.cpp.PETSc .kokkos.cxx.PETSc .c.PETSc .cxx.PETSc:
	-+@${OMAKE}  PETSC_ARCH=${PETSC_ARCH}  $* > trashz 2>&1
	-@grep -v clog trashz | grep -v "information sections" | \
          grep -v "warning C4003: not enough actual parameters for macro 'PETSC_PASTE3_" | \
          grep -v "(aka 'long \*') doesn't match specified 'MPI' type tag that requires 'long long \*'" | \
          grep -v "note: expanded from macro" |\
          grep -v "MPI_" | \
          grep -v "warnings generated" | \
          grep -v "WARNING: TOC" | \
          grep -v "D4024 : unrecognized" | \
          grep -v "tentative definition of size" | \
          grep -v "Extra instructions" | \
          grep -v "Unused external reference" | \
          grep -v "Warning: attribute unused is unsupported and will be skipped" | \
          grep -v "f90 continuing despite warning messages" | \
          grep -v "symbol if the" | \
          grep -v "ignoring symbol version info" | \
          grep -v "warning: initializer element is not computable at load time" | \
          grep -v "warning: ISO C90 forbids mixed declarations and code" | \
          grep -v "warning: ISO C90 does not support 'static' or type qualifiers in parameter array declarators" | \
          grep -v "warning, duplicate dylib" | \
          grep -v "warning: duplicate dylib" | \
          grep -v "preempts that definition" | \
          grep -v "is an array from" | \
	  grep -v "At least one PA 2.0" | \
          grep -v "Cannot cast" | \
          grep -v "WARNING 134: weak definition of" | \
          grep -v "Warning(s) detected" | \
          grep -v "object file assumed" | \
          grep -v "consider using mkstemp"  |\
          grep -v EXTERNAL  |\
          grep -v "warning prebinding disabled"  |\
          grep -v volatile  |\
          grep -v -i inconsistent |\
          grep -v Anachronism | \
          grep -v "/opt/ibmcmp/xlsmp/1.3/lib" | \
          grep -v "add line info to anonymous symbol" | \
          grep -v "/opt/ibmcmp/xlsmp/1.3/../.." | \
          grep -v "IPO Error: unresolved" | \
	  grep -v "is being replaced by a real definition" | \
          grep -v "may result in errors or" | \
          grep -v "is deprecated" | \
          grep -v "Werror=format-security" | \
          grep -v " -Werror " | \
          grep -v " was built for newer macOS version " | \
          grep -v "only the last is used because nvcc can only accept a single optimization setting" | \
	  grep -E -i '(Error|warning|Can|Unresolved)' >> /dev/null;\
	  if [ "$$?" != 1 ]; then \
          printf ${PETSC_TEXT_HILIGHT}"*******************Error detected during compile or link!*******************\n";\
          echo "See https://petsc.org/release/faq/";\
          echo ${PWD} $* ;\
          printf "*********************************************************************************"${PETSC_TEXT_NORMAL}"\n" ;\
	  cat trashz ; fi; ${RM} trashz

.F.PETSc .F90.PETSc:
	-+@${OMAKE}  PETSC_ARCH=${PETSC_ARCH}  $* > trashz 2>&1
	-@grep -v EXTERNAL trashz | grep -v Wall | \
          grep -v "warning: In-place macro substitution leaves line truncated" | \
          grep -v "Warning: Same actual argument associated with INTENT(IN) argument 'errorcode' and INTENT(OUT) argument 'ierror' at (1)" | \
          grep -v "Unused external reference" | \
          grep -v "D4024 : unrecognized" | \
          grep -v "WARNING: TOC overflow." | \
          grep -v "Extra instructions are being" | \
          grep -v "tentative definition of size" | \
          grep -v "symbol if the symbol" | \
          grep -v -i inconsistent | \
          grep -v -i "unused dummy" | \
          grep -v "alignment lost in merging tentative definition" | \
	  grep -v "WARNING:  -cpp is ignored" | \
          grep -v "ignoring symbol version info" | \
	  grep -v "At least one PA 2.0" | \
	  grep -v "Inconsistent structure" | \
          grep -v "object file assumed" | \
	  grep -v "ex20.F:30:" | \
	  grep -v "ex20f.F:31: warning" | \
	  grep -v "f90 continuing despite warning messages" | \
          grep -v "is an array from" | \
          grep -v "warning, duplicate dylib" | \
          grep -v "warning: duplicate dylib" | \
          grep -v "consider using mkstemp"  |\
          grep -v "Nonconforming tab character"  |\
	  grep -v "Unused external reference" | \
          grep -v "WARNING 134: weak definition of" | \
          grep -v 'continuing despite warning messages' | \
          grep -v "add line info to anonymous symbol" | \
          grep -v "warning prebinding disabled"  |\
          grep -v "ex20f.F:34: warning:" | \
	  grep -v "Unused dummy argument" | \
	  grep -v "is being replaced by a real definition" | \
          grep -v "IPO Error: unresolved" | \
          grep -v "warning multiple definitions of symbol _matdensegetarray_" | \
          grep -v "Werror=format-security" | \
          grep -v " -Werror " | \
          grep -v " was built for newer macOS version " | \
	  grep -E -i '(Error|warning|Can|Unresolved)'  >> /dev/null ; \
	  if [ "$$?" != 1 ]; then \
          printf ${PETSC_TEXT_HILIGHT}"*******************Error detected during compile or link!*******************\n";\
          echo "See https://petsc.org/release/faq/";\
          echo ${PWD} $* ;\
          printf "*********************************************************"${PETSC_TEXT_NORMAL}"\n" ;\
	  cat trashz ; fi; ${RM} trashz;

#--------------------------------------------------------------------------------------
remote_sshrsync:
	-@${RSYNC} makefile ${SOURCEALL} ${WORKMACHINE}:${WORKSPACE}
	-@echo ${SSH} ${WORKMACHINE} "cd ${WORKSPACE}; setenv PETSC_DIR ${WORKPETSCDIR} ; setenv PETSC_ARCH ${WORKPETSCARCH}; make ${EXECUTABLE}"
	-@${SSH} ${WORKMACHINE} "cd ${WORKSPACE}; setenv PETSC_DIR ${WORKPETSCDIR} ; setenv PETSC_ARCH ${WORKPETSCARCH}; make ${EXECUTABLE}"
	@IGNORE_THIS_ERROR

#---------------------------------------------------------------------------------------

deleteshared:
	@for LIBNAME in ${SHLIBS}; \
	do \
	   if [ -d ${INSTALL_LIB_DIR}/$${LIBNAME}.dylib.dSYM ]; then \
             echo ${RM} -rf ${INSTALL_LIB_DIR}/$${LIBNAME}.dylib.dSYM; \
	     ${RM} -rf ${INSTALL_LIB_DIR}/$${LIBNAME}.dylib.dSYM; \
	   fi; \
           echo ${RM} ${INSTALL_LIB_DIR}/$${LIBNAME}.${SL_LINKER_SUFFIX}; \
           ${RM} ${INSTALL_LIB_DIR}/$${LIBNAME}.${SL_LINKER_SUFFIX}; \
	done
	@if [ -f ${INSTALL_LIB_DIR}/so_locations ]; then \
          echo ${RM} ${INSTALL_LIB_DIR}/so_locations; \
          ${RM} ${INSTALL_LIB_DIR}/so_locations; \
	fi

# ---------------------------------------------------------------------------------------
#   Rules for the generation of manual pages, html of source code etc
#
#  If this produces an error such as Could not open output file /Users/barrysmith/Src/petsc/docs/manualpages/MissingSUBMANSEC/*
#  this indicates the makefile is missing a MANSEC definition or the include file is missing a SUBMANSEC definition
manualpages:
	-@base=`basename ${LOCDIR}`; \
        doctext_common_def="${PETSC_DIR}/doc/classic/doctext/doctextcommon.txt"; \
        if [ "${MANSEC}" = "" ] ; then \
          for f in ${SOURCED}; do \
            LMANSEC=`grep SUBMANSEC $${f} | sed s'?[ ]*/\*[ ]*SUBMANSEC[ ]*=[ ]*\([a-zA-Z]*\)[ ]*\*/?\1?'g`; \
            if [ "$${LMANSEC}" = "" ] ; then \
              LMANSEC="MissingSUBMANSEC"; \
              pwd | grep -e ftn-custom -e petsc/finclude -e petsc/private > /dev/null; fnd=$?; \
              if [ "$${fnd}" == "1" ]; then \
                echo "Missing MANSEC or SUBMANSEC definition in " `pwd`/$${f} ; \
              fi; \
            fi; \
            if [ ! -d "${LOC}/docs/manualpages/$${LMANSEC}" ]; then \
              echo Making directory ${LOC}/docs/manualpages/$${LMANSEC} for manual pages from $${f}; ${MKDIR} ${LOC}/docs/manualpages/$${LMANSEC}; \
            fi; \
            DOCTEXT_PATH=${PETSC_DIR}/doc/classic/doctext \
            ${DOCTEXT} -myst -mpath ${LOC}/docs/manualpages/$${LMANSEC} -heading PETSc -defn ${PETSC_DIR}/doc/classic/doctext/myst.def \
                -indexdir ../$${LMANSEC} -index ${LOC}/docs/manualpages/manualpages.cit -locdir ${LOCDIR} -Wargdesc $${doctext_common_def} $${f} 2>&1 | tee -a ${PETSC_DIR}/${PETSC_ARCH}/manualpages.err; \
          done; \
        else \
          if [ "${SUBMANSEC}" = "" ] ; then LMANSEC=${MANSEC}; else LMANSEC=${SUBMANSEC}; fi; \
          if [ ! -d "${LOC}/docs/manualpages/$${LMANSEC}" ]; then \
            echo Making directory ${LOC}/docs/manualpages/$${LMANSEC} for manual pages; ${MKDIR} ${LOC}/docs/manualpages/$${LMANSEC}; \
          fi; \
          DOCTEXT_PATH=${PETSC_DIR}/doc/classic/doctext  \
          ${DOCTEXT} -myst -mpath ${LOC}/docs/manualpages/$${LMANSEC} -heading PETSc -defn ${PETSC_DIR}/doc/classic/doctext/myst.def \
              -indexdir ../$${LMANSEC} -index ${LOC}/docs/manualpages/manualpages.cit -locdir ${LOCDIR} -Wargdesc $${doctext_common_def} ${SOURCED} 2>&1 | tee -a ${PETSC_DIR}/${PETSC_ARCH}/manualpages.err; \
        fi;
#
#   Example usage for manual pages; adds each example that uses a function to that functions
# manual page up to a limit of 10 examples.
#
# Note: PETSC_DOC_OUT_ROOT_PLACEHOLDER must match the term used elsewhere in doc/
manexamples:
	-@base=`basename ${LOCDIR}`; \
        if [ "$${base}" = "tutorials" ] ; then \
          echo "Generating manual example links" ; \
          for i in ${EXAMPLESALL} foo ; do \
            if [ "$$i" != "foo" ] ; then \
              a=`cat $$i | ${MAPNAMES} -map ${LOC}/docs/manualpages/manualpages.cit \
                   -printmatch-link -o /dev/null| cut -f 2 | cut -d '#' -f 1 |sed -e s~^../~~ | grep \\.md$$ | sort | uniq` ;  \
              for j in $$a ; do \
                b=`ls ${LOC}/docs/manualpages/$${j} | grep -v /all/ | cut -f9` ; \
                l=`grep "^<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER.*/tutorials/" $${b} | wc -l`; \
                if [ $$l -le 10 ] ; then \
                  if [ $$l -eq 0 ] ; then \
                    printf "\n## Examples\n" >> $$b; \
                  fi; \
                  echo  "<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/BB\">BB</A><BR>" | sed s?BB?${LOCDIR}$$i.html?g >> $$b; \
                fi; \
              done; \
            fi; \
	  done; \
        fi

#
#    Goes through all manual pages adding links to implementations of the method
# or class, at the end of the file.
#
# To find functions implementing methods, we use git grep to look for
# well-formed PETSc functions
# - with names containing a single underscore
# - in files of appropriate types (.cu .c .cxx .h),
# - in paths including "/impls/",
# - excluding any line with a semicolon (to avoid matching prototypes), and
# - excluding any line including "_Private",
# storing potential matches in implsFuncAll.txt.
#
# For each man page we then grep in this file for the item's name followed by
# a single underscore and process the resulting implsFunc.txt to generate HTML.
#
# To find class implementations, we populate implsClassAll.txt with candidates
# - of the form "struct _p_itemName {",  and
# - not containing a semicolon
# and then grep for particular values of itemName, generating implsClass.txt,
# which is processed to generate HTML.
#
# Note: PETSC_DOC_OUT_ROOT_PLACEHOLDER must match the term used elsewhere in doc/
manimplementations:
	-@git grep "struct\s\+_[pn]_[^\s]\+.*{" -- *.cpp *.cu *.c *.h *.cxx | grep -v -e ";" -e "/tests/" -e "/tutorials/" > implsClassAll.txt ; \
  git grep -n "^\(static \)\?\(PETSC_EXTERN \)\?\(PETSC_INTERN \)\?\(extern \)\?PetscErrorCode \+[^_ ]\+_[^_ ]\+(" -- '*/impls/*.c' '*/impls/*.cpp' '*/impls/*.cu' '*/impls/*.cxx' '*/impls/*.h' | grep -v -e ";" -e "_[Pp]rivate" > implsFuncAll.txt ; \
  for i in ${LOC}/docs/manualpages/*/*.md foo; do \
       if [ "$$i" != "foo" ] ; then \
          itemName=`basename $$i .md`; \
          grep "\s$${itemName}_" implsFuncAll.txt > implsFunc.txt ; \
          grep "_p_$${itemName}\b" implsClassAll.txt > implsClass.txt ; \
          if [ -s implsFunc.txt ] || [ -s implsClass.txt ] ; then \
            printf "\n## Implementations\n\n" >> $$i; \
          fi ; \
          if [ -s implsFunc.txt ] ; then \
            sed "s?\(.*\.[ch]x*u*\).*\($${itemName}.*\)(.*)?<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\1.html#\2\">\2 in \1</A><BR>?" implsFunc.txt >> $$i ; \
          fi ; \
          if [ -s implsClass.txt ] ; then \
            sed "s?\(.*\.[ch]x*u*\):.*\(_p_$${itemName}\)\b.*{?<A HREF=\"PETSC_DOC_OUT_ROOT_PLACEHOLDER/\1.html#\2\">\2 in \1</A><BR>?" implsClass.txt >> $$i ; \
          fi ; \
          ${RM} implsFunc.txt implsClass.txt; \
       fi ; \
  done ; \
  ${RM} implsClassAll.txt implsFuncAll.txt

#
#   Rules for generating html code from C and Fortran
#
checkmakefilelist:
	-@ls makefile ${SOURCEALL} ${EXAMPLESALL} 2>/dev/null | grep -v \\.\\. |  sort | uniq > /tmp/$$USER.$$.make ;\
	ls makefile *.{c,cxx,cpp,cu,F,F90,h,h90,m} 2>/dev/null | sort | uniq > /tmp/$$USER.$$.ls; \
	${DIFF} /tmp/$$USER.$$.make  /tmp/$$USER.$$.ls; \
	${RM}  /tmp/$$USER.$$.make  /tmp/$$USER.$$.ls

simplehtml: chk_c2html
	-@ROOT=`echo ${LOCDIR} | sed -e s?/[a-z]*?/..?g -e s?src/??g -e s?include/??g` ;\
          loc=`pwd | sed -e s?\$${PETSC_DIR}/src?$${PETSC_DIR}/$${PETSC_ARCH}/obj?g -e s?/disks??g`;  \
          for i in ${SOURCE} foo ; do\
	    if [ -f $$i ]; then \
              idir=`dirname $$i`;\
              if [ ! -d $${loc}/$${idir} ]; then ${MKDIR} -p $${loc}/$${idir}; fi ; \
              ${RM} $${loc}/$$i.html; \
              sed -E -e "/PetscCallBack|PetscCallBLAS|PetscCallExternal|PetscCallP4est|PetscCallP4estReturn|PetscCallHDF5|PetscCallHDF5Return|PetscCallParmetis|PetscCallMKLSparse/!s/PetscCall[A-Za-z_]*\((.*)\)\;/\1;/g" \
                     -e "s/\;ierr\;/;/g" \
                     -e "/\s*PetscFunctionBegin\;/d" \
                     -e "s/PetscFunctionReturn\(([-a-zA-Z_0-9]+)\)/return \1/g" \
                     -e "s/PetscFunctionReturnVoid\(\)/return/g" \
                     -e "s/ierr\s+=\s+//g" \
                     -e "s/PETSC[A-Z]*_DLLEXPORT//g" $$i | ${C2HTML} -n | \
              awk '{ sub(/<pre width="80">/,"<pre width=\"80\">\n"); print }' > $${loc}/$$i.html ; \
	    fi; \
         done

html: chk_c2html
	-@export htmlmap_tmp=$$(mktemp) ;\
          sed -e s?man+manualpages/?man+ROOT/docs/manualpages/? ${LOC}/docs/manualpages/htmlmap_modified > $$htmlmap_tmp ;\
          cat ${PETSC_DIR}/doc/classic/mpi.www.index >> $$htmlmap_tmp ;\
          ROOT=`echo ${LOCDIR} | sed -e s?/[a-z]*?/..?g -e s?src/??g -e s?include/??g` ;\
          loc=`pwd | sed -e s?\$${PETSC_DIR}?$${LOC}/?g -e s?/disks??g`;  \
          ${MKDIR} -p $${loc} ;\
          current_git_sha=$$(git rev-parse HEAD) ;\
          rel_dir=$$(echo ${PWD} | sed "s%^${PETSC_DIR}/%%") ;\
          for i in ${SOURCEALL} ${EXAMPLESALL} foo ; do\
            if [ -f $$i ]; then \
              idir=`dirname $$i`;\
              if [ ! -d $${loc}/$${idir} ]; then ${MKDIR} -p $${loc}/$${idir}; fi ; \
              iroot=`echo $$i | sed -e "s?[a-z.]*/??g"`;\
              IROOT=`echo $${i} | sed -e s?[.][.]??g` ;\
              if [ "$${IROOT}" != "$${i}" ] ; then \
                IROOT=".."; \
              else \
                IROOT=$${ROOT};\
              fi;\
              ${RM} $${loc}/$$i.html; \
              echo "<center><a href=\"https://gitlab.com/petsc/petsc/-/blob/$$current_git_sha/$$rel_dir/$$i\">Actual source code: $${iroot}</a></center><br>" > $${loc}/$$i.html; \
              sed -E -e "/PetscCallBack|PetscCallBLAS|PetscCallExternal|PetscCallP4est|PetscCallHDF5|PetscCallParmetis|PetscCallMKLSparse/!s/PetscCall[A-Za-z_]*\((.*)\)\;/\1;/g" \
                     -e "s/\;ierr\;/;/g" \
                     -e "/\s*PetscFunctionBegin\;/d" \
                     -e "s/PetscFunctionReturn\(([-a-zA-Z_0-9]+)\)/return \1/g" \
                     -e "s/PetscFunctionReturnVoid\(\)/return/g" \
                     -e "s/ierr\s+=\s+//g" \
                     -e "s/PETSC[A-Z]*_DLLEXPORT//g" $$i | ${C2HTML} -n | \
              awk '{ sub(/<pre width="80">/,"<pre width=\"80\">\n"); print }' | ${PYTHON} ${PETSC_DIR}/lib/petsc/bin/maint/fixinclude.py $$i $${PETSC_DIR} | \
              grep -E -v '(PetscValid|PetscFunctionBegin|PetscCheck|PetscErrorCode ierr;|#if !defined\(__|#define __|#undef __|EXTERN_C )' | \
              ${MAPNAMES} -map $$htmlmap_tmp -inhtml | sed -e s?ROOT?$${IROOT}?g >> $${loc}/$$i.html ; \
            fi; \
          done ;\
          ROOT=`echo ${LOCDIR} | sed -e s?/[a-z]*?/..?g -e s?src/??g -e s?include/??g` ;\
          loc=`pwd | sed -e s?\$${PETSC_DIR}?$${LOC}/?g -e s?/disks??g`; ${RM} $${loc}/index.html; \
          cat ${PETSC_DIR}/doc/classic/manualpages-sec/header_${MANSEC} | sed -e "s?<A HREF=\"PETSC_DIR[a-z/]*\">Examples</A>?<A HREF=\"$${ROOT}/docs/manualpages/${MANSEC}\">Manual pages</A>?g" -e "s?PETSC_DIR?$${ROOT}/?g"> $${loc}/index.html; \
          echo "<p>" >> $${loc}/index.html ;\
          loc=`pwd | sed -e s?\$${PETSC_DIR}?$${LOC}/?g -e s?/disks??g`;\
          if [ "${EXAMPLESC}" != "" ] ; then \
            for file in ${EXAMPLESC} foo ; do \
              if [ -f $$file ]; then \
                cmess=`grep "static\( const\)\? char help" $${file} | cut -d\" -f2 | cut -d\. -f1`; \
                echo "<a href=\"$${file}.html\">$${file}: $${cmess}</a><br>" >> $${loc}/index.html;\
                ${PYTHON} ${PETSC_DIR}/lib/petsc/bin/maint/latexinexamples.py $${loc}/$${file}.html;\
              fi; \
            done ;\
          else \
            for file in ${DIRS} foo; do \
              if [ -d $$file ]; then \
                echo "<a href=\"$${file}/\">$${file}/</a><br>" >> $${loc}/index.html; \
              fi; \
            done; \
            echo " " >> $${loc}/index.html; \
            for file in ${SOURCEALL} foo ; do \
              if [ -f $$file ]; then \
                echo "<a href=\"$${file}.html\">$${file}</a><br>" >> $${loc}/index.html; \
              fi; \
            done; \
          fi ;\
          echo " " >> $${loc}/index.html; \
          echo "<a href=\"makefile.html\">makefile</a><br>" >> $${loc}/index.html ;\
          loc=`pwd | sed -e s?\$${PETSC_DIR}?$${LOC}/?g -e s?/disks??g`;  \
          cat makefile | ${C2HTML}  | ${MAPNAMES} -map $$htmlmap_tmp -inhtml > $${loc}/makefile.html ;\
          ${RM} $$htmlmap_tmp

cleanhtml:
	-@${RM} {makefile,index}.html *.{c,cxx,cu,F,F90,h,h90,m}.html *.{c,cxx,cu}.gcov.html

# -------------------------------------------------------------------------------
#
# ----------------------------------------------------------------------------------------
# Coverage tests: what lines of source code are tested during running of test examples
#
# Removes files generated by gcov
#
cleangcov:
	@-find src -name \*.gcov -delete
#
#----------------------------------------------------------------------------------
checkbadPetscFunctionBegin:
	-@if [ "${SOURCED}" != "" ] ; then \
	${OMAKE} PETSC_ARCH=${PETSC_ARCH} \
	checkbadPetscFunctionBegin_private ; fi

GITSRC = '*.[chF]' '*.F90' '*.hpp' '*.cpp' '*.cxx' '*.cu' ${GITSRCEXCL}
GITSRCEXCL = \
':!*khash/*' \
':!*valgrind/*' \
':!*yaml/*'
GITCFSRC = '*.[ch]' '*.hpp' '*.cpp' '*.cxx' '*.cu' ${GITSRCEXCL} ${GITCFSRCEXCL}
GITCFSRCEXCL = \
':!*petscversion.h' \
':!*mpif.h' \
':!*mpiunifdef.h' \
':!*finclude/*' \
':!systems/*' \
':!*benchmarks/*' \
':!*binding/*' \
':!*-custom/*' \
':!*f90-mod/*'

# Format all the source code in the given directory and down according to .clang_format
clangformat:
	-@git --no-pager ls-files -z ${GITCFSRC} | xargs -0 -P $(MAKE_NP) -L 10 clang-format -i

checkbadSource:
	@git --no-pager grep -n -P 'self\.gitcommit' -- config/BuildSystem/config/packages | grep 'origin/' ; if [[ "$$?" == "0" ]]; then echo "Error: Do not use a branch name in a configure package file"; false; fi
	-@${RM} -f checkbadSource.out
	-@echo "------Double blank lines in file -----------------------------------" > checkbadSource.out
	-@git --no-pager grep -n -P '^$$' -- ${GITSRC} > doublelinecheck.out
	-@${PYTHON} ${PETSC_DIR}/lib/petsc/bin/maint/doublelinecheck.py doublelinecheck.out >> checkbadSource.out
	-@${RM} -f doublelinecheck.out
	-@echo "------Tabs in file -------------------------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P '\t' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------White space at end of line -----------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P ' $$' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------Two ;; -------------------------------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P -e ';;' -- ${GITSRC} | grep -v ' for (' >> checkbadSource.out;true
	-@echo "------PetscCall for an MPI error code ------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P -e '= MPI[U]*_\w*\(.*PetscCall' -- ${GITSRC} | grep -v MPIU_File >> checkbadSource.out;true
	-@echo "------Missing if (ierr) return ierr; -------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P -e 'ierr = PetscInitialize\(' -- '*.[ch]' '*.cpp' '*.cxx' '*.cu' | grep -v 'if (ierr) return ierr;' | grep -E "(test|tutorial)" >> checkbadSource.out;true
	-@echo "------DOS file (with DOS newlines) ---------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P '\r' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------{ before SETERRQ ---------------------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P '{SETERRQ' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------PetscCall following SETERRQ ----------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P 'SETERRQ' -- ${GITSRC} | grep ";PetscCall" >> checkbadSource.out;true
	-@echo "------SETERRQ() without defined error code -------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P 'SETERRQ\((?!\))' -- ${GITSRC} | grep -v PETSC_ERR  | grep " if " | grep -v "__VA_ARGS__" | grep -v flow.c >> checkbadSource.out;true
	-@echo "------SETERRQ() with trailing newline ------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P "SETERRQ[1-9]?.*\\\n\"" -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------Define keyword used in test definition -----------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P -e 'requires:.*define\(' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------No new line at end of file -----------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P '[^\n]\z' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------Using if (condition) SETERRQ(...) instead of PetscCheck() ----" >> checkbadSource.out
	-@git --no-pager grep -n -P ' if +(.*) *SETERRQ' -- ${GITSRC} | grep -v 'PetscUnlikelyDebug' | grep -v 'petscerror.h' >> checkbadSource.out;true
	-@echo "------Using if (PetscUnlikelyDebug(condition)) SETERRQ(...) instead of PetscAssert()" >> checkbadSource.out
	-@git --no-pager grep -n -P -E ' if +\(PetscUnlikelyDebug.*\) *SETERRQ' -- ${GITSRC} | grep -v petscerror.h >> checkbadSource.out;true
	-@echo "------Using PetscFunctionReturn(ierr) ------------------------------" >> checkbadSource.out
	-@git --no-pager grep -n -P 'PetscFunctionReturn(ierr)' -- ${GITSRC} >> checkbadSource.out;true
	-@echo "------Defining a returning macro without PetscMacroReturns() -------" >> checkbadSource.out
	-@git --no-pager grep -n -P 'define .*\w+;\s+do' -- ${GITSRC} | grep -E -v '(PetscMacroReturns|PetscDrawCollectiveBegin|MatPreallocateBegin|PetscOptionsBegin|PetscObjectOptionsBegin|PetscOptionsHeadEnd)' >> checkbadSource.out;true
	-@echo "------Defining an error checking macro using CHKERR style ----------" >> checkbadSource.out
	-@git --no-pager grep -n -P 'define\s+CHKERR\w*\(.*\)\s*do\s+{' -- ${GITSRC} >> checkbadSource.out;true
	@a=`cat checkbadSource.out | wc -l`; l=`expr $$a - 18` ;\
         if [ $$l -gt 0 ] ; then \
           echo $$l " files with errors detected in source code formatting" ;\
           cat checkbadSource.out ;\
         else \
	   ${RM} -f checkbadSource.out;\
         fi;\
         test ! $$l -gt 0
	-@git --no-pager grep -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" -- ${GITSRC} > badSourceChar.out;true
	-@w=`cat badSourceChar.out | wc -l`;\
         if [ $$w -gt 0 ] ; then \
           echo "Source files with non-ASCII characters ----------------" ;\
           cat badSourceChar.out ;\
         else \
	   ${RM} -f badSourceChar.out;\
         fi
	@test ! -s badSourceChar.out

#  The directories below contains files directly imported from an external package; they should not be directly edited or changed except to update from the package
checkbadFileChange:
	@git diff --stat --exit-code `lib/petsc/bin/maint/check-merge-branch.sh`..HEAD -- src/sys/yaml include/petsc/private/valgrind include/petsc/private/kash

vermin:
	@vermin -vvv -t=3.4- ${VERMIN_OPTIONS} ${PETSC_DIR}/config

lint:
	${PYTHON3} ${PETSC_DIR}/lib/petsc/bin/maint/petscClangLinter.py --verbose=${V} $(LINTER_OPTIONS)

help-lint:
	@${PYTHON3} ${PETSC_DIR}/lib/petsc/bin/maint/petscClangLinter.py --help
	-@echo "Basic usage:"
	-@echo "   make lint      <options>"
	-@echo "   make test-lint <options> <test only options>"
	-@echo
	-@echo "Options:"
	-@echo "  V=[1,0]                                Enable or disable verbose output"
	-@echo "  LINTER_OPTIONS=\"--opt1 --opt2 ...\"     See above for available options"
	-@echo
	-@echo "Test Only Options:"
	-@echo "  REPLACE=[1,0]                          Enable or disable replacing test output"
	-@echo

test-lint:
	${PYTHON3} ${PETSC_DIR}/lib/petsc/bin/maint/petscClangLinter.py --src-dir ${PETSC_DIR}/src/sys/tests/linter --test -j0 --replace=${REPLACE} --verbose=${V} $(LINTER_OPTIONS)

check_petsc4py_rst:
	@${RM} -f petsc4py_rst.log
	@echo "Checking src/binding/petsc4py/DESCRIPTION.rst"
	@rst2html src/binding/petsc4py/DESCRIPTION.rst > /dev/null 2> petsc4py_rst.log
	@if test -s petsc4py_rst.log; then cat petsc4py_rst.log; exit 1; fi

# TODO: checkTestCoverage: that makes sure every tutorial test has at least one test listed in the file, perhaps handled by gmakegentest.py
# TODO: check for PetscBeginFunctionUser in non-example source
# TODO: check for __ at start of #define or symbol
# TODO: checking for missing manual pages
# TODO: check for incorrect %d
# TODO: check for double blank lines
# TODO: check for ill-formed manual pages
# TODO: check for { on line after for
# TODO: check for } then else on following line
# TODO: check for } else { with SETERRQ on following line or if () { with SETERRQ on following line

#  Lists all the URLs in the PETSc repository that are unaccessible, nonexistent, or permanently moved (301)
#  REPLACE=1 locations marked as permanently moved (301) are replaced in the repository
#  This code is fragile; always check the changes after a use of REPLACE=1 before committing the changes
#
#  Notes:
#    The first tr in the line is split lines for the cases where multiple URLs are in the same line
#    The first sed handles the case (http[s]*://xxx)
#    The list is sorted by length so that if REPLACE is used the longer apply before the shorter
#    The code recursively follows the permanently moved (301) redirections until it reaches the final URL
#    For DropBox we need to check the validity of the new URL but do not want to return to user the internal "raw" URL
checkbadURLS:
	-@x=`git grep "http[s]*://" -- '*.[chF]' '*.html' '*.cpp' '*.cxx' '*.cu' '*.F90' '*.py' '*.tex' | grep -E -v "(config/packages|HandsOnExercises)" | tr '[[:blank:]]' '\n' | grep 'http[s]*://' | sed 's!.*(\(http[s]*://[-a-zA-Z0-9_./()?=&+%~]*\))!\1!g' | sed 's!.*\(http[s]*://[-a-zA-Z0-9_./()?=&+%~]*\).*!\1!g' | sed 's/\.$$//g' | sort | uniq| awk '{ print length, $$0 }' | sort -r -n -s | cut -d" " -f2` ; \
        for i in $$x; do \
          url=$$i; \
          msg=''; \
          while [[ "$${msg}D" == "D" ]] ; do \
            y1=`curl --connect-timeout 5 --head --silent $${url} | head -n 1`; \
            y2=`echo $${y1} | grep ' 4[0-9]* '`; \
            y3=`echo $${y1} | grep ' 301 '`; \
            if [[ "$${y1}D" == "D" ]] ; then \
              msg="Unable to reach site" ; \
            elif [[ "$${y2}D" != "D" ]] ; then \
              msg=$${y1} ; \
            elif [[ "$${y3}D" != "D" ]] ; then \
              l=`curl --connect-timeout 5 --head --silent $${url} | grep ocation | sed 's/.*ocation:[[:blank:]]\(.*\)/\1/g' | tr -d '\r'` ; \
              w=`echo $$l | grep 'http'` ; \
              if [[ "$${w}D" != "D" ]] ; then \
                url=$$l ; \
              else \
                ws=`echo $${url} | sed 's!\(http[s]*://[-a-zA-Z0-9_.]*\)/.*!\1!g'` ; \
                dp=`echo $${ws}$${l} | grep "dropbox.com/s/raw"` ; \
                if [[ "$${dp}D" != "D" ]] ; then \
                  b=`curl --connect-timeout 5 --head --silent $${ws}$$l | head -n 1` ; \
                  c=`echo $${b} | grep -E "( 2[0-9]* | 302 )"` ; \
                  if [[ "$${c}D" == "D" ]] ; then \
                    msg=`echo "dropbox file doesn't exist" $${c}` ; \
                  else \
                    break ; \
                  fi; \
                else \
                  url="$${ws}$$l" ; \
                fi; \
              fi; \
            else \
              break; \
            fi; \
          done;\
          if [[ "$${msg}D" == "D" && "$${url}" != "$$i" ]] ; then \
            echo "URL" $$i "has moved to valid final location:" $${url} ; \
            if [[ "$${REPLACE}D" != "D" ]] ; then \
              git psed $$i $$l ;\
            fi; \
          elif [[ "$${msg}D" != "D" && "$${url}" != "$$i" ]] ; then \
            echo "ERROR: URL" $$i "has moved to invalid final location:" $${url} $${msg} ; \
          elif [[ "$${msg}D" != "D" ]] ; then \
            echo "ERROR: URL" $$i "invalid:" $${msg} ; \
          fi; \
        done

checkbadSpelling:
	-@x=`python3 ../bin/extract.py | aspell list | sort -u` ;

updatedatafiles:
	-@if [ -d "${HOME}/datafiles" ]; then \
            echo " ** Updating datafiles at ${HOME}/datafiles **"; \
            cd "${HOME}/datafiles" && git pull -q; fi

include ${PETSC_DIR}/${PETSC_ARCH}/lib/petsc/conf/petscrules
