diff-lcs 1.2.5 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +6 -14
  2. data/.rspec +0 -1
  3. data/Code-of-Conduct.md +74 -0
  4. data/Contributing.md +84 -0
  5. data/History.md +278 -0
  6. data/{License.rdoc → License.md} +0 -0
  7. data/Manifest.txt +15 -8
  8. data/README.rdoc +18 -19
  9. data/Rakefile +41 -25
  10. data/autotest/discover.rb +3 -1
  11. data/bin/htmldiff +7 -4
  12. data/bin/ldiff +4 -1
  13. data/lib/diff-lcs.rb +1 -1
  14. data/lib/diff/lcs.rb +181 -254
  15. data/lib/diff/lcs/array.rb +1 -1
  16. data/lib/diff/lcs/backports.rb +9 -0
  17. data/lib/diff/lcs/block.rb +2 -2
  18. data/lib/diff/lcs/callbacks.rb +15 -12
  19. data/lib/diff/lcs/change.rb +33 -36
  20. data/lib/diff/lcs/htmldiff.rb +17 -16
  21. data/lib/diff/lcs/hunk.rb +67 -52
  22. data/lib/diff/lcs/internals.rb +43 -40
  23. data/lib/diff/lcs/ldiff.rb +44 -64
  24. data/lib/diff/lcs/string.rb +1 -1
  25. data/spec/change_spec.rb +31 -7
  26. data/spec/diff_spec.rb +24 -20
  27. data/spec/fixtures/aX +1 -0
  28. data/spec/fixtures/bXaX +1 -0
  29. data/spec/fixtures/ds1.csv +50 -0
  30. data/spec/fixtures/ds2.csv +51 -0
  31. data/spec/fixtures/ldiff/output.diff +4 -0
  32. data/spec/fixtures/ldiff/output.diff-c +7 -0
  33. data/spec/fixtures/ldiff/output.diff-e +3 -0
  34. data/spec/fixtures/ldiff/output.diff-f +3 -0
  35. data/spec/fixtures/ldiff/output.diff-u +5 -0
  36. data/spec/hunk_spec.rb +37 -37
  37. data/spec/issues_spec.rb +91 -17
  38. data/spec/lcs_spec.rb +24 -22
  39. data/spec/ldiff_spec.rb +86 -0
  40. data/spec/patch_spec.rb +182 -180
  41. data/spec/sdiff_spec.rb +91 -91
  42. data/spec/spec_helper.rb +143 -58
  43. data/spec/traverse_balanced_spec.rb +177 -177
  44. data/spec/traverse_sequences_spec.rb +63 -63
  45. metadata +87 -143
  46. checksums.yaml.gz.sig +0 -0
  47. data.tar.gz.sig +0 -3
  48. data/.autotest +0 -3
  49. data/.gemtest +0 -0
  50. data/.hoerc +0 -2
  51. data/.travis.yml +0 -22
  52. data/Contributing.rdoc +0 -64
  53. data/Gemfile +0 -20
  54. data/History.rdoc +0 -152
  55. metadata.gz.sig +0 -2
File without changes
@@ -1,12 +1,8 @@
1
- .autotest
2
- .gemtest
3
- .hoerc
4
1
  .rspec
5
- .travis.yml
6
- Contributing.rdoc
7
- Gemfile
8
- History.rdoc
9
- License.rdoc
2
+ Code-of-Conduct.md
3
+ Contributing.md
4
+ History.md
5
+ License.md
10
6
  Manifest.txt
11
7
  README.rdoc
12
8
  Rakefile
@@ -18,6 +14,7 @@ docs/artistic.txt
18
14
  lib/diff-lcs.rb
19
15
  lib/diff/lcs.rb
20
16
  lib/diff/lcs/array.rb
17
+ lib/diff/lcs/backports.rb
21
18
  lib/diff/lcs/block.rb
22
19
  lib/diff/lcs/callbacks.rb
23
20
  lib/diff/lcs/change.rb
@@ -28,9 +25,19 @@ lib/diff/lcs/ldiff.rb
28
25
  lib/diff/lcs/string.rb
29
26
  spec/change_spec.rb
30
27
  spec/diff_spec.rb
28
+ spec/fixtures/aX
29
+ spec/fixtures/bXaX
30
+ spec/fixtures/ds1.csv
31
+ spec/fixtures/ds2.csv
32
+ spec/fixtures/ldiff/output.diff
33
+ spec/fixtures/ldiff/output.diff-c
34
+ spec/fixtures/ldiff/output.diff-e
35
+ spec/fixtures/ldiff/output.diff-f
36
+ spec/fixtures/ldiff/output.diff-u
31
37
  spec/hunk_spec.rb
32
38
  spec/issues_spec.rb
33
39
  spec/lcs_spec.rb
40
+ spec/ldiff_spec.rb
34
41
  spec/patch_spec.rb
35
42
  spec/sdiff_spec.rb
36
43
  spec/spec_helper.rb
@@ -1,9 +1,10 @@
1
1
  = Diff::LCS
2
2
 
3
- home :: http://diff-lcs.rubyforge.org/
3
+ home :: https://github.com/halostatue/diff-lcs
4
4
  code :: https://github.com/halostatue/diff-lcs
5
5
  bugs :: https://github.com/halostatue/diff-lcs/issues
6
6
  rdoc :: http://rubydoc.info/github/halostatue/diff-lcs
