##// END OF EJS Templates
bdiff: drop duplicate definition of splitnewlines()...
Martin von Zweigbergk -
r41305:8b7973d4 default
parent child Browse files
Show More
@@ -1,102 +1,92 b''
1 1 # bdiff.py - Python implementation of bdiff.c
2 2 #
3 3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import difflib
11 11 import re
12 12 import struct
13 13
14 14 def splitnewlines(text):
15 15 '''like str.splitlines, but only split on newlines.'''
16 16 lines = [l + '\n' for l in text.split('\n')]
17 17 if lines:
18 18 if lines[-1] == '\n':
19 19 lines.pop()
20 20 else:
21 21 lines[-1] = lines[-1][:-1]
22 22 return lines
23 23
24 24 def _normalizeblocks(a, b, blocks):
25 25 prev = None
26 26 r = []
27 27 for curr in blocks:
28 28 if prev is None:
29 29 prev = curr
30 30 continue
31 31 shift = 0
32 32
33 33 a1, b1, l1 = prev
34 34 a1end = a1 + l1
35 35 b1end = b1 + l1
36 36
37 37 a2, b2, l2 = curr
38 38 a2end = a2 + l2
39 39 b2end = b2 + l2
40 40 if a1end == a2:
41 41 while (a1end + shift < a2end and
42 42 a[a1end + shift] == b[b1end + shift]):
43 43 shift += 1
44 44 elif b1end == b2:
45 45 while (b1end + shift < b2end and
46 46 a[a1end + shift] == b[b1end + shift]):
47 47 shift += 1
48 48 r.append((a1, b1, l1 + shift))
49 49 prev = a2 + shift, b2 + shift, l2 - shift
50 50 r.append(prev)
51 51 return r
52 52
53 53 def bdiff(a, b):
54 54 a = bytes(a).splitlines(True)
55 55 b = bytes(b).splitlines(True)
56 56
57 57 if not a:
58 58 s = "".join(b)
59 59 return s and (struct.pack(">lll", 0, 0, len(s)) + s)
60 60
61 61 bin = []
62 62 p = [0]
63 63 for i in a:
64 64 p.append(p[-1] + len(i))
65 65
66 66 d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
67 67 d = _normalizeblocks(a, b, d)
68 68 la = 0
69 69 lb = 0
70 70 for am, bm, size in d:
71 71 s = "".join(b[lb:bm])
72 72 if am > la or s:
73 73 bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
74 74 la = am + size
75 75 lb = bm + size
76 76
77 77 return "".join(bin)
78 78
79 79 def blocks(a, b):
80 80 an = splitnewlines(a)
81 81 bn = splitnewlines(b)
82 82 d = difflib.SequenceMatcher(None, an, bn).get_matching_blocks()
83 83 d = _normalizeblocks(an, bn, d)
84 84 return [(i, i + n, j, j + n) for (i, j, n) in d]
85 85
86 86 def fixws(text, allws):
87 87 if allws:
88 88 text = re.sub('[ \t\r]+', '', text)
89 89 else:
90 90 text = re.sub('[ \t\r]+', ' ', text)
91 91 text = text.replace(' \n', '\n')
92 92 return text
93
94 def splitnewlines(text):
95 '''like str.splitlines, but only split on newlines.'''
96 lines = [l + '\n' for l in text.split('\n')]
97 if lines:
98 if lines[-1] == '\n':
99 lines.pop()
100 else:
101 lines[-1] = lines[-1][:-1]
102 return lines
General Comments 0
You need to be logged in to leave comments. Login now