equal
deleted
inserted
replaced
9 |
9 |
10 import difflib |
10 import difflib |
11 import re |
11 import re |
12 import struct |
12 import struct |
13 |
13 |
|
14 |
14 def splitnewlines(text): |
15 def splitnewlines(text): |
15 '''like str.splitlines, but only split on newlines.''' |
16 '''like str.splitlines, but only split on newlines.''' |
16 lines = [l + '\n' for l in text.split('\n')] |
17 lines = [l + '\n' for l in text.split('\n')] |
17 if lines: |
18 if lines: |
18 if lines[-1] == '\n': |
19 if lines[-1] == '\n': |
19 lines.pop() |
20 lines.pop() |
20 else: |
21 else: |
21 lines[-1] = lines[-1][:-1] |
22 lines[-1] = lines[-1][:-1] |
22 return lines |
23 return lines |
|
24 |
23 |
25 |
24 def _normalizeblocks(a, b, blocks): |
26 def _normalizeblocks(a, b, blocks): |
25 prev = None |
27 prev = None |
26 r = [] |
28 r = [] |
27 for curr in blocks: |
29 for curr in blocks: |
36 |
38 |
37 a2, b2, l2 = curr |
39 a2, b2, l2 = curr |
38 a2end = a2 + l2 |
40 a2end = a2 + l2 |
39 b2end = b2 + l2 |
41 b2end = b2 + l2 |
40 if a1end == a2: |
42 if a1end == a2: |
41 while (a1end + shift < a2end and |
43 while ( |
42 a[a1end + shift] == b[b1end + shift]): |
44 a1end + shift < a2end and a[a1end + shift] == b[b1end + shift] |
|
45 ): |
43 shift += 1 |
46 shift += 1 |
44 elif b1end == b2: |
47 elif b1end == b2: |
45 while (b1end + shift < b2end and |
48 while ( |
46 a[a1end + shift] == b[b1end + shift]): |
49 b1end + shift < b2end and a[a1end + shift] == b[b1end + shift] |
|
50 ): |
47 shift += 1 |
51 shift += 1 |
48 r.append((a1, b1, l1 + shift)) |
52 r.append((a1, b1, l1 + shift)) |
49 prev = a2 + shift, b2 + shift, l2 - shift |
53 prev = a2 + shift, b2 + shift, l2 - shift |
50 r.append(prev) |
54 r.append(prev) |
51 return r |
55 return r |
|
56 |
52 |
57 |
53 def bdiff(a, b): |
58 def bdiff(a, b): |
54 a = bytes(a).splitlines(True) |
59 a = bytes(a).splitlines(True) |
55 b = bytes(b).splitlines(True) |
60 b = bytes(b).splitlines(True) |
56 |
61 |
74 la = am + size |
79 la = am + size |
75 lb = bm + size |
80 lb = bm + size |
76 |
81 |
77 return "".join(bin) |
82 return "".join(bin) |
78 |
83 |
|
84 |
79 def blocks(a, b): |
85 def blocks(a, b): |
80 an = splitnewlines(a) |
86 an = splitnewlines(a) |
81 bn = splitnewlines(b) |
87 bn = splitnewlines(b) |
82 d = difflib.SequenceMatcher(None, an, bn).get_matching_blocks() |
88 d = difflib.SequenceMatcher(None, an, bn).get_matching_blocks() |
83 d = _normalizeblocks(an, bn, d) |
89 d = _normalizeblocks(an, bn, d) |
84 return [(i, i + n, j, j + n) for (i, j, n) in d] |
90 return [(i, i + n, j, j + n) for (i, j, n) in d] |
|
91 |
85 |
92 |
86 def fixws(text, allws): |
93 def fixws(text, allws): |
87 if allws: |
94 if allws: |
88 text = re.sub('[ \t\r]+', '', text) |
95 text = re.sub('[ \t\r]+', '', text) |
89 else: |
96 else: |