7
+ continuous integration :: {<img src="https://github.com/halostatue/diff-lcs/workflows/CI/badge.svg" />}[https://github.com/halostatue/diff-lcs/actions]
7
8
 
8
9
  == Description
9
10
 
@@ -11,14 +12,15 @@ Diff::LCS computes the difference between two Enumerable sequences using the
11
12
  McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities
12
13
  to create a simple HTML diff output format and a standard diff-like tool.
13
14
 
14
- This is release 1.2.4, fixing a bug introduced after diff-lcs 1.1.3 that did
15
- not properly prune common sequences at the beginning of a comparison set.
16
- Thanks to Paul Kunysch for fixing this issue.
15
+ This is release 1.4.3, providing a simple extension that allows for
16
+ Diff::LCS::Change objects to be treated implicitly as arrays and fixes a
17
+ number of formatting issues.
17
18
 
18
- Coincident with the release of diff-lcs 1.2.3, we reported an issue with
19
- Rubinius in 1.9 mode
20
- ({rubinius/rubinius#2268}[https://github.com/rubinius/rubinius/issues/2268]).
21
- We are happy to report that this issue has been resolved.
19
+ Ruby versions below 2.5 are soft-deprecated, which means that older versions
20
+ are no longer part of the CI test suite. If any changes have been introduced
21
+ that break those versions, bug reports and patches will be accepted, but it
22
+ will be up to the reporter to verify any fixes prior to release. The next
23
+ major release will completely break compatibility.
22
24
 
23
25
  == Synopsis
24
26
 
@@ -69,17 +71,14 @@ or Array will perform best.
69
71
  Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt
70
72
  longest common subsequence (LCS) algorithm to compute intelligent differences
71
73
  between two sequenced enumerable containers. The implementation is based on
72
- Mario I. Wolczko's {Smalltalk version 1.2}[ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st]
74
+ Mario I. Wolczko's
75
+ {Smalltalk version 1.2}[ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st]
73
76
  (1993) and Ned Konz's Perl version
74
77
  {Algorithm::Diff 1.15}[http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/].
78
+ Diff::LCS#sdiff and Diff::LCS#traverse_balanced were originally written for the
79
+ Perl version by Mike Schilli.
75
80
 
76
- This library is called Diff::LCS because of an early version of Algorithm::Diff
77
- which was restrictively licensed.
78
-
79
- == Continuous Integration Status
80
-
81
- {<img src="https://travis-ci.org/halostatue/diff-lcs.png" />}[https://travis-ci.org/halostatue/diff-lcs]
82
-
83
- :include: Contributing.rdoc
84
-
85
- :include: License.rdoc
81
+ The algorithm is described in <em>A Fast Algorithm for Computing Longest Common
82
+ Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor
83
+ improvements to improve the speed. A simplified description of the algorithm,
84
+ originally written for the Perl version, was written by Mark-Jason Dominus.
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rubygems'
4
4
  require 'rspec'
@@ -6,36 +6,52 @@ require 'hoe'
6
6
 
7
7
  Hoe.plugin :bundler
8
8
  Hoe.plugin :doofus
9
- Hoe.plugin :email
10
9
  Hoe.plugin :gemspec2
11
10
  Hoe.plugin :git
12
- Hoe.plugin :rubyforge
13
- Hoe.plugin :travis
14
11
 
15
- Hoe.spec 'diff-lcs' do
16
- developer('Austin Ziegler', 'austin@rubyforge.org')
12
+ if RUBY_VERSION < '1.9'
13
+ class Array
14
+ def to_h
15
+ Hash[*self.flatten(1)]
16
+ end
17
+ end
18
+
19
+ class Gem::Specification
20
+ def metadata=(*)
21
+ end
22
+ end
23
+
24
+ class Object
25
+ def caller_locations(*)
26
+ []
27
+ end
28
+ end
29
+ end
30
+
31
+ _spec = Hoe.spec 'diff-lcs' do
32
+ developer('Austin Ziegler', 'halostatue@gmail.com')
17
33
 
18
- self.remote_rdoc_dir = '.'
19
- self.rsync_args << ' --exclude=statsvn/'
34
+ require_ruby_version '>= 1.8'
20
35
 
21
- self.history_file = 'History.rdoc'
36
+ self.history_file = 'History.md'
22
37
  self.readme_file = 'README.rdoc'
23
- self.extra_rdoc_files = FileList["*.rdoc"].to_a
24
-
25
- %w(MIT Perl\ Artistic\ v2 GNU\ GPL\ v2).each { |l| self.license l }
26
-
27
- self.extra_dev_deps << ['hoe-bundler', '~> 1.2']
28
- self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
29
- self.extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
30
- self.extra_dev_deps << ['hoe-git', '~> 1.5']
31
- self.extra_dev_deps << ['hoe-rubygems', '~> 1.0']
32
- self.extra_dev_deps << ['hoe-travis', '~> 1.2']
33
- self.extra_dev_deps << ['rake', '~> 10.0']
34
- self.extra_dev_deps << ['rspec', '~> 2.0']
38
+ self.licenses = ['MIT', 'Artistic-2.0', 'GPL-2.0+']
39
+
40
+ extra_dev_deps << ['hoe-doofus', '~> 1.0']
41
+ extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
42
+ extra_dev_deps << ['hoe-git', '~> 1.6']
43
+ extra_dev_deps << ['hoe-rubygems', '~> 1.0']
44
+ extra_dev_deps << ['rspec', '>= 2.0', '< 4']
45
+ extra_dev_deps << ['rake', '>= 10.0', '< 14']
46
+ extra_dev_deps << ['rdoc', '>= 0']
35
47
  end
36
48
 
37
- unless Rake::Task.task_defined? :test
38
- task :test => :spec
49
+ if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
50
+ namespace :spec do
51
+ desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
52
+ task :coverage do
53
+ ENV['COVERAGE'] = 'yes'
54
+ Rake::Task['spec'].execute
55
+ end
56
+ end
39
57
  end
40
-
41
- # vim: syntax=ruby
@@ -1 +1,3 @@
1
- Autotest.add_discovery { "rspec2" }
1
+ # frozen_string_literal: true
2
+
3
+ Autotest.add_discovery { 'rspec2' }
@@ -1,4 +1,5 @@
1
- #!ruby -w
1
+ #! /usr/bin/env ruby -w
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'diff/lcs'
4
5
  require 'diff/lcs/htmldiff'
@@ -10,8 +11,8 @@ rescue LoadError
10
11
  end
11
12
 
12
13
  if ARGV.size < 2 or ARGV.size > 3
13
- $stderr.puts "usage: #{File.basename($0)} old new [output.html]"
14
- $stderr.puts " #{File.basename($0)} old new > output.html"
14
+ warn "usage: #{File.basename($0)} old new [output.html]"
15
+ warn " #{File.basename($0)} old new > output.html"
15
16
  exit 127
16
17
  end
17
18
 
@@ -23,10 +24,12 @@ options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" }
23
24
  htmldiff = Diff::LCS::HTMLDiff.new(left, right, options)
24
25
 
25
26
  if ARGV[2]
26
- File.open(ARGV[2], "w") do |f|
27
+ File.open(ARGV[2], 'w') do |f|
27
28
  htmldiff.options[:output] = f
28
29
  htmldiff.run
29
30
  end
30
31
  else
31
32
  htmldiff.run
32
33
  end
34
+
35
+ # vim: ft=ruby
data/bin/ldiff CHANGED
@@ -1,6 +1,9 @@
1
- #!ruby -w
1
+ #! /usr/bin/env ruby -w
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'diff/lcs'
4
5
  require 'diff/lcs/ldiff'
5
6
 
6
7
  exit Diff::LCS::Ldiff.run(ARGV)
8
+
9
+ # vim: ft=ruby
@@ -1,3 +1,3 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'diff/lcs'
@@ -1,76 +1,24 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- module Diff; end unless defined? Diff
4
- # = Diff::LCS 1.2.5
5
- #
6
- # Computes "intelligent" differences between two sequenced Enumerables. This
7
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
8
- # objects that include Diffable.
9
- #
10
- # Based on Mario I. Wolczko's Smalltalk version (1.2, 1993) and Ned Konz's
11
- # Perl version (Algorithm::Diff 1.15).
12
- #
13
- # == Synopsis
14
- # require 'diff/lcs'
15
- #
16
- # seq1 = %w(a b c e h j l m n p)
17
- # seq2 = %w(b c d e f j k l m r s t)
18
- #
19
- # lcs = Diff::LCS.lcs(seq1, seq2)
20
- # diffs = Diff::LCS.diff(seq1, seq2)
21
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
22
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
23
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
24
- # seq2 == Diff::LCS.patch(seq1, diffs)
25
- # seq2 == Diff::LCS.patch!(seq1, diffs)
26
- # seq1 == Diff::LCS.unpatch(seq2, diffs)
27
- # seq1 == Diff::LCS.unpatch!(seq2, diffs)
28
- # seq2 == Diff::LCS.patch(seq1, sdiff)
29
- # seq2 == Diff::LCS.patch!(seq1, sdiff)
30
- # seq1 == Diff::LCS.unpatch(seq2, sdiff)
31
- # seq1 == Diff::LCS.unpatch!(seq2, sdiff)
32
- #
33
- # Alternatively, objects can be extended with Diff::LCS:
34
- #
35
- # seq1.extend(Diff::LCS)
36
- # lcs = seq1.lcs(seq2)
37
- # diffs = seq1.diff(seq2)
38
- # sdiff = seq1.sdiff(seq2)
39
- # seq = seq1.traverse_sequences(seq2, callback_obj)
40
- # bal = seq1.traverse_balanced(seq2, callback_obj)
41
- # seq2 == seq1.patch(diffs)
42
- # seq2 == seq1.patch!(diffs)
43
- # seq1 == seq2.unpatch(diffs)
44
- # seq1 == seq2.unpatch!(diffs)
45
- # seq2 == seq1.patch(sdiff)
46
- # seq2 == seq1.patch!(sdiff)
47
- # seq1 == seq2.unpatch(sdiff)
48
- # seq1 == seq2.unpatch!(sdiff)
49
- #
50
- # Default extensions are provided for Array and String objects through the
51
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
52
- #
53
- # == Introduction (by Mark-Jason Dominus)
54
- #
55
- # <em>The following text is from the Perl documentation. The only changes
56
- # have been to make the text appear better in Rdoc</em>.
3
+ module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
4
+
5
+ # == How Diff Works (by Mark-Jason Dominus)
57
6
  #
58
- # I once read an article written by the authors of +diff+; they said that
59
- # they hard worked very hard on the algorithm until they found the right
60
- # one.
7
+ # I once read an article written by the authors of +diff+; they said that they
8
+ # hard worked very hard on the algorithm until they found the right one.
61
9
  #
62
- # I think what they ended up using (and I hope someone will correct me,
63
- # because I am not very confident about this) was the `longest common
64
- # subsequence' method. In the LCS problem, you have two sequences of items:
10
+ # I think what they ended up using (and I hope someone will correct me, because
11
+ # I am not very confident about this) was the `longest common subsequence'
12
+ # method. In the LCS problem, you have two sequences of items:
65
13
  #
66
14
  # a b c d f g h j q z
67
15
  # a b c d e f g i j k r x y z
68
16
  #
69
17
  # and you want to find the longest sequence of items that is present in both
70
18
  # original sequences in the same order. That is, you want to find a new
71
- # sequence *S* which can be obtained from the first sequence by deleting
72
- # some items, and from the second sequence by deleting other items. You also
73
- # want *S* to be as long as possible. In this case *S* is:
19
+ # sequence *S* which can be obtained from the first sequence by deleting some
20
+ # items, and from the second sequence by deleting other items. You also want
21
+ # *S* to be as long as possible. In this case *S* is:
74
22
  #
75
23
  # a b c d f g j z
76
24
  #
@@ -82,9 +30,9 @@ module Diff; end unless defined? Diff
82
30
  # This module solves the LCS problem. It also includes a canned function to
83
31
  # generate +diff+-like output.
84
32
  #
85
- # It might seem from the example above that the LCS of two sequences is
86
- # always pretty obvious, but that's not always the case, especially when the
87
- # two sequences have many repeated elements. For example, consider
33
+ # It might seem from the example above that the LCS of two sequences is always
34
+ # pretty obvious, but that's not always the case, especially when the two
35
+ # sequences have many repeated elements. For example, consider
88
36
  #
89
37
  # a x b y c z p d q
90
38
  # a b c a x b y c z
@@ -95,57 +43,28 @@ module Diff; end unless defined? Diff
95
43
  # a x b y c z p d q
96
44
  # a b c a b y c z
97
45
  #
98
- # This finds the common subsequence +a b c z+. But actually, the LCS is +a x
99
- # b y c z+:
46
+ # This finds the common subsequence +a b c z+. But actually, the LCS is +a x b
47
+ # y c z+:
100
48
  #
101
49
  # a x b y c z p d q
102
50
  # a b c a x b y c z
103
- #
104
- # == Author
105
- # This version is by Austin Ziegler <austin@rubyforge.org>.
106
- #
107
- # It is based on the Perl Algorithm::Diff (1.15) by Ned Konz , copyright
108
- # &copy; 2000&ndash;2002 and the Smalltalk diff version by Mario I.
109
- # Wolczko, copyright &copy; 1993. Documentation includes work by
110
- # Mark-Jason Dominus.
111
- #
112
- # == Licence
113
- # Copyright &copy; 2004&ndash;2013 Austin Ziegler
114
- # This program is free software; you can redistribute it and/or modify it
115
- # under the same terms as Ruby, or alternatively under the Perl Artistic
116
- # licence.
117
- #
118
- # == Credits
119
- # Much of the documentation is taken directly from the Perl Algorithm::Diff
120
- # implementation and was written originally by Mark-Jason Dominus and later
121
- # by Ned Konz. The basic Ruby implementation was re-ported from the
122
- # Smalltalk implementation, available at
123
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
124
- #
125
- # #sdiff and #traverse_balanced were written for the Perl version by Mike
126
- # Schilli <m@perlmeister.com>.
127
- #
128
- # "The algorithm is described in <em>A Fast Algorithm for Computing Longest
129
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May
130
- # 1977, with a few minor improvements to improve the speed."
131
51
  module Diff::LCS
132
- VERSION = '1.2.5'
52
+ VERSION = '1.4.3'
133
53
  end
134
54
 
135
55
  require 'diff/lcs/callbacks'
136
56
  require 'diff/lcs/internals'
137
57
 
138
- module Diff::LCS
58
+ module Diff::LCS # rubocop:disable Style/Documentation
139
59
  # Returns an Array containing the longest common subsequence(s) between
140
- # +self+ and +other+. See Diff::LCS#LCS.
60
+ # +self+ and +other+. See Diff::LCS#lcs.
141
61
  #
142
62
  # lcs = seq1.lcs(seq2)
143
63
  def lcs(other, &block) #:yields self[i] if there are matched subsequences:
144
64
  Diff::LCS.lcs(self, other, &block)
145
65
  end
146
66
 
147
- # Returns the difference set between +self+ and +other+. See
148
- # Diff::LCS#diff.
67
+ # Returns the difference set between +self+ and +other+. See Diff::LCS#diff.
149
68
  def diff(other, callbacks = nil, &block)
150
69
  Diff::LCS.diff(self, other, callbacks, &block)
151
70
  end
@@ -159,29 +78,27 @@ module Diff::LCS
159
78
  # Traverses the discovered longest common subsequences between +self+ and
160
79
  # +other+. See Diff::LCS#traverse_sequences.
161
80
  def traverse_sequences(other, callbacks = nil, &block)
162
- traverse_sequences(self, other, callbacks ||
163
- Diff::LCS.YieldingCallbacks, &block)
81
+ traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block)
164
82
  end
165
83
 
166
84
  # Traverses the discovered longest common subsequences between +self+ and
167
85
  # +other+ using the alternate, balanced algorithm. See
168
86
  # Diff::LCS#traverse_balanced.
169
87
  def traverse_balanced(other, callbacks = nil, &block)
170
- traverse_balanced(self, other, callbacks ||
171
- Diff::LCS.YieldingCallbacks, &block)
88
+ traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block)
172
89
  end
173
90
 
174
- # Attempts to patch +self+ with the provided +patchset+. A new sequence
175
- # based on +self+ and the +patchset+ will be created. See Diff::LCS#patch.
176
- # Attempts to autodiscover the direction of the patch.
91
+ # Attempts to patch +self+ with the provided +patchset+. A new sequence based
92
+ # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Attempts
93
+ # to autodiscover the direction of the patch.
177
94
  def patch(patchset)
178
95
  Diff::LCS.patch(self, patchset)
179
96
  end
180
- alias_method :unpatch, :patch
97
+ alias unpatch patch
181
98
 
182
- # Attempts to patch +self+ with the provided +patchset+. A new sequence
183
- # based on +self+ and the +patchset+ will be created. See Diff::LCS#patch.
184
- # Does no patch direction autodiscovery.
99
+ # Attempts to patch +self+ with the provided +patchset+. A new sequence based
100
+ # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Does no
101
+ # patch direction autodiscovery.
185
102
  def patch!(patchset)
186
103
  Diff::LCS.patch!(self, patchset)
187
104
  end
@@ -194,8 +111,8 @@ module Diff::LCS
194
111
  end
195
112
 
196
113
  # Attempts to patch +self+ with the provided +patchset+, using #patch!. If
197
- # the sequence this is used on supports #replace, the value of +self+ will
198
- # be replaced. See Diff::LCS#patch. Does no patch direction autodiscovery.
114
+ # the sequence this is used on supports #replace, the value of +self+ will be
115
+ # replaced. See Diff::LCS#patch. Does no patch direction autodiscovery.
199
116
  def patch_me(patchset)
200
117
  if respond_to? :replace
201
118
  replace(patch!(patchset))
@@ -204,10 +121,9 @@ module Diff::LCS
204
121
  end
205
122
  end
206
123
 
207
- # Attempts to unpatch +self+ with the provided +patchset+, using
208
- # #unpatch!. If the sequence this is used on supports #replace, the value
209
- # of +self+ will be replaced. See Diff::LCS#unpatch. Does no patch direction
210
- # autodiscovery.
124
+ # Attempts to unpatch +self+ with the provided +patchset+, using #unpatch!.
125
+ # If the sequence this is used on supports #replace, the value of +self+ will
126
+ # be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery.
211
127
  def unpatch_me(patchset)
212
128
  if respond_to? :replace
213
129
  replace(unpatch!(patchset))
@@ -222,29 +138,28 @@ class << Diff::LCS
222
138
  matches = Diff::LCS::Internals.lcs(seq1, seq2)
223
139
  ret = []
224
140
  string = seq1.kind_of? String
225
- matches.each_with_index do |e, i|
226
- unless matches[i].nil?
227
- v = string ? seq1[i, 1] : seq1[i]
228
- v = block[v] if block
229
- ret << v
230
- end
141
+ matches.each_with_index do |_e, i|
142
+ next if matches[i].nil?
143
+
144
+ v = string ? seq1[i, 1] : seq1[i]
145
+ v = block[v] if block
146
+ ret << v
231
147
  end
232
148
  ret
233
149
  end
234
- alias_method :LCS, :lcs
150
+ alias LCS lcs
235
151
 
236
152
  # #diff computes the smallest set of additions and deletions necessary to
237
- # turn the first sequence into the second, and returns a description of
238
- # these changes.
153
+ # turn the first sequence into the second, and returns a description of these
154
+ # changes.
239
155
  #
240
156
  # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate
241
157
  # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a
242
158
  # Class argument is provided for +callbacks+, #diff will attempt to
243
- # initialise it. If the +callbacks+ object (possibly initialised) responds
244
- # to #finish, it will be called.
159
+ # initialise it. If the +callbacks+ object (possibly initialised) responds to
160
+ # #finish, it will be called.
245
161
  def diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
246
- diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks,
247
- &block)
162
+ diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block)
248
163
  end
