| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Text::Diff3::Diff3; |
|
2
|
|
|
|
|
|
|
# diff3 component |
|
3
|
6
|
|
|
6
|
|
89
|
use 5.006; |
|
|
6
|
|
|
|
|
18
|
|
|
|
6
|
|
|
|
|
233
|
|
|
4
|
6
|
|
|
6
|
|
45
|
use strict; |
|
|
6
|
|
|
|
|
19
|
|
|
|
6
|
|
|
|
|
179
|
|
|
5
|
6
|
|
|
6
|
|
32
|
use warnings; |
|
|
6
|
|
|
|
|
16
|
|
|
|
6
|
|
|
|
|
201
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
6
|
|
|
6
|
|
29
|
use base qw(Text::Diff3::Base); |
|
|
6
|
|
|
|
|
12
|
|
|
|
6
|
|
|
|
|
49
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
6
|
|
|
6
|
|
833
|
use version; our $VERSION = '0.08'; |
|
|
6
|
|
|
|
|
11
|
|
|
|
6
|
|
|
|
|
21
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# the three-way diff procedure based on the GNU diff3.c by Randy Smith. |
|
12
|
|
|
|
|
|
|
sub diff3 { |
|
13
|
21
|
|
|
21
|
1
|
34
|
my($self, $text0, $text2, $text1) = @_; |
|
14
|
21
|
|
|
|
|
50
|
my $f = $self->factory; |
|
15
|
21
|
50
|
|
|
|
52
|
if (! $self->_is_a_text($text0)) { |
|
16
|
0
|
|
|
|
|
0
|
$text0 = $f->create_text($text0); |
|
17
|
|
|
|
|
|
|
} |
|
18
|
21
|
50
|
|
|
|
44
|
if (! $self->_is_a_text($text2)) { |
|
19
|
0
|
|
|
|
|
0
|
$text0 = $f->create_text($text2); |
|
20
|
|
|
|
|
|
|
} |
|
21
|
21
|
50
|
|
|
|
40
|
if (! $self->_is_a_text($text1)) { |
|
22
|
0
|
|
|
|
|
0
|
$text0 = $f->create_text($text1); |
|
23
|
|
|
|
|
|
|
} |
|
24
|
21
|
|
|
|
|
72
|
my $diffp = $f->create_diff; |
|
25
|
21
|
|
|
|
|
59
|
my @diff2 = ( |
|
26
|
|
|
|
|
|
|
$diffp->diff($text2, $text0), |
|
27
|
|
|
|
|
|
|
$diffp->diff($text2, $text1), |
|
28
|
|
|
|
|
|
|
); |
|
29
|
21
|
|
|
|
|
66
|
my $diff3 = $f->create_list3; |
|
30
|
21
|
|
|
|
|
67
|
my $range3 = $f->create_null_range3; |
|
31
|
21
|
|
66
|
|
|
65
|
while (! $diff2[0]->is_empty || ! $diff2[1]->is_empty) { |
|
32
|
|
|
|
|
|
|
# find a continual range in text2 $lo2..$hi2 |
|
33
|
|
|
|
|
|
|
# changed by text0 or by text1. |
|
34
|
|
|
|
|
|
|
# |
|
35
|
|
|
|
|
|
|
# diff2[0] 222 222222222 |
|
36
|
|
|
|
|
|
|
# text2 ...L!!!!!!!!!!!!!!!!!!!!H... |
|
37
|
|
|
|
|
|
|
# diff2[1] 222222 22 2222222 |
|
38
|
33
|
|
|
|
|
83
|
my @range2 = ([], []); |
|
39
|
33
|
100
|
|
|
|
82
|
my $i = |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
$diff2[0]->is_empty ? 1 |
|
41
|
|
|
|
|
|
|
: $diff2[1]->is_empty ? 0 |
|
42
|
|
|
|
|
|
|
: $diff2[0]->first->loA <= $diff2[1]->first->loA ? 0 |
|
43
|
|
|
|
|
|
|
: 1; |
|
44
|
33
|
|
|
|
|
51
|
my $j = $i; |
|
45
|
33
|
|
|
|
|
36
|
my $k = $i ^ 1; |
|
46
|
33
|
|
|
|
|
87
|
my $hi = $diff2[$j]->first->hiA; |
|
47
|
33
|
|
|
|
|
39
|
push @{$range2[$j]}, $diff2[$j]->shift; |
|
|
33
|
|
|
|
|
88
|
|
|
48
|
33
|
|
100
|
|
|
90
|
while (! $diff2[$k]->is_empty && $diff2[$k]->first->loA <= $hi + 1) { |
|
49
|
10
|
|
|
|
|
31
|
my $hi_k = $diff2[$k]->first->hiA; |
|
50
|
10
|
|
|
|
|
13
|
push @{$range2[$k]}, $diff2[$k]->shift; |
|
|
10
|
|
|
|
|
26
|
|
|
51
|
10
|
50
|
|
|
|
37
|
if ($hi < $hi_k) { |
|
52
|
0
|
|
|
|
|
0
|
$hi = $hi_k; |
|
53
|
0
|
|
|
|
|
0
|
$j = $k; |
|
54
|
0
|
|
|
|
|
0
|
$k = $k ^ 1; |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
} |
|
57
|
33
|
|
|
|
|
109
|
my $lo2 = $range2[$i][ 0]->loA; |
|
58
|
33
|
|
|
|
|
96
|
my $hi2 = $range2[$j][-1]->hiA; |
|
59
|
|
|
|
|
|
|
# take the corresponding ranges in text0 $lo0..$hi0 |
|
60
|
|
|
|
|
|
|
# and in text1 $lo1..$hi1. |
|
61
|
|
|
|
|
|
|
# |
|
62
|
|
|
|
|
|
|
# text0 ..L!!!!!!!!!!!!!!!!!!!!!!!!!!!!H... |
|
63
|
|
|
|
|
|
|
# diff2[0] 222 222222222 |
|
64
|
|
|
|
|
|
|
# text2 ...00!1111!000!!00!111111... |
|
65
|
|
|
|
|
|
|
# diff2[1] 222222 22 2222222 |
|
66
|
|
|
|
|
|
|
# text1 ...L!!!!!!!!!!!!!!!!H... |
|
67
|
33
|
|
|
|
|
36
|
my($lo0, $hi0); |
|
68
|
33
|
100
|
|
|
|
31
|
if (@{$range2[0]}) { |
|
|
33
|
|
|
|
|
97
|
|
|
69
|
21
|
|
|
|
|
55
|
$lo0 = $range2[0][ 0]->loB - $range2[0][ 0]->loA + $lo2; |
|
70
|
21
|
|
|
|
|
53
|
$hi0 = $range2[0][-1]->hiB - $range2[0][-1]->hiA + $hi2; |
|
71
|
|
|
|
|
|
|
} else { |
|
72
|
12
|
|
|
|
|
32
|
$lo0 = $range3->hi0 - $range3->hi2 + $lo2; |
|
73
|
12
|
|
|
|
|
30
|
$hi0 = $range3->hi0 - $range3->hi2 + $hi2; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
33
|
|
|
|
|
38
|
my($lo1, $hi1); |
|
76
|
33
|
100
|
|
|
|
28
|
if (@{$range2[1]}) { |
|
|
33
|
|
|
|
|
68
|
|
|
77
|
22
|
|
|
|
|
58
|
$lo1 = $range2[1][ 0]->loB - $range2[1][ 0]->loA + $lo2; |
|
78
|
22
|
|
|
|
|
60
|
$hi1 = $range2[1][-1]->hiB - $range2[1][-1]->hiA + $hi2; |
|
79
|
|
|
|
|
|
|
} else { |
|
80
|
11
|
|
|
|
|
30
|
$lo1 = $range3->hi1 - $range3->hi2 + $lo2; |
|
81
|
11
|
|
|
|
|
31
|
$hi1 = $range3->hi1 - $range3->hi2 + $hi2; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
33
|
|
|
|
|
112
|
$range3 = $f->create_range3( |
|
84
|
|
|
|
|
|
|
undef, $lo0, $hi0, $lo1, $hi1, $lo2, $hi2 |
|
85
|
|
|
|
|
|
|
); |
|
86
|
|
|
|
|
|
|
# detect type of changes. |
|
87
|
33
|
100
|
|
|
|
83
|
if (! @{$range2[0]}) { |
|
|
33
|
100
|
|
|
|
61
|
|
|
|
21
|
100
|
|
|
|
52
|
|
|
88
|
12
|
|
|
|
|
29
|
$range3->type('1'); |
|
89
|
|
|
|
|
|
|
} elsif (! @{$range2[1]}) { |
|
90
|
11
|
|
|
|
|
30
|
$range3->type('0'); |
|
91
|
|
|
|
|
|
|
} elsif ($hi0 - $lo0 != $hi1 - $lo1) { |
|
92
|
2
|
|
|
|
|
7
|
$range3->type('A'); |
|
93
|
|
|
|
|
|
|
} else { |
|
94
|
8
|
|
|
|
|
19
|
$range3->type('2'); |
|
95
|
8
|
|
|
|
|
18
|
for my $d (0 .. $hi0 - $lo0) { |
|
96
|
13
|
100
|
|
|
|
33
|
if (! $text0->eq_at($lo0 + $d, $text1->at($lo1 + $d))) { |
|
97
|
2
|
|
|
|
|
6
|
$range3->type('A'); |
|
98
|
2
|
|
|
|
|
3
|
last; |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
} |
|
102
|
33
|
|
|
|
|
80
|
$diff3->push($range3); |
|
103
|
|
|
|
|
|
|
} |
|
104
|
21
|
|
|
|
|
138
|
return $diff3; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub _is_a_text { |
|
108
|
63
|
|
|
63
|
|
67
|
my($self, $x) = @_; |
|
109
|
63
|
|
33
|
|
|
61
|
return eval{ $x->can('at') } && eval{ $x->can('eq_at') }; |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
1; |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
__END__ |