726 # hunk data before patching. Otherwise, preserve input |
726 # hunk data before patching. Otherwise, preserve input |
727 # line-endings. |
727 # line-endings. |
728 h = h.getnormalized() |
728 h = h.getnormalized() |
729 |
729 |
730 # fast case first, no offsets, no fuzz |
730 # fast case first, no offsets, no fuzz |
731 old = h.old() |
731 old, new = h.fuzzit(0, False) |
732 start = h.starta + self.offset |
732 start = h.starta + self.offset |
733 # zero length hunk ranges already have their start decremented |
733 # zero length hunk ranges already have their start decremented |
734 if h.lena: |
734 if h.lena: |
735 start -= 1 |
735 start -= 1 |
736 orig_start = start |
736 orig_start = start |
739 # fast case code |
739 # fast case code |
740 if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: |
740 if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: |
741 if self.remove: |
741 if self.remove: |
742 self.backend.unlink(self.fname) |
742 self.backend.unlink(self.fname) |
743 else: |
743 else: |
744 self.lines[start : start + h.lena] = h.new() |
744 self.lines[start : start + h.lena] = new |
745 self.offset += h.lenb - h.lena |
745 self.offset += h.lenb - h.lena |
746 self.dirty = True |
746 self.dirty = True |
747 return 0 |
747 return 0 |
748 |
748 |
749 # ok, we couldn't match the hunk. Lets look for offsets and fuzz it |
749 # ok, we couldn't match the hunk. Lets look for offsets and fuzz it |
757 else: |
757 else: |
758 search_start = orig_start + self.skew |
758 search_start = orig_start + self.skew |
759 |
759 |
760 for fuzzlen in xrange(3): |
760 for fuzzlen in xrange(3): |
761 for toponly in [True, False]: |
761 for toponly in [True, False]: |
762 old = h.old(fuzzlen, toponly) |
762 old, new = h.fuzzit(fuzzlen, toponly) |
763 |
763 |
764 cand = self.findlines(old[0][1:], search_start) |
764 cand = self.findlines(old[0][1:], search_start) |
765 for l in cand: |
765 for l in cand: |
766 if diffhelpers.testhunk(old, self.lines, l) == 0: |
766 if diffhelpers.testhunk(old, self.lines, l) == 0: |
767 newlines = h.new(fuzzlen, toponly) |
767 self.lines[l : l + len(old)] = new |
768 self.lines[l : l + len(old)] = newlines |
768 self.offset += len(new) - len(old) |
769 self.offset += len(newlines) - len(old) |
|
770 self.skew = l - orig_start |
769 self.skew = l - orig_start |
771 self.dirty = True |
770 self.dirty = True |
772 offset = l - orig_start - fuzzlen |
771 offset = l - orig_start - fuzzlen |
773 if fuzzlen: |
772 if fuzzlen: |
774 msg = _("Hunk #%d succeeded at %d " |
773 msg = _("Hunk #%d succeeded at %d " |
969 lr.push(l) |
968 lr.push(l) |
970 |
969 |
971 def complete(self): |
970 def complete(self): |
972 return len(self.a) == self.lena and len(self.b) == self.lenb |
971 return len(self.a) == self.lena and len(self.b) == self.lenb |
973 |
972 |
974 def fuzzit(self, l, fuzz, toponly): |
973 def _fuzzit(self, old, new, fuzz, toponly): |
975 # this removes context lines from the top and bottom of list 'l'. It |
974 # this removes context lines from the top and bottom of list 'l'. It |
976 # checks the hunk to make sure only context lines are removed, and then |
975 # checks the hunk to make sure only context lines are removed, and then |
977 # returns a new shortened list of lines. |
976 # returns a new shortened list of lines. |
978 fuzz = min(fuzz, len(l)-1) |
977 fuzz = min(fuzz, len(old)-1) |
979 if fuzz: |
978 if fuzz: |
980 top = 0 |
979 top = 0 |
981 bot = 0 |
980 bot = 0 |
982 hlen = len(self.hunk) |
981 hlen = len(self.hunk) |
983 for x in xrange(hlen - 1): |
982 for x in xrange(hlen - 1): |
1003 if top < context: |
1002 if top < context: |
1004 top = max(0, fuzz - (context - top)) |
1003 top = max(0, fuzz - (context - top)) |
1005 else: |
1004 else: |
1006 top = min(fuzz, top) |
1005 top = min(fuzz, top) |
1007 |
1006 |
1008 return l[top:len(l)-bot] |
1007 return old[top:len(old)-bot], new[top:len(new)-bot] |
1009 return l |
1008 return old, new |
1010 |
1009 |
1011 def old(self, fuzz=0, toponly=False): |
1010 def fuzzit(self, fuzz, toponly): |
1012 return self.fuzzit(self.a, fuzz, toponly) |
1011 return self._fuzzit(self.a, self.b, fuzz, toponly) |
1013 |
|
1014 def new(self, fuzz=0, toponly=False): |
|
1015 return self.fuzzit(self.b, fuzz, toponly) |
|
1016 |
1012 |
1017 class binhunk(object): |
1013 class binhunk(object): |
1018 'A binary patch file. Only understands literals so far.' |
1014 'A binary patch file. Only understands literals so far.' |
1019 def __init__(self, lr): |
1015 def __init__(self, lr): |
1020 self.text = None |
1016 self.text = None |