249
164
 
250
165
  # #sdiff computes all necessary components to show two sequences and their
@@ -259,18 +174,31 @@ class << Diff::LCS
259
174
  # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate
260
175
  # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a
261
176
  # Class argument is provided for +callbacks+, #diff will attempt to
262
- # initialise it. If the +callbacks+ object (possibly initialised) responds
263
- # to #finish, it will be called.
177
+ # initialise it. If the +callbacks+ object (possibly initialised) responds to
178
+ # #finish, it will be called.
179
+ #
180
+ # Each element of a returned array is a Diff::LCS::ContextChange object,
181
+ # which can be implicitly converted to an array.
182
+ #
183
+ # Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)|
184
+ # case action
185
+ # when '!'
186
+ # # replace
187
+ # when '-'
188
+ # # delete
189
+ # when '+'
190
+ # # insert
191
+ # end
192
+ # end
264
193
  def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
265
- diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks,
266
- &block)
194
+ diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block)
267
195
  end
268
196
 
269
- # #traverse_sequences is the most general facility provided by this
270
- # module; #diff and #lcs are implemented as calls to it.
197
+ # #traverse_sequences is the most general facility provided by this module;
198
+ # #diff and #lcs are implemented as calls to it.
271
199
  #
272
- # The arguments to #traverse_sequences are the two sequences to traverse,
273
- # and a callback object, like this:
200
+ # The arguments to #traverse_sequences are the two sequences to traverse, and
201
+ # a callback object, like this:
274
202
  #
