diff-lcs 1.2.2 → 1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +0 -1
  3. data/Code-of-Conduct.md +74 -0
  4. data/Contributing.md +84 -0
  5. data/History.md +247 -0
  6. data/{License.rdoc → License.md} +0 -0
  7. data/Manifest.txt +15 -9
  8. data/README.rdoc +21 -18
  9. data/Rakefile +35 -23
  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 +1 -1
  18. data/lib/diff/lcs/callbacks.rb +15 -12
  19. data/lib/diff/lcs/change.rb +34 -37
  20. data/lib/diff/lcs/htmldiff.rb +17 -16
  21. data/lib/diff/lcs/hunk.rb +59 -47
  22. data/lib/diff/lcs/internals.rb +44 -40
  23. data/lib/diff/lcs/ldiff.rb +45 -65
  24. data/lib/diff/lcs/string.rb +1 -1
  25. data/spec/change_spec.rb +31 -7
  26. data/spec/diff_spec.rb +28 -18
  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 +54 -45
  37. data/spec/issues_spec.rb +50 -17
  38. data/spec/lcs_spec.rb +24 -22
  39. data/spec/ldiff_spec.rb +72 -0
  40. data/spec/patch_spec.rb +182 -180
  41. data/spec/sdiff_spec.rb +99 -87
  42. data/spec/spec_helper.rb +141 -58
  43. data/spec/traverse_balanced_spec.rb +177 -177
  44. data/spec/traverse_sequences_spec.rb +63 -63
  45. metadata +100 -169
  46. data.tar.gz.sig +0 -0
  47. data/.autotest +0 -3
  48. data/.gemtest +0 -0
  49. data/.hoerc +0 -2
  50. data/.travis.yml +0 -22
  51. data/Contributing.rdoc +0 -64
  52. data/Gemfile +0 -19
  53. data/History.rdoc +0 -117
  54. data/diff-lcs.gemspec +0 -63
  55. metadata.gz.sig +0 -4
@@ -1,9 +1,10 @@
1
1
  = Diff::LCS
2
2
 
3
- home :: http://diff-lcs.rubyforge.org/
4
- code :: https://github.com/halostatue/diff-lcs
5
- bugs :: https://github.com/halostatue/diff-lcs/issues
6
- rdoc :: http://rubydoc.info/github/halostatue/diff-lcs
3
+ home :: https://github.com/halostatue/diff-lcs
4
+ code :: https://github.com/halostatue/diff-lcs
5
+ bugs :: https://github.com/halostatue/diff-lcs/issues
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,9 +12,14 @@ 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.2, fixing a bug that prevented comparison of values that
15
- are not US-ASCII-compatible. Thanks to Jon Rowe for finding and providing most
16
- of the work behind this issue. This is a recommended release.
15
+ This is release 1.4, providing a simple extension that allows for
16
+ Diff::LCS::Change objects to be treated implicitly as arrays. Ruby versions
17
+ below 2.5 are soft-deprecated.
18
+
19
+ This means that older versions are no longer part of the CI test suite. If any
20
+ changes have been introduced that break those versions, bug reports and patches
21
+ will be accepted, but it will be up to the reporter to verify any fixes prior
22
+ to release. A future release will completely break compatibility.
17
23
 
18
24
  == Synopsis
19
25
 
@@ -64,17 +70,14 @@ or Array will perform best.
64
70
  Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt
65
71
  longest common subsequence (LCS) algorithm to compute intelligent differences
66
72
  between two sequenced enumerable containers. The implementation is based on
67
- Mario I. Wolczko's {Smalltalk version 1.2}[ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st]
73
+ Mario I. Wolczko's
74
+ {Smalltalk version 1.2}[ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st]
68
75
  (1993) and Ned Konz's Perl version
69
76
  {Algorithm::Diff 1.15}[http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/].
77
+ Diff::LCS#sdiff and Diff::LCS#traverse_balanced were originally written for the
78
+ Perl version by Mike Schilli.
70
79
 
