/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.9.2 by Aaron Bentley
Get single-parent comparison working
1
from difflib import SequenceMatcher
2
0.9.1 by Aaron Bentley
Get trivial case passing
3
class MultiParent(object):
4
0.9.2 by Aaron Bentley
Get single-parent comparison working
5
    def __init__(self, hunks=None):
6
        if hunks is not None:
7
            self.hunks = hunks
8
        else:
9
            self.hunks = []
10
11
    def __repr__(self):
12
        return "MultiParent(%r)" % self.hunks
13
14
    def __eq__(self, other):
15
        if self.__class__ is not other.__class__:
16
            return False
17
        return (self.hunks == other.hunks)
0.9.1 by Aaron Bentley
Get trivial case passing
18
19
    @staticmethod
20
    def from_lines(text, parents=()):
0.9.2 by Aaron Bentley
Get single-parent comparison working
21
        def compare(parent):
22
            return SequenceMatcher(None, parent, text).get_matching_blocks()
23
        parent_comparisons = [compare(p) for p in parents]
24
        cur_line = 0
25
        new_text = NewText([])
26
        parent_text = []
27
        block_iter = [iter(i) for i in parent_comparisons]
28
        diff = MultiParent([])
29
        def next_block(p):
30
            try:
31
                return block_iter[p].next()
32
            except StopIteration:
33
                return None
34
        cur_block = [next_block(p) for p, i in enumerate(block_iter)]
35
        while cur_line < len(text):
36
            #import pdb; pdb.set_trace()
37
            best_match = None
38
            for p, block in enumerate(cur_block):
39
                if block is None:
40
                    continue
41
                i, j, n = block
42
                while j + n < cur_line:
43
                    block = cur_block[p] = next_block(p)
44
                    if block is None:
45
                        break
46
                    i, j, n = block
47
                if block is None:
48
                    continue
49
                if j > cur_line:
50
                    continue
51
                offset = cur_line - j
52
                i += offset
53
                j = cur_line
54
                n -= offset
55
                if n == 0:
56
                    continue
57
                if best_match is None or n > best_match.num_lines:
58
                    best_match = ParentText(p, i, j, n)
59
            if best_match is None:
60
                new_text.lines.append(text[cur_line])
61
                cur_line += 1
62
            else:
63
                if len(new_text.lines) > 0:
64
                    diff.hunks.append(new_text)
65
                    new_text = NewText([])
66
                diff.hunks.append(best_match)
67
                cur_line += best_match.num_lines
68
        if len(new_text.lines) > 0:
69
            diff.hunks.append(new_text)
0.9.1 by Aaron Bentley
Get trivial case passing
70
        return diff
71
72
    @classmethod
73
    def from_texts(cls, text, parents=()):
74
        return cls.from_lines(text.splitlines(True),
75
                              [p.splitlines(True) for p in parents])
76
77
78
class NewText(object):
79
80
    def __init__(self, lines):
81
        self.lines = lines
82
83
    def __eq__(self, other):
84
        if self.__class__ is not other.__class__:
85
            return False
86
        return (other.lines == self.lines)
0.9.2 by Aaron Bentley
Get single-parent comparison working
87
88
    def __repr__(self):
89
        return 'NewText(%r)' % self.lines
90
91
92
class ParentText(object):
93
94
    def __init__(self, parent, parent_pos, child_pos, num_lines):
95
        self.parent = parent
96
        self.parent_pos = parent_pos
97
        self.child_pos = child_pos
98
        self.num_lines = num_lines
99
100
    def __repr__(self):
101
        return 'ParentText(%(parent)r, %(parent_pos)r, %(child_pos)r,'\
102
            ' %(num_lines)r)' % self.__dict__
103
104
    def __eq__(self, other):
105
        if self.__class__ != other.__class__:
106
            return False
107
        return (self.__dict__ == other.__dict__)