275
203
  # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
276
204
  #
@@ -298,56 +226,55 @@ class << Diff::LCS
298
226
  # ^
299
227
  # b---+
300
228
  #
301
- # If there are two arrows (+a+ and +b+) pointing to elements of sequences
302
- # +A+ and +B+, the arrows will initially point to the first elements of
303
- # their respective sequences. #traverse_sequences will advance the arrows
304
- # through the sequences one element at a time, calling a method on the
305
- # user-specified callback object before each advance. It will advance the
306
- # arrows in such a way that if there are elements <tt>A[i]</tt> and
307
- # <tt>B[j]</tt> which are both equal and part of the longest common
308
- # subsequence, there will be some moment during the execution of
309
- # #traverse_sequences when arrow +a+ is pointing to <tt>A[i]</tt> and
310
- # arrow +b+ is pointing to <tt>B[j]</tt>. When this happens,
311
- # #traverse_sequences will call <tt>callbacks#match</tt> and then it will
312
- # advance both arrows.
313
- #
314
- # Otherwise, one of the arrows is pointing to an element of its sequence
315
- # that is not part of the longest common subsequence. #traverse_sequences
316
- # will advance that arrow and will call <tt>callbacks#discard_a</tt> or
317
- # <tt>callbacks#discard_b</tt>, depending on which arrow it advanced. If
318
- # both arrows point to elements that are not part of the longest common
319
- # subsequence, then #traverse_sequences will advance one of them and call
320
- # the appropriate callback, but it is not specified which it will call.
321
- #
322
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
323
- # and <tt>callbacks#discard_b</tt> are invoked with an event comprising
324
- # the action ("=", "+", or "-", respectively), the indicies +i+ and +j+,
325
- # and the elements <tt>A[i]</tt> and <tt>B[j]</tt>. Return values are
326
- # discarded by #traverse_sequences.
229
+ # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+
230
+ # and +B+, the arrows will initially point to the first elements of their
231
+ # respective sequences. #traverse_sequences will advance the arrows through
232
+ # the sequences one element at a time, calling a method on the user-specified
233
+ # callback object before each advance. It will advance the arrows in such a
234
+ # way that if there are elements <tt>A[i]</tt> and <tt>B[j]</tt> which are
235
+ # both equal and part of the longest common subsequence, there will be some
236
+ # moment during the execution of #traverse_sequences when arrow +a+ is
237
+ # pointing to <tt>A[i]</tt> and arrow +b+ is pointing to <tt>B[j]</tt>. When
238
+ # this happens, #traverse_sequences will call <tt>callbacks#match</tt> and
239
+ # then it will advance both arrows.
240
+ #
241
+ # Otherwise, one of the arrows is pointing to an element of its sequence that
242
+ # is not part of the longest common subsequence. #traverse_sequences will
243
+ # advance that arrow and will call <tt>callbacks#discard_a</tt> or
244
+ # <tt>callbacks#discard_b</tt>, depending on which arrow it advanced. If both
245
+ # arrows point to elements that are not part of the longest common
246
+ # subsequence, then #traverse_sequences will advance one of them and call the
247
+ # appropriate callback, but it is not specified which it will call.
248
+ #
249
+ # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>, and
250
+ # <tt>callbacks#discard_b</tt> are invoked with an event comprising the
251
+ # action ("=", "+", or "-", respectively), the indicies +i+ and +j+, and the
252
+ # elements <tt>A[i]</tt> and <tt>B[j]</tt>. Return values are discarded by
253
+ # #traverse_sequences.
327
254
  #
