| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | #!/usr/bin/env mksh#-# Copyright (c) 2014#	Thorsten Glaser <tg@mirbsd.org># Copyright (c) 2006#	Thorsten Glaser <tg@freewrt.org>## Derived from the MirPorts Framework "update-patches" script:## Copyright (c) 2003, 2004, 2005#	Thorsten "mirabile" Glaser <tg@MirBSD.de># Based upon code and idea (c) 2000#	Marc Espie for the OpenBSD project. All rights reserved.## Provided that these terms and disclaimer and all copyright notices# are retained or reproduced in an accompanying document, permission# is granted to deal in this work without restriction, including un-# limited rights to use, publicly perform, distribute, sell, modify,# merge, give away, or sublicence.## This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to# the utmost extent permitted by applicable law, neither express nor# implied; without malicious intent or gross negligence. In no event# may a licensor, author or contributor be held liable for indirect,# direct, other damage, loss, or other issues arising in any way out# of dealing in the work, even if advised of the possibility of such# damage or existence of a defect, except proven that it results out# of said person's immediate fault when using the work as intended.do_diff() {	local f1=$2/$1	local f2=$3/$1	if [[ ! -e $f1 ]]; then		[[ -d ${f1%/*}/. ]] || mkdir -p "${f1%/*}"		if [[ ! -s $f2 ]]; then			cat <<EOF--- $f1	(non-existant)+++ $f2	(empty)@@ -0,0 +0,0 @@EOF			return 0		fi		touch -t 197001010000.00 "$f1"	fi	diff -adup "$f1" "$f2"	return $?}set -A accountedset -A editTRANSFORM='sed s/[.+]/\\\\&/g'PATCHDIR=$CURDIR/patchesEXTRADIR=$CURDIR/extramkdir -p "$PATCHDIR"SUBDIST=${WRKDIST##${WRKDIR1}?(/)}if [[ -n $SUBDIST ]]; then	mv "${WRKDIR1}.orig/${SUBDIST}" "${WRKDIR1}/${SUBDIST}.orig"	D_BASE=${WRKDIR1}	D_SUB=${SUBDIST}#	D_SUBP=$D_SUB	D_SUBP='[^/]*'	D_CMP=$D_SUBPelse	# WRKSRC == WRKDIR	D_BASE=$(dirname "${WRKDIR1}")	D_SUB=$(basename "${WRKDIR1}")	D_SUBP=$D_SUB	D_CMP=fiORGDIST=${D_BASE}/${D_SUB}.origif [[ -e $WRKDIST/.patched-newfiles ]]; then	touch "$ORGDIST/.patched-newfiles"	patch_newfiles=1else	patch_newfiles=0fiif [[ -e $WRKDIST/../.autoreconf_done ]]; then	touch "$ORGDIST/.autoreconf_done"fiDIFF_FLAGS="-adu -I \"^--- $(print -r -- "$D_SUBP.orig/" | $TRANSFORM)@@	.*\""DIFF_FLAGS="$DIFF_FLAGS -I \"^\+\+\+ $(print -r -- "$D_SUBP/" | $TRANSFORM)@@	.*\""(cd "${WRKDIST}"; find . -type f -print0) |&while IFS= read -p -d '' -r file; do	file=${file#./}	[[ ! -e $ORGDIST/$file && $patch_newfiles = 0 ]] && continue	for i in $DIFF_IGNOREFILES; do		[[ $file = $i ]] && continue 2	done	cmp -s "$ORGDIST/$file" "$WRKDIST/$file" && continue	print -ru2 -- "Processing ${file}..."	# look in patchdir for an existing patchfile matching this	cd "$PATCHDIR"	for i in $PATCH_LIST; do		# Ignore non-files, or old backup		[[ ! -f $i || $i = *@(.orig|.rej|~) ]] && continue		# Patch found. Is this the one?		if grep "^[+-][+-][+-] $D_CMP[^/]*/$file	" "$i" >/dev/null; then			# Multiple files in the diff?			if [[ $(grep -c "^--- $D_CMP" "$i") -gt 1 || \			    $(grep -c "^+++ $D_CMP" "$i") -gt 1 ]]; then				print -ru2 -- "Cannot process, $i contains patches"				print -ru2 -- "to multiple files! Aborting."				print -n 'FAIL\0'				[[ -n $SUBDIST ]] && mv \				    "${WRKDIR1}/${SUBDIST}.orig" \				    "${WRKDIR1}.orig/${SUBDIST}"				exit 0			fi			# Multiple diffs with this file?			let n=0			pflst=			for j in $PATCH_LIST; do				[[ ! -f $j || $j = *@(.orig|.rej|~) ]] && \				    continue				grep "^[+-][+-][+-] $D_CMP[^/]*/$file	" \				    "$j" >/dev/null || continue				let n++				pflst="$pflst '$j'"			done			if (( n != 1 )); then				print -ru2 -- "Cannot process, file $file"				print -ru2 -- "is contained in multiple patches:"				print -ru2 -- "$pflst"				print -n 'FAIL\0'				[[ -n $SUBDIST ]] && mv \				    "${WRKDIR1}/${SUBDIST}.orig" \				    "${WRKDIR1}.orig/${SUBDIST}"				exit 0			fi			# No, process this patch			accounted+=("$i")			# found it, copy preamble before comparision			( sed -e "/^--- /,\$d" <"$i"; \			  cd "$D_BASE" && do_diff "$file" "$D_SUB.orig" "$D_SUB" \			) >"$i.new"			# did it change? mark it as changed			tfile=$(print -r -- "$file" | $TRANSFORM)			if eval diff "$(print -r -- "${DIFF_FLAGS}" | sed \			    "s#@@#${tfile}#g")" '"$i" "$i.new"' 1>&2; then				rm "$i.new"			else				print -ru2 -- "Patch $i for $file updated"				mv "$i" "$i.orig"				mv "$i.new" "$i"				edit+=("$i")			fi			continue 2		fi	done	# Build a sensible name for the new patch file	patchname=patch-${file//[\/.- ]/_}	print -ru2 -- "No patch-* found for $file, creating $patchname"	( cd "$D_BASE" && do_diff "$file" "$D_SUB.orig" "$D_SUB" ) >"$patchname"	edit+=("$patchname")	accounted+=("$patchname")done# Verify all patches accounted forcd "$PATCHDIR"for i in *; do	[[ ! -f $i || $i = *@(.orig|.rej|~) ]] && continue	grep '^\\ No newline at end of file' "$i" >/dev/null && \	    print -ru2 -- "*** Patch $i needs manual intervention"	found=0	for j in "${accounted[@]}"; do		[[ $i = "$j" ]] || continue		found=1		break	done	(( found )) || print -ru2 -- "*** Patch $i not accounted for"donefor i in "${edit[@]}"; do	print -nr -- "$i"	print -n '\0'done[[ -n $SUBDIST ]] && mv "${WRKDIR1}/${SUBDIST}.orig" "${WRKDIR1}.orig/${SUBDIST}"exit 0
 |