# $NetBSD$
#
# Automatically creates patches for file modified in the working
# directory.
#
# Authors:
#    Roland Illig <roland.illig@gmx.de>, 2004.
#    Roland Illig <rillig@NetBSD.org>, 2005.

.if !defined(_BSD_PKG_MAKE_PATCHES_MK)
_BSD_PKG_MAKE_PATCHES_MK=	# defined

DIFF_REAL_CMD?=			diff
DIFF_FLAGS?=			-up
RI_DIFF?=			${DIFF_REAL_CMD:Q} ${DIFF_FLAGS}
MAKE_PATCHES_IGNORE=		CVS/* */CVS/* config.guess config.sub

.if defined(ORIGS) && !empty(ORIGS:M[Yy][Ee][Ss])
post-patch: do-make-origs
.endif
.PHONY: patches
patches: do-make-patches

.PHONY: do-make-origs
do-make-origs:
	@${ECHO_MSG} ${_PKGSRC_IN:Q}"> Creating backup copies for "${PKGNAME:Q}; \
	cd ${WRKSRC} && ${FIND} . -type f ! -name '*.orig'		\
	| while read fname; do 						\
	  case $fname in						\
	    *.orig | */.deps/*) continue;;				\
	    *)								\
	      if ${TEST} ! -f "$$fname.orig"; then			\
	        ${CP} -p "$$fname" "$$fname.orig";			\
	      fi;							\
	      ;;							\
	  esac;								\
	done;								\
	${CHMOD} -R u+rw .

_MAKE_PATCHES_IGNORE_CMD=	# empty
.for i in ${MAKE_PATCHES_IGNORE}
_MAKE_PATCHES_IGNORE_CMD+=	${i}) ;;
.endfor

# These files are involved in the patching process:
# new_file		=> the file in the working directory
# old_file		=> the backup of $new_file
# new_patch		=> the newly created patch
# old_patch		=> the old patch
# new_nodate		=> the new patch without the time information
# old_nodate		=> the old patch without the time information

.PHONY: do-make-patches
do-make-patches:
	${_PKG_SILENT}${_PKG_DEBUG}					\
	${ECHO_MSG} ${_PKGSRC_IN:Q}"> Updating patch files for "${PKGNAME:Q}; \
	if ${TEST} ! -d ${PATCHDIR:Q}; then				\
	  ${ECHO_MSG} "=> Creating patches directory";			\
	  ${MKDIR} ${PATCHDIR:Q};					\
	fi;								\
	cd ${WRKSRC:Q} &&						\
	${FIND} . -type f -name '*.orig' -print |			\
	while read fname; do						\
	  old_file=`${ECHO} "$$fname" | ${SED} -e 's,^\./,,'`;		\
	  new_file=`${ECHO} "$$old_file" | ${SED} -e 's,\.orig$$,,'`;	\
	  case "$$new_file" in						\
	  ${_MAKE_PATCHES_IGNORE_CMD}					\
	  *)								\
	  patchid=`${ECHO} "$$new_file" | ${SED} -e 's,[^A-Za-z0-9],_,g'`; \
	  new_nodate=${PATCHDIR:Q}/tmp-new-nodate;			\
	  old_nodate=${PATCHDIR:Q}/tmp-old-nodate;			\
	  new_patch=${PATCHDIR:Q}/tmp-new-patch;			\
	  old_patch="${PATCHDIR:Q}/patch-$$patchid";			\
	  if ${TEST} "`${ECHO} ${PATCHDIR:Q}/patch-*`" != ${PATCHDIR:Q}"/patch-*"; then \
	    for i in ${PATCHDIR:Q}/patch-*; do				\
	      if ${EGREP} '^\+\+\+ (\.+/)*'"$$new_file"'([ 	]|$$)' "$$i" >/dev/null; then \
	        old_patch="$$i";					\
	      fi;							\
	    done;							\
	  fi;								\
	  if ${TEST} ! -f "$$new_file"; then				\
	    ${ECHO_MSG} "=> $$new_file not found (skipped)";		\
	    continue;							\
	  fi;								\
	  if ${CMP} -s "$$old_file" "$$new_file"; then			\
	    if ${TEST} -f "$$old_patch"; then				\
	      ${RM} -f "$$old_patch";					\
	      ${ECHO_MSG} "=> Deleted $$old_patch";			\
	    fi;								\
	  else								\
	    { if ${TEST} -f "$$old_patch"; then				\
	        ${AWK} '/^---/{exit(0);} /.?/{print;}' "$$old_patch"; 	\
	      else							\
	        ${ECHO} "\$$""NetBSD""\$$";				\
	        ${ECHO};						\
	      fi;							\
	      ${RI_DIFF} "$$old_file" "$$new_file" || ${TRUE};		\
	    } > "$$new_patch";						\
	    if ${TEST} ! -f "$$old_patch"; then				\
	      ${MV} "$$new_patch" "$$old_patch";			\
	      ${ECHO_MSG} "=> Created $$old_patch";			\
	    else							\
	      ${AWK} 'write!=0&&$$1!="@@"{print;} /^\+\+\+/{write=1;}' "$$old_patch" > "$$old_nodate"; \
	      ${AWK} 'write!=0&&$$1!="@@"{print;} /^\+\+\+/{write=1;}' "$$new_patch" > "$$new_nodate"; \
	      if ${CMP} -s "$$old_nodate" "$$new_nodate"; then		\
	        : "=> Didn't change $$new_file";			\
	      else							\
	        ${MV} "$$new_patch" "$$old_patch";			\
	        ${ECHO_MSG} "=> Updated $$new_file";			\
	      fi;							\
	    fi;								\
	  fi;								\
	  ${RM} -f "$$new_patch" "$$old_nodate" "$$new_nodate";;	\
	  esac;								\
	done

.endif