328
255
  # === End of Sequences
329
256
  #
330
257
  # If arrow +a+ reaches the end of its sequence before arrow +b+ does,
331
- # #traverse_sequence will try to call <tt>callbacks#finished_a</tt> with
332
- # the last index and element of +A+ (<tt>A[-1]</tt>) and the current index
333
- # and element of +B+ (<tt>B[j]</tt>). If <tt>callbacks#finished_a</tt>
334
- # does not exist, then <tt>callbacks#discard_b</tt> will be called on each
335
- # element of +B+ until the end of the sequence is reached (the call will
336
- # be done with <tt>A[-1]</tt> and <tt>B[j]</tt> for each element).
258
+ # #traverse_sequence will try to call <tt>callbacks#finished_a</tt> with the
259
+ # last index and element of +A+ (<tt>A[-1]</tt>) and the current index and
260
+ # element of +B+ (<tt>B[j]</tt>). If <tt>callbacks#finished_a</tt> does not
261
+ # exist, then <tt>callbacks#discard_b</tt> will be called on each element of
262
+ # +B+ until the end of the sequence is reached (the call will be done with
263
+ # <tt>A[-1]</tt> and <tt>B[j]</tt> for each element).
337
264
  #
338
265
  # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+,
339
266
  # <tt>callbacks#finished_b</tt> will be called with the current index and
