diff options
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/patch-wrapper.in | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/bin/patch-wrapper.in b/bin/patch-wrapper.in new file mode 100755 index 0000000..4d6b108 --- /dev/null +++ b/bin/patch-wrapper.in @@ -0,0 +1,204 @@ +#! @BASH@ + +# This is a wrapper to GNU patch that recognizes the most common +# options and mimics GNU patch's behavior and output, and creates the +# quilt metadata as if quilt push was used to apply the patches. When +# options are used that this wrapper does not recognize, GNU patch is +# used directly, and no quilt metadata will get created. + +PATCH=patch +original_options=("$@") + +# GNU patch recognizes these environment variables +if [ -n "$SIMPLE_BACKUP_SUFFIX" ] +then + set -- --suffix "$SIMPLE_BACKUP_SUFFIX" "$@" +fi +if [ -n "$PATCH_VERSION_CONTROL" ] +then + set -- --version-control "$PATCH_VERSION_CONTROL" "$@" +elif [ -n "$VERSION_CONTROL" ] +then + set -- --version-control "$VERSION_CONTROL" "$@" +fi +if [ -n "$POSIXLY_CORRECT" ] +then + set -- --posix "$@" +fi + +backup_files() { + declare dir=${QUILT_PC:-.pc}/$patch + + if [ "$backup_mode" = --backup-if-mismatch ] + then + awk ' + /^patching file / \ + { file=$0 + sub(/^patching file /, "", file) + } + /^Hunk #[0-9]* / \ + { if (! file in backup) + print file > "/dev/stderr" + backup[file] = 1 + #print "ln "dir"/"file" "prefix file suffix \ + # > "/dev/stderr" + system("ln "dir"/"file" "prefix file suffix) + } + { if (!silent) + print + } + ' dir="${dir//\\/\\\\}" \ + prefix="${opt_prefix//\\/\\\\}" \ + suffix="${opt_suffix//\\/\\\\}" \ + silent="${opt_silent:+1}" + elif [ -n "$opt_silent" ]; then + cat > /dev/null + fi + if [ "$backup_mode" = --backup ] + then + for file in $(find "$dir" -type f -a ! -path "$path/.timestamp") + do + dest=$opt_prefix${file#$dir/}$opt_suffix + mkdir -p $(dirname "$dest") + ln $file $dest + done + fi +} + +options=`getopt -q -o bsB:z:i:p:d: \ + --long quiet,silent,backup,backup-if-mismatch \ + --long no-backup-if-mismatch,prefix: \ + --long suffix:,posix,input:,strip:,directory: -- "$@"` +if [ $? -ne 0 ] +then + cannot_handle=1 +elif [[ ! ${LC_ALL:-${LC_MESSAGES:-${LANG}}} =~ "^$|^C$|^POSIX$|^en" ]] +then + cannot_handle=1 +else + eval set -- "$options" + + backup_mode=--backup-if-mismatch + opt_prefix= + opt_suffix= + opt_silent= + opt_input= + opt_strip= + opt_directory=$PWD + + while : + do + case "$1" in + -b|--backup) + backup_mode=--backup + ;; + --backup-if-mismatch) + backup_mode=--backup-if-mismatch + ;; + -d|--directory) + cd "$2" || exit 1 + shift + ;; + -i|--input) + opt_input=$2 + new_options[${#new_options[@]}]=$1 + new_options[${#new_options[@]}]=$2 + shift + ;; + --no-backup-if-mismatch) + backup_mode=--no-backup-if-mismatch + ;; + -B|--prefix) + opt_prefix=$2 + new_options[${#new_options[@]}]=$1 + new_options[${#new_options[@]}]=$2 + shift + ;; + -s|--silent|--quiet) + opt_silent=--silent + ;; + -p|--strip) + opt_strip=-p$2 + new_options[${#new_options[@]}]=-p$2 + shift + ;; + -z|--suffix) + opt_suffix=$2 + new_options[${#new_options[@]}]=$1 + new_options[${#new_options[@]}]=$2 + shift + ;; + --posix) + backup_mode=--no-backup-if-mismatch + new_options[${#new_options[@]}]=$1 + ;; + --) + shift + break + ;; + *) + new_options[${#new_options[@]}]=$1 + ;; + esac + shift + done + + [ -n "$opt_prefix$opt_suffix" ] || opt_suffix=.orig + if [ -z "$opt_strip" -o $# -ne 0 ] + then + cannot_handle=1 + fi +fi + +if [ -n "$cannot_handle" ] +then + $PATCH "${original_options[@]}" + exit +fi + +if [ -n "$opt_input" ] +then + patch=$opt_input +else + patch=$(readlink /proc/self/fd/0) +fi +patch=${patch#$PWD/} + +quilt_patches=${QUILT_PATCHES:-patches} +if [ ! -e "$quilt_patches/$patch" ] +then + dir=$(dirname "$quilt_patches/$patch") + mkdir -p "$dir" + updir=../ + while ! [ "$dir/$updir$patch" -ef "$patch" ] + do + updir=$updir../ + done + ln -s "$updir$patch" "$quilt_patches/$patch" +fi + +if [ "$opt_strip" = -p1 ]; then + echo "$patch" +else + echo "$patch $opt_strip" +fi \ +>> $quilt_patches/series + +$PATCH "${new_options[@]}" --backup --prefix ${QUILT_PC:-.pc}/$patch/ \ + | backup_files +status=${PIPESTATUS[0]} +if [ $status -eq 0 ] +then + dir=${QUILT_PC:-.pc}/$patch + if [ ! -e "$dir" ] + then + mkdir -p "$dir" + fi + echo -n "" > $dir/.timestamp + if [ ! -e ${QUILT_PC:-.pc}/.version ] + then + echo 2 > ${QUILT_PC:-.pc}/.version + fi + echo $patch >> "${QUILT_PC:-.pc}/applied-patches" +fi +exit $status |