#!/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 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; }