340
267
  # element of +A+ (<tt>A[i]</tt>) and the last index and element of +B+
341
- # (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not exist
342
- # on the callback object, then <tt>callbacks#discard_a</tt> will be called
343
- # on each element of +A+ until the end of the sequence is reached
344
- # (<tt>A[i]</tt> and <tt>B[-1]</tt>).
268
+ # (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not exist on
269
+ # the callback object, then <tt>callbacks#discard_a</tt> will be called on
270
+ # each element of +A+ until the end of the sequence is reached (<tt>A[i]</tt>
271
+ # and <tt>B[-1]</tt>).
345
272
  #
346
273
  # There is a chance that one additional <tt>callbacks#discard_a</tt> or
347
- # <tt>callbacks#discard_b</tt> will be called after the end of the
348
- # sequence is reached, if +a+ has not yet reached the end of +A+ or +b+
349
- # has not yet reached the end of +B+.
350
- def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks, &block) #:yields change events:
274
+ # <tt>callbacks#discard_b</tt> will be called after the end of the sequence
275
+ # is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet
276
+ # reached the end of +B+.
277
+ def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) #:yields change events:
351
278
  callbacks ||= Diff::LCS::SequenceCallbacks
352
279
  matches = Diff::LCS::Internals.lcs(seq1, seq2)
353
280
 
@@ -373,6 +300,7 @@ class << Diff::LCS
373
300
  else
374
301
  loop do
375
302
  break unless bj < b_line
303
+
376
304
  bx = string ? seq2[bj, 1] : seq2[bj]
377
305
  event = Diff::LCS::ContextChange.new('+', i, ax, bj, bx)
378
306
  event = yield event if block_given?
@@ -389,12 +317,12 @@ class << Diff::LCS
389
317
  end
390
318
  ai += 1
391
319
 
392
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
393
- # just past the last matching lines in their sequences.
320
+ # The last entry (if any) processed was a match. +ai+ and +bj+ point just
321
+ # past the last matching lines in their sequences.
394
322
  while (ai < a_size) or (bj < b_size)
395
323
  # last A?
396
324
  if ai == a_size and bj < b_size
397
- if callbacks.respond_to?(:finished_a) and not run_finished_a
325
+ if callbacks.respond_to?(:finished_a) and !run_finished_a
398
326
  ax = string ? seq1[-1, 1] : seq1[-1]
399
327
  bx = string ? seq2[bj, 1] : seq2[bj]
400
328
  event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
@@ -416,7 +344,7 @@ class << Diff::LCS
416
344
 
417
345
  # last B?
418
346
  if bj == b_size and ai < a_size
419
- if callbacks.respond_to?(:finished_b) and not run_finished_b
347
+ if callbacks.respond_to?(:finished_b) and !run_finished_b
420
348
  ax = string ? seq1[ai, 1] : seq1[ai]
421
349
  bx = string ? seq2[-1, 1] : seq2[-1]
422
350
  event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
@@ -445,25 +373,25 @@ class << Diff::LCS
445
373
  ai += 1
446
374
  end
447
375
 
448
- if bj < b_size
449
- ax = string ? seq1[ai, 1] : seq1[ai]
450
- bx = string ? seq2[bj, 1] : seq2[bj]
451
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
452
- event = yield event if block_given?
453
- callbacks.discard_b(event)
454
- bj += 1
455
- end
376
+ next unless bj < b_size
377
+
378
+ ax = string ? seq1[ai, 1] : seq1[ai]
379
+ bx = string ? seq2[bj, 1] : seq2[bj]
380
+ event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
381
+ event = yield event if block_given?
382
+ callbacks.discard_b(event)
383
+ bj += 1
456
384
  end
