# -*- mode: makefile; coding: utf-8 -*-
# Copyright © 2002,2003 Colin Walters <walters@debian.org>
# Copyright © 2009-2010, 2014, 2016 Jonas Smedegaard <dr@jones.dk>
# Description: A sample patch system which uses separate files in debian/patches
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

####
# Patch suffix is specified by DEB_PATCH_SUFFIX. Defaults to .patch.
####

#PATH_RULES#

ifndef _cdbs_rules_patchsys
_cdbs_rules_patchsys = 1

include $(_cdbs_rules_path)/buildcore.mk$(_cdbs_makefile_suffix)

$(call cdbs_warn_deprecated,\
	simple-patchsys.mk,0.4.85,source format 3.0 (quilt))

ifeq ($(_cdbs_included_patchsys),)
_cdbs_included_patchsys = 1

_cdbs_patch_system_apply_rule = apply-patches
_cdbs_patch_system_unapply_rule = reverse-patches

DEB_PATCH_SUFFIX ?= .diff .diff.gz .diff.bz2 .diff.uu .patch .patch.gz .patch.bz2 .patch.uu
DEB_PATCHDIRS ?= debian/patches
close_parenthesis ?= )
# FIXME: Restructure to allow early override )or lowercase the variable!)
DEB_PATCHES := $(shell\
for dir in $(DEB_PATCHDIRS) ; do \
	for file in $$dir/* ; do \
		for suffix in $(DEB_PATCH_SUFFIX) ; do \
			case $$file in *$$suffix$(close_parenthesis) echo $$file ;; esac ; \
		done ; \
	done ; \
done)

# if we have any patches, check if some are patching config.{guess,sub,rpath}
# and print a warning
ifneq (, $(DEB_PATCHES))
CDBS_BUILD_DEPENDS_rules_simple-patchsys ?= patchutils
CDBS_BUILD_DEPENDS += , $(CDBS_BUILD_DEPENDS_rules_simple-patchsys)
evil_patches_that_do_nasty_things := $(shell\
if lsdiff=`which lsdiff` ; then \
  $$lsdiff -H $(DEB_PATCHES) \
  | egrep "/config\.(guess|sub|rpath)$$" | tr "\n" " " ; \
fi)
ifneq (, $(evil_patches_that_do_nasty_things))
$(call cdbs_warn,\
	The following patches are modifying auto-updated files. \
	Please exclude the following files from your patch: \
	$(evil_patches_that_do_nasty_things))
endif
endif

post-patches:: apply-patches

cleanbuilddir:: reverse-patches
	for dir in $(DEB_PATCHDIRS) ; do \
	    rm -f $$dir/*.log ; \
	done

# It's best to try the patch levels in this weird order, to avoid
# problems with patches that only create new files (see bug #365524).
cdbs_simple_patchsys_levels = 1 0 2

cdbs_update_stamp = if [ "$@" = "debian/stamp-patched" ]; then touch $(1); elif [ "$@" = "reverse-patches" ]; then rm -f $(1); fi

cdbs_patch_stamp_file = debian/stamp-patch-$$(echo $$patch | tr '/' '=')

# The patch subsystem
apply-patches: pre-build debian/stamp-patched
debian/stamp-patched: $(DEB_PATCHES)
debian/stamp-patched reverse-patches:
	$(MAKE) -f debian/rules reverse-config

	if [ "$@" = "reverse-patches" ]; then rm -f debian/stamp-patched; fi

	@echo "patches: $(DEB_PATCHES)"
	@set -e ; reverse=""; patches="$(DEB_PATCHES)"; \
	if [ "$@" = "reverse-patches" ]; then \
	  reverse="-R"; \
	  for patch in $$patches; do reversepatches="$$patch $$reversepatches"; done; \
	  patches="$$reversepatches"; \
	fi; \
	for patch in $$patches; do \
	  if [ "$@" = "reverse-patches" ]; then \
	    if [ ! -e $(cdbs_patch_stamp_file) ]; then \
	      echo "Patch $$patch is not applied."; continue; \
	    fi; \
	  else \
	    if [ -e $(cdbs_patch_stamp_file) ]; then \
	      echo "Patch $$patch is already applied."; continue; \
	    fi; \
	  fi; \
	  case $$patch in \
	    *.gz) cat=zcat ;; \
	    *.bz2) cat=bzcat ;; \
	    *.uu) cat="uudecode -o -" ;; \
	    *) cat=cat ;; \
	  esac; \
	  level=$$(head $$patch | egrep '^#DPATCHLEVEL=' | cut -f 2 -d '='); \
	  reverse=""; \
	  if [ "$@" = "reverse-patches" ]; then reverse="-R"; fi; \
	  success=""; \
	  if [ -z "$$level" ]; then \
	    echo -n "Trying "; if test -n "$$reverse"; then echo -n "reverse "; fi; echo -n "patch $$patch at level "; \
	    for level in $(cdbs_simple_patchsys_levels); do \
	      if test -z "$$success"; then \
	        echo -n "$$level ... "; \
	        if [ "$(DEB_PATCHDIRS_READONLY)" = "yes" ] ; then \
	          logfile="/dev/null" ; \
	        else \
	          logfile="$$patch.level-$$level.log" ; \
	        fi ; \
	        if $$cat $$patch | patch -d $(DEB_SRCDIR) $$reverse -E --dry-run -p$$level 1>$$logfile 2>&1; then \
	          if $$cat $$patch | patch -d $(DEB_SRCDIR) $$reverse -E --no-backup-if-mismatch -V never -p$$level 1>$$logfile 2>&1; then \
	            success=yes; \
	            $(call cdbs_update_stamp,$(cdbs_patch_stamp_file)); \
	            echo "success."; \
	          fi; \
	        fi; \
	      fi; \
	    done; \
	    if test -z "$$success"; then \
	      echo "failure."; \
	      exit 1; \
	    fi; \
	  else \
	    echo -n "Trying patch $$patch at level $$level ... "; \
	    echo -n "$$level ... "; \
	    if [ "$(DEB_PATCHDIRS_READONLY)" = "yes" ] ; then \
	      logfile="/dev/null" ; \
	    else \
	      logfile="$$patch.log" ; \
	    fi ; \
	    if $$cat $$patch | patch -d $(DEB_SRCDIR) $$reverse -E --no-backup-if-mismatch -V never -p$$level 1>$$logfile 2>&1; then \
	      $(call cdbs_update_stamp,$(cdbs_patch_stamp_file)); \
	      echo "success."; \
	    else \
	      echo "failure:"; \
	      cat $$logfile; \
	      exit 1; \
	    fi; \
	  fi; \
	done

	if [ "$@" != "reverse-patches" ]; then touch debian/stamp-patched; fi

# after reverting patches, we don't need update-config because:
#  - the tree is already in a consistent state.
#  - the initialisation of this routine is already in charge of making
#    the tree not only consistent, but also prepared to accept patching.
	if [ "$@" != "reverse-patches" ] ; then \
		$(MAKE) -f debian/rules update-config ; \
	fi

# standard targets
.PHONY: patch unpatch
patch: apply-patches
unpatch: reverse-patches

endif

endif
