cowpatch.sh 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/bin/sh
  2. #
  3. # cowpatch.sh, by Rich Felker
  4. #
  5. # Permission to use, copy, modify, and/or distribute this software for
  6. # any purpose with or without fee is hereby granted.
  7. #
  8. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  9. # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  10. # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  11. # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
  13. # OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  14. # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. # PERFORMANCE OF THIS SOFTWARE.
  16. #
  17. # Take the above disclaimer seriously! This is an experimental tool
  18. # still and does not yet take precautions against malformed/malicious
  19. # patch files like patch(1) does. It may act out-of-tree and clobber
  20. # stuff you didn't intend for it to clobber.
  21. #
  22. set -e
  23. echo () { printf "%s\n" "$*" ; }
  24. cow () {
  25. test -h "$1" || return 0
  26. if test -d "$1" ; then
  27. case "$1" in
  28. */*) set -- "${1%/*}/" "${1##*/}" ;;
  29. *) set -- "" "$1" ;;
  30. esac
  31. mkdir "$1$2.tmp.$$"
  32. mv "$1$2" "$1.$2.orig"
  33. mv "$1$2.tmp.$$" "$1$2"
  34. ( cd "$1$2" && ln -s ../".$2.orig"/* . )
  35. else
  36. cp "$1" "$1.tmp.$$"
  37. mv "$1.tmp.$$" "$1"
  38. fi
  39. }
  40. cowp () {
  41. while test "$1" ; do
  42. case "$1" in
  43. */*) set -- "${1#*/}" "$2${2:+/}${1%%/*}" ;;
  44. *) set -- "" "$2${2:+/}$1" ;;
  45. esac
  46. cow "$2"
  47. done
  48. }
  49. cowpatch () {
  50. plev=0
  51. while getopts ":p:i:RNE" opt ; do
  52. test "$opt" = p && plev="$OPTARG"
  53. done
  54. while IFS= read -r l ; do
  55. case "$l" in
  56. +++*)
  57. IFS=" " read -r junk pfile junk <<EOF
  58. $l
  59. EOF
  60. i=0; while test "$i" -lt "$plev" ; do pfile=${pfile#*/}; i=$((i+1)) ; done
  61. cowp "$pfile"
  62. echo "$l"
  63. ;;
  64. @@*)
  65. echo "$l"
  66. IFS=" ," read -r junk junk i junk j junk <<EOF
  67. $l
  68. EOF
  69. while test $i -gt 0 || test $j -gt 0 ; do
  70. IFS= read -r l
  71. echo "$l"
  72. case "$l" in
  73. +*) j=$((j-1)) ;;
  74. -*) i=$((i-1)) ;;
  75. *) i=$((i-1)) ; j=$((j-1)) ;;
  76. esac
  77. done ;;
  78. *) echo "$l" ;;
  79. esac
  80. done
  81. }
  82. cowpatch "$@" | patch "$@"