457
385
  end
458
386
 
459
387
  # #traverse_balanced is an alternative to #traverse_sequences. It uses a
460
- # different algorithm to iterate through the entries in the computed
461
- # longest common subsequence. Instead of viewing the changes as insertions
462
- # or deletions from one of the sequences, #traverse_balanced will report
388
+ # different algorithm to iterate through the entries in the computed longest
389
+ # common subsequence. Instead of viewing the changes as insertions or
390
+ # deletions from one of the sequences, #traverse_balanced will report
463
391
  # <em>changes</em> between the sequences.
464
392
  #
465
- # The arguments to #traverse_balanced are the two sequences to traverse
466
- # and a callback object, like this:
393
+ # The arguments to #traverse_balanced are the two sequences to traverse and a
394
+ # callback object, like this:
467
395
  #
468
396
  # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
469
397
  #
@@ -499,24 +427,23 @@ class << Diff::LCS
499
427
  #
500
428
  # === Matches
501
429
  #
502
- # If there are two arrows (+a+ and +b+) pointing to elements of sequences
503
- # +A+ and +B+, the arrows will initially point to the first elements of
504
- # their respective sequences. #traverse_sequences will advance the arrows
505
- # through the sequences one element at a time, calling a method on the
506
- # user-specified callback object before each advance. It will advance the
507
- # arrows in such a way that if there are elements <tt>A[i]</tt> and
508
- # <tt>B[j]</tt> which are both equal and part of the longest common
509
- # subsequence, there will be some moment during the execution of
510
- # #traverse_sequences when arrow +a+ is pointing to <tt>A[i]</tt> and
511
- # arrow +b+ is pointing to <tt>B[j]</tt>. When this happens,
512
- # #traverse_sequences will call <tt>callbacks#match</tt> and then it will
513
- # advance both arrows.
430
+ # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+
431
+ # and +B+, the arrows will initially point to the first elements of their
432
+ # respective sequences. #traverse_sequences will advance the arrows through
433
+ # the sequences one element at a time, calling a method on the user-specified
434
+ # callback object before each advance. It will advance the arrows in such a
435
+ # way that if there are elements <tt>A[i]</tt> and <tt>B[j]</tt> which are
436
+ # both equal and part of the longest common subsequence, there will be some
437
+ # moment during the execution of #traverse_sequences when arrow +a+ is
438
+ # pointing to <tt>A[i]</tt> and arrow +b+ is pointing to <tt>B[j]</tt>. When
439
+ # this happens, #traverse_sequences will call <tt>callbacks#match</tt> and
440
+ # then it will advance both arrows.
514
441
  #
515
442
  # === Discards
516
443
  #
517
- # Otherwise, one of the arrows is pointing to an element of its sequence
518
- # that is not part of the longest common subsequence. #traverse_sequences
519
- # will advance that arrow and will call <tt>callbacks#discard_a</tt> or
444
+ # Otherwise, one of the arrows is pointing to an element of its sequence that
445
+ # is not part of the longest common subsequence. #traverse_sequences will
446
+ # advance that arrow and will call <tt>callbacks#discard_a</tt> or
520
447
  # <tt>callbacks#discard_b</tt>, depending on which arrow it advanced.
521
448
  #
522
449
  # === Changes
@@ -530,14 +457,14 @@ class << Diff::LCS
530
457
  #
531
458
  # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
532
459
  # <tt>callbacks#discard_b</tt>, and <tt>callbacks#change</tt> are invoked
533
- # with an event comprising the action ("=", "+", "-", or "!",
534
- # respectively), the indicies +i+ and +j+, and the elements
535
- # <tt>A[i]</tt> and <tt>B[j]</tt>. Return values are discarded by
536
- # #traverse_balanced.
460
+ # with an event comprising the action ("=", "+", "-", or "!", respectively),
461
+ # the indicies +i+ and +j+, and the elements <tt>A[i]</tt> and <tt>B[j]</tt>.
462
+ # Return values are discarded by #traverse_balanced.
537
463
  #
538
464
  # === Context
539
- # Note that +i+ and +j+ may not be the same index position, even if +a+
540
- # and +b+ are considered to be pointing to matching or changed elements.
465
+ #
466
+ # Note that +i+ and +j+ may not be the same index position, even if +a+ and
467
+ # +b+ are considered to be pointing to matching or changed elements.
541
468
  def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
542
469
  matches = Diff::LCS::Internals.lcs(seq1, seq2)
543
470
  a_size = seq1.size
@@ -555,6 +482,7 @@ class << Diff::LCS
555
482
  end
556
483
 
557
484
  break if ma >= matches.size # end of matches?
485
+
558
486
  mb = matches[ma]
559
487
 
560
488
  # Change(seq2)
@@ -569,7 +497,6 @@ class << Diff::LCS
569
497
  event = yield event if block_given?
570
498
  callbacks.change(event)
571
499
  ai += 1
572
- bj += 1
573
500
  else
574
501
  event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
575
502
  event = yield event if block_given?
@@ -579,8 +506,9 @@ class << Diff::LCS
579
506
  event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
580
507
  event = yield event if block_given?
581
508
  callbacks.discard_b(event)
582
- bj += 1
583
509
  end
510
+
511
+ bj += 1
584
512
  when [true, false]
585
513
  event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
586
514
  event = yield event if block_given?
@@ -615,7 +543,6 @@ class << Diff::LCS
615
543
  event = yield event if block_given?
616
544
  callbacks.change(event)
617
545
  ai += 1
618
- bj += 1
619
546
  else
620
547
  event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
621
548
  event = yield event if block_given?
@@ -625,8 +552,9 @@ class << Diff::LCS
625
552
  event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
626
553
  event = yield event if block_given?
