summaryrefslogtreecommitdiffstats
path: root/scripts/patchfns.in
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2003-01-31 12:45:37 +0000
committerAndreas Gruenbacher <agruen@suse.de>2003-01-31 12:45:37 +0000
commit21a15e55a81ea4bd2bc21729ceebe6be6a9ccd9b (patch)
tree150f25f9add7ecb5ae144ab63a62c3b43d25f378 /scripts/patchfns.in
parentf07f43d191fe23209876061b7a31b5cb1e9a219d (diff)
downloadquilt-21a15e55a81ea4bd2bc21729ceebe6be6a9ccd9b.tar.gz
Install binary backup-files into /usr/lib/quilt and the remaining scripts under /usr/share/quilt/scripts.
Diffstat (limited to 'scripts/patchfns.in')
-rw-r--r--scripts/patchfns.in614
1 files changed, 614 insertions, 0 deletions
diff --git a/scripts/patchfns.in b/scripts/patchfns.in
new file mode 100644
index 0000000..e17d164
--- /dev/null
+++ b/scripts/patchfns.in
@@ -0,0 +1,614 @@
+# This file contains the common functions used in all quilt script
+# It is meant to be sourced by bash scripts.
+
+# This script is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# See the COPYING and AUTHORS files for more details.
+
+if [ -n "$PATCHSCRIPTS" ]
+then
+ P=$PATCHSCRIPTS/
+else
+ unset P
+fi
+
+if [ -e .pc/series ]
+then
+ SERIES=.pc/series
+elif [ -e series ]
+then
+ SERIES=series
+else
+ SERIES=${P}patches/series
+fi
+
+DB=".pc/applied-patches"
+
+# Define where diffstat lives (may be missing)
+DIFFSTAT=/usr/bin/diffstat
+
+quote_re()
+{
+ echo "$1" | sed -e 's:\([\^\$/.+*\[\\]\):\\\1:g'
+}
+
+#basename()
+#{
+# local path=${1%/}
+# echo "${path/*\/}"
+#}
+
+#dirname()
+#{
+# local path=${1%/}
+#}
+
+patch_file_name()
+{
+ local patch=$1
+
+ if [ -e $SERIES ]
+ then
+ awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { printf "'"$P"'patches/%s\n", $1
+ exit
+ }
+ ' $SERIES
+ fi
+}
+
+# The -pN option and possibly others that should be passed to patch.
+patch_args()
+{
+ local patch=$1
+
+ if [ -e $SERIES ]
+ then
+ awk '
+ /^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { if (NF >= 2)
+ for (i=2; i <= NF; i++)
+ print $i
+ else
+ print "-p1" ;
+ exit
+ }
+ ' $SERIES
+ fi
+}
+
+patch_strip_level()
+{
+ local patch=$1 i
+ for i in $(patch_args $patch)
+ do
+ case $i in
+ -p)
+ echo $2
+ return ;;
+ -p*)
+ echo ${i:2}
+ return ;;
+ esac
+ done
+ echo "1"
+}
+
+change_db_strip_level()
+{
+ local level=$1 patch=$2
+
+ if [ x$level != x-p1 ]
+ then
+ level="$level"
+ else
+ level=""
+ fi
+
+ if [ -e $SERIES ]
+ then
+ local tmpfile=$(@MKTEMP@ /tmp/patch-scripts.XXXXXX)
+ awk '
+ /^'"$(quote_re $patch)"'(\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { for(i=2; i<=NF; i++)
+ if ($i ~ /^-p/) {
+ $i="'"$level"'"
+ break
+ }
+ if (i > NF)
+ $i="'"$level"'"
+ }
+ { print }
+ ' $SERIES > $tmpfile
+ if cmp $SERIES $tmpfile >/dev/null 2>/dev/null
+ then
+ rm -f $tmpfile
+ else
+ mv -f $tmpfile $SERIES
+ fi
+ else
+ return 1
+ fi
+}
+
+patch_in_series()
+{
+ local patch=$1
+
+ if ! [ -e $SERIES ]
+ then
+ return 1
+ else
+ grep -q -E '^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)' $SERIES
+ fi
+}
+
+# Insert new patch after topmost patch
+insert_in_series()
+{
+ local patch=$1 patch_args=$2
+ local top=$(top_patch) tmpfile
+
+ if [ -n "$patch_args" ]
+ then
+ patch_args=" $patch_args"
+ fi
+
+ tmpfile=$(@MKTEMP@ /tmp/patch-scripts.XXXXXX) || return 1
+ mkdir -p $(dirname $SERIES)
+ if [ -n "$top" ]
+ then
+ awk '
+ { print }
+ /^'"$(quote_re $top)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { print "'"$patch$patch_args"'" }
+ ' $SERIES > $tmpfile
+ status=$?
+ if [ $status -ne 0 ]
+ then
+ rm -f $tmpfile
+ return 1
+ fi
+ else
+ echo $patch$patch_args > $tmpfile
+ if [ -e $SERIES ]
+ then
+ cat $SERIES >> $tmpfile
+ fi
+ fi
+ mv -f $tmpfile $SERIES
+}
+
+remove_from_series()
+{
+ local patch=$1
+
+ tmpfile=$(@MKTEMP@ /tmp/patch-scripts.XXXXXX) || return 1
+ awk '
+ ! /^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \
+ { print }
+ ' $SERIES > $tmpfile
+ if [ $? -eq 0 ]
+ then
+ mv -f $tmpfile $SERIES
+ else
+ rm -f $tmpfile
+ return 1
+ fi
+}
+
+pc_file_name()
+{
+ while [ $# -gt 0 ]
+ do
+ echo ".pc/$1/.pc"
+ shift
+ done
+
+}
+
+backup_file_name()
+{
+ local patch=$1
+ while [ $# -gt 1 ]
+ do
+ echo ".pc/$patch/$2"
+ shift
+ done
+}
+
+cat_series()
+{
+ if [ -e $SERIES ]
+ then
+ sed -e '/^#/d' -e 's/^[ \t]*//' -e 's/[ \t].*//' \
+ -e 's/\.gz$//' -e 's/\.bz2$//' \
+ -e 's/\.patch$//' -e 's/\.diff\?$//' $SERIES
+ else
+ return 1
+ fi
+}
+
+top_patch()
+{
+ [ -e $DB ] && tail -1 $DB
+}
+
+is_numeric()
+{
+ echo $1 | grep -q '^[0-9]*$'
+}
+
+is_applied_last()
+{
+ local patch=$1
+ [ "$(top_patch)" == $patch ]
+}
+
+is_applied()
+{
+ local patch=$1
+ [ -e $DB ] || return 1
+ grep -q -E "^$(quote_re $patch)\$" $DB
+}
+
+patches_before()
+{
+ local patch=$1
+
+ if [ -n "$patch" ]
+ then
+ cat_series \
+ | awk '
+ $0 == "'"$patch"'" { exit }
+ { print }
+ '
+ fi
+}
+
+patches_after()
+{
+ local patch=$1
+ if [ -n "$patch" ]
+ then
+ cat_series \
+ | awk '
+ seen { print }
+ $0 == "'"$patch"'" { seen=1 }
+ '
+ else
+ cat_series
+ fi
+}
+
+# List all patches that have been applied on top of patch $1
+patches_on_top_of()
+{
+ local patch=$1
+ [ -e $DB ] || return
+ awk '
+ $0 == "'"$patch"'" { seen=1 ; next }
+ seen { print }
+ ' $DB
+}
+
+# Print the name of the patch that modified the file $2 next after
+# patch $1, or print nothing if patch $1 is on top.
+next_patch_for_file()
+{
+ local patch=$1 file=$2
+ local patches_on_top=$(patches_on_top_of $patch)
+
+ if [ -n "$patches_on_top" ]
+ then
+ grep -l -E "^$(quote_re $file)\$" \
+ $(pc_file_name $patches_on_top) \
+ | head -1 \
+ | sed -e 's:^\.pc/::' -e 's:/\.pc$::'
+ fi
+
+ #modified_files $file -- $patches_on_top \
+ #| cut -d $'\t' -f2 \
+ #| cut -d ' ' -f1
+}
+
+# Create a list of files and the patches that modify them.
+refresh_patches_per_file()
+{
+ local pc_files=$(pc_file_name $(cat_series))
+ local ex_pc_files pc_file
+
+ if [ -e .pc/patches-per-file ]
+ then
+ local needs_refresh
+ for pc_file in pc_files
+ do
+ if [ .pc/patches-per-file -ot $pc_file ]
+ then
+ needs_refresh=1
+ break
+ fi
+ done
+ if [ -z "$needs_refresh" ]
+ then
+ return 0
+ fi
+ fi
+
+ for pc_file in $pc_files
+ do
+ if [ -e $pc_file ]
+ then
+ ex_pc_files[${#ex_pc_files[@]}]=$pc_file
+ fi
+ done
+
+ if [ ${#ex_pc_files[@]} -eq 0 ]
+ then
+ rm -f .pc/patches-per-file
+ return 0
+ fi
+
+ awk '
+ ARGIND!=saved { sub(/^.pc\//, "", FILENAME)
+ sub(/\/\.pc/, "", FILENAME)
+ saved=ARGIND
+ }
+ { if (files[$0])
+ files[$0]=files[$0] " " FILENAME
+ else
+ files[$0]=FILENAME
+ }
+ END { for (file in files)
+ printf "%s\t%s\n", file, files[file]
+ }
+ ' "${ex_pc_files[@]}" > .pc/patches-per-file
+}
+
+# For a lists of patches and a list of files, compute which patches
+# modify which files. Invoked as
+# modified_files file ... [-- patch ...]
+#
+modified_files()
+{
+ if ! refresh_patches_per_file
+ then
+ return 1
+ fi
+
+ awk '
+ BEGIN { no_files=1
+ no_patches=1
+ for (i=1; i<ARGC; i++) {
+ if (ARGV[i]=="--")
+ break
+ files[ARGV[i]]=1
+ no_files=0
+ }
+ for (i++; i<ARGC; i++) {
+ patches[ARGV[i]]=1
+ no_patches=0
+ }
+ split("", ARGV) # read from standard input
+ }
+ no_files || files[$1] {
+ if (no_patches) {
+ print
+ next
+ }
+ for (i=2; i<=NF; i++)
+ if ($i in patches) {
+ printf "%s\t%s", $1, $i
+ for (i++; i<=NF; i++)
+ if ($i in patches)
+ printf " %s", $i
+ printf "\n"
+ }
+ }
+ ' "$@" < .pc/patches-per-file
+}
+
+add_to_db()
+{
+ echo $1 >> $DB
+}
+
+remove_from_db()
+{
+ local patch=$1
+ local tmpfile
+ if tmpfile=$(@MKTEMP@ /tmp/patch-scripts.XXXXXX)
+ then
+ grep -v -E "^$(quote_re $patch)\$" $DB > $tmpfile
+ mv -f $tmpfile $DB
+ rm -f $tmpfile
+ [ -s $DB ] || rm -f $DB
+ fi
+}
+
+stripit()
+{
+ if [ -n "$1" ]
+ then
+ echo $1 |
+ sed -e 's/^\(\.\/\)*//' \
+ -e 's/^'"$P"'patches\///' -e 's/^\.pc\///' \
+ -e 's/\.gz$//' -e 's/\.bz2$//' \
+ -e 's/\.patch$//' -e 's/\.diff\?$//'
+ fi
+}
+
+file_in_patch()
+{
+ local file=$1 patch=$2
+ files_in_patch $patch \
+ | grep -q -E "^$(quote_re $file)\$"
+}
+
+files_in_patch()
+{
+ local pc_file=$(pc_file_name $1)
+ if [ -e "$pc_file" ]
+ then
+ cat $pc_file
+ fi
+}
+
+touched_by_patch()
+{
+ local strip=$1 patch=$2
+ cat_file $(patch_file_name $patch) \
+ | awk '
+ /^\+\+\+[ \t]/ {
+ sub(/^\+\+\+[ \t]/, "")
+ sub(/[ \t].*/, "")
+ sub(/^\/dev\/null/, "")
+ for (i=0; i<'$strip'; i++)
+ sub(/^[^\/]*\//, "")
+ print
+ }'
+}
+
+refresh_file_list()
+{
+ local patch=$1
+ local pc_file=$(pc_file_name $patch)
+ local patch_file=$(patch_file_name $patch)
+
+ if ! [ -e "$patch_file" ]
+ then
+ return 0
+ fi
+ if [ ! -e $pc_file -o \
+ $pc_file -ot $patch_file -o \
+ $pc_file -ot $SERIES ]
+ then
+ local tmpfile status
+ if ! mkdir -p $(dirname $pc_file) || \
+ ! tmpfile=$(@MKTEMP@ /tmp/patch-scripts.XXXXXX)
+ then
+ return 1
+ fi
+
+ if [ -e $pc_file ]
+ then
+ cat $pc_file >> $tmpfile
+ fi
+ if ! touched_by_patch $(patch_strip_level $patch) \
+ $patch >> $tmpfile
+ then
+ return 1
+ fi
+ sort $tmpfile | uniq > $pc_file
+ rm $tmpfile
+ return 0
+ fi
+}
+
+diff_file()
+{
+ local file=$1 suffix=$2 old_file=$3 new_file=$4
+ local old_file new_file
+
+ if [ ! -e "$old_file" -a ! -e "$new_file" ]
+ then
+ echo "File $file does not exist" >&2
+ return 0
+ fi
+ local old_hdr new_hdr
+ if [ $opt_strip_level -eq 0 ]
+ then
+ old_hdr=$file$suffix
+ new_hdr=$file
+ else
+ local dir=$(basename $PWD)
+ old_hdr=$dir$suffix/$file
+ new_hdr=$dir/$file
+ fi
+
+ echo Index: $new_hdr
+ @DIFF@ -Nu $DIFF_OPTS $old_file $new_file |
+ fix_diff_header $old_hdr $new_hdr
+}
+
+fix_diff_header()
+{
+ local from=$1 to=$2
+ sed -e 's:^--- [^ \t]*:--- '"$from"':' \
+ -e 's:^+++ [^ \t]*:+++ '"$to"':'
+}
+
+cat_file()
+{
+ local filename
+
+ for filename in "$@"
+ do
+ if [ -e "$filename" ]
+ then
+ case "$filename" in
+ *.gz|*.tgz)
+ gzip -cd "$filename" ;;
+ *.bz2)
+ bzip2 -cd "$filename" ;;
+ *)
+ cat "$filename" ;;
+ esac
+ fi
+ done
+}
+
+cat_to_file()
+{
+ local filename="$1"
+
+ if [ -z "$filename" ]
+ then
+ cat
+ else
+ case "$filename" in
+ *.gz|*.tgz)
+ gzip -c > "$filename" ;;
+ *.bz2)
+ bzip2 -c > "$filename" ;;
+ *)
+ cat > "$filename" ;;
+ esac
+ fi
+}
+
+patch_description()
+{
+ local patch_file=$1
+
+ if [ -e "$patch_file" -o -z "$patch_file" ]
+ then
+ awk '
+ $1 == "---" { exit }
+ $1 == "Index:" { eat = eat $0
+ next }
+ $1 == "diff" { eat = eat $0
+ next }
+ eat { print eat
+ eat="" }
+ { print }
+ ' $patch_file
+ fi
+}
+
+in_array()
+{
+ local a=$1
+ while [ $# -gt 1 ]
+ do
+ shift
+ [ "$a" = "$1" ] && return 0
+ done
+ return 1
+}
+### Local Variables:
+### mode: shell-script
+### End:
+# vim:filetype=sh