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