627
554
  callbacks.discard_b(event)
628
- bj += 1
629
555
  end
556
+
557
+ bj += 1
630
558
  when [true, false]
631
559
  event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
632
560
  event = yield event if block_given?
@@ -642,9 +570,9 @@ class << Diff::LCS
642
570
  end
643
571
 
644
572
  PATCH_MAP = { #:nodoc:
645
- :patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' },
646
- :unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }
647
- }
573
+ :patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' }.freeze,
574
+ :unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }.freeze
575
+ }.freeze
648
576
 
649
577
  # Applies a +patchset+ to the sequence +src+ according to the +direction+
650
578
  # (<tt>:patch</tt> or <tt>:unpatch</tt>), producing a new sequence.
@@ -657,23 +585,23 @@ class << Diff::LCS
657
585
  #
658
586
  # patch(s1, diff(s1, s2)) -> s2
659
587
  #
660
- # A +patchset+ can be considered to apply backward (<tt>:unpatch</tt>) if
661
- # the following expression is true:
588
+ # A +patchset+ can be considered to apply backward (<tt>:unpatch</tt>) if the
589
+ # following expression is true:
662
590
  #
663
591
  # patch(s2, diff(s1, s2)) -> s1
664
592
  #
665
- # If the +patchset+ contains no changes, the +src+ value will be returned
666
- # as either <tt>src.dup</tt> or +src+. A +patchset+ can be deemed as
667
- # having no changes if the following predicate returns true:
593
+ # If the +patchset+ contains no changes, the +src+ value will be returned as
594
+ # either <tt>src.dup</tt> or +src+. A +patchset+ can be deemed as having no
595
+ # changes if the following predicate returns true:
668
596
  #
669
597
  # patchset.empty? or
670
- # patchset.flatten.all? { |change| change.unchanged? }
598
+ # patchset.flatten(1).all? { |change| change.unchanged? }
671
599
  #
672
600
  # === Patchsets
673
601
  #
674
- # A +patchset+ is always an enumerable sequence of changes, hunks of
675
- # changes, or a mix of the two. A hunk of changes is an enumerable
676
- # sequence of changes:
602
+ # A +patchset+ is always an enumerable sequence of changes, hunks of changes,
603
+ # or a mix of the two. A hunk of changes is an enumerable sequence of
604
+ # changes:
677
605
  #
678
606
  # [ # patchset
679
607
  # # change
@@ -682,18 +610,15 @@ class << Diff::LCS
682
610
  # ]
683
611
  # ]
684
612
  #
685
- # The +patch+ method accepts <tt>patchset</tt>s that are enumerable
686
- # sequences containing either Diff::LCS::Change objects (or a subclass) or
687
- # the array representations of those objects. Prior to application, array
613
+ # The +patch+ method accepts <tt>patchset</tt>s that are enumerable sequences
614
+ # containing either Diff::LCS::Change objects (or a subclass) or the array
615
+ # representations of those objects. Prior to application, array
688
616
  # representations of Diff::LCS::Change objects will be reified.
689
617
  def patch(src, patchset, direction = nil)
690
618
  # Normalize the patchset.
691
619
  has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset)
692
620
 
693
- if not has_changes
694
- return src.dup if src.respond_to? :dup
695
- return src
696
- end
621
+ return src.respond_to?(:dup) ? src.dup : src unless has_changes
697
622
 
698
623
  string = src.kind_of?(String)
699
624
  # Start with a new empty type of the source's class
@@ -705,7 +630,7 @@ class << Diff::LCS
705
630
 
706
631
  patch_map = PATCH_MAP[direction]
707
632
 
708
- patchset.flatten.each do |change|
633
+ patchset.each do |change|
709
634
  # Both Change and ContextChange support #action
710
635
  action = patch_map[change.action]
711
636
 
@@ -737,8 +662,8 @@ class << Diff::LCS
737
662
  bj += 1
738
663
  end
739
664
 
740
- res << el
741
- bj += 1
665
+ res << el
666
+ bj += 1
742
667
  when '='
743
668
  # This only appears in sdiff output with the SDiff callback.
744
669
  # Therefore, we only need to worry about dealing with a single
@@ -754,10 +679,10 @@ class << Diff::LCS
754
679
  bj += 1
755
680
  end
756
681
 
757
- bj += 1
758
- ai += 1
682
+ bj += 1
683
+ ai += 1
759
684
 
760
- res << el
685
+ res << el
761
686
  end
762
687
  when Diff::LCS::Change
763
688
  case action
@@ -767,7 +692,7 @@ class << Diff::LCS
767
692
  ai += 1
768
693
  bj += 1
769
694
  end
770
- ai += 1
695
+ ai += 1
771
696
  when '+'
772
697
  while bj < change.position
773
698
  res << (string ? src[ai, 1] : src[ai])
@@ -775,9 +700,9 @@ class << Diff::LCS
775
700
  bj += 1
776
701
  end
777
702
 
778
- bj += 1
703
+ bj += 1
779
704
 
780
- res << change.element
705
+ res << change.element
781
706
  end
782
707
  end
783
708
  end
@@ -791,15 +716,17 @@ class << Diff::LCS
791
716
  res
792
717
  end
793
718
 
794
- # Given a set of patchset, convert the current version to the prior
795
- # version. Does no auto-discovery.
719
+ # Given a set of patchset, convert the current version to the prior version.
720
+ # Does no auto-discovery.
796
721
  def unpatch!(src, patchset)
797
722
  patch(src, patchset, :unpatch)
798
723
  end
799
724
 
800
- # Given a set of patchset, convert the current version to the next
801
- # version. Does no auto-discovery.
725
+ # Given a set of patchset, convert the current version to the next version.
726
+ # Does no auto-discovery.
802
727
  def patch!(src, patchset)
803
728
  patch(src, patchset, :patch)
804
729
  end
805
730
  end
731
+
732
+ require 'diff/lcs/backports'