aboutsummaryrefslogtreecommitdiff
path: root/bin/vipatch
blob: ecb45c971b6a896adcc3703e6e0116355b723c12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/sh -f

# vipatch -- edit unified diff

# This is a simple awk script that re-adjusts headers in
# a patch generated by diff -u, depending on the actual
# number of added/removed lines.

IFS=''

tmp=$(mktemp /tmp/vipatch.XXXXXX)
trap 'rm $tmp; trap -' INT QUIT EXIT

cat $1 > $tmp
${EDITOR:-vi} $tmp </dev/tty >/dev/tty

cat $tmp | awk -vname=${0##*/} '
/^@@ /			{ if (head) printpatch(); head = $0 "\n"; next }
head && /^---/		{ print; next }
head && /^\+\+\+/	{ print; next }
head && /^\+/		{ plus++ }
head && /^-/		{ minus++ }
head && /^ /		{ same++ }
head			{ body = body $0 "\n"; next }
			{ print }
END			{ if (head) printpatch() }

function printpatch() {
	match(head, /^@@ -[0-9]+,[0-9]+ \+[0-9]+,/)
	prefix = substr(head, RSTART, RLENGTH)

	match(head, / @@.*/)
	suffix = substr(head, RSTART, RLENGTH)

	match(head, /,[0-9]+/)
	old = substr(head, RSTART+1, RLENGTH-1)
	new = old + plus - minus

	diff = old - same - minus
	if (diff != 0) {
		printf "%s: %d %s incorrectly %s\n", name, abs(diff),
			(abs(diff) > 1) ? "lines" : "line",
			(diff > 0) ? "removed" : "added" > "/dev/stderr"
		printf "under header%s\n", substr(suffix, 4) > "/dev/stderr"
		head = ""
		exit 1
	}

	printf "%s%d%s", prefix, new, suffix
	printf "%s", body

	head = ""; body = ""; plus = 0; minus = 0; same = 0
}

function abs(n) {
	return (n > 0) ? n : -n;
}
' | { [ -z "$1" ] && cat || cat > $1; }