71
- This library is called Diff::LCS because of an early version of Algorithm::Diff
72
- which was restrictively licensed.
73
-
74
- == Continuous Integration Status
75
-
76
- {<img src="https://travis-ci.org/halostatue/diff-lcs.png" />}[https://travis-ci.org/halostatue/diff-lcs]
77
-
78
- :include: Contributing.rdoc
79
-
80
- :include: License.rdoc
80
+ The algorithm is described in <em>A Fast Algorithm for Computing Longest Common
81
+ Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor
82
+ improvements to improve the speed. A simplified description of the algorithm,
83
+ 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,34 +6,46 @@ require 'hoe'
6
6
 
7
7
  Hoe.plugin :bundler
8
8
  Hoe.plugin :doofus
9
- Hoe.plugin :email
10
- Hoe.plugin :gemspec
9
+ Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS']
10
+ Hoe.plugin :gemspec2
11
11
  Hoe.plugin :git
12
- Hoe.plugin :rubyforge
13
12
  Hoe.plugin :travis
14
13
 
15
- Hoe.spec 'diff-lcs' do
16
- developer('Austin Ziegler', 'austin@rubyforge.org')
14
+ _spec = Hoe.spec 'diff-lcs' do
15
+ developer('Austin Ziegler', 'halostatue@gmail.com')
17
16
 
18
- self.remote_rdoc_dir = '.'
19
- self.rsync_args << ' --exclude=statsvn/'
17
+ require_ruby_version '>= 1.8'
20
18
 
21
- self.history_file = 'History.rdoc'
19
+ self.history_file = 'History.md'
22
20
  self.readme_file = 'README.rdoc'
23
- self.extra_rdoc_files = FileList["*.rdoc"].to_a
24
-
25
- self.extra_dev_deps << ['hoe-bundler', '~> 1.2']
26
- self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
27
- self.extra_dev_deps << ['hoe-gemspec', '~> 1.0']
28
- self.extra_dev_deps << ['hoe-git', '~> 1.5']
29
- self.extra_dev_deps << ['hoe-rubygems', '~> 1.0']
30
- self.extra_dev_deps << ['hoe-travis', '~> 1.2']
31
- self.extra_dev_deps << ['rake', '~> 10.0']
32
- self.extra_dev_deps << ['rspec', '~> 2.0']
21
+ self.licenses = ['MIT', 'Artistic-2.0', 'GPL-2.0+']
22
+
23
+ extra_dev_deps << ['hoe-doofus', '~> 1.0']
24
+ extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
25
+ extra_dev_deps << ['hoe-git', '~> 1.6']
26
+ extra_dev_deps << ['hoe-rubygems', '~> 1.0']
27
+ extra_dev_deps << ['hoe-travis', '~> 1.2']
28
+ extra_dev_deps << ['rspec', '>= 2.0', '< 4']
29
+ extra_dev_deps << ['rake', '>= 10.0', '< 14']
30
+ extra_dev_deps << ['rdoc', '>= 0']
33
31
  end
34
32
 
35
- unless Rake::Task.task_defined? :test
36
- task :test => :spec
37
- end
33
+ require "rspec/core/rake_task"
38
34
 
39
- # vim: syntax=ruby
35
+ desc "Run all specifications"
36
+ RSpec::Core::RakeTask.new(:spec) do |t|
37
+ rspec_dirs = %w(spec lib)
38
+ t.rspec_opts = []
39
+ t.rspec_opts << "-I#{rspec_dirs.join(":")}" unless rspec_dirs.empty?
40
+ end
41
+ task :default => :spec
42
+
43
+ if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
44
+ namespace :spec do
45
+ desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
46
+ task :coverage do
47
+ ENV['COVERAGE'] = 'yes'
48
+ Rake::Task['spec'].execute
49
+ end
50
+ end
51
+ end
@@ -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.2
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.2'
52
+ VERSION = '1.4'
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'