summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Ziegler <austin@halostatue.ca>2011-07-30 19:40:23 -0400
committerAustin Ziegler <austin@halostatue.ca>2011-07-30 19:40:23 -0400
commit9feacf82a4859362662c05ffaaeaf26b40a36018 (patch)
tree57be359c74bcdabd2510835f5568b64ba61f769d
parentca444f81819ee49d3a174271dbca75061a4067f5 (diff)
downloaddiff-lcs-9feacf82a4859362662c05ffaaeaf26b40a36018.tar.gz
Converting diff-lcs from svn to git format.
-rw-r--r--ChangeLog (renamed from diff-lcs/tags/release-1.1.2/ChangeLog)0
-rw-r--r--Install (renamed from diff-lcs/tags/release-1.1.2/Install)0
-rw-r--r--README (renamed from diff-lcs/tags/release-1.1.2/README)0
-rw-r--r--Rakefile (renamed from diff-lcs/trunk/Rakefile)0
-rw-r--r--bin/htmldiff (renamed from diff-lcs/tags/release-1.1.2/htmldiff)0
-rw-r--r--bin/ldiff (renamed from diff-lcs/tags/release-1.1.1/ldiff)0
-rw-r--r--diff-lcs.gemspec (renamed from diff-lcs/tags/release-1.1.2/diff-lcs.gemspec)0
-rw-r--r--diff-lcs/tags/release-1.0.1/ChangeLog12
-rw-r--r--diff-lcs/tags/release-1.0.1/Install6
-rw-r--r--diff-lcs/tags/release-1.0.1/README65
-rw-r--r--diff-lcs/tags/release-1.0.1/diff-lcs.gemspec42
-rw-r--r--diff-lcs/tags/release-1.0.1/htmldiff111
-rw-r--r--diff-lcs/tags/release-1.0.1/htmldiff.bat21
-rw-r--r--diff-lcs/tags/release-1.0.1/install.rb189
-rw-r--r--diff-lcs/tags/release-1.0.1/ldiff235
-rw-r--r--diff-lcs/tags/release-1.0.1/ldiff.bat21
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs.rb758
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/array.rb20
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/block.rb49
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/callbacks.rb99
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/change.rb63
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/event.rb30
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/hunk.rb256
-rw-r--r--diff-lcs/tags/release-1.0.1/lib/diff/lcs/string.rb20
-rw-r--r--diff-lcs/tags/release-1.0.1/tests/00test.rb431
-rw-r--r--diff-lcs/tags/release-1.0.2/ChangeLog26
-rw-r--r--diff-lcs/tags/release-1.0.2/Install6
-rw-r--r--diff-lcs/tags/release-1.0.2/README66
-rw-r--r--diff-lcs/tags/release-1.0.2/diff-lcs.gemspec42
-rw-r--r--diff-lcs/tags/release-1.0.2/htmldiff111
-rw-r--r--diff-lcs/tags/release-1.0.2/install.rb264
-rw-r--r--diff-lcs/tags/release-1.0.2/ldiff237
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs.rb760
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/array.rb20
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/block.rb49
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/callbacks.rb99
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/change.rb63
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/event.rb30
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/hunk.rb256
-rw-r--r--diff-lcs/tags/release-1.0.2/lib/diff/lcs/string.rb20
-rw-r--r--diff-lcs/tags/release-1.0.2/tests/00test.rb525
-rw-r--r--diff-lcs/tags/release-1.0.3/ChangeLog20
-rw-r--r--diff-lcs/tags/release-1.0.3/Install6
-rw-r--r--diff-lcs/tags/release-1.0.3/README65
-rw-r--r--diff-lcs/tags/release-1.0.3/diff-lcs.gemspec42
-rw-r--r--diff-lcs/tags/release-1.0.3/htmldiff111
-rw-r--r--diff-lcs/tags/release-1.0.3/htmldiff.bat21
-rw-r--r--diff-lcs/tags/release-1.0.3/install.rb206
-rw-r--r--diff-lcs/tags/release-1.0.3/ldiff235
-rw-r--r--diff-lcs/tags/release-1.0.3/ldiff.bat21
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs.rb760
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/array.rb20
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/block.rb49
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/callbacks.rb99
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/change.rb63
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/event.rb30
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/hunk.rb256
-rw-r--r--diff-lcs/tags/release-1.0.3/lib/diff/lcs/string.rb20
-rw-r--r--diff-lcs/tags/release-1.0.3/tests/00test.rb525
-rw-r--r--diff-lcs/tags/release-1.0.4/ChangeLog26
-rw-r--r--diff-lcs/tags/release-1.0.4/Install6
-rw-r--r--diff-lcs/tags/release-1.0.4/README66
-rw-r--r--diff-lcs/tags/release-1.0.4/diff-lcs.gemspec42
-rw-r--r--diff-lcs/tags/release-1.0.4/htmldiff111
-rw-r--r--diff-lcs/tags/release-1.0.4/install.rb264
-rw-r--r--diff-lcs/tags/release-1.0.4/ldiff237
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs.rb760
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/array.rb20
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/block.rb49
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/callbacks.rb99
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/change.rb63
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/event.rb30
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/hunk.rb256
-rw-r--r--diff-lcs/tags/release-1.0.4/lib/diff/lcs/string.rb20
-rw-r--r--diff-lcs/tags/release-1.0.4/tests/00test.rb525
-rw-r--r--diff-lcs/tags/release-1.0/ChangeLog5
-rw-r--r--diff-lcs/tags/release-1.0/Install6
-rw-r--r--diff-lcs/tags/release-1.0/README65
-rw-r--r--diff-lcs/tags/release-1.0/diff230
-rw-r--r--diff-lcs/tags/release-1.0/diff-lcs.gemspec44
-rw-r--r--diff-lcs/tags/release-1.0/diff.bat21
-rw-r--r--diff-lcs/tags/release-1.0/htmldiff104
-rw-r--r--diff-lcs/tags/release-1.0/htmldiff.bat21
-rw-r--r--diff-lcs/tags/release-1.0/install.rb189
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs.rb758
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/array.rb20
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/block.rb49
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/callbacks.rb99
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/change.rb63
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/event.rb30
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/hunk.rb256
-rw-r--r--diff-lcs/tags/release-1.0/lib/diff/lcs/string.rb20
-rw-r--r--diff-lcs/tags/release-1.0/tests/00test.rb431
-rw-r--r--diff-lcs/tags/release-1.1.0/ChangeLog33
-rw-r--r--diff-lcs/tags/release-1.1.0/Install6
-rw-r--r--diff-lcs/tags/release-1.1.0/README76
-rw-r--r--diff-lcs/tags/release-1.1.0/diff-lcs.gemspec42
-rw-r--r--diff-lcs/tags/release-1.1.0/htmldiff111
-rw-r--r--diff-lcs/tags/release-1.1.0/install.rb264
-rw-r--r--diff-lcs/tags/release-1.1.0/ldiff237
-rw-r--r--diff-lcs/tags/release-1.1.0/lib/diff/lcs.rb1070
-rw-r--r--diff-lcs/tags/release-1.1.0/lib/diff/lcs/callbacks.rb320
-rw-r--r--diff-lcs/tags/release-1.1.0/tests/00test.rb595
-rw-r--r--diff-lcs/tags/release-1.1.1/ChangeLog42
-rw-r--r--diff-lcs/tags/release-1.1.1/Install6
-rw-r--r--diff-lcs/tags/release-1.1.1/README77
-rw-r--r--diff-lcs/tags/release-1.1.1/Rakefile103
-rw-r--r--diff-lcs/tags/release-1.1.1/diff-lcs.gemspec40
-rw-r--r--diff-lcs/tags/release-1.1.1/htmldiff111
-rw-r--r--diff-lcs/tags/release-1.1.1/lib/diff/lcs.rb1105
-rw-r--r--diff-lcs/tags/release-1.1.1/lib/diff/lcs/array.rb21
-rw-r--r--diff-lcs/tags/release-1.1.1/lib/diff/lcs/block.rb51
-rw-r--r--diff-lcs/tags/release-1.1.1/lib/diff/lcs/change.rb169
-rw-r--r--diff-lcs/tags/release-1.1.1/lib/diff/lcs/hunk.rb257
-rw-r--r--diff-lcs/tags/release-1.1.1/lib/diff/lcs/string.rb19
-rw-r--r--diff-lcs/tags/release-1.1.2/Rakefile116
-rw-r--r--diff-lcs/tags/release-1.1.2/install.rb262
-rw-r--r--diff-lcs/tags/release-1.1.2/ldiff45
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/array.rb21
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/block.rb51
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/callbacks.rb322
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/change.rb169
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/hunk.rb257
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/ldiff.rb226
-rw-r--r--diff-lcs/tags/release-1.1.2/lib/diff/lcs/string.rb19
-rw-r--r--diff-lcs/tags/release-1.1.2/tests/00test.rb626
-rw-r--r--diff-lcs/trunk/ChangeLog46
-rw-r--r--diff-lcs/trunk/Install6
-rw-r--r--diff-lcs/trunk/README76
-rw-r--r--diff-lcs/trunk/bin/htmldiff112
-rw-r--r--diff-lcs/trunk/bin/ldiff45
-rw-r--r--diff-lcs/trunk/diff-lcs.gemspec40
-rw-r--r--diff-lcs/trunk/install.rb262
-rw-r--r--diff-lcs/trunk/lib/diff/lcs.rb1105
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/array.rb21
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/block.rb51
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/callbacks.rb322
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/change.rb169
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/hunk.rb257
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/ldiff.rb226
-rw-r--r--diff-lcs/trunk/lib/diff/lcs/string.rb19
-rw-r--r--diff-lcs/trunk/tests/00test.rb626
-rw-r--r--install.rb (renamed from diff-lcs/tags/release-1.1.1/install.rb)0
-rw-r--r--lib/diff/lcs.rb (renamed from diff-lcs/tags/release-1.1.2/lib/diff/lcs.rb)0
-rw-r--r--lib/diff/lcs/array.rb (renamed from diff-lcs/tags/release-1.1.0/lib/diff/lcs/array.rb)0
-rw-r--r--lib/diff/lcs/block.rb (renamed from diff-lcs/tags/release-1.1.0/lib/diff/lcs/block.rb)0
-rw-r--r--lib/diff/lcs/callbacks.rb (renamed from diff-lcs/tags/release-1.1.1/lib/diff/lcs/callbacks.rb)0
-rw-r--r--lib/diff/lcs/change.rb (renamed from diff-lcs/tags/release-1.1.0/lib/diff/lcs/change.rb)0
-rw-r--r--lib/diff/lcs/hunk.rb (renamed from diff-lcs/tags/release-1.1.0/lib/diff/lcs/hunk.rb)0
-rw-r--r--lib/diff/lcs/ldiff.rb (renamed from diff-lcs/tags/release-1.1.1/lib/diff/lcs/ldiff.rb)0
-rw-r--r--lib/diff/lcs/string.rb (renamed from diff-lcs/tags/release-1.1.0/lib/diff/lcs/string.rb)0
-rw-r--r--tests/00test.rb (renamed from diff-lcs/tags/release-1.1.1/tests/00test.rb)0
152 files changed, 0 insertions, 22788 deletions
diff --git a/diff-lcs/tags/release-1.1.2/ChangeLog b/ChangeLog
index 08d3ee5..08d3ee5 100644
--- a/diff-lcs/tags/release-1.1.2/ChangeLog
+++ b/ChangeLog
diff --git a/diff-lcs/tags/release-1.1.2/Install b/Install
index 794796e..794796e 100644
--- a/diff-lcs/tags/release-1.1.2/Install
+++ b/Install
diff --git a/diff-lcs/tags/release-1.1.2/README b/README
index 4c9b517..4c9b517 100644
--- a/diff-lcs/tags/release-1.1.2/README
+++ b/README
diff --git a/diff-lcs/trunk/Rakefile b/Rakefile
index e2ce55b..e2ce55b 100644
--- a/diff-lcs/trunk/Rakefile
+++ b/Rakefile
diff --git a/diff-lcs/tags/release-1.1.2/htmldiff b/bin/htmldiff
index 509860c..509860c 100644
--- a/diff-lcs/tags/release-1.1.2/htmldiff
+++ b/bin/htmldiff
diff --git a/diff-lcs/tags/release-1.1.1/ldiff b/bin/ldiff
index ae2b245..ae2b245 100644
--- a/diff-lcs/tags/release-1.1.1/ldiff
+++ b/bin/ldiff
diff --git a/diff-lcs/tags/release-1.1.2/diff-lcs.gemspec b/diff-lcs.gemspec
index ba49ed6..ba49ed6 100644
--- a/diff-lcs/tags/release-1.1.2/diff-lcs.gemspec
+++ b/diff-lcs.gemspec
diff --git a/diff-lcs/tags/release-1.0.1/ChangeLog b/diff-lcs/tags/release-1.0.1/ChangeLog
deleted file mode 100644
index a288437..0000000
--- a/diff-lcs/tags/release-1.0.1/ChangeLog
+++ /dev/null
@@ -1,12 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.0.1/Install b/diff-lcs/tags/release-1.0.1/Install
deleted file mode 100644
index a0f2590..0000000
--- a/diff-lcs/tags/release-1.0.1/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.0.1.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.0.1/README b/diff-lcs/tags/release-1.0.1/README
deleted file mode 100644
index cc4d5eb..0000000
--- a/diff-lcs/tags/release-1.0.1/README
+++ /dev/null
@@ -1,65 +0,0 @@
-Diff::LCS README
-================
-This is the 1.0.1 release of Diff::LCS for Ruby, based originally on Perl's
-Algorithm::Diff[1]. It uses the McIlroy-Hunt longest common subsequence (LCS)
-algorithm to compute intelligent differences between two sequenced enumerable
-containers[2]. The implementation is based on Mario I. Wolczko's[3] Smalltalk
-version (1.2, 1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String
-will be extended for use this way.
-
-Copyright
-=========
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.0.1/diff-lcs.gemspec b/diff-lcs/tags/release-1.0.1/diff-lcs.gemspec
deleted file mode 100644
index 3d29622..0000000
--- a/diff-lcs/tags/release-1.0.1/diff-lcs.gemspec
+++ /dev/null
@@ -1,42 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.0.1}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
- s.platform = Gem::Platform::RUBY
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
- s.default_executable = %(ldiff)
-
- s.test_suite_file = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/tags/release-1.0.1/htmldiff b/diff-lcs/tags/release-1.0.1/htmldiff
deleted file mode 100644
index e013600..0000000
--- a/diff-lcs/tags/release-1.0.1/htmldiff
+++ /dev/null
@@ -1,111 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'diff/lcs/string'
-rescue
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.1"
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.0.1/htmldiff.bat b/diff-lcs/tags/release-1.0.1/htmldiff.bat
deleted file mode 100644
index 1432736..0000000
--- a/diff-lcs/tags/release-1.0.1/htmldiff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-REM --
-REM Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-REM adapted from:
-REM Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-REM Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-REM implements McIlroy-Hunt diff algorithm
-REM
-REM This program is free software. It may be redistributed and/or modified under
-REM the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-REM Ruby licence.
-REM
-REM $Id$
-REM ++
-if "%OS%"=="Windows_NT" goto WinNT
-ruby -x "htmldiff" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-ruby -x "htmldiff" %*
-goto done
-:done
diff --git a/diff-lcs/tags/release-1.0.1/install.rb b/diff-lcs/tags/release-1.0.1/install.rb
deleted file mode 100644
index 0ed8e45..0000000
--- a/diff-lcs/tags/release-1.0.1/install.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-##
-# Install utility for HaloStatue scripts and libraries. Based heavily on the
-# original RDoc installation script by Pragmatic Programmers.
-#
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-require 'test/unit/ui/console/testrunner'
-
-InstallOptions = OpenStruct.new
-
- # Set these values to what you want installed.
-bins = %w{bin/**/*}
-rdoc = %w{bin/**/*.rb lib/**/*.rb README ChangeLog Install}
-ri = %w(bin/**/*.rb lib/**/*.rb)
-libs = %w{lib/**/*.rb}
-tests = %w{tests/**/*.rb}
-
-def do_bins(bins, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--no-rdoc', FalseClass,
- 'Prevents the creation of RDoc output.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--no-ri', FalseClass,
- 'Prevents the creation of RI output.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--no-tests', FalseClass,
- 'Prevents the execution of nit tests.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers", "--show-hash"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(%w{--ri-site --line-numbers --show-hash} + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-end
-
-def run_tests(test_list)
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file)
- tmp_dir = nil
- BinDirs.each do |t|
- stat = File.stat(t) rescue next
- if stat.directory? and stat.writable?
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot finda temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- opfile += ".rb" if Config::CONFIG["target_os"] =~ /win/
- FileUtils.install(tmp_file, File.join(TargetBinDir, opfile), 0755, true)
- FileUtils.unlink(tmp_file)
-end
-
-def glob(list)
- g = []
- list.each { |i| g << Dir.glob(i) }
- g.flatten!
- g.compact!
- g
-end
-
-prepare_installation
-
-bins = glob(bins)
-rdoc = glob(rdoc)
-ri = glob(ri)
-libs = glob(libs)
-tests = glob(tests)
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins)
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.0.1/ldiff b/diff-lcs/tags/release-1.0.1/ldiff
deleted file mode 100644
index 01bc6e4..0000000
--- a/diff-lcs/tags/release-1.0.1/ldiff
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/user/bin/env ruby
-# = Diff::LCS 1.0.1
-# == ldiff Usage
-# ldiff [options] oldfile newfile
-#
-# -c:: Displays a context diff with 3 lines of context.
-# -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
-# -u:: Displays a unified diff with 3 lines of context.
-# -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
-# -e:: Creates an 'ed' script to change oldfile to newfile.
-# -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
-# -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
-# --binary:: Treats the files as binary.
-# -q, --brief:: Reports only whether or not the files differ, not the details.
-# --help:: Shows the command-line help.
-# --version:: Shows the version of Diff::LCS.
-#
-# By default, runs produces an "old-style" diff, with output like UNIX diff.
-#
-# == Copyright
-# Copyright &copy; 2004 Austin Ziegler
-#
-# Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
-# Austin Ziegler <diff-lcs@halostatue.ca>
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-
-require 'optparse'
-require 'ostruct'
-
-begin
- require 'diff/lcs'
-rescue
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.1"
-end
-
-require 'diff/lcs/hunk'
-
-module Diff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def diffprog(args, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- end
- end
-
- output << oldhunk.diff(@format)
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
-
-exit Diff::diffprog(ARGV, $stdout, $stderr)
diff --git a/diff-lcs/tags/release-1.0.1/ldiff.bat b/diff-lcs/tags/release-1.0.1/ldiff.bat
deleted file mode 100644
index ddf977f..0000000
--- a/diff-lcs/tags/release-1.0.1/ldiff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-REM --
-REM Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-REM adapted from:
-REM Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-REM Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-REM implements McIlroy-Hunt diff algorithm
-REM
-REM This program is free software. It may be redistributed and/or modified under
-REM the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-REM Ruby licence.
-REM
-REM $Id$
-REM ++
-if "%OS%"=="Windows_NT" goto WinNT
-ruby -x "ldiff" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-ruby -x "ldiff" %*
-goto done
-:done
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs.rb
deleted file mode 100644
index e3333c4..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs.rb
+++ /dev/null
@@ -1,758 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.0.1
- # Computes "intelligent" differences between two ordered Enumerables. This
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
- # objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version (1.2,
- # 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Default extensions are provided for Array and String objects through the
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- # I once read an article written by the authors of +diff+; they said that
- # they hard worked very hard on the algorithm until they found the right
- # one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the secend sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # === Key Generation
- # The Perl version accepts an optional hash-key generation code reference
- # because all comparisons are done stringwise. This is not necessary for
- # Ruby, as the spaceship operator (<=>) should be provided on classes that
- # may be present in an ordered Enumerable.
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written by Mark-Jason Dominus
- # <mjd-perl-diff@plover.com>. The basic Ruby implementation was reported
- # from the Smalltalk implementation, available at
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # +sdiff+ and +traverse_balanced+ were written for the Perl version by
- # Mike Schilli <m@perlmeister.com>.
- #
- # The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed.
- module LCS
- VERSION = '1.0.1' #:nodoc:
- end
-end
-
-require 'diff/lcs/event'
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns the Longest Common Subsequnce(s)
- # LCS returns an Array containing the longest common subsequence between
- # +self+ and +other+.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- def traverse_sequences(other)
- traverse_sequences(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def traverse_balanced(other)
- traverse_balanced(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def patch(diffs)
- Diff::LCS::patch(self, diffs)
- end
-end
-
-module Diff::LCS
- class << self
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # Compute the longest common subsequence between the ordered Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection.
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Given two ordered Enumerables, LCS returns an Array containing their
- # longest common subsequence.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- def LCS(a, b, &block) #:yields self[ii] if there are matched subsequences:
- matches = Diff::LCS.__lcs(a, b)
- ret = []
- matches.each_with_index do |e, ii|
- unless matches[ii].nil?
- ret << a[ii]
- yield a[ii] if block_given?
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes. The description is a list of +hunks+;
- # each hunk represents a contiguous section of items which should be
- # added, deleted, or replaced. The return value of +diff+ is an Array
- # of hunks.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # [ [ [ :-, 0, 'a' ] ],
- # # [ [ :+, 2, 'd' ] ],
- # # [ [ :-, 4, 'h' ],
- # # [ :+, 4, 'f' ] ],
- # # [ [ :+, 6, 'k' ] ],
- # # [ [ :-, 8, 'n' ],
- # # [ :-, 9, 'p' ],
- # # [ :+, 9, 'r' ],
- # # [ :+, 10, 's' ],
- # # [ :+, 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at
- # position 0 of the first sequence should be deleted (<tt>:-</tt>).
- # The second hunk says that the +d+ at position 2 of the second
- # sequence should be inserted (<tt>:+</tt>). The third hunk says that
- # the +h+ at position 4 of the first sequence should be removed and
- # replaced with the +f+ from position 4 of the second sequence. The
- # other two hunks similarly.
- def diff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::DiffCallbacks.new
- traverse_sequences(a, b, callbacks)
- callbacks.match(nil)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # It returns an Array of Arrays that contain display instructions.
- # Display instructions consist of three elements: A modifier indicator
- # (<tt>:+</tt>: Element added, <tt>:-</tt>: Element removed, +u+:
- # Element unmodified, +c+: Element changed) and the value of the old
- # and new elements, to be displayed side by side.
- #
- # sdiffs = Diff::LCS.sdiff(seq1, seq2)
- # # [ [ '-', 'a', '' ],
- # # [ 'u', 'b', 'b' ],
- # # [ 'u', 'c', 'c' ],
- # # [ '+', '', 'd' ],
- # # [ 'u', 'e', 'e' ],
- # # [ 'c', 'h', 'f' ],
- # # [ 'u', 'j', 'j' ],
- # # [ '+', '', 'k' ],
- # # [ 'u', 'l', 'l' ],
- # # [ 'u', 'm', 'm' ],
- # # [ 'c', 'n', 'r' ],
- # # [ 'c', 'p', 's' ],
- # # [ '+', '', 't' ] ]
- def sdiff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::SDiffCallbacks.new
- traverse_balanced(a, b, callbacks)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # Imagine that there are two arrows. Arrow A points to an element of
- # sequence A, and arrow B points to an element of the sequence B.
- # Initially, the arrows point to the first elements of the respective
- # sequences. +traverse_sequences+ will advance the arrows through the
- # sequences one element at a time, calling an appropriate
- # user-specified callback function before each advance. It will
- # advance the arrows in such a way that if there are equal elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt> which are equal and which are part
- # of the LCS, there will be some moment during the execution of
- # +traverse_sequences+ when arrow A is pointing to <tt>A[ii]</tt> and
- # arrow B is pointing to <tt>B[jj]</tt>. When this happens,
- # +traverse_sequences+ will call the <tt>:match</tt> lambda and then
- # it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its
- # sequence that is not part of the LCS. +traverse_sequences+ will
- # advance that arrow and will call the <tt>:discard_a</tt> or the
- # <tt>:discard_b</tt> lambdas, depending on which arrow it advanced.
- # If both arrows point to elements that are not part of the LCS, then
- # +traverse_sequences+ will advance one of them and call the
- # appropriate callback, but it is not specified which it will call.
- #
- # The arguments to +traverse_sequences+ are the two sequences to
- # traverse, and a hash which specifies the lambdas, like this:
- #
- # traverse_sequences(seq1, seq2,
- # :match => callback_1,
- # :discard_a => callback_2,
- # :discard_b => callback_3)
- #
- # The lambdas for <tt>:match</tt>, <tt>:discard_a</tt>, and
- # <tt>:discard_b</tt> are invoked with the indices of the two arrows
- # as their arguments and are not expected to return any values.
- #
- # If arrow A reaches the end of its sequence before arrow B does,
- # +traverse_sequences+ will call the <tt>:a_finished</tt> lambda with
- # the last index in A. If <tt>:a_finished</tt> does not exist, then
- # <tt>:discard_b</tt> will be called until the end of the B sequence.
- # If B terminates before A, then <tt>:b_finished</tt> or
- # <tt>:discard_a</tt> will be called.
- #
- # Omitted callbacks are not called.
- #
- def traverse_sequences(a, b, callbacks = Diff::LCS::SequenceCallbacks)
- matches = Diff::LCS.__lcs(a, b)
-
- run_finished_a = run_finished_b = false
- string = a.kind_of?(String)
-
- a_size = a.size
- b_size = b.size
- ai = bj = 0
-
- (0 ... matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? a[ii, 1] : a[ii]
- bx = string ? b[bj, 1] : b[bj]
-
- if b_line.nil?
- event = Diff::LCS::Event.new(:discard_a, ax, ii, bx, bj)
- callbacks.discard_a(event)
- else
- loop do
- break unless bj < b_line
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ii, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:match, ax, ii, bx, bj)
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? a[-1, 1] : a[-1]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:finished_a, ax, a_size - 1, bx, bj)
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? a[ai, 1] : a[ai]
- loop do
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[-1, 1] : b[-1]
- event = Diff::LCS::Event.new(:finished_b, ax, ai, bx, b_size - 1)
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? b[bj, 1] : b[bj]
- loop do
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # +traverse_balanced+ is an alternative to +traverse_sequences+. It
- # uses a different algorithm to iterate through the entries in the
- # computed LCS. Instead of sticking to one side and showing element
- # changes as insertions and deletions only, it will jump back and
- # forth between the two sequences and report <em>changes</em>
- # occurring as deletions on one side followed immediatly by an
- # insertion on the other side.
- #
- # In addition to the <tt>:discard_a</tt>, <tt>:discard_b</tt>, and
- # <tt>:match</tt> callbacks supported by +traverse_sequences+,
- # +traverse_balanced+ supports a <tt>:change</tt> callback indicating
- # that one element got +replaced+ by another:
- #
- # traverse_sequences(seq1, seq2,
- # :match => $callback_1,
- # :discard_a => $callback_2,
- # :discard_b => $callback_3,
- # :change => $callback_4,)
- #
- # If no <tt>:change</tt> callback is specified, +traverse_balanced+
- # will map <tt>:change</tt> events to <tt>:discard_a</tt> and
- # <tt>:discard_b</tt> actions, therefore resulting in a similar
- # behaviour as +traverse_sequences+ with different order of events.
- #
- # +traverse_balanced+ might be a bit slower than +traverse_sequences+,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # +traverse_balanced+.
- def traverse_balanced(a, b, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(a, b)
- a_size = a.size
- b_size = b.size
- ai = bj = mb = 0
- ma = -1
- string = a.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(s)
- while (ai < ma) or (bj < mb)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- def __diff_direction(src, diffs)
- left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- diffs.each do |change|
- text = string ? src[change.position, 1] : src[change.position]
- case change.action
- when :-
- if text == change.text
- left += 1
- else
- left_miss += 1
- end
- when :+
- if text == change.text
- right += 1
- else
- right_miss += 1
- end
- end
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided diff does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Given a set of diffs, convert the current version to the new version.
- def patch(src, diffs, direction = nil)
- diffs = diffs.flatten
- direction = Diff::LCS.__diff_direction(src, diffs) if direction.nil?
- string = src.kind_of?(String)
-
- n = src.class.new
- ai = bj = 0
-
- uses_splat = true
-
- diffs.each do |change|
- action = change.action
-
- if direction == :unpatch
- case action
- when :-
- action = :+
- when :+
- action = :-
- end
- end
-
- case action
- when :- # Delete
- while ai < change.position
- n << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += (change.text.kind_of?(String) ? 1 : change.text.size)
- when :+ # Insert
- while bj < change.position
- n << (string ? src[ai, 1]: src[ai])
- ai += 1
- bj += 1
- end
-
- if change.text.kind_of?(String)
- n << change.text
- else
- n.push(*change.text)
- end
-
- bj += (change.text.kind_of?(String) ? 1 : change.text.size)
- end
- end
-
- n
- end
-
- # Given a set of diffs, convert the current version to the prior
- # version.
- def unpatch(diffs)
- patch(diffs, :unpatch)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/array.rb
deleted file mode 100644
index fea3edc..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/block.rb
deleted file mode 100644
index 7ffdbab..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/diff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index eb0be60..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/change'
-
-class Diff::LCS::SequenceCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::BalancedCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::DiffCallbacks #:nodoc:
- attr_accessor :hunk
- attr_accessor :diffs
-
- def initialize
- @hunk = []
- @diffs = []
- end
-
- def match(event)
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_ix, event.old_el)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_ix, event.new_el)
- end
-end
-
-class Diff::LCS::SDiffCallbacks #:nodoc:
- attr_accessor :diffs
-
- def initialize
- @diffs = []
- end
-
- def match(event)
- @diffs << Diff::LCS::Change.new('u', event.old_el, event.new_el)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::Change.new('-', event.old_el, nil)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::Change.new('+', nil, event.new_el)
- end
-
- def change(event)
- @diffs << Diff::LCS::Change.new('!', event.old_el, event.new_el)
- end
-end
-
-class Diff::LCS::YieldingCallbacks #:nodoc:
- class << self
- def method_missing(symbol, *args)
- yield args if block_given?
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/change.rb
deleted file mode 100644
index a472f26..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Change
- attr_reader :action, :position, :text
-
- include Comparable
-
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.text == other.text)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.text <=> other.text if r.zero?
- r
- end
-
- def initialize(action, position, text)
- @action = action
- @position = position
- @text = text
- end
-
- def to_a
- [@action, @position, @text]
- end
-
- def self.from_a(*arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- def deleting?
- @action == :-
- end
-
- def adding?
- @action == :+
- end
-
- def unchanged?
- @action == :u
- end
-
- def changed?
- @changed == :c
- end
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/event.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/event.rb
deleted file mode 100644
index daa2414..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/event.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Event
- attr_reader :code
- attr_reader :old_el
- attr_reader :old_ix
- attr_reader :new_el
- attr_reader :new_ix
-
- def initialize(code, a, ai, b, bi)
- @code = code
- @old_el = a
- @old_ix = ai
- @new_el = b
- @new_ix = bi
- end
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/hunk.rb
deleted file mode 100644
index c57e4ba..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.0.1/lib/diff/lcs/string.rb
deleted file mode 100644
index 96a01fe..0000000
--- a/diff-lcs/tags/release-1.0.1/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/array'
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.1/tests/00test.rb b/diff-lcs/tags/release-1.0.1/tests/00test.rb
deleted file mode 100644
index e2613d5..0000000
--- a/diff-lcs/tags/release-1.0.1/tests/00test.rb
+++ /dev/null
@@ -1,431 +0,0 @@
-#! /usr/bin/env ruby
-#
-$:.unshift '../lib' if __FILE__ == $0 # Make this library first!
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-if __FILE__ == $0
- class TestLCS < Test::Unit::TestCase
- def setup
- @a = %w(a b c e h j l m n p)
- @b = %w(b c d e f j k l m r s t)
-
- @correct = %w(b c e j l m)
- @skipped_a = "a h n p"
- @skipped_b = "d f k r s t"
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '+', 9, 'r' ],
- [ '-', 9, 'p' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff)
- end
-
- def __map_diffs(diffs)
- diffs.map do |chunks|
- chunks.map do |changes|
- Diff::LCS::Change.from_a(*changes)
- end
- end
- end
-
- def __make_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_el
- @matched_b << event.new_el
- end
-
- def discard_b(event)
- @discards_b << event.new_el
- end
-
- def discard_a(event)
- @discards_a << event.old_el
- end
-
- def finished_a(event)
- @done_a << [event.old_el, event.old_ix]
- end
-
- def finished_b(event)
- @done_b << [event.new_el, event.new_ix]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@a, @b) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct.size)
- assert_nothing_raised { ares = (0...res.size).map { |i| res[i] ? @a[i] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |i| res[i] ? @b[res[i]] : nil } }
- assert_equal(@correct, ares.compact)
- assert_equal(@correct, bres.compact)
- end
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __make_callbacks
- class << callbacks
- undef finished_a
- undef finished_b
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_sequences(@a, @b, callbacks) }
- assert_equal(@correct.size, callbacks.matched_a.size)
- assert_equal(@correct.size, callbacks.matched_b.size)
- assert_equal(@skipped_a, callbacks.discards_a.join(" "))
- assert_equal(@skipped_b, callbacks.discards_b.join(" "))
- assert_nothing_raised { callbacks = __make_callbacks }
- assert_nothing_raised { Diff::LCS.traverse_sequences(@a, @b, callbacks) }
- assert_equal(@correct.size, callbacks.matched_a.size)
- assert_equal(@correct.size, callbacks.matched_b.size)
- assert_equal(@skipped_a, callbacks.discards_a.join(" "))
- assert_equal(@skipped_b, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
- end
-
- def test_LCS
- res = nil
- assert_nothing_raised { res = Diff::LCS.LCS(@a, @b) }
- assert_equal(res.compact, @correct)
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@a, @b) }
- assert_equal(@correct_diff, diff)
- end
-
- def test_sdiff_a
- sdiff = nil
- a = %w(abc def yyy xxx ghi jkl)
- b = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- ['u', 'abc', 'abc'],
- ['!', 'def', 'dxf'],
- ['-', 'yyy', nil],
- ['u', 'xxx', 'xxx'],
- ['u', 'ghi', 'ghi'],
- ['u', 'jkl', 'jkl'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- ['-', 'a', nil],
- ['u', 'b', 'b'],
- ['u', 'c', 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'],
- ['!', 'h', 'f'],
- ['u', 'j', 'j'],
- ['+', nil, 'k'],
- ['u', 'l', 'l'],
- ['u', 'm', 'm'],
- ['!', 'n', 'r'],
- ['!', 'p', 's'],
- ['+', nil, 't'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@a, @b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- a = %w(a b c d e)
- b = %w(a e)
- correct_sdiff = [
- ['u', 'a', 'a' ],
- ['-', 'b', nil ],
- ['-', 'c', nil ],
- ['-', 'd', nil ],
- ['u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- a = %w(a e)
- b = %w(a b c d e)
- correct_sdiff = [
- ['u', 'a', 'a' ],
- ['+', nil, 'b' ],
- ['+', nil, 'c' ],
- ['+', nil, 'd' ],
- ['u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- a = %w(v x a e)
- b = %w(w y a b c d e)
- correct_sdiff = [
- ['!', 'v', 'w' ],
- ['!', 'x', 'y' ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- a = %w(x a e)
- b = %w(a b c d e)
- correct_sdiff = [
- ['-', 'x', nil ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- a = %w(a e)
- b = %w(x a b c d e)
- correct_sdiff = [
- ['+', nil, 'x' ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- a = %w(a e v)
- b = %w(x a b c d e w x)
- correct_sdiff = [
- ['+', nil, 'x' ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'],
- ['!', 'v', 'w'],
- ['+', nil, 'x']
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- a = %w()
- b = %w(a b c)
- correct_sdiff = [
- ['+', nil, 'a' ],
- ['+', nil, 'b' ],
- ['+', nil, 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- a = %w(a b c)
- b = %w()
- correct_sdiff = [
- ['-', 'a', nil ],
- ['-', 'b', nil ],
- ['-', 'c', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- a = %w(a b c)
- b = %w(1)
- correct_sdiff = [
- ['!', 'a', '1' ],
- ['-', 'b', nil ],
- ['-', 'c', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- a = %w(a b c)
- b = %w(c)
- correct_sdiff = [
- ['-', 'a', nil ],
- ['-', 'b', nil ],
- ['u', 'c', 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M #{event.old_ix} #{event.new_ix}"
- end
-
- def discard_a(event)
- @result << "DA #{event.old_ix} #{event.new_ix}"
- end
-
- def discard_b(event)
- @result << "DB #{event.old_ix} #{event.new_ix}"
- end
-
- def change(event)
- @result << "C #{event.old_ix} #{event.new_ix}"
- end
- end
- cb.reset
- cb
- end
-
- def test_balanced_a
- a = %w(a b c)
- b = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0C 1 1M 2 2", callback.result)
- end
-
- def test_balanced_b
- a = %w(a b c)
- b = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0DA 1 1DB 2 1M 2 2", callback.result)
- end
-
- def test_balanced_c
- a = %w(a x y c)
- b = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0C 1 1C 2 2M 3 3", callback.result)
- end
-
- def test_balanced_d
- a = %w(x y c)
- b = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("C 0 0C 1 1M 2 2", callback.result)
- end
-
- def test_balanced_e
- a = %w(a x y z)
- b = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("C 0 0C 1 1C 2 2DA 3 3", callback.result)
- end
-
- def test_balanced_f
- a = %w(a z)
- b = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0DA 1 1", callback.result)
- end
-
- def test_balanced_g
- a = %w(z a)
- b = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("DA 0 0M 1 0", callback.result)
- end
-
- def test_balanced_h
- a = %w(a b c)
- b = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("C 0 0C 1 1C 2 2", callback.result)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/ChangeLog b/diff-lcs/tags/release-1.0.2/ChangeLog
deleted file mode 100644
index 75a392e..0000000
--- a/diff-lcs/tags/release-1.0.2/ChangeLog
+++ /dev/null
@@ -1,26 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.0.4
-* Fixed a problem with bin/ldiff output, especially for unified format.
- Newlines that should have been present weren't.
-* Changed the .tar.gz installer to generate Windows batch files if ones do not
- exist already. Removed the existing batch files as they didn't work.
-
-== Diff::LCS 1.0.3
-* Fixed a problem with #traverse_sequences where the first difference from the
- left sequence might not be appropriately captured.
-
-== Diff::LCS 1.0.2
-* Fixed an issue with ldiff not working because actions were changed from
- symbols to strings.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.0.2/Install b/diff-lcs/tags/release-1.0.2/Install
deleted file mode 100644
index b583d3f..0000000
--- a/diff-lcs/tags/release-1.0.2/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.0.4.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.0.2/README b/diff-lcs/tags/release-1.0.2/README
deleted file mode 100644
index a7021e7..0000000
--- a/diff-lcs/tags/release-1.0.2/README
+++ /dev/null
@@ -1,66 +0,0 @@
-Diff::LCS README
-================
-Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt
-longest common subsequence (LCS) algorithm to compute intelligent
-differences between two sequenced enumerable containers[2]. The
-implementation is based on Mario I. Wolczko's[3] Smalltalk version (1.2,
-1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-This release is version 1.0.4. It contains only bug fixes over 1.0.2 and
-1.0.3.
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = seq1.traverse_sequences(seq2, callback_obj)
- bal = seq1.traverse_balanced(seq2, callback_obj)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will
-be extended for use this way.
-
-Copyright
-=========
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.0.2/diff-lcs.gemspec b/diff-lcs/tags/release-1.0.2/diff-lcs.gemspec
deleted file mode 100644
index 93ca917..0000000
--- a/diff-lcs/tags/release-1.0.2/diff-lcs.gemspec
+++ /dev/null
@@ -1,42 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.0.4}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
- s.platform = Gem::Platform::RUBY
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
- s.default_executable = %(ldiff)
-
- s.test_suite_file = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/tags/release-1.0.2/htmldiff b/diff-lcs/tags/release-1.0.2/htmldiff
deleted file mode 100644
index ef41888..0000000
--- a/diff-lcs/tags/release-1.0.2/htmldiff
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.4"
- require 'diff/lcs/string'
-rescue LoadError
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.0.2/install.rb b/diff-lcs/tags/release-1.0.2/install.rb
deleted file mode 100644
index 5772e0b..0000000
--- a/diff-lcs/tags/release-1.0.2/install.rb
+++ /dev/null
@@ -1,264 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.0.2/ldiff b/diff-lcs/tags/release-1.0.2/ldiff
deleted file mode 100644
index a60a19d..0000000
--- a/diff-lcs/tags/release-1.0.2/ldiff
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env ruby
-# = Diff::LCS 1.0.4
-# == ldiff Usage
-# ldiff [options] oldfile newfile
-#
-# -c:: Displays a context diff with 3 lines of context.
-# -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
-# -u:: Displays a unified diff with 3 lines of context.
-# -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
-# -e:: Creates an 'ed' script to change oldfile to newfile.
-# -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
-# -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
-# --binary:: Treats the files as binary.
-# -q, --brief:: Reports only whether or not the files differ, not the details.
-# --help:: Shows the command-line help.
-# --version:: Shows the version of Diff::LCS.
-#
-# By default, runs produces an "old-style" diff, with output like UNIX diff.
-#
-# == Copyright
-# Copyright &copy; 2004 Austin Ziegler
-#
-# Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
-# Austin Ziegler <diff-lcs@halostatue.ca>
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-
-require 'optparse'
-require 'ostruct'
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.4"
-rescue LoadError
- require 'diff/lcs'
-end
-
-require 'diff/lcs/hunk'
-
-module Diff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def diffprog(args, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
-
- output << oldhunk.diff(@format)
- output << "\n"
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
-
-exit Diff::diffprog(ARGV, $stdout, $stderr)
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs.rb
deleted file mode 100644
index ad3c1c2..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs.rb
+++ /dev/null
@@ -1,760 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.0.4
- # Computes "intelligent" differences between two ordered Enumerables. This
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
- # objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version (1.2,
- # 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Default extensions are provided for Array and String objects through the
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- # I once read an article written by the authors of +diff+; they said that
- # they hard worked very hard on the algorithm until they found the right
- # one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the secend sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # === Key Generation
- # The Perl version accepts an optional hash-key generation code reference
- # because all comparisons are done stringwise. This is not necessary for
- # Ruby, as the spaceship operator (<=>) should be provided on classes that
- # may be present in an ordered Enumerable.
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written by Mark-Jason Dominus
- # <mjd-perl-diff@plover.com>. The basic Ruby implementation was reported
- # from the Smalltalk implementation, available at
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # +sdiff+ and +traverse_balanced+ were written for the Perl version by
- # Mike Schilli <m@perlmeister.com>.
- #
- # The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed.
- module LCS
- VERSION = '1.0.4' #:nodoc:
- end
-end
-
-require 'diff/lcs/event'
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns the Longest Common Subsequnce(s)
- # LCS returns an Array containing the longest common subsequence between
- # +self+ and +other+.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- def traverse_sequences(other)
- traverse_sequences(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def traverse_balanced(other)
- traverse_balanced(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def patch(diffs)
- Diff::LCS::patch(self, diffs)
- end
-end
-
-module Diff::LCS
- class << self
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # Compute the longest common subsequence between the ordered Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection.
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Given two ordered Enumerables, LCS returns an Array containing their
- # longest common subsequence.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- def LCS(a, b, &block) #:yields self[ii] if there are matched subsequences:
- matches = Diff::LCS.__lcs(a, b)
- ret = []
- matches.each_with_index do |e, ii|
- unless matches[ii].nil?
- ret << a[ii]
- yield a[ii] if block_given?
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes. The description is a list of +hunks+;
- # each hunk represents a contiguous section of items which should be
- # added, deleted, or replaced. The return value of +diff+ is an Array
- # of hunks.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # [ [ [ :-, 0, 'a' ] ],
- # # [ [ :+, 2, 'd' ] ],
- # # [ [ :-, 4, 'h' ],
- # # [ :+, 4, 'f' ] ],
- # # [ [ :+, 6, 'k' ] ],
- # # [ [ :-, 8, 'n' ],
- # # [ :-, 9, 'p' ],
- # # [ :+, 9, 'r' ],
- # # [ :+, 10, 's' ],
- # # [ :+, 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at
- # position 0 of the first sequence should be deleted (<tt>:-</tt>).
- # The second hunk says that the +d+ at position 2 of the second
- # sequence should be inserted (<tt>:+</tt>). The third hunk says that
- # the +h+ at position 4 of the first sequence should be removed and
- # replaced with the +f+ from position 4 of the second sequence. The
- # other two hunks similarly.
- def diff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::DiffCallbacks.new
- traverse_sequences(a, b, callbacks)
- callbacks.match(nil)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # It returns an Array of Arrays that contain display instructions.
- # Display instructions consist of three elements: A modifier indicator
- # (<tt>:+</tt>: Element added, <tt>:-</tt>: Element removed, +u+:
- # Element unmodified, +c+: Element changed) and the value of the old
- # and new elements, to be displayed side by side.
- #
- # sdiffs = Diff::LCS.sdiff(seq1, seq2)
- # # [ [ '-', 'a', '' ],
- # # [ 'u', 'b', 'b' ],
- # # [ 'u', 'c', 'c' ],
- # # [ '+', '', 'd' ],
- # # [ 'u', 'e', 'e' ],
- # # [ 'c', 'h', 'f' ],
- # # [ 'u', 'j', 'j' ],
- # # [ '+', '', 'k' ],
- # # [ 'u', 'l', 'l' ],
- # # [ 'u', 'm', 'm' ],
- # # [ 'c', 'n', 'r' ],
- # # [ 'c', 'p', 's' ],
- # # [ '+', '', 't' ] ]
- def sdiff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::SDiffCallbacks.new
- traverse_balanced(a, b, callbacks)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # Imagine that there are two arrows. Arrow A points to an element of
- # sequence A, and arrow B points to an element of the sequence B.
- # Initially, the arrows point to the first elements of the respective
- # sequences. +traverse_sequences+ will advance the arrows through the
- # sequences one element at a time, calling an appropriate
- # user-specified callback function before each advance. It will
- # advance the arrows in such a way that if there are equal elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt> which are equal and which are part
- # of the LCS, there will be some moment during the execution of
- # +traverse_sequences+ when arrow A is pointing to <tt>A[ii]</tt> and
- # arrow B is pointing to <tt>B[jj]</tt>. When this happens,
- # +traverse_sequences+ will call the <tt>:match</tt> lambda and then
- # it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its
- # sequence that is not part of the LCS. +traverse_sequences+ will
- # advance that arrow and will call the <tt>:discard_a</tt> or the
- # <tt>:discard_b</tt> lambdas, depending on which arrow it advanced.
- # If both arrows point to elements that are not part of the LCS, then
- # +traverse_sequences+ will advance one of them and call the
- # appropriate callback, but it is not specified which it will call.
- #
- # The arguments to +traverse_sequences+ are the two sequences to
- # traverse, and a hash which specifies the lambdas, like this:
- #
- # traverse_sequences(seq1, seq2,
- # :match => callback_1,
- # :discard_a => callback_2,
- # :discard_b => callback_3)
- #
- # The lambdas for <tt>:match</tt>, <tt>:discard_a</tt>, and
- # <tt>:discard_b</tt> are invoked with the indices of the two arrows
- # as their arguments and are not expected to return any values.
- #
- # If arrow A reaches the end of its sequence before arrow B does,
- # +traverse_sequences+ will call the <tt>:a_finished</tt> lambda with
- # the last index in A. If <tt>:a_finished</tt> does not exist, then
- # <tt>:discard_b</tt> will be called until the end of the B sequence.
- # If B terminates before A, then <tt>:b_finished</tt> or
- # <tt>:discard_a</tt> will be called.
- #
- # Omitted callbacks are not called.
- #
- def traverse_sequences(a, b, callbacks = Diff::LCS::SequenceCallbacks)
- matches = Diff::LCS.__lcs(a, b)
-
- run_finished_a = run_finished_b = false
- string = a.kind_of?(String)
-
- a_size = a.size
- b_size = b.size
- ai = bj = 0
-
- (0 .. matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? a[ii, 1] : a[ii]
- bx = string ? b[bj, 1] : b[bj]
-
- if b_line.nil?
- unless ax.nil?
- event = Diff::LCS::Event.new(:discard_a, ax, ii, bx, bj)
- callbacks.discard_a(event)
- end
- else
- loop do
- break unless bj < b_line
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ii, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:match, ax, ii, bx, bj)
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? a[-1, 1] : a[-1]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:finished_a, ax, a_size - 1, bx, bj)
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? a[ai, 1] : a[ai]
- loop do
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[-1, 1] : b[-1]
- event = Diff::LCS::Event.new(:finished_b, ax, ai, bx, b_size - 1)
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? b[bj, 1] : b[bj]
- loop do
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # +traverse_balanced+ is an alternative to +traverse_sequences+. It
- # uses a different algorithm to iterate through the entries in the
- # computed LCS. Instead of sticking to one side and showing element
- # changes as insertions and deletions only, it will jump back and
- # forth between the two sequences and report <em>changes</em>
- # occurring as deletions on one side followed immediatly by an
- # insertion on the other side.
- #
- # In addition to the <tt>:discard_a</tt>, <tt>:discard_b</tt>, and
- # <tt>:match</tt> callbacks supported by +traverse_sequences+,
- # +traverse_balanced+ supports a <tt>:change</tt> callback indicating
- # that one element got +replaced+ by another:
- #
- # traverse_sequences(seq1, seq2,
- # :match => $callback_1,
- # :discard_a => $callback_2,
- # :discard_b => $callback_3,
- # :change => $callback_4,)
- #
- # If no <tt>:change</tt> callback is specified, +traverse_balanced+
- # will map <tt>:change</tt> events to <tt>:discard_a</tt> and
- # <tt>:discard_b</tt> actions, therefore resulting in a similar
- # behaviour as +traverse_sequences+ with different order of events.
- #
- # +traverse_balanced+ might be a bit slower than +traverse_sequences+,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # +traverse_balanced+.
- def traverse_balanced(a, b, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(a, b)
- a_size = a.size
- b_size = b.size
- ai = bj = mb = 0
- ma = -1
- string = a.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(s)
- while (ai < ma) or (bj < mb)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- def __diff_direction(src, diffs)
- left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- diffs.each do |change|
- text = string ? src[change.position, 1] : src[change.position]
- case change.action
- when :-
- if text == change.text
- left += 1
- else
- left_miss += 1
- end
- when :+
- if text == change.text
- right += 1
- else
- right_miss += 1
- end
- end
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided diff does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Given a set of diffs, convert the current version to the new version.
- def patch(src, diffs, direction = nil)
- diffs = diffs.flatten
- direction = Diff::LCS.__diff_direction(src, diffs) if direction.nil?
- string = src.kind_of?(String)
-
- n = src.class.new
- ai = bj = 0
-
- uses_splat = true
-
- diffs.each do |change|
- action = change.action
-
- if direction == :unpatch
- case action
- when :-
- action = :+
- when :+
- action = :-
- end
- end
-
- case action
- when :- # Delete
- while ai < change.position
- n << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += (change.text.kind_of?(String) ? 1 : change.text.size)
- when :+ # Insert
- while bj < change.position
- n << (string ? src[ai, 1]: src[ai])
- ai += 1
- bj += 1
- end
-
- if change.text.kind_of?(String)
- n << change.text
- else
- n.push(*change.text)
- end
-
- bj += (change.text.kind_of?(String) ? 1 : change.text.size)
- end
- end
-
- n
- end
-
- # Given a set of diffs, convert the current version to the prior
- # version.
- def unpatch(diffs)
- patch(diffs, :unpatch)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/array.rb
deleted file mode 100644
index fea3edc..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/block.rb
deleted file mode 100644
index 7ffdbab..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/diff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index eb0be60..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/change'
-
-class Diff::LCS::SequenceCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::BalancedCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::DiffCallbacks #:nodoc:
- attr_accessor :hunk
- attr_accessor :diffs
-
- def initialize
- @hunk = []
- @diffs = []
- end
-
- def match(event)
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_ix, event.old_el)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_ix, event.new_el)
- end
-end
-
-class Diff::LCS::SDiffCallbacks #:nodoc:
- attr_accessor :diffs
-
- def initialize
- @diffs = []
- end
-
- def match(event)
- @diffs << Diff::LCS::Change.new('u', event.old_el, event.new_el)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::Change.new('-', event.old_el, nil)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::Change.new('+', nil, event.new_el)
- end
-
- def change(event)
- @diffs << Diff::LCS::Change.new('!', event.old_el, event.new_el)
- end
-end
-
-class Diff::LCS::YieldingCallbacks #:nodoc:
- class << self
- def method_missing(symbol, *args)
- yield args if block_given?
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/change.rb
deleted file mode 100644
index ae5e904..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Change
- attr_reader :action, :position, :text
-
- include Comparable
-
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.text == other.text)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.text <=> other.text if r.zero?
- r
- end
-
- def initialize(action, position, text)
- @action = action
- @position = position
- @text = text
- end
-
- def to_a
- [@action, @position, @text]
- end
-
- def self.from_a(*arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- def deleting?
- @action == '-'
- end
-
- def adding?
- @action == '+'
- end
-
- def unchanged?
- @action == 'u'
- end
-
- def changed?
- @changed == 'c'
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/event.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/event.rb
deleted file mode 100644
index daa2414..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/event.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Event
- attr_reader :code
- attr_reader :old_el
- attr_reader :old_ix
- attr_reader :new_el
- attr_reader :new_ix
-
- def initialize(code, a, ai, b, bi)
- @code = code
- @old_el = a
- @old_ix = ai
- @new_el = b
- @new_ix = bi
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/hunk.rb
deleted file mode 100644
index c57e4ba..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.0.2/lib/diff/lcs/string.rb
deleted file mode 100644
index 96a01fe..0000000
--- a/diff-lcs/tags/release-1.0.2/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/array'
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.2/tests/00test.rb b/diff-lcs/tags/release-1.0.2/tests/00test.rb
deleted file mode 100644
index ef8c945..0000000
--- a/diff-lcs/tags/release-1.0.2/tests/00test.rb
+++ /dev/null
@@ -1,525 +0,0 @@
-#! /usr/bin/env ruby
-#
-$:.unshift '../lib' if __FILE__ == $0 # Make this library first!
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-module Diff::LCS::Tests
- def __format_diffs(diffs)
- diffs.map do |e|
- if e.kind_of?(Array)
- e.map { |f| f.to_a.join }.join(", ")
- else
- e.to_a.join
- end
- end.join("; ")
- end
-
- def __map_diffs(diffs, klass = Diff::LCS::Change)
- diffs.map do |chunks|
- chunks.map { |changes| klass.from_a(*changes) }
- end
- end
-
- def __simple_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_el
- @matched_b << event.new_el
- end
-
- def discard_b(event)
- @discards_b << event.new_el
- end
-
- def discard_a(event)
- @discards_a << event.old_el
- end
-
- def finished_a(event)
- @done_a << [event.old_el, event.old_ix]
- end
-
- def finished_b(event)
- @done_b << [event.new_el, event.new_ix]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M#{event.old_ix}#{event.new_ix} "
- end
-
- def discard_a(event)
- @result << "DA#{event.old_ix}#{event.new_ix} "
- end
-
- def discard_b(event)
- @result << "DB#{event.old_ix}#{event.new_ix} "
- end
-
- def change(event)
- @result << "C#{event.old_ix}#{event.new_ix} "
- end
- end
- cb.reset
- cb
- end
-
- def setup
- @seq1 = %w(a b c e h j l m n p)
- @seq2 = %w(b c d e f j k l m r s t)
-
- @correct_lcs = %w(b c e j l m)
-
- @skipped_seq1 = 'a h n p'
- @skipped_seq2 = 'd f k r s t'
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '-', 9, 'p' ],
- [ '+', 9, 'r' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
- end
-end
-
-class TestLCS < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct_lcs.size)
- res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
- assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
- assert_equal(@correct_lcs, ares.compact)
- assert_equal(@correct_lcs, bres.compact)
- assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
- assert_equal(res.compact, @correct_lcs)
- end
-end
-
-class TestSequences < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __simple_callbacks
- class << callbacks
- undef :finished_a
- undef :finished_b
- end
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_nothing_raised do
- callbacks = __simple_callbacks
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
-
-# seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
-# assert_nothing_raised do
-# callbacks = __simple_callbacks
-# class << callbacks
-# undef :finished_a
-# undef :finished_b
-# end
-# Diff::LCS.traverse_sequences(seqw, [], callbacks)
-# end
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
- assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
- assert_equal(@correct_diff, diff)
- end
-
- def test_diff_empty
- seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
- correct_diff = [
- [ [ '-', 0, 'abcd' ],
- [ '-', 1, 'efgh' ],
- [ '-', 2, 'ijkl' ],
- [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
- diff = nil
-
- assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
-
- correct_diff = [
- [ [ '+', 0, 'abcd' ],
- [ '+', 1, 'efgh' ],
- [ '+', 2, 'ijkl' ],
- [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
- assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
- end
-end
-
-class TestBalanced < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sdiff_a
- sdiff = nil
- seq1 = %w(abc def yyy xxx ghi jkl)
- seq2 = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- [ 'u', 'abc', 'abc' ],
- [ '!', 'def', 'dxf' ],
- [ '-', 'yyy', nil ],
- [ 'u', 'xxx', 'xxx' ],
- [ 'u', 'ghi', 'ghi' ],
- [ 'u', 'jkl', 'jkl' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ 'u', 'b', 'b' ],
- [ 'u', 'c', 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ],
- [ '!', 'h', 'f' ],
- [ 'u', 'j', 'j' ],
- [ '+', nil, 'k' ],
- [ 'u', 'l', 'l' ],
- [ 'u', 'm', 'm' ],
- [ '!', 'n', 'r' ],
- [ '!', 'p', 's' ],
- [ '+', nil, 't' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- seq1 = %w(a b c d e)
- seq2 = %w(a e)
- correct_sdiff = [
- [ 'u', 'a', 'a' ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ],
- [ '-', 'd', nil ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- seq1 = %w(v x a e)
- seq2 = %w(w y a b c d e)
- correct_sdiff = [
- [ '!', 'v', 'w' ],
- [ '!', 'x', 'y' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- seq1 = %w(x a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '-', 'x', nil ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(x a b c d e)
- correct_sdiff = [
- [ '+', nil, 'x' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- seq1 = %w(a e v)
- seq2 = %w(x a b c d e w x)
- correct_sdiff = [
- [ '+', nil, 'x' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ],
- [ '!', 'v', 'w' ],
- [ '+', nil, 'x' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- seq1 = %w()
- seq2 = %w(a b c)
- correct_sdiff = [
- [ '+', nil, 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w()
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(1)
- correct_sdiff = [
- [ '!', 'a', '1' ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(c)
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ '-', 'b', nil ],
- [ 'u', 'c', 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_m
- sdiff = nil
- seq1 = %w(abcd efgh ijkl mnop)
- seq2 = []
- correct_sdiff = [
- [ '-', 'abcd', nil ],
- [ '-', 'efgh', nil ],
- [ '-', 'ijkl', nil ],
- [ '-', 'mnop', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_n
- sdiff = nil
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnop)
- correct_sdiff = [
- [ '+', nil, 'abcd' ],
- [ '+', nil, 'efgh' ],
- [ '+', nil, 'ijkl' ],
- [ '+', nil, 'mnop' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_balanced_a
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 M22 ", callback.result)
- end
-
- def test_balanced_b
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 DB21 M22 ", callback.result)
- end
-
- def test_balanced_c
- seq1 = %w(a x y c)
- seq2 = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 C22 M33 ", callback.result)
- end
-
- def test_balanced_d
- seq1 = %w(x y c)
- seq2 = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 M22 ", callback.result)
- end
-
- def test_balanced_e
- seq1 = %w(a x y z)
- seq2 = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 DA33 ", callback.result)
- end
-
- def test_balanced_f
- seq1 = %w(a z)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 ", callback.result)
- end
-
- def test_balanced_g
- seq1 = %w(z a)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 M10 ", callback.result)
- end
-
- def test_balanced_h
- seq1 = %w(a b c)
- seq2 = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 ", callback.result)
- end
-
- def test_balanced_i
- seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- seq2 = []
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
- end
-
- def test_balanced_j
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/ChangeLog b/diff-lcs/tags/release-1.0.3/ChangeLog
deleted file mode 100644
index eeccc3b..0000000
--- a/diff-lcs/tags/release-1.0.3/ChangeLog
+++ /dev/null
@@ -1,20 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.0.3
-* Fixed a problem with #traverse_sequences where the first difference from the
- left sequence might not be appropriately captured.
-
-== Diff::LCS 1.0.2
-* Fixed an issue with ldiff not working because actions were changed from
- symbols to strings.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.0.3/Install b/diff-lcs/tags/release-1.0.3/Install
deleted file mode 100644
index 681b189..0000000
--- a/diff-lcs/tags/release-1.0.3/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.0.3.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.0.3/README b/diff-lcs/tags/release-1.0.3/README
deleted file mode 100644
index 8585fe3..0000000
--- a/diff-lcs/tags/release-1.0.3/README
+++ /dev/null
@@ -1,65 +0,0 @@
-Diff::LCS README
-================
-Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt longest
-common subsequence (LCS) algorithm to compute intelligent differences between
-two sequenced enumerable containers[2]. The implementation is based on Mario I.
-Wolczko's[3] Smalltalk version (1.2, 1993)[4] and Ned Konz's[5] Perl version
-(Algorithm::Diff)[6].
-
-This release is version 1.0.3. It contains only bug fixes over 1.0.2.
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = seq1.traverse_sequences(seq2, callback_obj)
- bal = seq1.traverse_balanced(seq2, callback_obj)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will be
-extended for use this way.
-
-Copyright
-=========
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.0.3/diff-lcs.gemspec b/diff-lcs/tags/release-1.0.3/diff-lcs.gemspec
deleted file mode 100644
index edf3535..0000000
--- a/diff-lcs/tags/release-1.0.3/diff-lcs.gemspec
+++ /dev/null
@@ -1,42 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.0.3}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
- s.platform = Gem::Platform::RUBY
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
- s.default_executable = %(ldiff)
-
- s.test_suite_file = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/tags/release-1.0.3/htmldiff b/diff-lcs/tags/release-1.0.3/htmldiff
deleted file mode 100644
index 9ef34a4..0000000
--- a/diff-lcs/tags/release-1.0.3/htmldiff
+++ /dev/null
@@ -1,111 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'diff/lcs/string'
-rescue
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.3"
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.0.3/htmldiff.bat b/diff-lcs/tags/release-1.0.3/htmldiff.bat
deleted file mode 100644
index 1432736..0000000
--- a/diff-lcs/tags/release-1.0.3/htmldiff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-REM --
-REM Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-REM adapted from:
-REM Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-REM Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-REM implements McIlroy-Hunt diff algorithm
-REM
-REM This program is free software. It may be redistributed and/or modified under
-REM the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-REM Ruby licence.
-REM
-REM $Id$
-REM ++
-if "%OS%"=="Windows_NT" goto WinNT
-ruby -x "htmldiff" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-ruby -x "htmldiff" %*
-goto done
-:done
diff --git a/diff-lcs/tags/release-1.0.3/install.rb b/diff-lcs/tags/release-1.0.3/install.rb
deleted file mode 100644
index 2b85c59..0000000
--- a/diff-lcs/tags/release-1.0.3/install.rb
+++ /dev/null
@@ -1,206 +0,0 @@
-##
-# Install utility for HaloStatue scripts and libraries. Based heavily on the
-# original RDoc installation script by Pragmatic Programmers.
-#
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-require 'test/unit/ui/console/testrunner'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = []
- list.each { |i| g << Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--no-rdoc', FalseClass,
- 'Prevents the creation of RDoc output.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri',
- 'Prevents the creation of RI output.',
- 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--no-tests', FalseClass,
- 'Prevents the execution of unit tests.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers", "--show-hash"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(%w{--ri-site --show-hash} + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/i
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- op_file += ".rb" if not installed_wrapper
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.0.3/ldiff b/diff-lcs/tags/release-1.0.3/ldiff
deleted file mode 100644
index 047e022..0000000
--- a/diff-lcs/tags/release-1.0.3/ldiff
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/user/bin/env ruby
-# = Diff::LCS 1.0.3
-# == ldiff Usage
-# ldiff [options] oldfile newfile
-#
-# -c:: Displays a context diff with 3 lines of context.
-# -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
-# -u:: Displays a unified diff with 3 lines of context.
-# -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
-# -e:: Creates an 'ed' script to change oldfile to newfile.
-# -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
-# -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
-# --binary:: Treats the files as binary.
-# -q, --brief:: Reports only whether or not the files differ, not the details.
-# --help:: Shows the command-line help.
-# --version:: Shows the version of Diff::LCS.
-#
-# By default, runs produces an "old-style" diff, with output like UNIX diff.
-#
-# == Copyright
-# Copyright &copy; 2004 Austin Ziegler
-#
-# Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
-# Austin Ziegler <diff-lcs@halostatue.ca>
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-
-require 'optparse'
-require 'ostruct'
-
-begin
- require 'diff/lcs'
-rescue
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.3"
-end
-
-require 'diff/lcs/hunk'
-
-module Diff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def diffprog(args, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- end
- end
-
- output << oldhunk.diff(@format)
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
-
-exit Diff::diffprog(ARGV, $stdout, $stderr)
diff --git a/diff-lcs/tags/release-1.0.3/ldiff.bat b/diff-lcs/tags/release-1.0.3/ldiff.bat
deleted file mode 100644
index ddf977f..0000000
--- a/diff-lcs/tags/release-1.0.3/ldiff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-REM --
-REM Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-REM adapted from:
-REM Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-REM Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-REM implements McIlroy-Hunt diff algorithm
-REM
-REM This program is free software. It may be redistributed and/or modified under
-REM the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-REM Ruby licence.
-REM
-REM $Id$
-REM ++
-if "%OS%"=="Windows_NT" goto WinNT
-ruby -x "ldiff" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-ruby -x "ldiff" %*
-goto done
-:done
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs.rb
deleted file mode 100644
index 6489a21..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs.rb
+++ /dev/null
@@ -1,760 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.0.3
- # Computes "intelligent" differences between two ordered Enumerables. This
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
- # objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version (1.2,
- # 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Default extensions are provided for Array and String objects through the
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- # I once read an article written by the authors of +diff+; they said that
- # they hard worked very hard on the algorithm until they found the right
- # one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the secend sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # === Key Generation
- # The Perl version accepts an optional hash-key generation code reference
- # because all comparisons are done stringwise. This is not necessary for
- # Ruby, as the spaceship operator (<=>) should be provided on classes that
- # may be present in an ordered Enumerable.
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written by Mark-Jason Dominus
- # <mjd-perl-diff@plover.com>. The basic Ruby implementation was reported
- # from the Smalltalk implementation, available at
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # +sdiff+ and +traverse_balanced+ were written for the Perl version by
- # Mike Schilli <m@perlmeister.com>.
- #
- # The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed.
- module LCS
- VERSION = '1.0.3' #:nodoc:
- end
-end
-
-require 'diff/lcs/event'
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns the Longest Common Subsequnce(s)
- # LCS returns an Array containing the longest common subsequence between
- # +self+ and +other+.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- def traverse_sequences(other)
- traverse_sequences(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def traverse_balanced(other)
- traverse_balanced(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def patch(diffs)
- Diff::LCS::patch(self, diffs)
- end
-end
-
-module Diff::LCS
- class << self
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # Compute the longest common subsequence between the ordered Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection.
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Given two ordered Enumerables, LCS returns an Array containing their
- # longest common subsequence.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- def LCS(a, b, &block) #:yields self[ii] if there are matched subsequences:
- matches = Diff::LCS.__lcs(a, b)
- ret = []
- matches.each_with_index do |e, ii|
- unless matches[ii].nil?
- ret << a[ii]
- yield a[ii] if block_given?
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes. The description is a list of +hunks+;
- # each hunk represents a contiguous section of items which should be
- # added, deleted, or replaced. The return value of +diff+ is an Array
- # of hunks.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # [ [ [ :-, 0, 'a' ] ],
- # # [ [ :+, 2, 'd' ] ],
- # # [ [ :-, 4, 'h' ],
- # # [ :+, 4, 'f' ] ],
- # # [ [ :+, 6, 'k' ] ],
- # # [ [ :-, 8, 'n' ],
- # # [ :-, 9, 'p' ],
- # # [ :+, 9, 'r' ],
- # # [ :+, 10, 's' ],
- # # [ :+, 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at
- # position 0 of the first sequence should be deleted (<tt>:-</tt>).
- # The second hunk says that the +d+ at position 2 of the second
- # sequence should be inserted (<tt>:+</tt>). The third hunk says that
- # the +h+ at position 4 of the first sequence should be removed and
- # replaced with the +f+ from position 4 of the second sequence. The
- # other two hunks similarly.
- def diff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::DiffCallbacks.new
- traverse_sequences(a, b, callbacks)
- callbacks.match(nil)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # It returns an Array of Arrays that contain display instructions.
- # Display instructions consist of three elements: A modifier indicator
- # (<tt>:+</tt>: Element added, <tt>:-</tt>: Element removed, +u+:
- # Element unmodified, +c+: Element changed) and the value of the old
- # and new elements, to be displayed side by side.
- #
- # sdiffs = Diff::LCS.sdiff(seq1, seq2)
- # # [ [ '-', 'a', '' ],
- # # [ 'u', 'b', 'b' ],
- # # [ 'u', 'c', 'c' ],
- # # [ '+', '', 'd' ],
- # # [ 'u', 'e', 'e' ],
- # # [ 'c', 'h', 'f' ],
- # # [ 'u', 'j', 'j' ],
- # # [ '+', '', 'k' ],
- # # [ 'u', 'l', 'l' ],
- # # [ 'u', 'm', 'm' ],
- # # [ 'c', 'n', 'r' ],
- # # [ 'c', 'p', 's' ],
- # # [ '+', '', 't' ] ]
- def sdiff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::SDiffCallbacks.new
- traverse_balanced(a, b, callbacks)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # Imagine that there are two arrows. Arrow A points to an element of
- # sequence A, and arrow B points to an element of the sequence B.
- # Initially, the arrows point to the first elements of the respective
- # sequences. +traverse_sequences+ will advance the arrows through the
- # sequences one element at a time, calling an appropriate
- # user-specified callback function before each advance. It will
- # advance the arrows in such a way that if there are equal elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt> which are equal and which are part
- # of the LCS, there will be some moment during the execution of
- # +traverse_sequences+ when arrow A is pointing to <tt>A[ii]</tt> and
- # arrow B is pointing to <tt>B[jj]</tt>. When this happens,
- # +traverse_sequences+ will call the <tt>:match</tt> lambda and then
- # it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its
- # sequence that is not part of the LCS. +traverse_sequences+ will
- # advance that arrow and will call the <tt>:discard_a</tt> or the
- # <tt>:discard_b</tt> lambdas, depending on which arrow it advanced.
- # If both arrows point to elements that are not part of the LCS, then
- # +traverse_sequences+ will advance one of them and call the
- # appropriate callback, but it is not specified which it will call.
- #
- # The arguments to +traverse_sequences+ are the two sequences to
- # traverse, and a hash which specifies the lambdas, like this:
- #
- # traverse_sequences(seq1, seq2,
- # :match => callback_1,
- # :discard_a => callback_2,
- # :discard_b => callback_3)
- #
- # The lambdas for <tt>:match</tt>, <tt>:discard_a</tt>, and
- # <tt>:discard_b</tt> are invoked with the indices of the two arrows
- # as their arguments and are not expected to return any values.
- #
- # If arrow A reaches the end of its sequence before arrow B does,
- # +traverse_sequences+ will call the <tt>:a_finished</tt> lambda with
- # the last index in A. If <tt>:a_finished</tt> does not exist, then
- # <tt>:discard_b</tt> will be called until the end of the B sequence.
- # If B terminates before A, then <tt>:b_finished</tt> or
- # <tt>:discard_a</tt> will be called.
- #
- # Omitted callbacks are not called.
- #
- def traverse_sequences(a, b, callbacks = Diff::LCS::SequenceCallbacks)
- matches = Diff::LCS.__lcs(a, b)
-
- run_finished_a = run_finished_b = false
- string = a.kind_of?(String)
-
- a_size = a.size
- b_size = b.size
- ai = bj = 0
-
- (0 .. matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? a[ii, 1] : a[ii]
- bx = string ? b[bj, 1] : b[bj]
-
- if b_line.nil?
- unless ax.nil?
- event = Diff::LCS::Event.new(:discard_a, ax, ii, bx, bj)
- callbacks.discard_a(event)
- end
- else
- loop do
- break unless bj < b_line
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ii, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:match, ax, ii, bx, bj)
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? a[-1, 1] : a[-1]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:finished_a, ax, a_size - 1, bx, bj)
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? a[ai, 1] : a[ai]
- loop do
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[-1, 1] : b[-1]
- event = Diff::LCS::Event.new(:finished_b, ax, ai, bx, b_size - 1)
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? b[bj, 1] : b[bj]
- loop do
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # +traverse_balanced+ is an alternative to +traverse_sequences+. It
- # uses a different algorithm to iterate through the entries in the
- # computed LCS. Instead of sticking to one side and showing element
- # changes as insertions and deletions only, it will jump back and
- # forth between the two sequences and report <em>changes</em>
- # occurring as deletions on one side followed immediatly by an
- # insertion on the other side.
- #
- # In addition to the <tt>:discard_a</tt>, <tt>:discard_b</tt>, and
- # <tt>:match</tt> callbacks supported by +traverse_sequences+,
- # +traverse_balanced+ supports a <tt>:change</tt> callback indicating
- # that one element got +replaced+ by another:
- #
- # traverse_sequences(seq1, seq2,
- # :match => $callback_1,
- # :discard_a => $callback_2,
- # :discard_b => $callback_3,
- # :change => $callback_4,)
- #
- # If no <tt>:change</tt> callback is specified, +traverse_balanced+
- # will map <tt>:change</tt> events to <tt>:discard_a</tt> and
- # <tt>:discard_b</tt> actions, therefore resulting in a similar
- # behaviour as +traverse_sequences+ with different order of events.
- #
- # +traverse_balanced+ might be a bit slower than +traverse_sequences+,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # +traverse_balanced+.
- def traverse_balanced(a, b, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(a, b)
- a_size = a.size
- b_size = b.size
- ai = bj = mb = 0
- ma = -1
- string = a.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(s)
- while (ai < ma) or (bj < mb)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- def __diff_direction(src, diffs)
- left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- diffs.each do |change|
- text = string ? src[change.position, 1] : src[change.position]
- case change.action
- when :-
- if text == change.text
- left += 1
- else
- left_miss += 1
- end
- when :+
- if text == change.text
- right += 1
- else
- right_miss += 1
- end
- end
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided diff does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Given a set of diffs, convert the current version to the new version.
- def patch(src, diffs, direction = nil)
- diffs = diffs.flatten
- direction = Diff::LCS.__diff_direction(src, diffs) if direction.nil?
- string = src.kind_of?(String)
-
- n = src.class.new
- ai = bj = 0
-
- uses_splat = true
-
- diffs.each do |change|
- action = change.action
-
- if direction == :unpatch
- case action
- when :-
- action = :+
- when :+
- action = :-
- end
- end
-
- case action
- when :- # Delete
- while ai < change.position
- n << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += (change.text.kind_of?(String) ? 1 : change.text.size)
- when :+ # Insert
- while bj < change.position
- n << (string ? src[ai, 1]: src[ai])
- ai += 1
- bj += 1
- end
-
- if change.text.kind_of?(String)
- n << change.text
- else
- n.push(*change.text)
- end
-
- bj += (change.text.kind_of?(String) ? 1 : change.text.size)
- end
- end
-
- n
- end
-
- # Given a set of diffs, convert the current version to the prior
- # version.
- def unpatch(diffs)
- patch(diffs, :unpatch)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/array.rb
deleted file mode 100644
index fea3edc..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/block.rb
deleted file mode 100644
index 7ffdbab..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/diff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index eb0be60..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/change'
-
-class Diff::LCS::SequenceCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::BalancedCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::DiffCallbacks #:nodoc:
- attr_accessor :hunk
- attr_accessor :diffs
-
- def initialize
- @hunk = []
- @diffs = []
- end
-
- def match(event)
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_ix, event.old_el)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_ix, event.new_el)
- end
-end
-
-class Diff::LCS::SDiffCallbacks #:nodoc:
- attr_accessor :diffs
-
- def initialize
- @diffs = []
- end
-
- def match(event)
- @diffs << Diff::LCS::Change.new('u', event.old_el, event.new_el)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::Change.new('-', event.old_el, nil)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::Change.new('+', nil, event.new_el)
- end
-
- def change(event)
- @diffs << Diff::LCS::Change.new('!', event.old_el, event.new_el)
- end
-end
-
-class Diff::LCS::YieldingCallbacks #:nodoc:
- class << self
- def method_missing(symbol, *args)
- yield args if block_given?
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/change.rb
deleted file mode 100644
index ae5e904..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Change
- attr_reader :action, :position, :text
-
- include Comparable
-
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.text == other.text)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.text <=> other.text if r.zero?
- r
- end
-
- def initialize(action, position, text)
- @action = action
- @position = position
- @text = text
- end
-
- def to_a
- [@action, @position, @text]
- end
-
- def self.from_a(*arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- def deleting?
- @action == '-'
- end
-
- def adding?
- @action == '+'
- end
-
- def unchanged?
- @action == 'u'
- end
-
- def changed?
- @changed == 'c'
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/event.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/event.rb
deleted file mode 100644
index daa2414..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/event.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Event
- attr_reader :code
- attr_reader :old_el
- attr_reader :old_ix
- attr_reader :new_el
- attr_reader :new_ix
-
- def initialize(code, a, ai, b, bi)
- @code = code
- @old_el = a
- @old_ix = ai
- @new_el = b
- @new_ix = bi
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/hunk.rb
deleted file mode 100644
index c57e4ba..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.0.3/lib/diff/lcs/string.rb
deleted file mode 100644
index 96a01fe..0000000
--- a/diff-lcs/tags/release-1.0.3/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/array'
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.3/tests/00test.rb b/diff-lcs/tags/release-1.0.3/tests/00test.rb
deleted file mode 100644
index ef8c945..0000000
--- a/diff-lcs/tags/release-1.0.3/tests/00test.rb
+++ /dev/null
@@ -1,525 +0,0 @@
-#! /usr/bin/env ruby
-#
-$:.unshift '../lib' if __FILE__ == $0 # Make this library first!
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-module Diff::LCS::Tests
- def __format_diffs(diffs)
- diffs.map do |e|
- if e.kind_of?(Array)
- e.map { |f| f.to_a.join }.join(", ")
- else
- e.to_a.join
- end
- end.join("; ")
- end
-
- def __map_diffs(diffs, klass = Diff::LCS::Change)
- diffs.map do |chunks|
- chunks.map { |changes| klass.from_a(*changes) }
- end
- end
-
- def __simple_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_el
- @matched_b << event.new_el
- end
-
- def discard_b(event)
- @discards_b << event.new_el
- end
-
- def discard_a(event)
- @discards_a << event.old_el
- end
-
- def finished_a(event)
- @done_a << [event.old_el, event.old_ix]
- end
-
- def finished_b(event)
- @done_b << [event.new_el, event.new_ix]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M#{event.old_ix}#{event.new_ix} "
- end
-
- def discard_a(event)
- @result << "DA#{event.old_ix}#{event.new_ix} "
- end
-
- def discard_b(event)
- @result << "DB#{event.old_ix}#{event.new_ix} "
- end
-
- def change(event)
- @result << "C#{event.old_ix}#{event.new_ix} "
- end
- end
- cb.reset
- cb
- end
-
- def setup
- @seq1 = %w(a b c e h j l m n p)
- @seq2 = %w(b c d e f j k l m r s t)
-
- @correct_lcs = %w(b c e j l m)
-
- @skipped_seq1 = 'a h n p'
- @skipped_seq2 = 'd f k r s t'
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '-', 9, 'p' ],
- [ '+', 9, 'r' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
- end
-end
-
-class TestLCS < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct_lcs.size)
- res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
- assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
- assert_equal(@correct_lcs, ares.compact)
- assert_equal(@correct_lcs, bres.compact)
- assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
- assert_equal(res.compact, @correct_lcs)
- end
-end
-
-class TestSequences < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __simple_callbacks
- class << callbacks
- undef :finished_a
- undef :finished_b
- end
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_nothing_raised do
- callbacks = __simple_callbacks
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
-
-# seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
-# assert_nothing_raised do
-# callbacks = __simple_callbacks
-# class << callbacks
-# undef :finished_a
-# undef :finished_b
-# end
-# Diff::LCS.traverse_sequences(seqw, [], callbacks)
-# end
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
- assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
- assert_equal(@correct_diff, diff)
- end
-
- def test_diff_empty
- seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
- correct_diff = [
- [ [ '-', 0, 'abcd' ],
- [ '-', 1, 'efgh' ],
- [ '-', 2, 'ijkl' ],
- [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
- diff = nil
-
- assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
-
- correct_diff = [
- [ [ '+', 0, 'abcd' ],
- [ '+', 1, 'efgh' ],
- [ '+', 2, 'ijkl' ],
- [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
- assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
- end
-end
-
-class TestBalanced < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sdiff_a
- sdiff = nil
- seq1 = %w(abc def yyy xxx ghi jkl)
- seq2 = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- [ 'u', 'abc', 'abc' ],
- [ '!', 'def', 'dxf' ],
- [ '-', 'yyy', nil ],
- [ 'u', 'xxx', 'xxx' ],
- [ 'u', 'ghi', 'ghi' ],
- [ 'u', 'jkl', 'jkl' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ 'u', 'b', 'b' ],
- [ 'u', 'c', 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ],
- [ '!', 'h', 'f' ],
- [ 'u', 'j', 'j' ],
- [ '+', nil, 'k' ],
- [ 'u', 'l', 'l' ],
- [ 'u', 'm', 'm' ],
- [ '!', 'n', 'r' ],
- [ '!', 'p', 's' ],
- [ '+', nil, 't' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- seq1 = %w(a b c d e)
- seq2 = %w(a e)
- correct_sdiff = [
- [ 'u', 'a', 'a' ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ],
- [ '-', 'd', nil ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- seq1 = %w(v x a e)
- seq2 = %w(w y a b c d e)
- correct_sdiff = [
- [ '!', 'v', 'w' ],
- [ '!', 'x', 'y' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- seq1 = %w(x a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '-', 'x', nil ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(x a b c d e)
- correct_sdiff = [
- [ '+', nil, 'x' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- seq1 = %w(a e v)
- seq2 = %w(x a b c d e w x)
- correct_sdiff = [
- [ '+', nil, 'x' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ],
- [ '!', 'v', 'w' ],
- [ '+', nil, 'x' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- seq1 = %w()
- seq2 = %w(a b c)
- correct_sdiff = [
- [ '+', nil, 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w()
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(1)
- correct_sdiff = [
- [ '!', 'a', '1' ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(c)
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ '-', 'b', nil ],
- [ 'u', 'c', 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_m
- sdiff = nil
- seq1 = %w(abcd efgh ijkl mnop)
- seq2 = []
- correct_sdiff = [
- [ '-', 'abcd', nil ],
- [ '-', 'efgh', nil ],
- [ '-', 'ijkl', nil ],
- [ '-', 'mnop', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_n
- sdiff = nil
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnop)
- correct_sdiff = [
- [ '+', nil, 'abcd' ],
- [ '+', nil, 'efgh' ],
- [ '+', nil, 'ijkl' ],
- [ '+', nil, 'mnop' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_balanced_a
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 M22 ", callback.result)
- end
-
- def test_balanced_b
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 DB21 M22 ", callback.result)
- end
-
- def test_balanced_c
- seq1 = %w(a x y c)
- seq2 = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 C22 M33 ", callback.result)
- end
-
- def test_balanced_d
- seq1 = %w(x y c)
- seq2 = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 M22 ", callback.result)
- end
-
- def test_balanced_e
- seq1 = %w(a x y z)
- seq2 = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 DA33 ", callback.result)
- end
-
- def test_balanced_f
- seq1 = %w(a z)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 ", callback.result)
- end
-
- def test_balanced_g
- seq1 = %w(z a)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 M10 ", callback.result)
- end
-
- def test_balanced_h
- seq1 = %w(a b c)
- seq2 = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 ", callback.result)
- end
-
- def test_balanced_i
- seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- seq2 = []
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
- end
-
- def test_balanced_j
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/ChangeLog b/diff-lcs/tags/release-1.0.4/ChangeLog
deleted file mode 100644
index 75a392e..0000000
--- a/diff-lcs/tags/release-1.0.4/ChangeLog
+++ /dev/null
@@ -1,26 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.0.4
-* Fixed a problem with bin/ldiff output, especially for unified format.
- Newlines that should have been present weren't.
-* Changed the .tar.gz installer to generate Windows batch files if ones do not
- exist already. Removed the existing batch files as they didn't work.
-
-== Diff::LCS 1.0.3
-* Fixed a problem with #traverse_sequences where the first difference from the
- left sequence might not be appropriately captured.
-
-== Diff::LCS 1.0.2
-* Fixed an issue with ldiff not working because actions were changed from
- symbols to strings.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.0.4/Install b/diff-lcs/tags/release-1.0.4/Install
deleted file mode 100644
index b583d3f..0000000
--- a/diff-lcs/tags/release-1.0.4/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.0.4.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.0.4/README b/diff-lcs/tags/release-1.0.4/README
deleted file mode 100644
index a7021e7..0000000
--- a/diff-lcs/tags/release-1.0.4/README
+++ /dev/null
@@ -1,66 +0,0 @@
-Diff::LCS README
-================
-Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt
-longest common subsequence (LCS) algorithm to compute intelligent
-differences between two sequenced enumerable containers[2]. The
-implementation is based on Mario I. Wolczko's[3] Smalltalk version (1.2,
-1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-This release is version 1.0.4. It contains only bug fixes over 1.0.2 and
-1.0.3.
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = seq1.traverse_sequences(seq2, callback_obj)
- bal = seq1.traverse_balanced(seq2, callback_obj)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will
-be extended for use this way.
-
-Copyright
-=========
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.0.4/diff-lcs.gemspec b/diff-lcs/tags/release-1.0.4/diff-lcs.gemspec
deleted file mode 100644
index 93ca917..0000000
--- a/diff-lcs/tags/release-1.0.4/diff-lcs.gemspec
+++ /dev/null
@@ -1,42 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.0.4}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
- s.platform = Gem::Platform::RUBY
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
- s.default_executable = %(ldiff)
-
- s.test_suite_file = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/tags/release-1.0.4/htmldiff b/diff-lcs/tags/release-1.0.4/htmldiff
deleted file mode 100644
index ef41888..0000000
--- a/diff-lcs/tags/release-1.0.4/htmldiff
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.4"
- require 'diff/lcs/string'
-rescue LoadError
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.0.4/install.rb b/diff-lcs/tags/release-1.0.4/install.rb
deleted file mode 100644
index 5772e0b..0000000
--- a/diff-lcs/tags/release-1.0.4/install.rb
+++ /dev/null
@@ -1,264 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.0.4/ldiff b/diff-lcs/tags/release-1.0.4/ldiff
deleted file mode 100644
index a60a19d..0000000
--- a/diff-lcs/tags/release-1.0.4/ldiff
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env ruby
-# = Diff::LCS 1.0.4
-# == ldiff Usage
-# ldiff [options] oldfile newfile
-#
-# -c:: Displays a context diff with 3 lines of context.
-# -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
-# -u:: Displays a unified diff with 3 lines of context.
-# -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
-# -e:: Creates an 'ed' script to change oldfile to newfile.
-# -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
-# -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
-# --binary:: Treats the files as binary.
-# -q, --brief:: Reports only whether or not the files differ, not the details.
-# --help:: Shows the command-line help.
-# --version:: Shows the version of Diff::LCS.
-#
-# By default, runs produces an "old-style" diff, with output like UNIX diff.
-#
-# == Copyright
-# Copyright &copy; 2004 Austin Ziegler
-#
-# Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
-# Austin Ziegler <diff-lcs@halostatue.ca>
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-
-require 'optparse'
-require 'ostruct'
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.0.4"
-rescue LoadError
- require 'diff/lcs'
-end
-
-require 'diff/lcs/hunk'
-
-module Diff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def diffprog(args, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
-
- output << oldhunk.diff(@format)
- output << "\n"
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
-
-exit Diff::diffprog(ARGV, $stdout, $stderr)
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs.rb
deleted file mode 100644
index ad3c1c2..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs.rb
+++ /dev/null
@@ -1,760 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.0.4
- # Computes "intelligent" differences between two ordered Enumerables. This
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
- # objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version (1.2,
- # 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Default extensions are provided for Array and String objects through the
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- # I once read an article written by the authors of +diff+; they said that
- # they hard worked very hard on the algorithm until they found the right
- # one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the secend sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # === Key Generation
- # The Perl version accepts an optional hash-key generation code reference
- # because all comparisons are done stringwise. This is not necessary for
- # Ruby, as the spaceship operator (<=>) should be provided on classes that
- # may be present in an ordered Enumerable.
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written by Mark-Jason Dominus
- # <mjd-perl-diff@plover.com>. The basic Ruby implementation was reported
- # from the Smalltalk implementation, available at
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # +sdiff+ and +traverse_balanced+ were written for the Perl version by
- # Mike Schilli <m@perlmeister.com>.
- #
- # The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed.
- module LCS
- VERSION = '1.0.4' #:nodoc:
- end
-end
-
-require 'diff/lcs/event'
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns the Longest Common Subsequnce(s)
- # LCS returns an Array containing the longest common subsequence between
- # +self+ and +other+.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- def traverse_sequences(other)
- traverse_sequences(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def traverse_balanced(other)
- traverse_balanced(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def patch(diffs)
- Diff::LCS::patch(self, diffs)
- end
-end
-
-module Diff::LCS
- class << self
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # Compute the longest common subsequence between the ordered Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection.
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Given two ordered Enumerables, LCS returns an Array containing their
- # longest common subsequence.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- def LCS(a, b, &block) #:yields self[ii] if there are matched subsequences:
- matches = Diff::LCS.__lcs(a, b)
- ret = []
- matches.each_with_index do |e, ii|
- unless matches[ii].nil?
- ret << a[ii]
- yield a[ii] if block_given?
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes. The description is a list of +hunks+;
- # each hunk represents a contiguous section of items which should be
- # added, deleted, or replaced. The return value of +diff+ is an Array
- # of hunks.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # [ [ [ :-, 0, 'a' ] ],
- # # [ [ :+, 2, 'd' ] ],
- # # [ [ :-, 4, 'h' ],
- # # [ :+, 4, 'f' ] ],
- # # [ [ :+, 6, 'k' ] ],
- # # [ [ :-, 8, 'n' ],
- # # [ :-, 9, 'p' ],
- # # [ :+, 9, 'r' ],
- # # [ :+, 10, 's' ],
- # # [ :+, 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at
- # position 0 of the first sequence should be deleted (<tt>:-</tt>).
- # The second hunk says that the +d+ at position 2 of the second
- # sequence should be inserted (<tt>:+</tt>). The third hunk says that
- # the +h+ at position 4 of the first sequence should be removed and
- # replaced with the +f+ from position 4 of the second sequence. The
- # other two hunks similarly.
- def diff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::DiffCallbacks.new
- traverse_sequences(a, b, callbacks)
- callbacks.match(nil)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # It returns an Array of Arrays that contain display instructions.
- # Display instructions consist of three elements: A modifier indicator
- # (<tt>:+</tt>: Element added, <tt>:-</tt>: Element removed, +u+:
- # Element unmodified, +c+: Element changed) and the value of the old
- # and new elements, to be displayed side by side.
- #
- # sdiffs = Diff::LCS.sdiff(seq1, seq2)
- # # [ [ '-', 'a', '' ],
- # # [ 'u', 'b', 'b' ],
- # # [ 'u', 'c', 'c' ],
- # # [ '+', '', 'd' ],
- # # [ 'u', 'e', 'e' ],
- # # [ 'c', 'h', 'f' ],
- # # [ 'u', 'j', 'j' ],
- # # [ '+', '', 'k' ],
- # # [ 'u', 'l', 'l' ],
- # # [ 'u', 'm', 'm' ],
- # # [ 'c', 'n', 'r' ],
- # # [ 'c', 'p', 's' ],
- # # [ '+', '', 't' ] ]
- def sdiff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::SDiffCallbacks.new
- traverse_balanced(a, b, callbacks)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # Imagine that there are two arrows. Arrow A points to an element of
- # sequence A, and arrow B points to an element of the sequence B.
- # Initially, the arrows point to the first elements of the respective
- # sequences. +traverse_sequences+ will advance the arrows through the
- # sequences one element at a time, calling an appropriate
- # user-specified callback function before each advance. It will
- # advance the arrows in such a way that if there are equal elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt> which are equal and which are part
- # of the LCS, there will be some moment during the execution of
- # +traverse_sequences+ when arrow A is pointing to <tt>A[ii]</tt> and
- # arrow B is pointing to <tt>B[jj]</tt>. When this happens,
- # +traverse_sequences+ will call the <tt>:match</tt> lambda and then
- # it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its
- # sequence that is not part of the LCS. +traverse_sequences+ will
- # advance that arrow and will call the <tt>:discard_a</tt> or the
- # <tt>:discard_b</tt> lambdas, depending on which arrow it advanced.
- # If both arrows point to elements that are not part of the LCS, then
- # +traverse_sequences+ will advance one of them and call the
- # appropriate callback, but it is not specified which it will call.
- #
- # The arguments to +traverse_sequences+ are the two sequences to
- # traverse, and a hash which specifies the lambdas, like this:
- #
- # traverse_sequences(seq1, seq2,
- # :match => callback_1,
- # :discard_a => callback_2,
- # :discard_b => callback_3)
- #
- # The lambdas for <tt>:match</tt>, <tt>:discard_a</tt>, and
- # <tt>:discard_b</tt> are invoked with the indices of the two arrows
- # as their arguments and are not expected to return any values.
- #
- # If arrow A reaches the end of its sequence before arrow B does,
- # +traverse_sequences+ will call the <tt>:a_finished</tt> lambda with
- # the last index in A. If <tt>:a_finished</tt> does not exist, then
- # <tt>:discard_b</tt> will be called until the end of the B sequence.
- # If B terminates before A, then <tt>:b_finished</tt> or
- # <tt>:discard_a</tt> will be called.
- #
- # Omitted callbacks are not called.
- #
- def traverse_sequences(a, b, callbacks = Diff::LCS::SequenceCallbacks)
- matches = Diff::LCS.__lcs(a, b)
-
- run_finished_a = run_finished_b = false
- string = a.kind_of?(String)
-
- a_size = a.size
- b_size = b.size
- ai = bj = 0
-
- (0 .. matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? a[ii, 1] : a[ii]
- bx = string ? b[bj, 1] : b[bj]
-
- if b_line.nil?
- unless ax.nil?
- event = Diff::LCS::Event.new(:discard_a, ax, ii, bx, bj)
- callbacks.discard_a(event)
- end
- else
- loop do
- break unless bj < b_line
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ii, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:match, ax, ii, bx, bj)
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? a[-1, 1] : a[-1]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:finished_a, ax, a_size - 1, bx, bj)
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? a[ai, 1] : a[ai]
- loop do
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[-1, 1] : b[-1]
- event = Diff::LCS::Event.new(:finished_b, ax, ai, bx, b_size - 1)
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? b[bj, 1] : b[bj]
- loop do
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # +traverse_balanced+ is an alternative to +traverse_sequences+. It
- # uses a different algorithm to iterate through the entries in the
- # computed LCS. Instead of sticking to one side and showing element
- # changes as insertions and deletions only, it will jump back and
- # forth between the two sequences and report <em>changes</em>
- # occurring as deletions on one side followed immediatly by an
- # insertion on the other side.
- #
- # In addition to the <tt>:discard_a</tt>, <tt>:discard_b</tt>, and
- # <tt>:match</tt> callbacks supported by +traverse_sequences+,
- # +traverse_balanced+ supports a <tt>:change</tt> callback indicating
- # that one element got +replaced+ by another:
- #
- # traverse_sequences(seq1, seq2,
- # :match => $callback_1,
- # :discard_a => $callback_2,
- # :discard_b => $callback_3,
- # :change => $callback_4,)
- #
- # If no <tt>:change</tt> callback is specified, +traverse_balanced+
- # will map <tt>:change</tt> events to <tt>:discard_a</tt> and
- # <tt>:discard_b</tt> actions, therefore resulting in a similar
- # behaviour as +traverse_sequences+ with different order of events.
- #
- # +traverse_balanced+ might be a bit slower than +traverse_sequences+,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # +traverse_balanced+.
- def traverse_balanced(a, b, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(a, b)
- a_size = a.size
- b_size = b.size
- ai = bj = mb = 0
- ma = -1
- string = a.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(s)
- while (ai < ma) or (bj < mb)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- def __diff_direction(src, diffs)
- left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- diffs.each do |change|
- text = string ? src[change.position, 1] : src[change.position]
- case change.action
- when :-
- if text == change.text
- left += 1
- else
- left_miss += 1
- end
- when :+
- if text == change.text
- right += 1
- else
- right_miss += 1
- end
- end
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided diff does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Given a set of diffs, convert the current version to the new version.
- def patch(src, diffs, direction = nil)
- diffs = diffs.flatten
- direction = Diff::LCS.__diff_direction(src, diffs) if direction.nil?
- string = src.kind_of?(String)
-
- n = src.class.new
- ai = bj = 0
-
- uses_splat = true
-
- diffs.each do |change|
- action = change.action
-
- if direction == :unpatch
- case action
- when :-
- action = :+
- when :+
- action = :-
- end
- end
-
- case action
- when :- # Delete
- while ai < change.position
- n << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += (change.text.kind_of?(String) ? 1 : change.text.size)
- when :+ # Insert
- while bj < change.position
- n << (string ? src[ai, 1]: src[ai])
- ai += 1
- bj += 1
- end
-
- if change.text.kind_of?(String)
- n << change.text
- else
- n.push(*change.text)
- end
-
- bj += (change.text.kind_of?(String) ? 1 : change.text.size)
- end
- end
-
- n
- end
-
- # Given a set of diffs, convert the current version to the prior
- # version.
- def unpatch(diffs)
- patch(diffs, :unpatch)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/array.rb
deleted file mode 100644
index fea3edc..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/block.rb
deleted file mode 100644
index 7ffdbab..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/diff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index eb0be60..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/change'
-
-class Diff::LCS::SequenceCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::BalancedCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::DiffCallbacks #:nodoc:
- attr_accessor :hunk
- attr_accessor :diffs
-
- def initialize
- @hunk = []
- @diffs = []
- end
-
- def match(event)
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_ix, event.old_el)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_ix, event.new_el)
- end
-end
-
-class Diff::LCS::SDiffCallbacks #:nodoc:
- attr_accessor :diffs
-
- def initialize
- @diffs = []
- end
-
- def match(event)
- @diffs << Diff::LCS::Change.new('u', event.old_el, event.new_el)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::Change.new('-', event.old_el, nil)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::Change.new('+', nil, event.new_el)
- end
-
- def change(event)
- @diffs << Diff::LCS::Change.new('!', event.old_el, event.new_el)
- end
-end
-
-class Diff::LCS::YieldingCallbacks #:nodoc:
- class << self
- def method_missing(symbol, *args)
- yield args if block_given?
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/change.rb
deleted file mode 100644
index ae5e904..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Change
- attr_reader :action, :position, :text
-
- include Comparable
-
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.text == other.text)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.text <=> other.text if r.zero?
- r
- end
-
- def initialize(action, position, text)
- @action = action
- @position = position
- @text = text
- end
-
- def to_a
- [@action, @position, @text]
- end
-
- def self.from_a(*arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- def deleting?
- @action == '-'
- end
-
- def adding?
- @action == '+'
- end
-
- def unchanged?
- @action == 'u'
- end
-
- def changed?
- @changed == 'c'
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/event.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/event.rb
deleted file mode 100644
index daa2414..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/event.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Event
- attr_reader :code
- attr_reader :old_el
- attr_reader :old_ix
- attr_reader :new_el
- attr_reader :new_ix
-
- def initialize(code, a, ai, b, bi)
- @code = code
- @old_el = a
- @old_ix = ai
- @new_el = b
- @new_ix = bi
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/hunk.rb
deleted file mode 100644
index c57e4ba..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.0.4/lib/diff/lcs/string.rb
deleted file mode 100644
index 96a01fe..0000000
--- a/diff-lcs/tags/release-1.0.4/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/array'
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0.4/tests/00test.rb b/diff-lcs/tags/release-1.0.4/tests/00test.rb
deleted file mode 100644
index ef8c945..0000000
--- a/diff-lcs/tags/release-1.0.4/tests/00test.rb
+++ /dev/null
@@ -1,525 +0,0 @@
-#! /usr/bin/env ruby
-#
-$:.unshift '../lib' if __FILE__ == $0 # Make this library first!
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-module Diff::LCS::Tests
- def __format_diffs(diffs)
- diffs.map do |e|
- if e.kind_of?(Array)
- e.map { |f| f.to_a.join }.join(", ")
- else
- e.to_a.join
- end
- end.join("; ")
- end
-
- def __map_diffs(diffs, klass = Diff::LCS::Change)
- diffs.map do |chunks|
- chunks.map { |changes| klass.from_a(*changes) }
- end
- end
-
- def __simple_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_el
- @matched_b << event.new_el
- end
-
- def discard_b(event)
- @discards_b << event.new_el
- end
-
- def discard_a(event)
- @discards_a << event.old_el
- end
-
- def finished_a(event)
- @done_a << [event.old_el, event.old_ix]
- end
-
- def finished_b(event)
- @done_b << [event.new_el, event.new_ix]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M#{event.old_ix}#{event.new_ix} "
- end
-
- def discard_a(event)
- @result << "DA#{event.old_ix}#{event.new_ix} "
- end
-
- def discard_b(event)
- @result << "DB#{event.old_ix}#{event.new_ix} "
- end
-
- def change(event)
- @result << "C#{event.old_ix}#{event.new_ix} "
- end
- end
- cb.reset
- cb
- end
-
- def setup
- @seq1 = %w(a b c e h j l m n p)
- @seq2 = %w(b c d e f j k l m r s t)
-
- @correct_lcs = %w(b c e j l m)
-
- @skipped_seq1 = 'a h n p'
- @skipped_seq2 = 'd f k r s t'
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '-', 9, 'p' ],
- [ '+', 9, 'r' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
- end
-end
-
-class TestLCS < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct_lcs.size)
- res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
- assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
- assert_equal(@correct_lcs, ares.compact)
- assert_equal(@correct_lcs, bres.compact)
- assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
- assert_equal(res.compact, @correct_lcs)
- end
-end
-
-class TestSequences < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __simple_callbacks
- class << callbacks
- undef :finished_a
- undef :finished_b
- end
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_nothing_raised do
- callbacks = __simple_callbacks
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
-
-# seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
-# assert_nothing_raised do
-# callbacks = __simple_callbacks
-# class << callbacks
-# undef :finished_a
-# undef :finished_b
-# end
-# Diff::LCS.traverse_sequences(seqw, [], callbacks)
-# end
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
- assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
- assert_equal(@correct_diff, diff)
- end
-
- def test_diff_empty
- seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
- correct_diff = [
- [ [ '-', 0, 'abcd' ],
- [ '-', 1, 'efgh' ],
- [ '-', 2, 'ijkl' ],
- [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
- diff = nil
-
- assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
-
- correct_diff = [
- [ [ '+', 0, 'abcd' ],
- [ '+', 1, 'efgh' ],
- [ '+', 2, 'ijkl' ],
- [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
- assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
- end
-end
-
-class TestBalanced < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sdiff_a
- sdiff = nil
- seq1 = %w(abc def yyy xxx ghi jkl)
- seq2 = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- [ 'u', 'abc', 'abc' ],
- [ '!', 'def', 'dxf' ],
- [ '-', 'yyy', nil ],
- [ 'u', 'xxx', 'xxx' ],
- [ 'u', 'ghi', 'ghi' ],
- [ 'u', 'jkl', 'jkl' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ 'u', 'b', 'b' ],
- [ 'u', 'c', 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ],
- [ '!', 'h', 'f' ],
- [ 'u', 'j', 'j' ],
- [ '+', nil, 'k' ],
- [ 'u', 'l', 'l' ],
- [ 'u', 'm', 'm' ],
- [ '!', 'n', 'r' ],
- [ '!', 'p', 's' ],
- [ '+', nil, 't' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- seq1 = %w(a b c d e)
- seq2 = %w(a e)
- correct_sdiff = [
- [ 'u', 'a', 'a' ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ],
- [ '-', 'd', nil ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- seq1 = %w(v x a e)
- seq2 = %w(w y a b c d e)
- correct_sdiff = [
- [ '!', 'v', 'w' ],
- [ '!', 'x', 'y' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- seq1 = %w(x a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '-', 'x', nil ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(x a b c d e)
- correct_sdiff = [
- [ '+', nil, 'x' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- seq1 = %w(a e v)
- seq2 = %w(x a b c d e w x)
- correct_sdiff = [
- [ '+', nil, 'x' ],
- [ 'u', 'a', 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ],
- [ '+', nil, 'd' ],
- [ 'u', 'e', 'e' ],
- [ '!', 'v', 'w' ],
- [ '+', nil, 'x' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- seq1 = %w()
- seq2 = %w(a b c)
- correct_sdiff = [
- [ '+', nil, 'a' ],
- [ '+', nil, 'b' ],
- [ '+', nil, 'c' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w()
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(1)
- correct_sdiff = [
- [ '!', 'a', '1' ],
- [ '-', 'b', nil ],
- [ '-', 'c', nil ] ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(c)
- correct_sdiff = [
- [ '-', 'a', nil ],
- [ '-', 'b', nil ],
- [ 'u', 'c', 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_m
- sdiff = nil
- seq1 = %w(abcd efgh ijkl mnop)
- seq2 = []
- correct_sdiff = [
- [ '-', 'abcd', nil ],
- [ '-', 'efgh', nil ],
- [ '-', 'ijkl', nil ],
- [ '-', 'mnop', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_sdiff_n
- sdiff = nil
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnop)
- correct_sdiff = [
- [ '+', nil, 'abcd' ],
- [ '+', nil, 'efgh' ],
- [ '+', nil, 'ijkl' ],
- [ '+', nil, 'mnop' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff[0], sdiff)
- end
-
- def test_balanced_a
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 M22 ", callback.result)
- end
-
- def test_balanced_b
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 DB21 M22 ", callback.result)
- end
-
- def test_balanced_c
- seq1 = %w(a x y c)
- seq2 = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 C22 M33 ", callback.result)
- end
-
- def test_balanced_d
- seq1 = %w(x y c)
- seq2 = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 M22 ", callback.result)
- end
-
- def test_balanced_e
- seq1 = %w(a x y z)
- seq2 = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 DA33 ", callback.result)
- end
-
- def test_balanced_f
- seq1 = %w(a z)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 ", callback.result)
- end
-
- def test_balanced_g
- seq1 = %w(z a)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 M10 ", callback.result)
- end
-
- def test_balanced_h
- seq1 = %w(a b c)
- seq2 = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 ", callback.result)
- end
-
- def test_balanced_i
- seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- seq2 = []
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
- end
-
- def test_balanced_j
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
- end
-end
diff --git a/diff-lcs/tags/release-1.0/ChangeLog b/diff-lcs/tags/release-1.0/ChangeLog
deleted file mode 100644
index 06c33d4..0000000
--- a/diff-lcs/tags/release-1.0/ChangeLog
+++ /dev/null
@@ -1,5 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.0/Install b/diff-lcs/tags/release-1.0/Install
deleted file mode 100644
index f359da0..0000000
--- a/diff-lcs/tags/release-1.0/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.0.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.0/README b/diff-lcs/tags/release-1.0/README
deleted file mode 100644
index 7bb69c1..0000000
--- a/diff-lcs/tags/release-1.0/README
+++ /dev/null
@@ -1,65 +0,0 @@
-Diff::LCS README
-================
-This is the 1.0 release of Diff::LCS for Ruby, based originally on Perl's
-Algorithm::Diff[1]. It uses the McIlroy-Hunt longest common subsequence (LCS)
-algorithm to compute intelligent differences between two sequenced enumerable
-containers[2]. The implementation is based on Mario I. Wolczko's[3] Smalltalk
-version (1.2, 1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String
-will be extended for use this way.
-
-Copyright
-=========
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the orderr of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.0/diff b/diff-lcs/tags/release-1.0/diff
deleted file mode 100644
index 953094d..0000000
--- a/diff-lcs/tags/release-1.0/diff
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/user/bin/env ruby
-# = Diff::LCS 1.0
-# == diff Usage
-# diff [options] oldfile newfile
-#
-# -c:: Displays a context diff with 3 lines of context.
-# -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
-# -u:: Displays a unified diff with 3 lines of context.
-# -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
-# -e:: Creates an 'ed' script to change oldfile to newfile.
-# -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
-# -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
-# --binary:: Treats the files as binary.
-# -q, --brief:: Reports only whether or not the files differ, not the details.
-# --help:: Shows the command-line help.
-# --version:: Shows the version of Diff::LCS.
-#
-# By default, runs produces an "old-style" diff, with output like UNIX diff.
-#
-# == Copyright
-# Copyright &copy; 2004 Austin Ziegler
-#
-# Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
-# Austin Ziegler <diff-lcs@halostatue.ca>
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-
-require 'optparse'
-require 'ostruct'
-require 'diff/lcs'
-require 'diff/lcs/hunk'
-
-module Diff
- BANNER = <<-COPYRIGHT
-diff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def diffprog(args, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- end
- end
-
- output << oldhunk.diff(@format)
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
-
-if __FILE__ == $0
- exit Diff::diffprog(ARGV, $stdout, $stderr)
-end
diff --git a/diff-lcs/tags/release-1.0/diff-lcs.gemspec b/diff-lcs/tags/release-1.0/diff-lcs.gemspec
deleted file mode 100644
index ba17d3d..0000000
--- a/diff-lcs/tags/release-1.0/diff-lcs.gemspec
+++ /dev/null
@@ -1,44 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.0.0}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
- s.platform = Gem::Platform::RUBY
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-
- s.required_ruby_version = %(0.0.0)
-
- s.executables = %w(diff htmldiff)
- s.bindir = %(bin)
- s.default_executable = %(diff)
-
- s.test_suite_file = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- s.bindir = %{bin}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-end
diff --git a/diff-lcs/tags/release-1.0/diff.bat b/diff-lcs/tags/release-1.0/diff.bat
deleted file mode 100644
index 361e045..0000000
--- a/diff-lcs/tags/release-1.0/diff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-REM --
-REM Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-REM adapted from:
-REM Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-REM Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-REM implements McIlroy-Hunt diff algorithm
-REM
-REM This program is free software. It may be redistributed and/or modified under
-REM the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-REM Ruby licence.
-REM
-REM $Id$
-REM ++
-if "%OS%"=="Windows_NT" goto WinNT
-ruby -x "diff" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-ruby -x "diff" %*
-goto done
-:done
diff --git a/diff-lcs/tags/release-1.0/htmldiff b/diff-lcs/tags/release-1.0/htmldiff
deleted file mode 100644
index 8ad9e95..0000000
--- a/diff-lcs/tags/release-1.0/htmldiff
+++ /dev/null
@@ -1,104 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/string'
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.0/htmldiff.bat b/diff-lcs/tags/release-1.0/htmldiff.bat
deleted file mode 100644
index 1432736..0000000
--- a/diff-lcs/tags/release-1.0/htmldiff.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-@echo off
-REM --
-REM Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-REM adapted from:
-REM Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-REM Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-REM implements McIlroy-Hunt diff algorithm
-REM
-REM This program is free software. It may be redistributed and/or modified under
-REM the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-REM Ruby licence.
-REM
-REM $Id$
-REM ++
-if "%OS%"=="Windows_NT" goto WinNT
-ruby -x "htmldiff" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-ruby -x "htmldiff" %*
-goto done
-:done
diff --git a/diff-lcs/tags/release-1.0/install.rb b/diff-lcs/tags/release-1.0/install.rb
deleted file mode 100644
index 0ed8e45..0000000
--- a/diff-lcs/tags/release-1.0/install.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-##
-# Install utility for HaloStatue scripts and libraries. Based heavily on the
-# original RDoc installation script by Pragmatic Programmers.
-#
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-require 'test/unit/ui/console/testrunner'
-
-InstallOptions = OpenStruct.new
-
- # Set these values to what you want installed.
-bins = %w{bin/**/*}
-rdoc = %w{bin/**/*.rb lib/**/*.rb README ChangeLog Install}
-ri = %w(bin/**/*.rb lib/**/*.rb)
-libs = %w{lib/**/*.rb}
-tests = %w{tests/**/*.rb}
-
-def do_bins(bins, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--no-rdoc', FalseClass,
- 'Prevents the creation of RDoc output.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--no-ri', FalseClass,
- 'Prevents the creation of RI output.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--no-tests', FalseClass,
- 'Prevents the execution of nit tests.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers", "--show-hash"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(%w{--ri-site --line-numbers --show-hash} + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-end
-
-def run_tests(test_list)
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file)
- tmp_dir = nil
- BinDirs.each do |t|
- stat = File.stat(t) rescue next
- if stat.directory? and stat.writable?
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot finda temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- opfile += ".rb" if Config::CONFIG["target_os"] =~ /win/
- FileUtils.install(tmp_file, File.join(TargetBinDir, opfile), 0755, true)
- FileUtils.unlink(tmp_file)
-end
-
-def glob(list)
- g = []
- list.each { |i| g << Dir.glob(i) }
- g.flatten!
- g.compact!
- g
-end
-
-prepare_installation
-
-bins = glob(bins)
-rdoc = glob(rdoc)
-ri = glob(ri)
-libs = glob(libs)
-tests = glob(tests)
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins)
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs.rb
deleted file mode 100644
index 53ebd33..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs.rb
+++ /dev/null
@@ -1,758 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.0
- # Computes "intelligent" differences between two ordered Enumerables. This
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
- # objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version (1.2,
- # 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Default extensions are provided for Array and String objects through the
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- # I once read an article written by the authors of +diff+; they said that
- # they hard worked very hard on the algorithm until they found the right
- # one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the secend sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # === Key Generation
- # The Perl version accepts an optional hash-key generation code reference
- # because all comparisons are done stringwise. This is not necessary for
- # Ruby, as the spaceship operator (<=>) should be provided on classes that
- # may be present in an ordered Enumerable.
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written by Mark-Jason Dominus
- # <mjd-perl-diff@plover.com>. The basic Ruby implementation was reported
- # from the Smalltalk implementation, available at
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # +sdiff+ and +traverse_balanced+ were written for the Perl version by
- # Mike Schilli <m@perlmeister.com>.
- #
- # The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed.
- module LCS
- VERSION = '1.0' #:nodoc:
- end
-end
-
-require 'diff/lcs/event'
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns the Longest Common Subsequnce(s)
- # LCS returns an Array containing the longest common subsequence between
- # +self+ and +other+.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- def traverse_sequences(other)
- traverse_sequences(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def traverse_balanced(other)
- traverse_balanced(self, other, Diff::LCS::YieldingCallbacks)
- end
-
- def patch(diffs)
- Diff::LCS::patch(self, diffs)
- end
-end
-
-module Diff::LCS
- class << self
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # Compute the longest common subsequence between the ordered Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection.
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Given two ordered Enumerables, LCS returns an Array containing their
- # longest common subsequence.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- def LCS(a, b, &block) #:yields self[ii] if there are matched subsequences:
- matches = Diff::LCS.__lcs(a, b)
- ret = []
- matches.each_with_index do |e, ii|
- unless matches[ii].nil?
- ret << a[ii]
- yield a[ii] if block_given?
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes. The description is a list of +hunks+;
- # each hunk represents a contiguous section of items which should be
- # added, deleted, or replaced. The return value of +diff+ is an Array
- # of hunks.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # [ [ [ :-, 0, 'a' ] ],
- # # [ [ :+, 2, 'd' ] ],
- # # [ [ :-, 4, 'h' ],
- # # [ :+, 4, 'f' ] ],
- # # [ [ :+, 6, 'k' ] ],
- # # [ [ :-, 8, 'n' ],
- # # [ :-, 9, 'p' ],
- # # [ :+, 9, 'r' ],
- # # [ :+, 10, 's' ],
- # # [ :+, 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at
- # position 0 of the first sequence should be deleted (<tt>:-</tt>).
- # The second hunk says that the +d+ at position 2 of the second
- # sequence should be inserted (<tt>:+</tt>). The third hunk says that
- # the +h+ at position 4 of the first sequence should be removed and
- # replaced with the +f+ from position 4 of the second sequence. The
- # other two hunks similarly.
- def diff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::DiffCallbacks.new
- traverse_sequences(a, b, callbacks)
- callbacks.match(nil)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # It returns an Array of Arrays that contain display instructions.
- # Display instructions consist of three elements: A modifier indicator
- # (<tt>:+</tt>: Element added, <tt>:-</tt>: Element removed, +u+:
- # Element unmodified, +c+: Element changed) and the value of the old
- # and new elements, to be displayed side by side.
- #
- # sdiffs = Diff::LCS.sdiff(seq1, seq2)
- # # [ [ '-', 'a', '' ],
- # # [ 'u', 'b', 'b' ],
- # # [ 'u', 'c', 'c' ],
- # # [ '+', '', 'd' ],
- # # [ 'u', 'e', 'e' ],
- # # [ 'c', 'h', 'f' ],
- # # [ 'u', 'j', 'j' ],
- # # [ '+', '', 'k' ],
- # # [ 'u', 'l', 'l' ],
- # # [ 'u', 'm', 'm' ],
- # # [ 'c', 'n', 'r' ],
- # # [ 'c', 'p', 's' ],
- # # [ '+', '', 't' ] ]
- def sdiff(a, b, callbacks = nil, &block)
- callbacks ||= Diff::LCS::SDiffCallbacks.new
- traverse_balanced(a, b, callbacks)
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # Imagine that there are two arrows. Arrow A points to an element of
- # sequence A, and arrow B points to an element of the sequence B.
- # Initially, the arrows point to the first elements of the respective
- # sequences. +traverse_sequences+ will advance the arrows through the
- # sequences one element at a time, calling an appropriate
- # user-specified callback function before each advance. It will
- # advance the arrows in such a way that if there are equal elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt> which are equal and which are part
- # of the LCS, there will be some moment during the execution of
- # +traverse_sequences+ when arrow A is pointing to <tt>A[ii]</tt> and
- # arrow B is pointing to <tt>B[jj]</tt>. When this happens,
- # +traverse_sequences+ will call the <tt>:match</tt> lambda and then
- # it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its
- # sequence that is not part of the LCS. +traverse_sequences+ will
- # advance that arrow and will call the <tt>:discard_a</tt> or the
- # <tt>:discard_b</tt> lambdas, depending on which arrow it advanced.
- # If both arrows point to elements that are not part of the LCS, then
- # +traverse_sequences+ will advance one of them and call the
- # appropriate callback, but it is not specified which it will call.
- #
- # The arguments to +traverse_sequences+ are the two sequences to
- # traverse, and a hash which specifies the lambdas, like this:
- #
- # traverse_sequences(seq1, seq2,
- # :match => callback_1,
- # :discard_a => callback_2,
- # :discard_b => callback_3)
- #
- # The lambdas for <tt>:match</tt>, <tt>:discard_a</tt>, and
- # <tt>:discard_b</tt> are invoked with the indices of the two arrows
- # as their arguments and are not expected to return any values.
- #
- # If arrow A reaches the end of its sequence before arrow B does,
- # +traverse_sequences+ will call the <tt>:a_finished</tt> lambda with
- # the last index in A. If <tt>:a_finished</tt> does not exist, then
- # <tt>:discard_b</tt> will be called until the end of the B sequence.
- # If B terminates before A, then <tt>:b_finished</tt> or
- # <tt>:discard_a</tt> will be called.
- #
- # Omitted callbacks are not called.
- #
- def traverse_sequences(a, b, callbacks = Diff::LCS::SequenceCallbacks)
- matches = Diff::LCS.__lcs(a, b)
-
- run_finished_a = run_finished_b = false
- string = a.kind_of?(String)
-
- a_size = a.size
- b_size = b.size
- ai = bj = 0
-
- (0 ... matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? a[ii, 1] : a[ii]
- bx = string ? b[bj, 1] : b[bj]
-
- if b_line.nil?
- event = Diff::LCS::Event.new(:discard_a, ax, ii, bx, bj)
- callbacks.discard_a(event)
- else
- loop do
- break unless bj < b_line
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ii, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:match, ax, ii, bx, bj)
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? a[-1, 1] : a[-1]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:finished_a, ax, a_size - 1, bx, bj)
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? a[ai, 1] : a[ai]
- loop do
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[-1, 1] : b[-1]
- event = Diff::LCS::Event.new(:finished_b, ax, ai, bx, b_size - 1)
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? b[bj, 1] : b[bj]
- loop do
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # +traverse_balanced+ is an alternative to +traverse_sequences+. It
- # uses a different algorithm to iterate through the entries in the
- # computed LCS. Instead of sticking to one side and showing element
- # changes as insertions and deletions only, it will jump back and
- # forth between the two sequences and report <em>changes</em>
- # occurring as deletions on one side followed immediatly by an
- # insertion on the other side.
- #
- # In addition to the <tt>:discard_a</tt>, <tt>:discard_b</tt>, and
- # <tt>:match</tt> callbacks supported by +traverse_sequences+,
- # +traverse_balanced+ supports a <tt>:change</tt> callback indicating
- # that one element got +replaced+ by another:
- #
- # traverse_sequences(seq1, seq2,
- # :match => $callback_1,
- # :discard_a => $callback_2,
- # :discard_b => $callback_3,
- # :change => $callback_4,)
- #
- # If no <tt>:change</tt> callback is specified, +traverse_balanced+
- # will map <tt>:change</tt> events to <tt>:discard_a</tt> and
- # <tt>:discard_b</tt> actions, therefore resulting in a similar
- # behaviour as +traverse_sequences+ with different order of events.
- #
- # +traverse_balanced+ might be a bit slower than +traverse_sequences+,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # +traverse_balanced+.
- def traverse_balanced(a, b, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(a, b)
- a_size = a.size
- b_size = b.size
- ai = bj = mb = 0
- ma = -1
- string = a.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(s)
- while (ai < ma) or (bj < mb)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, ax, ai, bx, bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
- event = Diff::LCS::Event.new(:discard_a, ax, ai, bx, bj)
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? a[ai, 1] : a[ai]
- bx = string ? b[bj, 1] : b[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::Event.new(:change, ax, ai, bx, bj)
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- ax = string ? a[ai, 1] : a[ai]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::Event.new(:discard_a, a[ai], ai, b[bj], bj)
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::Event.new(:discard_b, a[ai], ai, b[bj], bj)
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- def __diff_direction(src, diffs)
- left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- diffs.each do |change|
- text = string ? src[change.position, 1] : src[change.position]
- case change.action
- when :-
- if text == change.text
- left += 1
- else
- left_miss += 1
- end
- when :+
- if text == change.text
- right += 1
- else
- right_miss += 1
- end
- end
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided diff does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Given a set of diffs, convert the current version to the new version.
- def patch(src, diffs, direction = nil)
- diffs = diffs.flatten
- direction = Diff::LCS.__diff_direction(src, diffs) if direction.nil?
- string = src.kind_of?(String)
-
- n = src.class.new
- ai = bj = 0
-
- uses_splat = true
-
- diffs.each do |change|
- action = change.action
-
- if direction == :unpatch
- case action
- when :-
- action = :+
- when :+
- action = :-
- end
- end
-
- case action
- when :- # Delete
- while ai < change.position
- n << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += (change.text.kind_of?(String) ? 1 : change.text.size)
- when :+ # Insert
- while bj < change.position
- n << (string ? src[ai, 1]: src[ai])
- ai += 1
- bj += 1
- end
-
- if change.text.kind_of?(String)
- n << change.text
- else
- n.push(*change.text)
- end
-
- bj += (change.text.kind_of?(String) ? 1 : change.text.size)
- end
- end
-
- n
- end
-
- # Given a set of diffs, convert the current version to the prior
- # version.
- def unpatch(diffs)
- patch(diffs, :unpatch)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/array.rb
deleted file mode 100644
index fea3edc..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/block.rb
deleted file mode 100644
index 7ffdbab..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/diff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index eb0be60..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/change'
-
-class Diff::LCS::SequenceCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::BalancedCallbacks #:nodoc:
- class << self
- def match(event)
- event
- end
- def discard_a(event)
- event
- end
- def discard_b(event)
- event
- end
- end
-end
-
-class Diff::LCS::DiffCallbacks #:nodoc:
- attr_accessor :hunk
- attr_accessor :diffs
-
- def initialize
- @hunk = []
- @diffs = []
- end
-
- def match(event)
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_ix, event.old_el)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_ix, event.new_el)
- end
-end
-
-class Diff::LCS::SDiffCallbacks #:nodoc:
- attr_accessor :diffs
-
- def initialize
- @diffs = []
- end
-
- def match(event)
- @diffs << Diff::LCS::Change.new('u', event.old_el, event.new_el)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::Change.new('-', event.old_el, nil)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::Change.new('+', nil, event.new_el)
- end
-
- def change(event)
- @diffs << Diff::LCS::Change.new('!', event.old_el, event.new_el)
- end
-end
-
-class Diff::LCS::YieldingCallbacks #:nodoc:
- class << self
- def method_missing(symbol, *args)
- yield args if block_given?
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/change.rb
deleted file mode 100644
index a472f26..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Change
- attr_reader :action, :position, :text
-
- include Comparable
-
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.text == other.text)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.text <=> other.text if r.zero?
- r
- end
-
- def initialize(action, position, text)
- @action = action
- @position = position
- @text = text
- end
-
- def to_a
- [@action, @position, @text]
- end
-
- def self.from_a(*arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- def deleting?
- @action == :-
- end
-
- def adding?
- @action == :+
- end
-
- def unchanged?
- @action == :u
- end
-
- def changed?
- @changed == :c
- end
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/event.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/event.rb
deleted file mode 100644
index daa2414..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/event.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-class Diff::LCS::Event
- attr_reader :code
- attr_reader :old_el
- attr_reader :old_ix
- attr_reader :new_el
- attr_reader :new_ix
-
- def initialize(code, a, ai, b, bi)
- @code = code
- @old_el = a
- @old_ix = ai
- @new_el = b
- @new_ix = bi
- end
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/hunk.rb
deleted file mode 100644
index c57e4ba..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.0/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.0/lib/diff/lcs/string.rb
deleted file mode 100644
index 96a01fe..0000000
--- a/diff-lcs/tags/release-1.0/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-require 'diff/array'
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.0/tests/00test.rb b/diff-lcs/tags/release-1.0/tests/00test.rb
deleted file mode 100644
index e2613d5..0000000
--- a/diff-lcs/tags/release-1.0/tests/00test.rb
+++ /dev/null
@@ -1,431 +0,0 @@
-#! /usr/bin/env ruby
-#
-$:.unshift '../lib' if __FILE__ == $0 # Make this library first!
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-if __FILE__ == $0
- class TestLCS < Test::Unit::TestCase
- def setup
- @a = %w(a b c e h j l m n p)
- @b = %w(b c d e f j k l m r s t)
-
- @correct = %w(b c e j l m)
- @skipped_a = "a h n p"
- @skipped_b = "d f k r s t"
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '+', 9, 'r' ],
- [ '-', 9, 'p' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff)
- end
-
- def __map_diffs(diffs)
- diffs.map do |chunks|
- chunks.map do |changes|
- Diff::LCS::Change.from_a(*changes)
- end
- end
- end
-
- def __make_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_el
- @matched_b << event.new_el
- end
-
- def discard_b(event)
- @discards_b << event.new_el
- end
-
- def discard_a(event)
- @discards_a << event.old_el
- end
-
- def finished_a(event)
- @done_a << [event.old_el, event.old_ix]
- end
-
- def finished_b(event)
- @done_b << [event.new_el, event.new_ix]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@a, @b) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct.size)
- assert_nothing_raised { ares = (0...res.size).map { |i| res[i] ? @a[i] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |i| res[i] ? @b[res[i]] : nil } }
- assert_equal(@correct, ares.compact)
- assert_equal(@correct, bres.compact)
- end
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __make_callbacks
- class << callbacks
- undef finished_a
- undef finished_b
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_sequences(@a, @b, callbacks) }
- assert_equal(@correct.size, callbacks.matched_a.size)
- assert_equal(@correct.size, callbacks.matched_b.size)
- assert_equal(@skipped_a, callbacks.discards_a.join(" "))
- assert_equal(@skipped_b, callbacks.discards_b.join(" "))
- assert_nothing_raised { callbacks = __make_callbacks }
- assert_nothing_raised { Diff::LCS.traverse_sequences(@a, @b, callbacks) }
- assert_equal(@correct.size, callbacks.matched_a.size)
- assert_equal(@correct.size, callbacks.matched_b.size)
- assert_equal(@skipped_a, callbacks.discards_a.join(" "))
- assert_equal(@skipped_b, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
- end
-
- def test_LCS
- res = nil
- assert_nothing_raised { res = Diff::LCS.LCS(@a, @b) }
- assert_equal(res.compact, @correct)
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@a, @b) }
- assert_equal(@correct_diff, diff)
- end
-
- def test_sdiff_a
- sdiff = nil
- a = %w(abc def yyy xxx ghi jkl)
- b = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- ['u', 'abc', 'abc'],
- ['!', 'def', 'dxf'],
- ['-', 'yyy', nil],
- ['u', 'xxx', 'xxx'],
- ['u', 'ghi', 'ghi'],
- ['u', 'jkl', 'jkl'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- ['-', 'a', nil],
- ['u', 'b', 'b'],
- ['u', 'c', 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'],
- ['!', 'h', 'f'],
- ['u', 'j', 'j'],
- ['+', nil, 'k'],
- ['u', 'l', 'l'],
- ['u', 'm', 'm'],
- ['!', 'n', 'r'],
- ['!', 'p', 's'],
- ['+', nil, 't'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@a, @b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- a = %w(a b c d e)
- b = %w(a e)
- correct_sdiff = [
- ['u', 'a', 'a' ],
- ['-', 'b', nil ],
- ['-', 'c', nil ],
- ['-', 'd', nil ],
- ['u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- a = %w(a e)
- b = %w(a b c d e)
- correct_sdiff = [
- ['u', 'a', 'a' ],
- ['+', nil, 'b' ],
- ['+', nil, 'c' ],
- ['+', nil, 'd' ],
- ['u', 'e', 'e' ] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- a = %w(v x a e)
- b = %w(w y a b c d e)
- correct_sdiff = [
- ['!', 'v', 'w' ],
- ['!', 'x', 'y' ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- a = %w(x a e)
- b = %w(a b c d e)
- correct_sdiff = [
- ['-', 'x', nil ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- a = %w(a e)
- b = %w(x a b c d e)
- correct_sdiff = [
- ['+', nil, 'x' ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'] ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- a = %w(a e v)
- b = %w(x a b c d e w x)
- correct_sdiff = [
- ['+', nil, 'x' ],
- ['u', 'a', 'a' ],
- ['+', nil, 'b'],
- ['+', nil, 'c'],
- ['+', nil, 'd'],
- ['u', 'e', 'e'],
- ['!', 'v', 'w'],
- ['+', nil, 'x']
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- a = %w()
- b = %w(a b c)
- correct_sdiff = [
- ['+', nil, 'a' ],
- ['+', nil, 'b' ],
- ['+', nil, 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- a = %w(a b c)
- b = %w()
- correct_sdiff = [
- ['-', 'a', nil ],
- ['-', 'b', nil ],
- ['-', 'c', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- a = %w(a b c)
- b = %w(1)
- correct_sdiff = [
- ['!', 'a', '1' ],
- ['-', 'b', nil ],
- ['-', 'c', nil ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- a = %w(a b c)
- b = %w(c)
- correct_sdiff = [
- ['-', 'a', nil ],
- ['-', 'b', nil ],
- ['u', 'c', 'c' ]
- ]
- correct_sdiff = __map_diffs([correct_sdiff])[0]
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(a, b) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M #{event.old_ix} #{event.new_ix}"
- end
-
- def discard_a(event)
- @result << "DA #{event.old_ix} #{event.new_ix}"
- end
-
- def discard_b(event)
- @result << "DB #{event.old_ix} #{event.new_ix}"
- end
-
- def change(event)
- @result << "C #{event.old_ix} #{event.new_ix}"
- end
- end
- cb.reset
- cb
- end
-
- def test_balanced_a
- a = %w(a b c)
- b = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0C 1 1M 2 2", callback.result)
- end
-
- def test_balanced_b
- a = %w(a b c)
- b = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0DA 1 1DB 2 1M 2 2", callback.result)
- end
-
- def test_balanced_c
- a = %w(a x y c)
- b = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0C 1 1C 2 2M 3 3", callback.result)
- end
-
- def test_balanced_d
- a = %w(x y c)
- b = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("C 0 0C 1 1M 2 2", callback.result)
- end
-
- def test_balanced_e
- a = %w(a x y z)
- b = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("C 0 0C 1 1C 2 2DA 3 3", callback.result)
- end
-
- def test_balanced_f
- a = %w(a z)
- b = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("M 0 0DA 1 1", callback.result)
- end
-
- def test_balanced_g
- a = %w(z a)
- b = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("DA 0 0M 1 0", callback.result)
- end
-
- def test_balanced_h
- a = %w(a b c)
- b = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(a, b, callback) }
- assert_equal("C 0 0C 1 1C 2 2", callback.result)
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.1.0/ChangeLog b/diff-lcs/tags/release-1.1.0/ChangeLog
deleted file mode 100644
index a9f012f..0000000
--- a/diff-lcs/tags/release-1.1.0/ChangeLog
+++ /dev/null
@@ -1,33 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.1.0
-* Eliminated the need for Diff::LCS::Event and removed it.
-* Added a contextual diff callback, Diff::LCS::ContextDiffCallback.
-* Implemented patching/unpatching for standard Diff callback output formats
- with both #diff and #sdiff.
-* Extensive documentation changes.
-
-== Diff::LCS 1.0.4
-* Fixed a problem with bin/ldiff output, especially for unified format.
- Newlines that should have been present weren't.
-* Changed the .tar.gz installer to generate Windows batch files if ones do not
- exist already. Removed the existing batch files as they didn't work.
-
-== Diff::LCS 1.0.3
-* Fixed a problem with #traverse_sequences where the first difference from the
- left sequence might not be appropriately captured.
-
-== Diff::LCS 1.0.2
-* Fixed an issue with ldiff not working because actions were changed from
- symbols to strings.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.1.0/Install b/diff-lcs/tags/release-1.1.0/Install
deleted file mode 100644
index 825629b..0000000
--- a/diff-lcs/tags/release-1.1.0/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.1.0.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.1.0/README b/diff-lcs/tags/release-1.1.0/README
deleted file mode 100644
index cf5156c..0000000
--- a/diff-lcs/tags/release-1.1.0/README
+++ /dev/null
@@ -1,76 +0,0 @@
-Diff::LCS README
-================
-Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt
-longest common subsequence (LCS) algorithm to compute intelligent
-differences between two sequenced enumerable containers[2]. The
-implementation is based on Mario I. Wolczko's[3] Smalltalk version (1.2,
-1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-This release is version 1.1.0 with the addition of new features,
-including the ability to #patch and #unpatch changes as well as a new
-contextual diff callback, Diff::LCS::ContextDiffCallbacks, that should
-improve the context sensitivity of patching.
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- seq2 == Diff::LCS.patch!(seq1, diffs)
- seq1 == Diff::LCS.unpatch!(seq2, diffs)
- seq2 == Diff::LCS.patch!(seq1, sdiff)
- seq1 == Diff::LCS.unpatch!(seq2, sdiff)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = seq1.traverse_sequences(seq2, callback_obj)
- bal = seq1.traverse_balanced(seq2, callback_obj)
- seq2 == seq1.patch!(diffs)
- seq1 == seq2.unpatch!(diffs)
- seq2 == seq1.patch!(sdiff)
- seq1 == seq2.unpatch!(sdiff)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will
-be extended for use this way.
-
-Copyright
-=========
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.1.0/diff-lcs.gemspec b/diff-lcs/tags/release-1.1.0/diff-lcs.gemspec
deleted file mode 100644
index 2e8d2b7..0000000
--- a/diff-lcs/tags/release-1.1.0/diff-lcs.gemspec
+++ /dev/null
@@ -1,42 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.1.0}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
- s.platform = Gem::Platform::RUBY
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
- s.default_executable = %(ldiff)
-
- s.test_suite_file = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/tags/release-1.1.0/htmldiff b/diff-lcs/tags/release-1.1.0/htmldiff
deleted file mode 100644
index 6140410..0000000
--- a/diff-lcs/tags/release-1.1.0/htmldiff
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.1.0"
- require 'diff/lcs/string'
-rescue LoadError
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.1.0/install.rb b/diff-lcs/tags/release-1.1.0/install.rb
deleted file mode 100644
index 5772e0b..0000000
--- a/diff-lcs/tags/release-1.1.0/install.rb
+++ /dev/null
@@ -1,264 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.1.0/ldiff b/diff-lcs/tags/release-1.1.0/ldiff
deleted file mode 100644
index 4525991..0000000
--- a/diff-lcs/tags/release-1.1.0/ldiff
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env ruby
-# = Diff::LCS 1.1.0
-# == ldiff Usage
-# ldiff [options] oldfile newfile
-#
-# -c:: Displays a context diff with 3 lines of context.
-# -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
-# -u:: Displays a unified diff with 3 lines of context.
-# -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
-# -e:: Creates an 'ed' script to change oldfile to newfile.
-# -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
-# -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
-# --binary:: Treats the files as binary.
-# -q, --brief:: Reports only whether or not the files differ, not the details.
-# --help:: Shows the command-line help.
-# --version:: Shows the version of Diff::LCS.
-#
-# By default, runs produces an "old-style" diff, with output like UNIX diff.
-#
-# == Copyright
-# Copyright &copy; 2004 Austin Ziegler
-#
-# Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
-# Austin Ziegler <diff-lcs@halostatue.ca>
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-
-require 'optparse'
-require 'ostruct'
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.1.0"
-rescue LoadError
- require 'diff/lcs'
-end
-
-require 'diff/lcs/hunk'
-
-module Diff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def diffprog(args, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
-
- output << oldhunk.diff(@format)
- output << "\n"
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
-
-exit Diff::diffprog(ARGV, $stdout, $stderr)
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs.rb b/diff-lcs/tags/release-1.1.0/lib/diff/lcs.rb
deleted file mode 100644
index 7740231..0000000
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs.rb
+++ /dev/null
@@ -1,1070 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.1.0
- # Computes "intelligent" differences between two sequenced Enumerables. This
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
- # objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version (1.2,
- # 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = seq1.traverse_sequences(seq2, callback_obj)
- # bal = seq1.traverse_balanced(seq2, callback_obj)
- #
- # Default extensions are provided for Array and String objects through the
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- #
- # <em>The following text is from the Perl documentation. The only changes
- # have been to make the text appear better in Rdoc</em>.
- #
- # I once read an article written by the authors of +diff+; they said that
- # they hard worked very hard on the algorithm until they found the right
- # one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the second sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993. Documentation includes work by Mark-Jason Dominus.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written originally by Mark-Jason
- # Dominus <mjd-perl-diff@plover.com> and later by Ned Konz. The basic Ruby
- # implementation was re-ported from the Smalltalk implementation, available
- # at ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # #sdiff and #traverse_balanced were written for the Perl version by Mike
- # Schilli <m@perlmeister.com>.
- #
- # "The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed."
- module LCS
- VERSION = '1.1.0'
- end
-end
-
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns an Array containing the longest common subsequence(s) between
- # +self+ and +other+. See Diff::LCS#LCS.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- # Returns the difference set between +self+ and +other+. See
- # Diff::LCS#diff.
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- # Returns the balanced ("side-by-side") difference set between +self+ and
- # +other+. See Diff::LCS#sdiff.
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- # Traverses the discovered longest common subsequences between +self+ and
- # +other+. See Diff::LCS#traverse_sequences.
- def traverse_sequences(other, callbacks = nil, &block)
- traverse_sequences(self, other, callbacks || Diff::LCS::YieldingCallbacks,
- &block)
- end
-
- # Traverses the discovered longest common subsequences between +self+ and
- # +other+ using the alternate, balanced algorithm. See
- # Diff::LCS#traverse_balanced.
- def traverse_balanced(other, callbacks = nil, &block)
- traverse_balanced(self, other, callbacks || Diff::LCS::YieldingCallbacks,
- &block)
- end
-
- # Attempts to patch +self+ with the provided +patchset+. See Diff::LCS#patch.
- def patch(patchset)
- Diff::LCS::patch(self, patchset)
- end
-
- # Attempts to unpatch +self+ with the provided +patchset+. See
- # Diff::LCS#patch!. Does no autodiscovery.
- def patch!(patchset)
- Diff::LCS::patch!(self, patchset)
- end
-
- # Attempts to unpatch +self+ with the provided +patchset+. See
- # Diff::LCS#unpatch. Does no autodiscovery.
- def unpatch!(patchset)
- Diff::LCS::unpatch!(self, patchset)
- end
-end
-
-module Diff::LCS
- class << self
- # Given two sequenced Enumerables, LCS returns an Array containing their
- # longest common subsequences.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- #
- # This array whose contents is such that:
- #
- # lcs.each_with_index do |ee, ii|
- # assert(ee.nil? || (seq1[ii] == seq2[ee]))
- # end
- #
- # If a block is provided, the matching subsequences will be yielded from
- # +seq1+ in turn and may be modified before they are placed into the
- # returned Array of subsequences.
- def LCS(seq1, seq2, &block) #:yields seq1[ii] for each matched:
- matches = Diff::LCS.__lcs(seq1, seq2)
- ret = []
- matches.each_with_index do |ee, ii|
- unless matches[ii].nil?
- if block_given?
- ret << (yield seq1[ii])
- else
- ret << seq1[ii]
- end
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes.
- #
- # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate
- # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If
- # a Class argument is provided for +callbacks+, #diff will attempt to
- # initialise it. If the +callbacks+ object (possibly initialised)
- # responds to #finish, it will be called.
- def diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
- callbacks ||= Diff::LCS::DiffCallbacks
- callbacks = callbacks.new if callbacks.kind_of?(Class)
- traverse_sequences(seq1, seq2, callbacks)
- callbacks.finish if callbacks.respond_to?(:finish)
-
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # old < -
- # same same
- # before | after
- # - > new
- #
- # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate
- # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If
- # a Class argument is provided for +callbacks+, #diff will attempt to
- # initialise it. If the +callbacks+ object (possibly initialised)
- # responds to #finish, it will be called.
- def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
- callbacks ||= Diff::LCS::SDiffCallbacks
- callbacks = callbacks.new if callbacks.kind_of?(Class)
- traverse_balanced(seq1, seq2, callbacks)
- callbacks.finish if callbacks.respond_to?(:finish)
-
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # The arguments to #traverse_sequences are the two sequences to
- # traverse, and a callback object, like this:
- #
- # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
- #
- # #diff is implemented with #traverse_sequences.
- #
- # == Callback Methods
- # Optional callback methods are <em>emphasized</em>.
- #
- # callbacks#match:: Called when +a+ and +b+ are pointing
- # to common elements in +A+ and +B+.
- # callbacks#discard_a:: Called when +a+ is pointing to an
- # element not in +B+.
- # callbacks#discard_b:: Called when +b+ is pointing to an
- # element not in +A+.
- # <em>callbacks#finished_a</em>:: Called when +a+ has reached the end of
- # sequence +A+.
- # <em>callbacks#finished_b</em>:: Called when +b+ has reached the end of
- # sequence +B+.
- #
- # == Algorithm
- # a---+
- # v
- # A = a b c e h j l m n p
- # B = b c d e f j k l m r s t
- # ^
- # b---+
- #
- # If there are two arrows (+a+ and +b+) pointing to elements of
- # sequences +A+ and +B+, the arrows will initially point to the first
- # elements of their respective sequences. #traverse_sequences will
- # advance the arrows through the sequences one element at a time,
- # calling a method on the user-specified callback object before each
- # advance. It will advance the arrows in such a way that if there are
- # elements <tt>A[ii]</tt> and <tt>B[jj]</tt> which are both equal and
- # part of the longest common subsequence, there will be some moment
- # during the execution of #traverse_sequences when arrow +a+ is pointing
- # to <tt>A[ii]</tt> and arrow +b+ is pointing to <tt>B[jj]</tt>. When
- # this happens, #traverse_sequences will call <tt>callbacks#match</tt>
- # and then it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its sequence
- # that is not part of the longest common subsequence.
- # #traverse_sequences will advance that arrow and will call
- # <tt>callbacks#discard_a</tt> or <tt>callbacks#discard_b</tt>, depending
- # on which arrow it advanced. If both arrows point to elements that are
- # not part of the longest common subsequence, then #traverse_sequences
- # will advance one of them and call the appropriate callback, but it is
- # not specified which it will call.
- #
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
- # and <tt>callbacks#discard_b</tt> are invoked with an event comprising
- # the action ("=", "+", or "-", respectively), the indicies +ii+ and
- # +jj+, and the elements <tt>A[ii]</tt> and <tt>B[jj]</tt>. Return
- # values are discarded by #traverse_sequences.
- #
- # === End of Sequences
- # If arrow +a+ reaches the end of its sequence before arrow +b+ does,
- # #traverse_sequence try to call <tt>callbacks#finished_a</tt> with the
- # last index and element of +A+ (<tt>A[-1]</tt>) and the current index
- # and element of +B+ (<tt>B[jj]</tt>). If <tt>callbacks#finished_a</tt>
- # does not exist, then <tt>callbacks#discard_b</tt> will be called on
- # each element of +B+ until the end of the sequence is reached (the call
- # will be done with <tt>A[-1]</tt> and <tt>B[jj]</tt> for each element).
- #
- # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+,
- # <tt>callbacks#finished_b</tt> will be called with the current index
- # and element of +A+ (<tt>A[ii]</tt>) and the last index and element of
- # +B+ (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not
- # exist on the callback object, then <tt>callbacks#discard_a</tt> will
- # be called on each element of +A+ until the end of the sequence is
- # reached (<tt>A[ii]</tt> and <tt>B[-1]</tt>).
- #
- # There is a chance that one additional <tt>callbacks#discard_a</tt> or
- # <tt>callbacks#discard_b</tt> will be called after the end of the
- # sequence is reached, if +a+ has not yet reached the end of +A+ or +b+
- # has not yet reached the end of +B+.
- def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks, &block) #:yields change events:
- matches = Diff::LCS.__lcs(seq1, seq2)
-
- run_finished_a = run_finished_b = false
- string = seq1.kind_of?(String)
-
- a_size = seq1.size
- b_size = seq2.size
- ai = bj = 0
-
- (0 .. matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? seq1[ii, 1] : seq1[ii]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- if b_line.nil?
- unless ax.nil?
- event = Diff::LCS::ContextChange.new('-', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- end
- else
- loop do
- break unless bj < b_line
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('=', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? seq1[-1, 1] : seq1[-1]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
- event = yield event if block_given?
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? seq1[ai, 1] : seq1[ai]
- loop do
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[-1, 1] : seq2[-1]
- event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
- event = yield event if block_given?
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? seq2[bj, 1] : seq2[bj]
- loop do
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # #traverse_balanced is an alternative to #traverse_sequences. It
- # uses a different algorithm to iterate through the entries in the
- # computed longest common subsequence. Instead of viewing the changes as
- # insertions or deletions from one of the sequences, #traverse_balanced
- # will report <em>changes</em> between the sequences. To represent a
- #
- # The arguments to #traverse_balanced are the two sequences to traverse
- # and a callback object, like this:
- #
- # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
- #
- # #sdiff is implemented with #traverse_balanced.
- #
- # == Callback Methods
- # Optional callback methods are <em>emphasized</em>.
- #
- # callbacks#match:: Called when +a+ and +b+ are pointing
- # to common elements in +A+ and +B+.
- # callbacks#discard_a:: Called when +a+ is pointing to an
- # element not in +B+.
- # callbacks#discard_b:: Called when +b+ is pointing to an
- # element not in +A+.
- # <em>callbacks#change</em>:: Called when +a+ and +b+ are pointing
- # to the same relative position, but
- # <tt>A[a]</tt> and <tt>B[b]</tt> are
- # not the same; a <em>change</em> has
- # occurred.
- #
- # #traverse_balanced might be a bit slower than #traverse_sequences,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # #traverse_balanced.
- #
- # == Algorithm
- # a---+
- # v
- # A = a b c e h j l m n p
- # B = b c d e f j k l m r s t
- # ^
- # b---+
- #
- # === Matches
- # If there are two arrows (+a+ and +b+) pointing to elements of
- # sequences +A+ and +B+, the arrows will initially point to the first
- # elements of their respective sequences. #traverse_sequences will
- # advance the arrows through the sequences one element at a time,
- # calling a method on the user-specified callback object before each
- # advance. It will advance the arrows in such a way that if there are
- # elements <tt>A[ii]</tt> and <tt>B[jj]</tt> which are both equal and
- # part of the longest common subsequence, there will be some moment
- # during the execution of #traverse_sequences when arrow +a+ is pointing
- # to <tt>A[ii]</tt> and arrow +b+ is pointing to <tt>B[jj]</tt>. When
- # this happens, #traverse_sequences will call <tt>callbacks#match</tt>
- # and then it will advance both arrows.
- #
- # === Discards
- # Otherwise, one of the arrows is pointing to an element of its sequence
- # that is not part of the longest common subsequence.
- # #traverse_sequences will advance that arrow and will call
- # <tt>callbacks#discard_a</tt> or <tt>callbacks#discard_b</tt>,
- # depending on which arrow it advanced.
- #
- # === Changes
- # If both +a+ and +b+ point to elements that are not part of the longest
- # common subsequence, then #traverse_sequences will try to call
- # <tt>callbacks#change</tt> and advance both arrows. If
- # <tt>callbacks#change</tt> is not implemented, then
- # <tt>callbacks#discard_a</tt> and <tt>callbacks#discard_b</tt> will be
- # called in turn.
- #
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
- # <tt>callbacks#discard_b</tt>, and <tt>callbacks#change</tt> are
- # invoked with an event comprising the action ("=", "+", "-", or "!",
- # respectively), the indicies +ii+ and +jj+, and the elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt>. Return values are discarded by
- # #traverse_balanced.
- #
- # === Context
- # Note that +ii+ and +jj+ may not be the same index position, even if
- # +a+ and +b+ are considered to be pointing to matching or changed
- # elements.
- def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(seq1, seq2)
- a_size = seq1.size
- b_size = seq2.size
- ai = bj = mb = 0
- ma = -1
- string = seq1.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(seq2)
- while (ai < ma) or (bj < mb)
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- PATCH_MAP = { #:nodoc:
- :patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' },
- :unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }
- }
-
- # Given a patchset, convert the current version to the new
- # version. If +direction+ is not specified (must be
- # <tt>:patch</tt> or <tt>:unpatch</tt>), then discovery of the
- # direction of the patch will be attempted.
- def patch(src, patchset, direction = nil)
- string = src.kind_of?(String)
- # Start with a new empty type of the source's class
- res = src.class.new
-
- # Normalize the patchset.
- patchset = __normalize_patchset(patchset)
-
- direction ||= Diff::LCS.__diff_direction(src, patchset)
- direction ||= :patch
-
- ai = bj = 0
-
- patchset.each do |change|
- # Both Change and ContextChange support #action
- action = PATCH_MAP[direction][change.action]
-
- case change
- when Diff::LCS::ContextChange
- case direction
- when :patch
- el = change.new_element
- op = change.old_position
- np = change.new_position
- when :unpatch
- el = change.old_element
- op = change.new_position
- np = change.old_position
- end
-
- case action
- when '-' # Remove details from the old string
- while ai < op
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += 1
- when '+'
- while bj < np
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- res << el
- bj += 1
- when '='
- # This only appears in sdiff output with the SDiff callback.
- # Therefore, we only need to worry about dealing with a single
- # element.
- res << el
-
- ai += 1
- bj += 1
- when '!'
- while ai < op
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- bj += 1
- ai += 1
-
- res << el
- end
- when Diff::LCS::Change
- case action
- when '-'
- while ai < change.position
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += 1
- when '+'
- while bj < change.position
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- bj += 1
-
- res << change.element
- end
- end
- end
-
- res
- end
-
- # Given a set of patchset, convert the current version to the prior
- # version. Does no auto-discovery.
- def unpatch!(src, patchset)
- Diff::LCS.patch(src, patchset, :unpatch)
- end
-
- # Given a set of patchset, convert the current version to the next
- # version. Does no auto-discovery.
- def patch!(src, patchset)
- Diff::LCS.patch(src, patchset, :patch)
- end
-
-# private
- # Compute the longest common subsequence between the sequenced Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection. (Currently unused.)
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Examine the patchset and the source to see in which direction the
- # patch should be applied.
- #
- # WARNING: By default, this examines the whole patch, so this could take
- # some time. This also works better with Diff::LCS::ContextChange or
- # Diff::LCS::Change as its source, as an array will cause the creation
- # of one of the above.
- def __diff_direction(src, patchset, limit = nil)
- count = left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- patchset.each do |change|
- count += 1
-
- case change
- when Diff::LCS::Change
- # With a simplistic change, we can't tell the difference between
- # the left and right on '!' actions, so we ignore those. On '='
- # actions, if there's a miss, we miss both left and right.
- element = string ? src[change.position, 1] : src[change.position]
-
- case change.action
- when '-'
- if element == change.element
- left += 1
- else
- left_miss += 1
- end
- when '+'
- if element == change.element
- right += 1
- else
- right_miss += 1
- end
- when '='
- if element != change.element
- left_miss += 1
- right_miss += 1
- end
- end
- when Diff::LCS::ContextChange
- case change.action
- when '-' # Remove details from the old string
- element = string ? src[change.old_position, 1] : src[change.old_position]
- if element == change.old_element
- left += 1
- else
- left_miss += 1
- end
- when '+'
- element = string ? src[change.new_position, 1] : src[change.new_position]
- if element == change.new_element
- right += 1
- else
- right_miss += 1
- end
- when '='
- le = string ? src[change.old_position, 1] : src[change.old_position]
- re = string ? src[change.new_position, 1] : src[change.new_position]
-
- left_miss += 1 if le != change.old_element
- right_miss += 1 if re != change.new_element
- when '!'
- element = string ? src[change.old_position, 1] : src[change.old_position]
- if element == change.old_element
- left += 1
- else
- element = string ? src[change.new_position, 1] : src[change.new_position]
- if element == change.new_element
- right += 1
- else
- left_miss += 1
- right_miss += 1
- end
- end
- end
- end
-
- break if not limit.nil? and count > limit
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided patchset does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Normalize the patchset. A patchset is always a sequence of changes, but
- # how those changes are represented may vary, depending on how they were
- # generated. In all cases we support, we also support the array
- # representation of the changes. The formats are:
- #
- # [ # patchset <- Diff::LCS.diff(a, b)
- # [ # one or more hunks
- # Diff::LCS::Change # one or more changes
- # ] ]
- #
- # [ # patchset, equivalent to the above
- # [ # one or more hunks
- # [ action, line, value ] # one or more changes
- # ] ]
- #
- # [ # patchset <- Diff::LCS.diff(a, b, Diff::LCS::ContextDiffCallbacks)
- # # OR <- Diff::LCS.sdiff(a, b, Diff::LCS::ContextDiffCallbacks)
- # [ # one or more hunks
- # Diff::LCS::ContextChange # one or more changes
- # ] ]
- #
- # [ # patchset, equivalent to the above
- # [ # one or more hunks
- # [ action, [ old line, old value ], [ new line, new value ] ]
- # # one or more changes
- # ] ]
- #
- # [ # patchset <- Diff::LCS.sdiff(a, b)
- # # OR <- Diff::LCS.diff(a, b, Diff::LCS::SDiffCallbacks)
- # Diff::LCS::ContextChange # one or more changes
- # ]
- #
- # [ # patchset, equivalent to the above
- # [ action, [ old line, old value ], [ new line, new value ] ]
- # # one or more changes
- # ]
- #
- # The result of this will be either of the following.
- #
- # [ # patchset
- # Diff::LCS::ContextChange # one or more changes
- # ]
- #
- # [ # patchset
- # Diff::LCS::Change # one or more changes
- # ]
- #
- # If either of the above is provided, it will be returned as such.
- #
- def __normalize_patchset(patchset)
- patchset.map do |hunk|
- case hunk
- when Diff::LCS::ContextChange, Diff::LCS::Change
- hunk
- when Array
- if (not hunk[0].kind_of?(Array)) and hunk[1].kind_of?(Array) and hunk[2].kind_of?(Array)
- Diff::LCS::ContextChange.from_a(hunk)
- else
- hunk.map do |change|
- case change
- when Diff::LCS::ContextChange, Diff::LCS::Change
- change
- when Array
- # change[1] will ONLY be an array in a ContextChange#to_a call.
- # In Change#to_a, it represents the line (singular).
- if change[1].kind_of?(Array)
- Diff::LCS::ContextChange.from_a(change)
- else
- Diff::LCS::Change.from_a(change)
- end
- end
- end
- end
- else
- raise ArgumentError, "Cannot normalise a hunk of class #{hunk.class}."
- end
- end.flatten
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.1.0/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index a786daf..0000000
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,320 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains definitions for all default callback objects.
-
-require 'diff/lcs/change'
-
-module Diff::LCS
- # This callback object implements the default set of callback events, which
- # only returns the event itself. Note that #finished_a and #finished_b are
- # not implemented -- I haven't yet figured out where they would be useful.
- #
- # Note that this is intended to be called as is, e.g.,
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks)
- class DefaultCallbacks
- class << self
- # Called when two items match.
- def match(event)
- event
- end
- # Called when the old value is discarded in favour of the new value.
- def discard_a(event)
- event
- end
- # Called when the new value is discarded in favour of the old value.
- def discard_b(event)
- event
- end
- # Called when both the old and new values have changed.
- def change(event)
- event
- end
- end
- end
-
- # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_sequences.
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks)
- SequenceCallbacks = DefaultCallbacks
- # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_balanced.
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks)
- BalancedCallbacks = DefaultCallbacks
-end
-
- # This will produce a compound array of simple diff change objects. Each
- # element in the #diffs array is a +hunk+ or +hunk+ array, where each
- # element in each +hunk+ array is a single Change object representing the
- # addition or removal of a single element from one of the two tested
- # sequences. The +hunk+ provides the full context for the changes.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # This example shows a simplified array format.
- # # [ [ [ '-', 0, 'a' ] ], # 1
- # # [ [ '+', 2, 'd' ] ], # 2
- # # [ [ '-', 4, 'h' ], # 3
- # # [ '+', 4, 'f' ] ],
- # # [ [ '+', 6, 'k' ] ], # 4
- # # [ [ '-', 8, 'n' ], # 5
- # # [ '-', 9, 'p' ],
- # # [ '+', 9, 'r' ],
- # # [ '+', 10, 's' ],
- # # [ '+', 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at position 0
- # of the first sequence should be deleted (<tt>'-'</tt>). The second hunk
- # says that the +d+ at position 2 of the second sequence should be inserted
- # (<tt>'+'</tt>). The third hunk says that the +h+ at position 4 of the
- # first sequence should be removed and replaced with the +f+ from position 4
- # of the second sequence. The other two hunks are described similarly.
- #
- # === Use
- # This callback object must be initialised and is used by the Diff::LCS#diff
- # method.
- #
- # cbo = Diff::LCS::DiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- # cbo.finish
- #
- # Note that the call to #finish is absolutely necessary, or the last set of
- # changes will not be visible. Alternatively, can be used as:
- #
- # cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # The necessary #finish call will be made.
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.map { |f| f.to_a } }
-class Diff::LCS::DiffCallbacks
- # Returns the difference set collected during the diff process.
- attr_reader :diffs
-
- def initialize # :yields self:
- @hunk = []
- @diffs = []
-
- if block_given?
- begin
- yield self
- ensure
- self.finish
- end
- end
- end
-
- # Finalizes the diff process. If an unprocessed hunk still exists, then it
- # is appended to the diff list.
- def finish
- add_nonempty_hunk
- end
-
- def match(event)
- add_nonempty_hunk
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element)
- end
-
-private
- def add_nonempty_hunk
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-end
-
- # This will produce a compound array of contextual diff change objects. Each
- # element in the #diffs array is a "hunk" array, where each element in each
- # "hunk" array is a single change. Each change is a Diff::LCS::ContextChange
- # that contains both the old index and new index values for the change. The
- # "hunk" provides the full context for the changes. Both old and new objects
- # will be presented for changed objects. +nil+ will be substituted for a
- # discarded object.
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks)
- # # This example shows a simplified array format.
- # # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1
- # # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2
- # # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3
- # # [ '+', [ 5, nil ], [ 4, 'f' ] ] ],
- # # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4
- # # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5
- # # [ '+', [ 9, nil ], [ 9, 'r' ] ],
- # # [ '-', [ 9, 'p' ], [ 10, nil ] ],
- # # [ '+', [ 10, nil ], [ 10, 's' ] ],
- # # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ]
- #
- # The five hunks shown are comprised of individual changes; if there is a
- # related set of changes, they are still shown individually.
- #
- # This callback can also be used with Diff::LCS#sdiff, which will produce
- # results like:
- #
- # diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks)
- # # This example shows a simplified array format.
- # # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1
- # # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2
- # # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3
- # # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4
- # # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5
- # # [ "!", [ 9, "p" ], [ 10, "s" ] ],
- # # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ]
- #
- # The five hunks are still present, but are significantly shorter in total
- # presentation, because changed items are shown as changes ("!") instead of
- # potentially "mismatched" pairs of additions and deletions.
- #
- # The result of this operation is similar to that of
- # Diff::LCS::SDiffCallbacks. They may be compared as:
- #
- # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
- #
- # s == c # -> true
- #
- # === Use
- # This callback object must be initialised and can be used by the
- # Diff::LCS#diff or Diff::LCS#sdiff methods.
- #
- # cbo = Diff::LCS::ContextDiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- # cbo.finish
- #
- # Note that the call to #finish is absolutely necessary, or the last set of
- # changes will not be visible. Alternatively, can be used as:
- #
- # cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # The necessary #finish call will be made.
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.map { |f| f.to_a } }
-class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks
- def discard_a(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-
- def change(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-end
-
- # This will produce a simple array of diff change objects. Each element in
- # the #diffs array is a single ContextChange. In the set of #diffs provided
- # by SDiffCallbacks, both old and new objects will be presented for both
- # changed <strong>and unchanged</strong> objects. +nil+ will be substituted
- # for a discarded object.
- #
- # The diffset produced by this callback, when provided to Diff::LCS#sdiff,
- # will compute and display the necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix utility
- # +sdiff+.
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # diffs = Diff::LCS.sdiff(seq1, seq2)
- # # This example shows a simplified array format.
- # # [ [ "-", [ 0, "a"], [ 0, nil ] ],
- # # [ "=", [ 1, "b"], [ 0, "b" ] ],
- # # [ "=", [ 2, "c"], [ 1, "c" ] ],
- # # [ "+", [ 3, nil], [ 2, "d" ] ],
- # # [ "=", [ 3, "e"], [ 3, "e" ] ],
- # # [ "!", [ 4, "h"], [ 4, "f" ] ],
- # # [ "=", [ 5, "j"], [ 5, "j" ] ],
- # # [ "+", [ 6, nil], [ 6, "k" ] ],
- # # [ "=", [ 6, "l"], [ 7, "l" ] ],
- # # [ "=", [ 7, "m"], [ 8, "m" ] ],
- # # [ "!", [ 8, "n"], [ 9, "r" ] ],
- # # [ "!", [ 9, "p"], [ 10, "s" ] ],
- # # [ "+", [ 10, nil], [ 11, "t" ] ] ]
- #
- # The result of this operation is similar to that of
- # Diff::LCS::ContextDiffCallbacks. They may be compared as:
- #
- # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
- #
- # s == c # -> true
- #
- # === Use
- # This callback object must be initialised and is used by the Diff::LCS#sdiff
- # method.
- #
- # cbo = Diff::LCS::SDiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- #
- # As with the other initialisable callback objects, Diff::LCS::SDiffCallbacks
- # can be initialised with a block. As there is no "fininishing" to be done,
- # this has no effect on the state of the object.
- #
- # cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.to_a }
-class Diff::LCS::SDiffCallbacks
- # Returns the difference set collected during the diff process.
- attr_reader :diffs
-
- def initialize #:yields self:
- @diffs = []
- yield self if block_given?
- end
-
- def match(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def change(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-end
diff --git a/diff-lcs/tags/release-1.1.0/tests/00test.rb b/diff-lcs/tags/release-1.1.0/tests/00test.rb
deleted file mode 100644
index e603d39..0000000
--- a/diff-lcs/tags/release-1.1.0/tests/00test.rb
+++ /dev/null
@@ -1,595 +0,0 @@
-#! /usr/bin/env ruby
-#
-$:.unshift '../lib' if __FILE__ == $0 # Make this library first!
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-module Diff::LCS::Tests
- def __format_diffs(diffs)
- diffs.map do |e|
- if e.kind_of?(Array)
- e.map { |f| f.to_a.join }.join(", ")
- else
- e.to_a.join
- end
- end.join("; ")
- end
-
- def __map_diffs(diffs, klass = Diff::LCS::ContextChange)
- diffs.map do |chunks|
- if klass == Diff::LCS::ContextChange
- klass.from_a(chunks)
- else
- chunks.map { |changes| klass.from_a(changes) }
- end
- end
- end
-
- def __simple_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_element
- @matched_b << event.new_element
- end
-
- def discard_b(event)
- @discards_b << event.new_element
- end
-
- def discard_a(event)
- @discards_a << event.old_element
- end
-
- def finished_a(event)
- @done_a << [event.old_element, event.old_position]
- end
-
- def finished_b(event)
- @done_b << [event.new_element, event.new_position]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M#{event.old_position}#{event.new_position} "
- end
-
- def discard_a(event)
- @result << "DA#{event.old_position}#{event.new_position} "
- end
-
- def discard_b(event)
- @result << "DB#{event.old_position}#{event.new_position} "
- end
-
- def change(event)
- @result << "C#{event.old_position}#{event.new_position} "
- end
- end
- cb.reset
- cb
- end
-
- def setup
- @seq1 = %w(a b c e h j l m n p)
- @seq2 = %w(b c d e f j k l m r s t)
-
- @correct_lcs = %w(b c e j l m)
-
- @skipped_seq1 = 'a h n p'
- @skipped_seq2 = 'd f k r s t'
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '-', 9, 'p' ],
- [ '+', 9, 'r' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
- end
-end
-
-class TestLCS < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct_lcs.size)
- res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
- assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
- assert_equal(@correct_lcs, ares.compact)
- assert_equal(@correct_lcs, bres.compact)
- assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
- assert_equal(res.compact, @correct_lcs)
- end
-end
-
-class TestSequences < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __simple_callbacks
- class << callbacks
- undef :finished_a
- undef :finished_b
- end
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_nothing_raised do
- callbacks = __simple_callbacks
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
-
-# seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
-# assert_nothing_raised do
-# callbacks = __simple_callbacks
-# class << callbacks
-# undef :finished_a
-# undef :finished_b
-# end
-# Diff::LCS.traverse_sequences(seqw, [], callbacks)
-# end
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
- assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
- assert_equal(@correct_diff, diff)
- end
-
- def test_diff_empty
- seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
- correct_diff = [
- [ [ '-', 0, 'abcd' ],
- [ '-', 1, 'efgh' ],
- [ '-', 2, 'ijkl' ],
- [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
- diff = nil
-
- assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
-
- correct_diff = [
- [ [ '+', 0, 'abcd' ],
- [ '+', 1, 'efgh' ],
- [ '+', 2, 'ijkl' ],
- [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
- assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
- end
-end
-
-class TestBalanced < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sdiff_a
- sdiff = nil
- seq1 = %w(abc def yyy xxx ghi jkl)
- seq2 = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- [ '=', [ 0, 'abc' ], [ 0, 'abc' ] ],
- [ '!', [ 1, 'def' ], [ 1, 'dxf' ] ],
- [ '-', [ 2, 'yyy' ], [ 2, nil ] ],
- [ '=', [ 3, 'xxx' ], [ 2, 'xxx' ] ],
- [ '=', [ 4, 'ghi' ], [ 3, 'ghi' ] ],
- [ '=', [ 5, 'jkl' ], [ 4, 'jkl' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '=', [ 1, 'b' ], [ 0, 'b' ] ],
- [ '=', [ 2, 'c' ], [ 1, 'c' ] ],
- [ '+', [ 3, nil ], [ 2, 'd' ] ],
- [ '=', [ 3, 'e' ], [ 3, 'e' ] ],
- [ '!', [ 4, 'h' ], [ 4, 'f' ] ],
- [ '=', [ 5, 'j' ], [ 5, 'j' ] ],
- [ '+', [ 6, nil ], [ 6, 'k' ] ],
- [ '=', [ 6, 'l' ], [ 7, 'l' ] ],
- [ '=', [ 7, 'm' ], [ 8, 'm' ] ],
- [ '!', [ 8, 'n' ], [ 9, 'r' ] ],
- [ '!', [ 9, 'p' ], [ 10, 's' ] ],
- [ '+', [ 10, nil ], [ 11, 't' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- seq1 = %w(a b c d e)
- seq2 = %w(a e)
- correct_sdiff = [
- [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
- [ '-', [ 1, 'b' ], [ 1, nil ] ],
- [ '-', [ 2, 'c' ], [ 1, nil ] ],
- [ '-', [ 3, 'd' ], [ 1, nil ] ],
- [ '=', [ 4, 'e' ], [ 1, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
- [ '+', [ 1, nil ], [ 1, 'b' ] ],
- [ '+', [ 1, nil ], [ 2, 'c' ] ],
- [ '+', [ 1, nil ], [ 3, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 4, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- seq1 = %w(v x a e)
- seq2 = %w(w y a b c d e)
- correct_sdiff = [
- [ '!', [ 0, 'v' ], [ 0, 'w' ] ],
- [ '!', [ 1, 'x' ], [ 1, 'y' ] ],
- [ '=', [ 2, 'a' ], [ 2, 'a' ] ],
- [ '+', [ 3, nil ], [ 3, 'b' ] ],
- [ '+', [ 3, nil ], [ 4, 'c' ] ],
- [ '+', [ 3, nil ], [ 5, 'd' ] ],
- [ '=', [ 3, 'e' ], [ 6, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- seq1 = %w(x a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '-', [ 0, 'x' ], [ 0, nil ] ],
- [ '=', [ 1, 'a' ], [ 0, 'a' ] ],
- [ '+', [ 2, nil ], [ 1, 'b' ] ],
- [ '+', [ 2, nil ], [ 2, 'c' ] ],
- [ '+', [ 2, nil ], [ 3, 'd' ] ],
- [ '=', [ 2, 'e' ], [ 4, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(x a b c d e)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'x' ] ],
- [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
- [ '+', [ 1, nil ], [ 2, 'b' ] ],
- [ '+', [ 1, nil ], [ 3, 'c' ] ],
- [ '+', [ 1, nil ], [ 4, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 5, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- seq1 = %w(a e v)
- seq2 = %w(x a b c d e w x)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'x' ] ],
- [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
- [ '+', [ 1, nil ], [ 2, 'b' ] ],
- [ '+', [ 1, nil ], [ 3, 'c' ] ],
- [ '+', [ 1, nil ], [ 4, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 5, 'e' ] ],
- [ '!', [ 2, 'v' ], [ 6, 'w' ] ],
- [ '+', [ 3, nil ], [ 7, 'x' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- seq1 = %w()
- seq2 = %w(a b c)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'a' ] ],
- [ '+', [ 0, nil ], [ 1, 'b' ] ],
- [ '+', [ 0, nil ], [ 2, 'c' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w()
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '-', [ 1, 'b' ], [ 0, nil ] ],
- [ '-', [ 2, 'c' ], [ 0, nil ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(1)
- correct_sdiff = [
- [ '!', [ 0, 'a' ], [ 0, '1' ] ],
- [ '-', [ 1, 'b' ], [ 1, nil ] ],
- [ '-', [ 2, 'c' ], [ 1, nil ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(c)
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '-', [ 1, 'b' ], [ 0, nil ] ],
- [ '=', [ 2, 'c' ], [ 0, 'c' ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_m
- sdiff = nil
- seq1 = %w(abcd efgh ijkl mnop)
- seq2 = []
- correct_sdiff = [
- [ '-', [ 0, 'abcd' ], [ 0, nil ] ],
- [ '-', [ 1, 'efgh' ], [ 0, nil ] ],
- [ '-', [ 2, 'ijkl' ], [ 0, nil ] ],
- [ '-', [ 3, 'mnop' ], [ 0, nil ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_n
- sdiff = nil
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnop)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'abcd' ] ],
- [ '+', [ 0, nil ], [ 1, 'efgh' ] ],
- [ '+', [ 0, nil ], [ 2, 'ijkl' ] ],
- [ '+', [ 0, nil ], [ 3, 'mnop' ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_balanced_a
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 M22 ", callback.result)
- end
-
- def test_balanced_b
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 DB21 M22 ", callback.result)
- end
-
- def test_balanced_c
- seq1 = %w(a x y c)
- seq2 = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 C22 M33 ", callback.result)
- end
-
- def test_balanced_d
- seq1 = %w(x y c)
- seq2 = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 M22 ", callback.result)
- end
-
- def test_balanced_e
- seq1 = %w(a x y z)
- seq2 = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 DA33 ", callback.result)
- end
-
- def test_balanced_f
- seq1 = %w(a z)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 ", callback.result)
- end
-
- def test_balanced_g
- seq1 = %w(z a)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 M10 ", callback.result)
- end
-
- def test_balanced_h
- seq1 = %w(a b c)
- seq2 = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 ", callback.result)
- end
-
- def test_balanced_i
- seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- seq2 = []
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
- end
-
- def test_balanced_j
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
- end
-end
-
-class TestPatching < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_patch_diff
- ps = ms1 = ms2 = ms3 = nil
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms2 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::SDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- end
-
- def test_patch_sdiff
- ps = ms1 = ms2 = ms3 = nil
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::DiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- end
-end
diff --git a/diff-lcs/tags/release-1.1.1/ChangeLog b/diff-lcs/tags/release-1.1.1/ChangeLog
deleted file mode 100644
index 9285da7..0000000
--- a/diff-lcs/tags/release-1.1.1/ChangeLog
+++ /dev/null
@@ -1,42 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.1.1
-* Fixed bug #891:
- http://rubyforge.org/tracker/?func=detail&atid=407&aid=891&group_id=84
-* Fixed a problem with callback initialisation code (it assumed that all
- callbacks passed as classes can be initialised; now, it rescues
- NoMethodError in the event of private :new being called).
-* Modified the non-initialisable callbacks to have a private #new method.
-* Moved ldiff core code to Diff::LCS::Ldiff (diff/lcs/ldiff.rb).
-
-== Diff::LCS 1.1.0
-* Eliminated the need for Diff::LCS::Event and removed it.
-* Added a contextual diff callback, Diff::LCS::ContextDiffCallback.
-* Implemented patching/unpatching for standard Diff callback output formats
- with both #diff and #sdiff.
-* Extensive documentation changes.
-
-== Diff::LCS 1.0.4
-* Fixed a problem with bin/ldiff output, especially for unified format.
- Newlines that should have been present weren't.
-* Changed the .tar.gz installer to generate Windows batch files if ones do not
- exist already. Removed the existing batch files as they didn't work.
-
-== Diff::LCS 1.0.3
-* Fixed a problem with #traverse_sequences where the first difference from the
- left sequence might not be appropriately captured.
-
-== Diff::LCS 1.0.2
-* Fixed an issue with ldiff not working because actions were changed from
- symbols to strings.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/tags/release-1.1.1/Install b/diff-lcs/tags/release-1.1.1/Install
deleted file mode 100644
index 016f2ce..0000000
--- a/diff-lcs/tags/release-1.1.1/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.1.1.gem from the usual sources.
diff --git a/diff-lcs/tags/release-1.1.1/README b/diff-lcs/tags/release-1.1.1/README
deleted file mode 100644
index f2b9e02..0000000
--- a/diff-lcs/tags/release-1.1.1/README
+++ /dev/null
@@ -1,77 +0,0 @@
-Diff::LCS README
-================
-Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt
-longest common subsequence (LCS) algorithm to compute intelligent
-differences between two sequenced enumerable containers[2]. The
-implementation is based on Mario I. Wolczko's[3] Smalltalk version (1.2,
-1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-This release is version 1.1.1, fixing a reported #patch bug in 1.1.0.
-Version 1.1.0 added new features, including the ability to #patch and
-#unpatch changes as well as a new contextual diff callback,
-Diff::LCS::ContextDiffCallbacks, that should improve the context
-sensitivity of patching.
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- seq2 == Diff::LCS.patch!(seq1, diffs)
- seq1 == Diff::LCS.unpatch!(seq2, diffs)
- seq2 == Diff::LCS.patch!(seq1, sdiff)
- seq1 == Diff::LCS.unpatch!(seq2, sdiff)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = seq1.traverse_sequences(seq2, callback_obj)
- bal = seq1.traverse_balanced(seq2, callback_obj)
- seq2 == seq1.patch!(diffs)
- seq1 == seq2.unpatch!(diffs)
- seq2 == seq1.patch!(sdiff)
- seq1 == seq2.unpatch!(sdiff)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will
-be extended for use this way.
-
-Copyright
-=========
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/tags/release-1.1.1/Rakefile b/diff-lcs/tags/release-1.1.1/Rakefile
deleted file mode 100644
index b4a277e..0000000
--- a/diff-lcs/tags/release-1.1.1/Rakefile
+++ /dev/null
@@ -1,103 +0,0 @@
-#! /usr/bin/env rake
-$LOAD_PATH.unshift('lib')
-
-require 'rubygems'
-require 'rake/gempackagetask'
-require 'rake/contrib/rubyforgepublisher'
-require 'diff/lcs'
-require 'archive/tar/minitar'
-require 'zlib'
-
-DISTDIR = "diff-lcs-#{Diff::LCS::VERSION}"
-TARDIST = "../#{DISTDIR}.tar.gz"
-
-DATE_RE = %r<(\d{4})[./-]?(\d{2})[./-]?(\d{2})(?:[\sT]?(\d{2})[:.]?(\d{2})[:.]?(\d{2})?)?>
-
-if ENV['RELEASE_DATE']
- year, month, day, hour, minute, second = DATE_RE.match(ENV['RELEASE_DATE']).captures
- year ||= 0
- month ||= 0
- day ||= 0
- hour ||= 0
- minute ||= 0
- second ||= 0
- ReleaseDate = Time.mktime(year, month, day, hour, minute, second)
-else
- ReleaseDate = nil
-end
-
-task :test do |t|
- require 'test/unit/testsuite'
- require 'test/unit/ui/console/testrunner'
-
- runner = Test::Unit::UI::Console::TestRunner
-
- $LOAD_PATH.unshift('tests')
- $stderr.puts "Checking for test cases:" if t.verbose
- Dir['tests/*test*.rb'].each do |testcase|
- $stderr.puts "\t#{testcase}" if t.verbose
- load testcase
- end
-
- suite = Test::Unit::TestSuite.new
-
- ObjectSpace.each_object(Class) do |testcase|
- suite << testcase.suite if testcase < Test::Unit::TestCase
- end
-
- runner.run(suite)
-end
-
-spec = eval(File.read("diff-lcs.gemspec"))
-desc "Build the RubyGem for Diff::LCS."
-task :gem => [ :test ]
-Rake::GemPackageTask.new(spec) do |g|
- g.need_tar = false
- g.need_zip = false
- g.package_dir = ".."
-end
-
-desc "Build an Diff::LCS .tar.gz distribution."
-task :tar => [ TARDIST ]
-file TARDIST => [ :test ] do |t|
- current = File.basename(Dir.pwd)
- Dir.chdir("..") do
- begin
- files = Dir["#{current}/**/*"].select { |dd| dd !~ %r{(?:/CVS/?|~$)} }
- files.map! do |dd|
- ddnew = dd.gsub(/^#{current}/, DISTDIR)
- mtime = ReleaseDate || File.stat(dd).mtime
- if File.directory?(dd)
- { :name => ddnew, :mode => 0555, :dir => true, :mtime => mtime }
- else
- if dd =~ %r{bin/}
- mode = 0755
- else
- mode = 0644
- end
- data = File.read(dd)
- { :name => ddnew, :mode => mode, :data => data, :size => data.size,
- :mtime => mtime }
- end
- end
-
- ff = File.open(t.name.gsub(%r{^\.\./}o, ''), "wb")
- gz = Zlib::GzipWriter.new(ff)
- tw = Archive::Tar::Minitar::Writer.new(gz)
-
- files.each do |entry|
- if entry[:dir]
- tw.mkdir(entry[:name], entry)
- else
- tw.add_file_simple(entry[:name], entry) { |os| os.write(entry[:data]) }
- end
- end
- ensure
- tw.close if tw
- gz.close if gz
- end
- end
-end
-
-desc "Build everything."
-task :default => [ :tar, :gem ]
diff --git a/diff-lcs/tags/release-1.1.1/diff-lcs.gemspec b/diff-lcs/tags/release-1.1.1/diff-lcs.gemspec
deleted file mode 100644
index 26d2b55..0000000
--- a/diff-lcs/tags/release-1.1.1/diff-lcs.gemspec
+++ /dev/null
@@ -1,40 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.1.1}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
-
- s.test_files = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/tags/release-1.1.1/htmldiff b/diff-lcs/tags/release-1.1.1/htmldiff
deleted file mode 100644
index 8fe23e0..0000000
--- a/diff-lcs/tags/release-1.1.1/htmldiff
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.1.1"
- require 'diff/lcs/string'
-rescue LoadError
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_el}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_el}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs.rb b/diff-lcs/tags/release-1.1.1/lib/diff/lcs.rb
deleted file mode 100644
index 78fe1cd..0000000
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs.rb
+++ /dev/null
@@ -1,1105 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.1.1
- # Computes "intelligent" differences between two sequenced Enumerables.
- # This is an implementation of the McIlroy-Hunt "diff" algorithm for
- # Enumerable objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version
- # (1.2, 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- # seq2 == Diff::LCS.patch(seq1, diffs)
- # seq2 == Diff::LCS.patch!(seq1, diffs)
- # seq1 == Diff::LCS.unpatch(seq2, diffs)
- # seq1 == Diff::LCS.unpatch!(seq2, diffs)
- # seq2 == Diff::LCS.patch(seq1, sdiff)
- # seq2 == Diff::LCS.patch!(seq1, sdiff)
- # seq1 == Diff::LCS.unpatch(seq2, sdiff)
- # seq1 == Diff::LCS.unpatch!(seq2, sdiff)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = seq1.traverse_sequences(seq2, callback_obj)
- # bal = seq1.traverse_balanced(seq2, callback_obj)
- # seq2 == seq1.patch(diffs)
- # seq2 == seq1.patch!(diffs)
- # seq1 == seq2.unpatch(diffs)
- # seq1 == seq2.unpatch!(diffs)
- # seq2 == seq1.patch(sdiff)
- # seq2 == seq1.patch!(sdiff)
- # seq1 == seq2.unpatch(sdiff)
- # seq1 == seq2.unpatch!(sdiff)
- #
- # Default extensions are provided for Array and String objects through
- # the use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- #
- # <em>The following text is from the Perl documentation. The only
- # changes have been to make the text appear better in Rdoc</em>.
- #
- # I once read an article written by the authors of +diff+; they said
- # that they hard worked very hard on the algorithm until they found the
- # right one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the second sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993. Documentation includes work by Mark-Jason Dominus.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written originally by Mark-Jason
- # Dominus <mjd-perl-diff@plover.com> and later by Ned Konz. The basic Ruby
- # implementation was re-ported from the Smalltalk implementation, available
- # at ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # #sdiff and #traverse_balanced were written for the Perl version by Mike
- # Schilli <m@perlmeister.com>.
- #
- # "The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed."
- module LCS
- VERSION = '1.1.1'
- end
-end
-
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns an Array containing the longest common subsequence(s) between
- # +self+ and +other+. See Diff::LCS#LCS.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- # Returns the difference set between +self+ and +other+. See
- # Diff::LCS#diff.
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- # Returns the balanced ("side-by-side") difference set between +self+ and
- # +other+. See Diff::LCS#sdiff.
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- # Traverses the discovered longest common subsequences between +self+ and
- # +other+. See Diff::LCS#traverse_sequences.
- def traverse_sequences(other, callbacks = nil, &block)
- traverse_sequences(self, other, callbacks || Diff::LCS::YieldingCallbacks,
- &block)
- end
-
- # Traverses the discovered longest common subsequences between +self+ and
- # +other+ using the alternate, balanced algorithm. See
- # Diff::LCS#traverse_balanced.
- def traverse_balanced(other, callbacks = nil, &block)
- traverse_balanced(self, other, callbacks || Diff::LCS::YieldingCallbacks,
- &block)
- end
-
- # Attempts to patch a copy of +self+ with the provided +patchset+. See
- # Diff::LCS#patch.
- def patch(patchset)
- Diff::LCS::patch(self.dup, patchset)
- end
-
- # Attempts to unpatch a copy of +self+ with the provided +patchset+.
- # See Diff::LCS#patch.
- def unpatch(patchset)
- Diff::LCS::unpatch(self.dup, patchset)
- end
-
- # Attempts to patch +self+ with the provided +patchset+. See
- # Diff::LCS#patch!. Does no autodiscovery.
- def patch!(patchset)
- Diff::LCS::patch!(self, patchset)
- end
-
- # Attempts to unpatch +self+ with the provided +patchset+. See
- # Diff::LCS#unpatch. Does no autodiscovery.
- def unpatch!(patchset)
- Diff::LCS::unpatch!(self, patchset)
- end
-end
-
-module Diff::LCS
- class << self
- # Given two sequenced Enumerables, LCS returns an Array containing their
- # longest common subsequences.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- #
- # This array whose contents is such that:
- #
- # lcs.each_with_index do |ee, ii|
- # assert(ee.nil? || (seq1[ii] == seq2[ee]))
- # end
- #
- # If a block is provided, the matching subsequences will be yielded from
- # +seq1+ in turn and may be modified before they are placed into the
- # returned Array of subsequences.
- def LCS(seq1, seq2, &block) #:yields seq1[ii] for each matched:
- matches = Diff::LCS.__lcs(seq1, seq2)
- ret = []
- matches.each_with_index do |ee, ii|
- unless matches[ii].nil?
- if block_given?
- ret << (yield seq1[ii])
- else
- ret << seq1[ii]
- end
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes.
- #
- # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate
- # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks.
- # If a Class argument is provided for +callbacks+, #diff will attempt
- # to initialise it. If the +callbacks+ object (possibly initialised)
- # responds to #finish, it will be called.
- def diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
- callbacks ||= Diff::LCS::DiffCallbacks
- if callbacks.kind_of?(Class)
- cb = callbacks.new rescue callbacks
- callbacks = cb
- end
- traverse_sequences(seq1, seq2, callbacks)
- callbacks.finish if callbacks.respond_to?(:finish)
-
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # old < -
- # same same
- # before | after
- # - > new
- #
- # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate
- # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If
- # a Class argument is provided for +callbacks+, #diff will attempt to
- # initialise it. If the +callbacks+ object (possibly initialised)
- # responds to #finish, it will be called.
- def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
- callbacks ||= Diff::LCS::SDiffCallbacks
- if callbacks.kind_of?(Class)
- cb = callbacks.new rescue callbacks
- callbacks = cb
- end
- traverse_balanced(seq1, seq2, callbacks)
- callbacks.finish if callbacks.respond_to?(:finish)
-
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # The arguments to #traverse_sequences are the two sequences to
- # traverse, and a callback object, like this:
- #
- # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
- #
- # #diff is implemented with #traverse_sequences.
- #
- # == Callback Methods
- # Optional callback methods are <em>emphasized</em>.
- #
- # callbacks#match:: Called when +a+ and +b+ are pointing
- # to common elements in +A+ and +B+.
- # callbacks#discard_a:: Called when +a+ is pointing to an
- # element not in +B+.
- # callbacks#discard_b:: Called when +b+ is pointing to an
- # element not in +A+.
- # <em>callbacks#finished_a</em>:: Called when +a+ has reached the end of
- # sequence +A+.
- # <em>callbacks#finished_b</em>:: Called when +b+ has reached the end of
- # sequence +B+.
- #
- # == Algorithm
- # a---+
- # v
- # A = a b c e h j l m n p
- # B = b c d e f j k l m r s t
- # ^
- # b---+
- #
- # If there are two arrows (+a+ and +b+) pointing to elements of
- # sequences +A+ and +B+, the arrows will initially point to the first
- # elements of their respective sequences. #traverse_sequences will
- # advance the arrows through the sequences one element at a time,
- # calling a method on the user-specified callback object before each
- # advance. It will advance the arrows in such a way that if there are
- # elements <tt>A[ii]</tt> and <tt>B[jj]</tt> which are both equal and
- # part of the longest common subsequence, there will be some moment
- # during the execution of #traverse_sequences when arrow +a+ is pointing
- # to <tt>A[ii]</tt> and arrow +b+ is pointing to <tt>B[jj]</tt>. When
- # this happens, #traverse_sequences will call <tt>callbacks#match</tt>
- # and then it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its sequence
- # that is not part of the longest common subsequence.
- # #traverse_sequences will advance that arrow and will call
- # <tt>callbacks#discard_a</tt> or <tt>callbacks#discard_b</tt>, depending
- # on which arrow it advanced. If both arrows point to elements that are
- # not part of the longest common subsequence, then #traverse_sequences
- # will advance one of them and call the appropriate callback, but it is
- # not specified which it will call.
- #
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
- # and <tt>callbacks#discard_b</tt> are invoked with an event comprising
- # the action ("=", "+", or "-", respectively), the indicies +ii+ and
- # +jj+, and the elements <tt>A[ii]</tt> and <tt>B[jj]</tt>. Return
- # values are discarded by #traverse_sequences.
- #
- # === End of Sequences
- # If arrow +a+ reaches the end of its sequence before arrow +b+ does,
- # #traverse_sequence try to call <tt>callbacks#finished_a</tt> with the
- # last index and element of +A+ (<tt>A[-1]</tt>) and the current index
- # and element of +B+ (<tt>B[jj]</tt>). If <tt>callbacks#finished_a</tt>
- # does not exist, then <tt>callbacks#discard_b</tt> will be called on
- # each element of +B+ until the end of the sequence is reached (the call
- # will be done with <tt>A[-1]</tt> and <tt>B[jj]</tt> for each element).
- #
- # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+,
- # <tt>callbacks#finished_b</tt> will be called with the current index
- # and element of +A+ (<tt>A[ii]</tt>) and the last index and element of
- # +B+ (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not
- # exist on the callback object, then <tt>callbacks#discard_a</tt> will
- # be called on each element of +A+ until the end of the sequence is
- # reached (<tt>A[ii]</tt> and <tt>B[-1]</tt>).
- #
- # There is a chance that one additional <tt>callbacks#discard_a</tt> or
- # <tt>callbacks#discard_b</tt> will be called after the end of the
- # sequence is reached, if +a+ has not yet reached the end of +A+ or +b+
- # has not yet reached the end of +B+.
- def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks, &block) #:yields change events:
- matches = Diff::LCS.__lcs(seq1, seq2)
-
- run_finished_a = run_finished_b = false
- string = seq1.kind_of?(String)
-
- a_size = seq1.size
- b_size = seq2.size
- ai = bj = 0
-
- (0 .. matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? seq1[ii, 1] : seq1[ii]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- if b_line.nil?
- unless ax.nil?
- event = Diff::LCS::ContextChange.new('-', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- end
- else
- loop do
- break unless bj < b_line
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('=', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? seq1[-1, 1] : seq1[-1]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
- event = yield event if block_given?
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? seq1[ai, 1] : seq1[ai]
- loop do
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[-1, 1] : seq2[-1]
- event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
- event = yield event if block_given?
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? seq2[bj, 1] : seq2[bj]
- loop do
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # #traverse_balanced is an alternative to #traverse_sequences. It
- # uses a different algorithm to iterate through the entries in the
- # computed longest common subsequence. Instead of viewing the changes as
- # insertions or deletions from one of the sequences, #traverse_balanced
- # will report <em>changes</em> between the sequences. To represent a
- #
- # The arguments to #traverse_balanced are the two sequences to traverse
- # and a callback object, like this:
- #
- # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
- #
- # #sdiff is implemented with #traverse_balanced.
- #
- # == Callback Methods
- # Optional callback methods are <em>emphasized</em>.
- #
- # callbacks#match:: Called when +a+ and +b+ are pointing
- # to common elements in +A+ and +B+.
- # callbacks#discard_a:: Called when +a+ is pointing to an
- # element not in +B+.
- # callbacks#discard_b:: Called when +b+ is pointing to an
- # element not in +A+.
- # <em>callbacks#change</em>:: Called when +a+ and +b+ are pointing
- # to the same relative position, but
- # <tt>A[a]</tt> and <tt>B[b]</tt> are
- # not the same; a <em>change</em> has
- # occurred.
- #
- # #traverse_balanced might be a bit slower than #traverse_sequences,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # #traverse_balanced.
- #
- # == Algorithm
- # a---+
- # v
- # A = a b c e h j l m n p
- # B = b c d e f j k l m r s t
- # ^
- # b---+
- #
- # === Matches
- # If there are two arrows (+a+ and +b+) pointing to elements of
- # sequences +A+ and +B+, the arrows will initially point to the first
- # elements of their respective sequences. #traverse_sequences will
- # advance the arrows through the sequences one element at a time,
- # calling a method on the user-specified callback object before each
- # advance. It will advance the arrows in such a way that if there are
- # elements <tt>A[ii]</tt> and <tt>B[jj]</tt> which are both equal and
- # part of the longest common subsequence, there will be some moment
- # during the execution of #traverse_sequences when arrow +a+ is pointing
- # to <tt>A[ii]</tt> and arrow +b+ is pointing to <tt>B[jj]</tt>. When
- # this happens, #traverse_sequences will call <tt>callbacks#match</tt>
- # and then it will advance both arrows.
- #
- # === Discards
- # Otherwise, one of the arrows is pointing to an element of its sequence
- # that is not part of the longest common subsequence.
- # #traverse_sequences will advance that arrow and will call
- # <tt>callbacks#discard_a</tt> or <tt>callbacks#discard_b</tt>,
- # depending on which arrow it advanced.
- #
- # === Changes
- # If both +a+ and +b+ point to elements that are not part of the longest
- # common subsequence, then #traverse_sequences will try to call
- # <tt>callbacks#change</tt> and advance both arrows. If
- # <tt>callbacks#change</tt> is not implemented, then
- # <tt>callbacks#discard_a</tt> and <tt>callbacks#discard_b</tt> will be
- # called in turn.
- #
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
- # <tt>callbacks#discard_b</tt>, and <tt>callbacks#change</tt> are
- # invoked with an event comprising the action ("=", "+", "-", or "!",
- # respectively), the indicies +ii+ and +jj+, and the elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt>. Return values are discarded by
- # #traverse_balanced.
- #
- # === Context
- # Note that +ii+ and +jj+ may not be the same index position, even if
- # +a+ and +b+ are considered to be pointing to matching or changed
- # elements.
- def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(seq1, seq2)
- a_size = seq1.size
- b_size = seq2.size
- ai = bj = mb = 0
- ma = -1
- string = seq1.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(seq2)
- while (ai < ma) or (bj < mb)
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- PATCH_MAP = { #:nodoc:
- :patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' },
- :unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }
- }
-
- # Given a patchset, convert the current version to the new
- # version. If +direction+ is not specified (must be
- # <tt>:patch</tt> or <tt>:unpatch</tt>), then discovery of the
- # direction of the patch will be attempted.
- def patch(src, patchset, direction = nil)
- string = src.kind_of?(String)
- # Start with a new empty type of the source's class
- res = src.class.new
-
- # Normalize the patchset.
- patchset = __normalize_patchset(patchset)
-
- direction ||= Diff::LCS.__diff_direction(src, patchset)
- direction ||= :patch
-
- ai = bj = 0
-
- patchset.each do |change|
- # Both Change and ContextChange support #action
- action = PATCH_MAP[direction][change.action]
-
- case change
- when Diff::LCS::ContextChange
- case direction
- when :patch
- el = change.new_element
- op = change.old_position
- np = change.new_position
- when :unpatch
- el = change.old_element
- op = change.new_position
- np = change.old_position
- end
-
- case action
- when '-' # Remove details from the old string
- while ai < op
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += 1
- when '+'
- while bj < np
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- res << el
- bj += 1
- when '='
- # This only appears in sdiff output with the SDiff callback.
- # Therefore, we only need to worry about dealing with a single
- # element.
- res << el
-
- ai += 1
- bj += 1
- when '!'
- while ai < op
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- bj += 1
- ai += 1
-
- res << el
- end
- when Diff::LCS::Change
- case action
- when '-'
- while ai < change.position
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += 1
- when '+'
- while bj < change.position
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- bj += 1
-
- res << change.element
- end
- end
- end
-
- while ai < src.size
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- res
- end
-
- # Given a set of patchset, convert the current version to the prior
- # version. Does no auto-discovery.
- def unpatch!(src, patchset)
- Diff::LCS.patch(src, patchset, :unpatch)
- end
-
- # Given a set of patchset, convert the current version to the next
- # version. Does no auto-discovery.
- def patch!(src, patchset)
- Diff::LCS.patch(src, patchset, :patch)
- end
-
-# private
- # Compute the longest common subsequence between the sequenced Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection. (Currently unused.)
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Examine the patchset and the source to see in which direction the
- # patch should be applied.
- #
- # WARNING: By default, this examines the whole patch, so this could take
- # some time. This also works better with Diff::LCS::ContextChange or
- # Diff::LCS::Change as its source, as an array will cause the creation
- # of one of the above.
- def __diff_direction(src, patchset, limit = nil)
- count = left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- patchset.each do |change|
- count += 1
-
- case change
- when Diff::LCS::Change
- # With a simplistic change, we can't tell the difference between
- # the left and right on '!' actions, so we ignore those. On '='
- # actions, if there's a miss, we miss both left and right.
- element = string ? src[change.position, 1] : src[change.position]
-
- case change.action
- when '-'
- if element == change.element
- left += 1
- else
- left_miss += 1
- end
- when '+'
- if element == change.element
- right += 1
- else
- right_miss += 1
- end
- when '='
- if element != change.element
- left_miss += 1
- right_miss += 1
- end
- end
- when Diff::LCS::ContextChange
- case change.action
- when '-' # Remove details from the old string
- element = string ? src[change.old_position, 1] : src[change.old_position]
- if element == change.old_element
- left += 1
- else
- left_miss += 1
- end
- when '+'
- element = string ? src[change.new_position, 1] : src[change.new_position]
- if element == change.new_element
- right += 1
- else
- right_miss += 1
- end
- when '='
- le = string ? src[change.old_position, 1] : src[change.old_position]
- re = string ? src[change.new_position, 1] : src[change.new_position]
-
- left_miss += 1 if le != change.old_element
- right_miss += 1 if re != change.new_element
- when '!'
- element = string ? src[change.old_position, 1] : src[change.old_position]
- if element == change.old_element
- left += 1
- else
- element = string ? src[change.new_position, 1] : src[change.new_position]
- if element == change.new_element
- right += 1
- else
- left_miss += 1
- right_miss += 1
- end
- end
- end
- end
-
- break if not limit.nil? and count > limit
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided patchset does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Normalize the patchset. A patchset is always a sequence of changes, but
- # how those changes are represented may vary, depending on how they were
- # generated. In all cases we support, we also support the array
- # representation of the changes. The formats are:
- #
- # [ # patchset <- Diff::LCS.diff(a, b)
- # [ # one or more hunks
- # Diff::LCS::Change # one or more changes
- # ] ]
- #
- # [ # patchset, equivalent to the above
- # [ # one or more hunks
- # [ action, line, value ] # one or more changes
- # ] ]
- #
- # [ # patchset <- Diff::LCS.diff(a, b, Diff::LCS::ContextDiffCallbacks)
- # # OR <- Diff::LCS.sdiff(a, b, Diff::LCS::ContextDiffCallbacks)
- # [ # one or more hunks
- # Diff::LCS::ContextChange # one or more changes
- # ] ]
- #
- # [ # patchset, equivalent to the above
- # [ # one or more hunks
- # [ action, [ old line, old value ], [ new line, new value ] ]
- # # one or more changes
- # ] ]
- #
- # [ # patchset <- Diff::LCS.sdiff(a, b)
- # # OR <- Diff::LCS.diff(a, b, Diff::LCS::SDiffCallbacks)
- # Diff::LCS::ContextChange # one or more changes
- # ]
- #
- # [ # patchset, equivalent to the above
- # [ action, [ old line, old value ], [ new line, new value ] ]
- # # one or more changes
- # ]
- #
- # The result of this will be either of the following.
- #
- # [ # patchset
- # Diff::LCS::ContextChange # one or more changes
- # ]
- #
- # [ # patchset
- # Diff::LCS::Change # one or more changes
- # ]
- #
- # If either of the above is provided, it will be returned as such.
- #
- def __normalize_patchset(patchset)
- patchset.map do |hunk|
- case hunk
- when Diff::LCS::ContextChange, Diff::LCS::Change
- hunk
- when Array
- if (not hunk[0].kind_of?(Array)) and hunk[1].kind_of?(Array) and hunk[2].kind_of?(Array)
- Diff::LCS::ContextChange.from_a(hunk)
- else
- hunk.map do |change|
- case change
- when Diff::LCS::ContextChange, Diff::LCS::Change
- change
- when Array
- # change[1] will ONLY be an array in a ContextChange#to_a call.
- # In Change#to_a, it represents the line (singular).
- if change[1].kind_of?(Array)
- Diff::LCS::ContextChange.from_a(change)
- else
- Diff::LCS::Change.from_a(change)
- end
- end
- end
- end
- else
- raise ArgumentError, "Cannot normalise a hunk of class #{hunk.class}."
- end
- end.flatten
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.1.1/lib/diff/lcs/array.rb
deleted file mode 100644
index e07f8aa..0000000
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Includes Diff::LCS into the Array built-in class.
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.1.1/lib/diff/lcs/block.rb
deleted file mode 100644
index 7dceb48..0000000
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains Diff::LCS::Block for bin/ldiff.
-
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/ldiff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else # [true, true]
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.1.1/lib/diff/lcs/change.rb
deleted file mode 100644
index 6ecdf7e..0000000
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,169 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Provides Diff::LCS::Change and Diff::LCS::ContextChange.
-
- # Centralises the change test code in Diff::LCS::Change and
- # Diff::LCS::ContextChange, since it's the same for both classes.
-module Diff::LCS::ChangeTypeTests
- def deleting?
- @action == '-'
- end
-
- def adding?
- @action == '+'
- end
-
- def unchanged?
- @action == '='
- end
-
- def changed?
- @changed == '!'
- end
-
- def finished_a?
- @changed == '>'
- end
-
- def finished_b?
- @changed == '<'
- end
-end
-
- # Represents a simplistic (non-contextual) change. Represents the removal or
- # addition of an element from either the old or the new sequenced enumerable.
-class Diff::LCS::Change
- # Returns the action this Change represents. Can be '+' (#adding?), '-'
- # (#deleting?), '=' (#unchanged?), # or '!' (#changed?). When created by
- # Diff::LCS#diff or Diff::LCS#sdiff, it may also be '>' (#finished_a?) or
- # '<' (#finished_b?).
- attr_reader :action
- attr_reader :position
- attr_reader :element
-
- include Comparable
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.element == other.element)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.element <=> other.element if r.zero?
- r
- end
-
- def initialize(action, position, element)
- @action = action
- @position = position
- @element = element
- end
-
- # Creates a Change from an array produced by Change#to_a.
- def to_a
- [@action, @position, @element]
- end
-
- def self.from_a(arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- include Diff::LCS::ChangeTypeTests
-end
-
- # Represents a contextual change. Contains the position and values of the
- # elements in the old and the new sequenced enumerables as well as the action
- # taken.
-class Diff::LCS::ContextChange
- # Returns the action this Change represents. Can be '+' (#adding?), '-'
- # (#deleting?), '=' (#unchanged?), # or '!' (#changed?). When
- # created by Diff::LCS#diff or Diff::LCS#sdiff, it may also be '>'
- # (#finished_a?) or '<' (#finished_b?).
- attr_reader :action
- attr_reader :old_position
- attr_reader :old_element
- attr_reader :new_position
- attr_reader :new_element
-
- include Comparable
-
- def ==(other)
- (@action == other.action) and
- (@old_position == other.old_position) and
- (@new_position == other.new_position) and
- (@old_element == other.old_element) and
- (@new_element == other.new_element)
- end
-
- def inspect(*args)
- %Q(#<#{self.class.name}:#{__id__} @action=#{action} positions=#{old_position},#{new_position} elements=#{old_element.inspect},#{new_element.inspect}>)
- end
-
- def <=>(other)
- r = @action <=> other.action
- r = @old_position <=> other.old_position if r.zero?
- r = @new_position <=> other.new_position if r.zero?
- r = @old_element <=> other.old_element if r.zero?
- r = @new_element <=> other.new_element if r.zero?
- r
- end
-
- def initialize(action, old_position, old_element, new_position, new_element)
- @action = action
- @old_position = old_position
- @old_element = old_element
- @new_position = new_position
- @new_element = new_element
- end
-
- def to_a
- [@action, [@old_position, @old_element], [@new_position, @new_element]]
- end
-
- # Creates a ContextChange from an array produced by ContextChange#to_a.
- def self.from_a(arr)
- if arr.size == 5
- Diff::LCS::ContextChange.new(arr[0], arr[1], arr[2], arr[3], arr[4])
- else
- Diff::LCS::ContextChange.new(arr[0], arr[1][0], arr[1][1], arr[2][0],
- arr[2][1])
- end
- end
-
- # Simplifies a context change for use in some diff callbacks. '<' actions
- # are converted to '-' and '>' actions are converted to '+'.
- def self.simplify(event)
- ea = event.to_a
-
- case ea[0]
- when '-'
- ea[2][1] = nil
- when '<'
- ea[0] = '-'
- ea[2][1] = nil
- when '+'
- ea[1][1] = nil
- when '>'
- ea[0] = '+'
- ea[1][1] = nil
- end
-
- Diff::LCS::ContextChange.from_a(ea)
- end
-
- include Diff::LCS::ChangeTypeTests
-end
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.1.1/lib/diff/lcs/hunk.rb
deleted file mode 100644
index 58fac9f..0000000
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,257 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains Diff::LCS::Hunk for bin/ldiff.
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.1.1/lib/diff/lcs/string.rb
deleted file mode 100644
index 2de7d1f..0000000
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Includes Diff::LCS into String.
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.1.2/Rakefile b/diff-lcs/tags/release-1.1.2/Rakefile
deleted file mode 100644
index 6a2f963..0000000
--- a/diff-lcs/tags/release-1.1.2/Rakefile
+++ /dev/null
@@ -1,116 +0,0 @@
-#! /usr/bin/env rake
-$LOAD_PATH.unshift('lib')
-
-require 'rubygems'
-require 'rake/gempackagetask'
-require 'rake/contrib/rubyforgepublisher'
-require 'diff/lcs'
-require 'archive/tar/minitar'
-require 'zlib'
-
-DISTDIR = "diff-lcs-#{Diff::LCS::VERSION}"
-TARDIST = "../#{DISTDIR}.tar.gz"
-
-DATE_RE = %r<(\d{4})[./-]?(\d{2})[./-]?(\d{2})(?:[\sT]?(\d{2})[:.]?(\d{2})[:.]?(\d{2})?)?>
-
-if ENV['RELEASE_DATE']
- year, month, day, hour, minute, second = DATE_RE.match(ENV['RELEASE_DATE']).captures
- year ||= 0
- month ||= 0
- day ||= 0
- hour ||= 0
- minute ||= 0
- second ||= 0
- ReleaseDate = Time.mktime(year, month, day, hour, minute, second)
-else
- ReleaseDate = nil
-end
-
-task :test do |t|
- require 'test/unit/testsuite'
- require 'test/unit/ui/console/testrunner'
-
- runner = Test::Unit::UI::Console::TestRunner
-
- $LOAD_PATH.unshift('tests')
- $stderr.puts "Checking for test cases:" if t.verbose
- Dir['tests/*test*.rb'].each do |testcase|
- $stderr.puts "\t#{testcase}" if t.verbose
- load testcase
- end
-
- suite = Test::Unit::TestSuite.new
-
- ObjectSpace.each_object(Class) do |testcase|
- suite << testcase.suite if testcase < Test::Unit::TestCase
- end
-
- runner.run(suite)
-end
-
-spec = eval(File.read("diff-lcs.gemspec"))
-desc "Build the RubyGem for Diff::LCS."
-task :gem => [ :test ]
-Rake::GemPackageTask.new(spec) do |g|
- g.need_tar = false
- g.need_zip = false
- g.package_dir = ".."
-end
-
-desc "Build an Diff::LCS .tar.gz distribution."
-task :tar => [ TARDIST ]
-file TARDIST => [ :test ] do |t|
- current = File.basename(Dir.pwd)
- Dir.chdir("..") do
- begin
- files = Dir["#{current}/**/*"].select { |dd| dd !~ %r{(?:/CVS/?|~$)} }
- files.map! do |dd|
- ddnew = dd.gsub(/^#{current}/, DISTDIR)
- mtime = ReleaseDate || File.stat(dd).mtime
- if File.directory?(dd)
- { :name => ddnew, :mode => 0755, :dir => true, :mtime => mtime }
- else
- if dd =~ %r{bin/}
- mode = 0755
- else
- mode = 0644
- end
- data = File.read(dd)
- { :name => ddnew, :mode => mode, :data => data, :size => data.size,
- :mtime => mtime }
- end
- end
-
- ff = File.open(t.name.gsub(%r{^\.\./}o, ''), "wb")
- gz = Zlib::GzipWriter.new(ff)
- tw = Archive::Tar::Minitar::Writer.new(gz)
-
- files.each do |entry|
- if entry[:dir]
- tw.mkdir(entry[:name], entry)
- else
- tw.add_file_simple(entry[:name], entry) { |os| os.write(entry[:data]) }
- end
- end
- ensure
- tw.close if tw
- gz.close if gz
- end
- end
-end
-task TARDIST => [ :test ]
-
-def sign(file)
- sh %("C:\\Program Files\\Windows Privacy Tools\\GnuPG\\Gpg.exe" -ba #{file})
-end
-
-task :signtar => [ :tar ] do
- sign TARDIST
-end
-task :signgem => [ :gem ] do
- sign "../#{DISTDIR}.gem"
-end
-
-desc "Build everything."
-task :default => [ :signtar, :signgem ] do
-end
diff --git a/diff-lcs/tags/release-1.1.2/install.rb b/diff-lcs/tags/release-1.1.2/install.rb
deleted file mode 100644
index 4bd3d7a..0000000
--- a/diff-lcs/tags/release-1.1.2/install.rb
+++ /dev/null
@@ -1,262 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = Test::Unit::TestSuite.new
- ObjectSpace.each_object(Class) { |o| tests << o.suite if o < Test::Unit::TestCase }
-
- Test::Unit::UI::Console::TestRunner.run(tests)
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/diff-lcs/tags/release-1.1.2/ldiff b/diff-lcs/tags/release-1.1.2/ldiff
deleted file mode 100644
index ae2b245..0000000
--- a/diff-lcs/tags/release-1.1.2/ldiff
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
- # 1) Try to load Ruwiki from the gem.
- # 2) Try to load Ruwiki from $LOAD_PATH.
- # 3) Modify $LOAD_PATH and try to load it from the modified $LOAD_PATH.
- # 4) Fail hard.
-load_state = 1
- begin
- if 1 == load_state
- require 'rubygems'
- require_gem 'diff-lcs', '= 1.1.1'
- else
- require 'diff/lcs'
- end
- rescue LoadError
- load_state += 1
-
- case load_state
- when 3
- $LOAD_PATH.unshift "#{File.dirname($0)}/../lib"
- when 4
- $LOAD_PATH.shift
- $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
- when 5
- raise
- end
- retry
- end
-
-require 'diff/lcs/ldiff'
-
-exit Diff::LCS::Ldiff.run(ARGV)
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/array.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/array.rb
deleted file mode 100644
index e07f8aa..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Includes Diff::LCS into the Array built-in class.
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/block.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/block.rb
deleted file mode 100644
index 7dceb48..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains Diff::LCS::Block for bin/ldiff.
-
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/ldiff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else # [true, true]
- '^'
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/callbacks.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index 74a1cdc..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,322 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains definitions for all default callback objects.
-
-require 'diff/lcs/change'
-
-module Diff::LCS
- # This callback object implements the default set of callback events, which
- # only returns the event itself. Note that #finished_a and #finished_b are
- # not implemented -- I haven't yet figured out where they would be useful.
- #
- # Note that this is intended to be called as is, e.g.,
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks)
- class DefaultCallbacks
- class << self
- # Called when two items match.
- def match(event)
- event
- end
- # Called when the old value is discarded in favour of the new value.
- def discard_a(event)
- event
- end
- # Called when the new value is discarded in favour of the old value.
- def discard_b(event)
- event
- end
- # Called when both the old and new values have changed.
- def change(event)
- event
- end
-
- private :new
- end
- end
-
- # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_sequences.
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks)
- SequenceCallbacks = DefaultCallbacks
- # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_balanced.
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks)
- BalancedCallbacks = DefaultCallbacks
-end
-
- # This will produce a compound array of simple diff change objects. Each
- # element in the #diffs array is a +hunk+ or +hunk+ array, where each
- # element in each +hunk+ array is a single Change object representing the
- # addition or removal of a single element from one of the two tested
- # sequences. The +hunk+ provides the full context for the changes.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # This example shows a simplified array format.
- # # [ [ [ '-', 0, 'a' ] ], # 1
- # # [ [ '+', 2, 'd' ] ], # 2
- # # [ [ '-', 4, 'h' ], # 3
- # # [ '+', 4, 'f' ] ],
- # # [ [ '+', 6, 'k' ] ], # 4
- # # [ [ '-', 8, 'n' ], # 5
- # # [ '-', 9, 'p' ],
- # # [ '+', 9, 'r' ],
- # # [ '+', 10, 's' ],
- # # [ '+', 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at position 0
- # of the first sequence should be deleted (<tt>'-'</tt>). The second hunk
- # says that the +d+ at position 2 of the second sequence should be inserted
- # (<tt>'+'</tt>). The third hunk says that the +h+ at position 4 of the
- # first sequence should be removed and replaced with the +f+ from position 4
- # of the second sequence. The other two hunks are described similarly.
- #
- # === Use
- # This callback object must be initialised and is used by the Diff::LCS#diff
- # method.
- #
- # cbo = Diff::LCS::DiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- # cbo.finish
- #
- # Note that the call to #finish is absolutely necessary, or the last set of
- # changes will not be visible. Alternatively, can be used as:
- #
- # cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # The necessary #finish call will be made.
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.map { |f| f.to_a } }
-class Diff::LCS::DiffCallbacks
- # Returns the difference set collected during the diff process.
- attr_reader :diffs
-
- def initialize # :yields self:
- @hunk = []
- @diffs = []
-
- if block_given?
- begin
- yield self
- ensure
- self.finish
- end
- end
- end
-
- # Finalizes the diff process. If an unprocessed hunk still exists, then it
- # is appended to the diff list.
- def finish
- add_nonempty_hunk
- end
-
- def match(event)
- add_nonempty_hunk
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element)
- end
-
-private
- def add_nonempty_hunk
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-end
-
- # This will produce a compound array of contextual diff change objects. Each
- # element in the #diffs array is a "hunk" array, where each element in each
- # "hunk" array is a single change. Each change is a Diff::LCS::ContextChange
- # that contains both the old index and new index values for the change. The
- # "hunk" provides the full context for the changes. Both old and new objects
- # will be presented for changed objects. +nil+ will be substituted for a
- # discarded object.
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks)
- # # This example shows a simplified array format.
- # # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1
- # # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2
- # # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3
- # # [ '+', [ 5, nil ], [ 4, 'f' ] ] ],
- # # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4
- # # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5
- # # [ '+', [ 9, nil ], [ 9, 'r' ] ],
- # # [ '-', [ 9, 'p' ], [ 10, nil ] ],
- # # [ '+', [ 10, nil ], [ 10, 's' ] ],
- # # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ]
- #
- # The five hunks shown are comprised of individual changes; if there is a
- # related set of changes, they are still shown individually.
- #
- # This callback can also be used with Diff::LCS#sdiff, which will produce
- # results like:
- #
- # diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks)
- # # This example shows a simplified array format.
- # # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1
- # # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2
- # # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3
- # # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4
- # # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5
- # # [ "!", [ 9, "p" ], [ 10, "s" ] ],
- # # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ]
- #
- # The five hunks are still present, but are significantly shorter in total
- # presentation, because changed items are shown as changes ("!") instead of
- # potentially "mismatched" pairs of additions and deletions.
- #
- # The result of this operation is similar to that of
- # Diff::LCS::SDiffCallbacks. They may be compared as:
- #
- # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
- #
- # s == c # -> true
- #
- # === Use
- # This callback object must be initialised and can be used by the
- # Diff::LCS#diff or Diff::LCS#sdiff methods.
- #
- # cbo = Diff::LCS::ContextDiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- # cbo.finish
- #
- # Note that the call to #finish is absolutely necessary, or the last set of
- # changes will not be visible. Alternatively, can be used as:
- #
- # cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # The necessary #finish call will be made.
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.map { |f| f.to_a } }
-class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks
- def discard_a(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-
- def change(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-end
-
- # This will produce a simple array of diff change objects. Each element in
- # the #diffs array is a single ContextChange. In the set of #diffs provided
- # by SDiffCallbacks, both old and new objects will be presented for both
- # changed <strong>and unchanged</strong> objects. +nil+ will be substituted
- # for a discarded object.
- #
- # The diffset produced by this callback, when provided to Diff::LCS#sdiff,
- # will compute and display the necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix utility
- # +sdiff+.
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # diffs = Diff::LCS.sdiff(seq1, seq2)
- # # This example shows a simplified array format.
- # # [ [ "-", [ 0, "a"], [ 0, nil ] ],
- # # [ "=", [ 1, "b"], [ 0, "b" ] ],
- # # [ "=", [ 2, "c"], [ 1, "c" ] ],
- # # [ "+", [ 3, nil], [ 2, "d" ] ],
- # # [ "=", [ 3, "e"], [ 3, "e" ] ],
- # # [ "!", [ 4, "h"], [ 4, "f" ] ],
- # # [ "=", [ 5, "j"], [ 5, "j" ] ],
- # # [ "+", [ 6, nil], [ 6, "k" ] ],
- # # [ "=", [ 6, "l"], [ 7, "l" ] ],
- # # [ "=", [ 7, "m"], [ 8, "m" ] ],
- # # [ "!", [ 8, "n"], [ 9, "r" ] ],
- # # [ "!", [ 9, "p"], [ 10, "s" ] ],
- # # [ "+", [ 10, nil], [ 11, "t" ] ] ]
- #
- # The result of this operation is similar to that of
- # Diff::LCS::ContextDiffCallbacks. They may be compared as:
- #
- # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
- #
- # s == c # -> true
- #
- # === Use
- # This callback object must be initialised and is used by the Diff::LCS#sdiff
- # method.
- #
- # cbo = Diff::LCS::SDiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- #
- # As with the other initialisable callback objects, Diff::LCS::SDiffCallbacks
- # can be initialised with a block. As there is no "fininishing" to be done,
- # this has no effect on the state of the object.
- #
- # cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.to_a }
-class Diff::LCS::SDiffCallbacks
- # Returns the difference set collected during the diff process.
- attr_reader :diffs
-
- def initialize #:yields self:
- @diffs = []
- yield self if block_given?
- end
-
- def match(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def change(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-end
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/change.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/change.rb
deleted file mode 100644
index 6ecdf7e..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,169 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Provides Diff::LCS::Change and Diff::LCS::ContextChange.
-
- # Centralises the change test code in Diff::LCS::Change and
- # Diff::LCS::ContextChange, since it's the same for both classes.
-module Diff::LCS::ChangeTypeTests
- def deleting?
- @action == '-'
- end
-
- def adding?
- @action == '+'
- end
-
- def unchanged?
- @action == '='
- end
-
- def changed?
- @changed == '!'
- end
-
- def finished_a?
- @changed == '>'
- end
-
- def finished_b?
- @changed == '<'
- end
-end
-
- # Represents a simplistic (non-contextual) change. Represents the removal or
- # addition of an element from either the old or the new sequenced enumerable.
-class Diff::LCS::Change
- # Returns the action this Change represents. Can be '+' (#adding?), '-'
- # (#deleting?), '=' (#unchanged?), # or '!' (#changed?). When created by
- # Diff::LCS#diff or Diff::LCS#sdiff, it may also be '>' (#finished_a?) or
- # '<' (#finished_b?).
- attr_reader :action
- attr_reader :position
- attr_reader :element
-
- include Comparable
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.element == other.element)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.element <=> other.element if r.zero?
- r
- end
-
- def initialize(action, position, element)
- @action = action
- @position = position
- @element = element
- end
-
- # Creates a Change from an array produced by Change#to_a.
- def to_a
- [@action, @position, @element]
- end
-
- def self.from_a(arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- include Diff::LCS::ChangeTypeTests
-end
-
- # Represents a contextual change. Contains the position and values of the
- # elements in the old and the new sequenced enumerables as well as the action
- # taken.
-class Diff::LCS::ContextChange
- # Returns the action this Change represents. Can be '+' (#adding?), '-'
- # (#deleting?), '=' (#unchanged?), # or '!' (#changed?). When
- # created by Diff::LCS#diff or Diff::LCS#sdiff, it may also be '>'
- # (#finished_a?) or '<' (#finished_b?).
- attr_reader :action
- attr_reader :old_position
- attr_reader :old_element
- attr_reader :new_position
- attr_reader :new_element
-
- include Comparable
-
- def ==(other)
- (@action == other.action) and
- (@old_position == other.old_position) and
- (@new_position == other.new_position) and
- (@old_element == other.old_element) and
- (@new_element == other.new_element)
- end
-
- def inspect(*args)
- %Q(#<#{self.class.name}:#{__id__} @action=#{action} positions=#{old_position},#{new_position} elements=#{old_element.inspect},#{new_element.inspect}>)
- end
-
- def <=>(other)
- r = @action <=> other.action
- r = @old_position <=> other.old_position if r.zero?
- r = @new_position <=> other.new_position if r.zero?
- r = @old_element <=> other.old_element if r.zero?
- r = @new_element <=> other.new_element if r.zero?
- r
- end
-
- def initialize(action, old_position, old_element, new_position, new_element)
- @action = action
- @old_position = old_position
- @old_element = old_element
- @new_position = new_position
- @new_element = new_element
- end
-
- def to_a
- [@action, [@old_position, @old_element], [@new_position, @new_element]]
- end
-
- # Creates a ContextChange from an array produced by ContextChange#to_a.
- def self.from_a(arr)
- if arr.size == 5
- Diff::LCS::ContextChange.new(arr[0], arr[1], arr[2], arr[3], arr[4])
- else
- Diff::LCS::ContextChange.new(arr[0], arr[1][0], arr[1][1], arr[2][0],
- arr[2][1])
- end
- end
-
- # Simplifies a context change for use in some diff callbacks. '<' actions
- # are converted to '-' and '>' actions are converted to '+'.
- def self.simplify(event)
- ea = event.to_a
-
- case ea[0]
- when '-'
- ea[2][1] = nil
- when '<'
- ea[0] = '-'
- ea[2][1] = nil
- when '+'
- ea[1][1] = nil
- when '>'
- ea[0] = '+'
- ea[1][1] = nil
- end
-
- Diff::LCS::ContextChange.from_a(ea)
- end
-
- include Diff::LCS::ChangeTypeTests
-end
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/hunk.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/hunk.rb
deleted file mode 100644
index 58fac9f..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,257 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains Diff::LCS::Hunk for bin/ldiff.
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/ldiff.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/ldiff.rb
deleted file mode 100644
index 61abc47..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/ldiff.rb
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'optparse'
-require 'ostruct'
-require 'diff/lcs/hunk'
-
- # == ldiff Usage
- # ldiff [options] oldfile newfile
- #
- # -c:: Displays a context diff with 3 lines of context.
- # -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
- # -u:: Displays a unified diff with 3 lines of context.
- # -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
- # -e:: Creates an 'ed' script to change oldfile to newfile.
- # -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
- # -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
- # --binary:: Treats the files as binary.
- # -q, --brief:: Reports only whether or not the files differ, not the details.
- # --help:: Shows the command-line help.
- # --version:: Shows the version of Diff::LCS.
- #
- # By default, runs produces an "old-style" diff, with output like UNIX diff.
- #
- # == Copyright
- # Copyright &copy; 2004 Austin Ziegler
- #
- # Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
- # Austin Ziegler <diff-lcs@halostatue.ca>
- #
- # This program is free software. It may be redistributed and/or modified under
- # the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- # Ruby licence.
-module Diff::LCS::Ldiff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def run(args, input = $stdin, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
-
- output << oldhunk.diff(@format)
- output << "\n"
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/string.rb b/diff-lcs/tags/release-1.1.2/lib/diff/lcs/string.rb
deleted file mode 100644
index 2de7d1f..0000000
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Includes Diff::LCS into String.
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/tags/release-1.1.2/tests/00test.rb b/diff-lcs/tags/release-1.1.2/tests/00test.rb
deleted file mode 100644
index 8872dfd..0000000
--- a/diff-lcs/tags/release-1.1.2/tests/00test.rb
+++ /dev/null
@@ -1,626 +0,0 @@
-#! /usr/bin/env ruby
-#
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-module Diff::LCS::Tests
- def __format_diffs(diffs)
- diffs.map do |e|
- if e.kind_of?(Array)
- e.map { |f| f.to_a.join }.join(", ")
- else
- e.to_a.join
- end
- end.join("; ")
- end
-
- def __map_diffs(diffs, klass = Diff::LCS::ContextChange)
- diffs.map do |chunks|
- if klass == Diff::LCS::ContextChange
- klass.from_a(chunks)
- else
- chunks.map { |changes| klass.from_a(changes) }
- end
- end
- end
-
- def __simple_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_element
- @matched_b << event.new_element
- end
-
- def discard_b(event)
- @discards_b << event.new_element
- end
-
- def discard_a(event)
- @discards_a << event.old_element
- end
-
- def finished_a(event)
- @done_a << [event.old_element, event.old_position]
- end
-
- def finished_b(event)
- @done_b << [event.new_element, event.new_position]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M#{event.old_position}#{event.new_position} "
- end
-
- def discard_a(event)
- @result << "DA#{event.old_position}#{event.new_position} "
- end
-
- def discard_b(event)
- @result << "DB#{event.old_position}#{event.new_position} "
- end
-
- def change(event)
- @result << "C#{event.old_position}#{event.new_position} "
- end
- end
- cb.reset
- cb
- end
-
- def setup
- @seq1 = %w(a b c e h j l m n p)
- @seq2 = %w(b c d e f j k l m r s t)
-
- @correct_lcs = %w(b c e j l m)
-
- @skipped_seq1 = 'a h n p'
- @skipped_seq2 = 'd f k r s t'
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '-', 9, 'p' ],
- [ '+', 9, 'r' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
- end
-end
-
-class TestLCS < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct_lcs.size)
- res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
- assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
- assert_equal(@correct_lcs, ares.compact)
- assert_equal(@correct_lcs, bres.compact)
- assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
- assert_equal(res.compact, @correct_lcs)
- end
-end
-
-class TestSequences < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __simple_callbacks
- class << callbacks
- undef :finished_a
- undef :finished_b
- end
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_nothing_raised do
- callbacks = __simple_callbacks
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
-
-# seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
-# assert_nothing_raised do
-# callbacks = __simple_callbacks
-# class << callbacks
-# undef :finished_a
-# undef :finished_b
-# end
-# Diff::LCS.traverse_sequences(seqw, [], callbacks)
-# end
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
- assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
- assert_equal(@correct_diff, diff)
- end
-
- def test_diff_empty
- seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
- correct_diff = [
- [ [ '-', 0, 'abcd' ],
- [ '-', 1, 'efgh' ],
- [ '-', 2, 'ijkl' ],
- [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
- diff = nil
-
- assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
-
- correct_diff = [
- [ [ '+', 0, 'abcd' ],
- [ '+', 1, 'efgh' ],
- [ '+', 2, 'ijkl' ],
- [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
- assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
- end
-end
-
-class TestBalanced < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sdiff_a
- sdiff = nil
- seq1 = %w(abc def yyy xxx ghi jkl)
- seq2 = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- [ '=', [ 0, 'abc' ], [ 0, 'abc' ] ],
- [ '!', [ 1, 'def' ], [ 1, 'dxf' ] ],
- [ '-', [ 2, 'yyy' ], [ 2, nil ] ],
- [ '=', [ 3, 'xxx' ], [ 2, 'xxx' ] ],
- [ '=', [ 4, 'ghi' ], [ 3, 'ghi' ] ],
- [ '=', [ 5, 'jkl' ], [ 4, 'jkl' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '=', [ 1, 'b' ], [ 0, 'b' ] ],
- [ '=', [ 2, 'c' ], [ 1, 'c' ] ],
- [ '+', [ 3, nil ], [ 2, 'd' ] ],
- [ '=', [ 3, 'e' ], [ 3, 'e' ] ],
- [ '!', [ 4, 'h' ], [ 4, 'f' ] ],
- [ '=', [ 5, 'j' ], [ 5, 'j' ] ],
- [ '+', [ 6, nil ], [ 6, 'k' ] ],
- [ '=', [ 6, 'l' ], [ 7, 'l' ] ],
- [ '=', [ 7, 'm' ], [ 8, 'm' ] ],
- [ '!', [ 8, 'n' ], [ 9, 'r' ] ],
- [ '!', [ 9, 'p' ], [ 10, 's' ] ],
- [ '+', [ 10, nil ], [ 11, 't' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- seq1 = %w(a b c d e)
- seq2 = %w(a e)
- correct_sdiff = [
- [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
- [ '-', [ 1, 'b' ], [ 1, nil ] ],
- [ '-', [ 2, 'c' ], [ 1, nil ] ],
- [ '-', [ 3, 'd' ], [ 1, nil ] ],
- [ '=', [ 4, 'e' ], [ 1, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
- [ '+', [ 1, nil ], [ 1, 'b' ] ],
- [ '+', [ 1, nil ], [ 2, 'c' ] ],
- [ '+', [ 1, nil ], [ 3, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 4, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- seq1 = %w(v x a e)
- seq2 = %w(w y a b c d e)
- correct_sdiff = [
- [ '!', [ 0, 'v' ], [ 0, 'w' ] ],
- [ '!', [ 1, 'x' ], [ 1, 'y' ] ],
- [ '=', [ 2, 'a' ], [ 2, 'a' ] ],
- [ '+', [ 3, nil ], [ 3, 'b' ] ],
- [ '+', [ 3, nil ], [ 4, 'c' ] ],
- [ '+', [ 3, nil ], [ 5, 'd' ] ],
- [ '=', [ 3, 'e' ], [ 6, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- seq1 = %w(x a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '-', [ 0, 'x' ], [ 0, nil ] ],
- [ '=', [ 1, 'a' ], [ 0, 'a' ] ],
- [ '+', [ 2, nil ], [ 1, 'b' ] ],
- [ '+', [ 2, nil ], [ 2, 'c' ] ],
- [ '+', [ 2, nil ], [ 3, 'd' ] ],
- [ '=', [ 2, 'e' ], [ 4, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(x a b c d e)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'x' ] ],
- [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
- [ '+', [ 1, nil ], [ 2, 'b' ] ],
- [ '+', [ 1, nil ], [ 3, 'c' ] ],
- [ '+', [ 1, nil ], [ 4, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 5, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- seq1 = %w(a e v)
- seq2 = %w(x a b c d e w x)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'x' ] ],
- [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
- [ '+', [ 1, nil ], [ 2, 'b' ] ],
- [ '+', [ 1, nil ], [ 3, 'c' ] ],
- [ '+', [ 1, nil ], [ 4, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 5, 'e' ] ],
- [ '!', [ 2, 'v' ], [ 6, 'w' ] ],
- [ '+', [ 3, nil ], [ 7, 'x' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- seq1 = %w()
- seq2 = %w(a b c)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'a' ] ],
- [ '+', [ 0, nil ], [ 1, 'b' ] ],
- [ '+', [ 0, nil ], [ 2, 'c' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w()
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '-', [ 1, 'b' ], [ 0, nil ] ],
- [ '-', [ 2, 'c' ], [ 0, nil ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(1)
- correct_sdiff = [
- [ '!', [ 0, 'a' ], [ 0, '1' ] ],
- [ '-', [ 1, 'b' ], [ 1, nil ] ],
- [ '-', [ 2, 'c' ], [ 1, nil ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(c)
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '-', [ 1, 'b' ], [ 0, nil ] ],
- [ '=', [ 2, 'c' ], [ 0, 'c' ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_m
- sdiff = nil
- seq1 = %w(abcd efgh ijkl mnop)
- seq2 = []
- correct_sdiff = [
- [ '-', [ 0, 'abcd' ], [ 0, nil ] ],
- [ '-', [ 1, 'efgh' ], [ 0, nil ] ],
- [ '-', [ 2, 'ijkl' ], [ 0, nil ] ],
- [ '-', [ 3, 'mnop' ], [ 0, nil ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_n
- sdiff = nil
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnop)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'abcd' ] ],
- [ '+', [ 0, nil ], [ 1, 'efgh' ] ],
- [ '+', [ 0, nil ], [ 2, 'ijkl' ] ],
- [ '+', [ 0, nil ], [ 3, 'mnop' ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_balanced_a
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 M22 ", callback.result)
- end
-
- def test_balanced_b
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 DB21 M22 ", callback.result)
- end
-
- def test_balanced_c
- seq1 = %w(a x y c)
- seq2 = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 C22 M33 ", callback.result)
- end
-
- def test_balanced_d
- seq1 = %w(x y c)
- seq2 = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 M22 ", callback.result)
- end
-
- def test_balanced_e
- seq1 = %w(a x y z)
- seq2 = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 DA33 ", callback.result)
- end
-
- def test_balanced_f
- seq1 = %w(a z)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 ", callback.result)
- end
-
- def test_balanced_g
- seq1 = %w(z a)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 M10 ", callback.result)
- end
-
- def test_balanced_h
- seq1 = %w(a b c)
- seq2 = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 ", callback.result)
- end
-
- def test_balanced_i
- seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- seq2 = []
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
- end
-
- def test_balanced_j
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
- end
-end
-
-class TestPatching < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_patch_diff
- ps = ms1 = ms2 = ms3 = nil
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms2 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::SDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- end
-
- # Tests patch bug #891:
- # http://rubyforge.org/tracker/?func=detail&atid=407&aid=891&group_id=84
- def test_patch_bug891
- s1 = s2 = s3 = s4 = s5 = ps = nil
- assert_nothing_raised do
- s1 = %w{a b c d e f g h i j k }
- s2 = %w{a b c d D e f g h i j k }
- ps = Diff::LCS::diff(s1, s2)
- s3 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::ContextDiffCallbacks)
- s4 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::SDiffCallbacks)
- s5 = Diff::LCS.patch(s1, ps, :patch)
- end
- assert_equal(s2, s3)
- assert_equal(s2, s4)
- assert_equal(s2, s5)
-
- assert_nothing_raised do
- ps = Diff::LCS::sdiff(s1, s2)
- s3 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::ContextDiffCallbacks)
- s4 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::DiffCallbacks)
- s5 = Diff::LCS.patch(s1, ps, :patch)
- end
- assert_equal(s2, s3)
- assert_equal(s2, s4)
- assert_equal(s2, s5)
- end
-
- def test_patch_sdiff
- ps = ms1 = ms2 = ms3 = nil
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::DiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- end
-end
diff --git a/diff-lcs/trunk/ChangeLog b/diff-lcs/trunk/ChangeLog
deleted file mode 100644
index 08d3ee5..0000000
--- a/diff-lcs/trunk/ChangeLog
+++ /dev/null
@@ -1,46 +0,0 @@
-Revision history for Ruby library Diff::LCS. Unless explicitly noted otherwise,
-all changes are produced by Austin Ziegler <diff-lcs@halostatue.ca>.
-
-== Diff::LCS 1.1.2
-* Fixed a problem reported by Mauricio Fernandez in htmldiff. Future versions
- of Diff::LCS will be removing this program.
-
-== Diff::LCS 1.1.1
-* Fixed bug #891:
- http://rubyforge.org/tracker/?func=detail&atid=407&aid=891&group_id=84
-* Fixed a problem with callback initialisation code (it assumed that all
- callbacks passed as classes can be initialised; now, it rescues
- NoMethodError in the event of private :new being called).
-* Modified the non-initialisable callbacks to have a private #new method.
-* Moved ldiff core code to Diff::LCS::Ldiff (diff/lcs/ldiff.rb).
-
-== Diff::LCS 1.1.0
-* Eliminated the need for Diff::LCS::Event and removed it.
-* Added a contextual diff callback, Diff::LCS::ContextDiffCallback.
-* Implemented patching/unpatching for standard Diff callback output formats
- with both #diff and #sdiff.
-* Extensive documentation changes.
-
-== Diff::LCS 1.0.4
-* Fixed a problem with bin/ldiff output, especially for unified format.
- Newlines that should have been present weren't.
-* Changed the .tar.gz installer to generate Windows batch files if ones do not
- exist already. Removed the existing batch files as they didn't work.
-
-== Diff::LCS 1.0.3
-* Fixed a problem with #traverse_sequences where the first difference from the
- left sequence might not be appropriately captured.
-
-== Diff::LCS 1.0.2
-* Fixed an issue with ldiff not working because actions were changed from
- symbols to strings.
-
-== Diff::LCS 1.0.1
-* Minor modifications to the gemspec, the README.
-* Renamed the diff program to ldiff (as well as the companion batch file) so as
- to not collide with the standard diff program.
-* Fixed issues with RubyGEMs. Requires RubyGems > 0.6.1 or >= 0.6.1 with the
- latest CVS version.
-
-== Diff::LCS 1.0
-* Initial release based mostly on Perl's Algorithm::Diff.
diff --git a/diff-lcs/trunk/Install b/diff-lcs/trunk/Install
deleted file mode 100644
index 794796e..0000000
--- a/diff-lcs/trunk/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Diff::LCS available as
-diff-lcs-1.1.2.gem from the usual sources.
diff --git a/diff-lcs/trunk/README b/diff-lcs/trunk/README
deleted file mode 100644
index 4c9b517..0000000
--- a/diff-lcs/trunk/README
+++ /dev/null
@@ -1,76 +0,0 @@
-Diff::LCS README
-================
-Diff::LCS is a port of Algorithm::Diff[1] that uses the McIlroy-Hunt
-longest common subsequence (LCS) algorithm to compute intelligent
-differences between two sequenced enumerable containers[2]. The
-implementation is based on Mario I. Wolczko's[3] Smalltalk version (1.2,
-1993)[4] and Ned Konz's[5] Perl version (Algorithm::Diff)[6].
-
-This release is version 1.1.2, fixing an htmldiff bug in 1.1.1. Version 1.1.0
-added new features, including the ability to #patch and #unpatch changes as
-well as a new contextual diff callback, Diff::LCS::ContextDiffCallbacks, that
-should improve the context sensitivity of patching.
-
-Using this module is quite simple. By default, Diff::LCS does not extend
-objects with the Diff::LCS interface, but will be called as if it were a
-function:
-
- require 'diff/lcs'
-
- seq1 = %w(a b c e h j l m n p)
- seq2 = %w(b c d e f j k l m r s t)
-
- lcs = Diff::LCS.LCS(seq1, seq2)
- diffs = Diff::LCS.diff(seq1, seq2)
- sdiff = Diff::LCS.sdiff(seq1, seq2)
- seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- seq2 == Diff::LCS.patch!(seq1, diffs)
- seq1 == Diff::LCS.unpatch!(seq2, diffs)
- seq2 == Diff::LCS.patch!(seq1, sdiff)
- seq1 == Diff::LCS.unpatch!(seq2, sdiff)
-
-Objects can be extended with Diff::LCS:
-
- seq1.extend(Diff::LCS)
- lcs = seq1.lcs(seq2)
- diffs = seq1.diff(seq2)
- sdiff = seq1.sdiff(seq2)
- seq = seq1.traverse_sequences(seq2, callback_obj)
- bal = seq1.traverse_balanced(seq2, callback_obj)
- seq2 == seq1.patch!(diffs)
- seq1 == seq2.unpatch!(diffs)
- seq2 == seq1.patch!(sdiff)
- seq1 == seq2.unpatch!(sdiff)
-
-By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will
-be extended for use this way.
-
-Copyright
-=========
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-
-Footnotes
-=========
-[1] This library is called Diff::LCS because there are multiple
- Ruby libraries called Algorithm::Diff maintained by other authors.
-[2] By sequenced enumerable, I mean that the order of enumeration is
- predictable and consistent for the same set of data. While it is
- theoretically possible to generate a diff for unordereded hash, it
- will only be meaningful if the enumeration of the hashes is
- consistent. In general, this will mean that containers that behave
- like String or Array will perform best.
-[3] mario@wolczko.com
-[4] ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
-[5] perl@bike-nomad.com
-[6] http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/
diff --git a/diff-lcs/trunk/bin/htmldiff b/diff-lcs/trunk/bin/htmldiff
deleted file mode 100644
index 509860c..0000000
--- a/diff-lcs/trunk/bin/htmldiff
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
-begin
- require 'rubygems'
- require_gem 'diff-lcs', "1.1.1"
- require 'diff/lcs/string'
-rescue LoadError
- require 'diff/lcs'
- require 'diff/lcs/string'
-end
-
-require 'text/format'
-
-class HTMLDiff #:nodoc:
- attr_accessor :output
-
- def initialize(output)
- @output = output
- end
-
- # This will be called with both lines are the same
- def match(event)
- @output << %Q|<pre class="match">#{event.old_element}</pre>\n|
- end
-
- # This will be called when there is a line in A that isn't in B
- def discard_a(event)
- @output << %Q|<pre class="only_a">#{event.old_element}</pre>\n|
- end
-
- # This will be called when there is a line in B that isn't in A
- def discard_b(event)
- @output << %Q|<pre class="only_b">#{event.new_element}</pre>\n|
- end
-end
-
-if ARGV.size != 2
- puts "usage: #{File.basename($0)} old new > output.html"
- exit 255
-end
-
-hd = HTMLDiff.new($stdout)
-tf = Text::Format.new
-tf.tabstop = 4
-
-preprocess = lambda { |line| tf.expand(line.chomp) }
-
-a = IO.readlines(ARGV[0]).map(&preprocess)
-b = IO.readlines(ARGV[1]).map(&preprocess)
-
-$stdout.write <<-START
-<html>
- <head>
- <title>diff #{ARGV[0]} #{ARGV[1]}</title>
- <style>
- body { margin: 0; }
- .diff
- {
- border: 1px solid black;
- margin: 1em 2em;
- }
- pre
- {
- padding-left: 1em;
- margin: 0;
- font-family: Lucida, Courier, monospaced;
- white-space: pre;
- }
- .match { }
- .only_a
- {
- background-color: #fdd;
- color: red;
- text-decoration: line-through;
- }
- .only_b
- {
- background-color: #ddf;
- color: blue;
- border-left: 3px solid blue
- }
- h1 { margin-left: 2em; }
- </style>
- </head>
- <body>
- <h1>diff&nbsp;
- <span class="only_a">#{ARGV[0]}</span>&nbsp;
- <span class="only_b">#{ARGV[1]}</span>
- </h1>
- <div class="diff">
-START
-
-Diff::LCS.traverse_sequences(a, b, hd)
-
-$stdout.write <<-END
- </div>
- </body>
-</html>
-END
diff --git a/diff-lcs/trunk/bin/ldiff b/diff-lcs/trunk/bin/ldiff
deleted file mode 100644
index ae2b245..0000000
--- a/diff-lcs/trunk/bin/ldiff
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-
- # 1) Try to load Ruwiki from the gem.
- # 2) Try to load Ruwiki from $LOAD_PATH.
- # 3) Modify $LOAD_PATH and try to load it from the modified $LOAD_PATH.
- # 4) Fail hard.
-load_state = 1
- begin
- if 1 == load_state
- require 'rubygems'
- require_gem 'diff-lcs', '= 1.1.1'
- else
- require 'diff/lcs'
- end
- rescue LoadError
- load_state += 1
-
- case load_state
- when 3
- $LOAD_PATH.unshift "#{File.dirname($0)}/../lib"
- when 4
- $LOAD_PATH.shift
- $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
- when 5
- raise
- end
- retry
- end
-
-require 'diff/lcs/ldiff'
-
-exit Diff::LCS::Ldiff.run(ARGV)
diff --git a/diff-lcs/trunk/diff-lcs.gemspec b/diff-lcs/trunk/diff-lcs.gemspec
deleted file mode 100644
index ba49ed6..0000000
--- a/diff-lcs/trunk/diff-lcs.gemspec
+++ /dev/null
@@ -1,40 +0,0 @@
-Gem::Specification.new do |s|
- s.name = %{diff-lcs}
- s.version = %{1.1.2}
- s.author = %{Austin Ziegler}
- s.email = %{diff-lcs@halostatue.ca}
- s.homepage = %{http://rubyforge.org/projects/ruwiki/}
- s.rubyforge_project = %{ruwiki}
-
- s.files = Dir.glob("**/*").delete_if do |item|
- item.include?("CVS") or item.include?(".svn") or
- item == "install.rb" or item =~ /~$/ or
- item =~ /gem(?:spec)?$/
- end
-
- s.summary = %{Provides a list of changes that represent the difference between two sequenced collections.}
-
- s.required_ruby_version = %(>=1.8.1)
-
- s.executables = %w(ldiff htmldiff)
- s.bindir = %(bin)
-
- s.test_files = %w{tests/00test.rb}
-
- s.autorequire = %{diff/lcs}
- s.require_paths = %w{lib}
-
- description = []
- File.open("README") do |file|
- file.each do |line|
- line.chomp!
- break if line.empty?
- description << "#{line.gsub(/\[\d\]/, '')}"
- end
- end
- s.description = description[2..-1].join(" ")
-
- s.has_rdoc = true
- s.rdoc_options = ["--title", "Diff::LCS -- A Diff Algorithm", "--main", "README", "--line-numbers"]
- s.extra_rdoc_files = %w(README ChangeLog Install)
-end
diff --git a/diff-lcs/trunk/install.rb b/diff-lcs/trunk/install.rb
deleted file mode 100644
index 4bd3d7a..0000000
--- a/diff-lcs/trunk/install.rb
+++ /dev/null
@@ -1,262 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = Test::Unit::TestSuite.new
- ObjectSpace.each_object(Class) { |o| tests << o.suite if o < Test::Unit::TestCase }
-
- Test::Unit::UI::Console::TestRunner.run(tests)
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/diff-lcs/trunk/lib/diff/lcs.rb b/diff-lcs/trunk/lib/diff/lcs.rb
deleted file mode 100644
index b74b2d3..0000000
--- a/diff-lcs/trunk/lib/diff/lcs.rb
+++ /dev/null
@@ -1,1105 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later), the Perl Artistic
-# licence, or the Ruby licence.
-#
-# $Id$
-#++
-
-module Diff
- # = Diff::LCS 1.1.2
- # Computes "intelligent" differences between two sequenced Enumerables.
- # This is an implementation of the McIlroy-Hunt "diff" algorithm for
- # Enumerable objects that include Diffable.
- #
- # Based on Mario I. Wolczko's <mario@wolczko.com> Smalltalk version
- # (1.2, 1993) and Ned Konz's <perl@bike-nomad.com> Perl version
- # (Algorithm::Diff).
- #
- # == Synopsis
- # require 'diff/lcs'
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- # diffs = Diff::LCS.diff(seq1, seq2)
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
- # seq2 == Diff::LCS.patch(seq1, diffs)
- # seq2 == Diff::LCS.patch!(seq1, diffs)
- # seq1 == Diff::LCS.unpatch(seq2, diffs)
- # seq1 == Diff::LCS.unpatch!(seq2, diffs)
- # seq2 == Diff::LCS.patch(seq1, sdiff)
- # seq2 == Diff::LCS.patch!(seq1, sdiff)
- # seq1 == Diff::LCS.unpatch(seq2, sdiff)
- # seq1 == Diff::LCS.unpatch!(seq2, sdiff)
- #
- # Alternatively, objects can be extended with Diff::LCS:
- #
- # seq1.extend(Diff::LCS)
- # lcs = seq1.lcs(seq2)
- # diffs = seq1.diff(seq2)
- # sdiff = seq1.sdiff(seq2)
- # seq = seq1.traverse_sequences(seq2, callback_obj)
- # bal = seq1.traverse_balanced(seq2, callback_obj)
- # seq2 == seq1.patch(diffs)
- # seq2 == seq1.patch!(diffs)
- # seq1 == seq2.unpatch(diffs)
- # seq1 == seq2.unpatch!(diffs)
- # seq2 == seq1.patch(sdiff)
- # seq2 == seq1.patch!(sdiff)
- # seq1 == seq2.unpatch(sdiff)
- # seq1 == seq2.unpatch!(sdiff)
- #
- # Default extensions are provided for Array and String objects through
- # the use of 'diff/lcs/array' and 'diff/lcs/string'.
- #
- # == Introduction (by Mark-Jason Dominus)
- #
- # <em>The following text is from the Perl documentation. The only
- # changes have been to make the text appear better in Rdoc</em>.
- #
- # I once read an article written by the authors of +diff+; they said
- # that they hard worked very hard on the algorithm until they found the
- # right one.
- #
- # I think what they ended up using (and I hope someone will correct me,
- # because I am not very confident about this) was the `longest common
- # subsequence' method. In the LCS problem, you have two sequences of
- # items:
- #
- # a b c d f g h j q z
- # a b c d e f g i j k r x y z
- #
- # and you want to find the longest sequence of items that is present in
- # both original sequences in the same order. That is, you want to find a
- # new sequence *S* which can be obtained from the first sequence by
- # deleting some items, and from the second sequence by deleting other
- # items. You also want *S* to be as long as possible. In this case *S*
- # is:
- #
- # a b c d f g j z
- #
- # From there it's only a small step to get diff-like output:
- #
- # e h i k q r x y
- # + - + + - + + +
- #
- # This module solves the LCS problem. It also includes a canned function
- # to generate +diff+-like output.
- #
- # It might seem from the example above that the LCS of two sequences is
- # always pretty obvious, but that's not always the case, especially when
- # the two sequences have many repeated elements. For example, consider
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # A naive approach might start by matching up the +a+ and +b+ that
- # appear at the beginning of each sequence, like this:
- #
- # a x b y c z p d q
- # a b c a b y c z
- #
- # This finds the common subsequence +a b c z+. But actually, the LCS is
- # +a x b y c z+:
- #
- # a x b y c z p d q
- # a b c a x b y c z
- #
- # == Author
- # This version is by Austin Ziegler <diff-lcs@halostatue.ca>.
- #
- # It is based on the Perl Algorithm::Diff by Ned Konz
- # <perl@bike-nomad.com>, copyright &copy; 2000 - 2002 and the Smalltalk
- # diff version by Mario I. Wolczko <mario@wolczko.com>, copyright &copy;
- # 1993. Documentation includes work by Mark-Jason Dominus.
- #
- # == Licence
- # Copyright &copy; 2004 Austin Ziegler
- # This program is free software; you can redistribute it and/or modify it
- # under the same terms as Ruby, or alternatively under the Perl Artistic
- # licence.
- #
- # == Credits
- # Much of the documentation is taken directly from the Perl
- # Algorithm::Diff implementation and was written originally by Mark-Jason
- # Dominus <mjd-perl-diff@plover.com> and later by Ned Konz. The basic Ruby
- # implementation was re-ported from the Smalltalk implementation, available
- # at ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
- #
- # #sdiff and #traverse_balanced were written for the Perl version by Mike
- # Schilli <m@perlmeister.com>.
- #
- # "The algorithm is described in <em>A Fast Algorithm for Computing Longest
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May 1977, with
- # a few minor improvements to improve the speed."
- module LCS
- VERSION = '1.1.2'
- end
-end
-
-require 'diff/lcs/callbacks'
-
-module Diff::LCS
- # Returns an Array containing the longest common subsequence(s) between
- # +self+ and +other+. See Diff::LCS#LCS.
- #
- # lcs = seq1.lcs(seq2)
- def lcs(other, &block) #:yields self[ii] if there are matched subsequences:
- Diff::LCS.LCS(self, other, &block)
- end
-
- # Returns the difference set between +self+ and +other+. See
- # Diff::LCS#diff.
- def diff(other, callbacks = nil, &block)
- Diff::LCS::diff(self, other, callbacks, &block)
- end
-
- # Returns the balanced ("side-by-side") difference set between +self+ and
- # +other+. See Diff::LCS#sdiff.
- def sdiff(other, callbacks = nil, &block)
- Diff::LCS::sdiff(self, other, callbacks, &block)
- end
-
- # Traverses the discovered longest common subsequences between +self+ and
- # +other+. See Diff::LCS#traverse_sequences.
- def traverse_sequences(other, callbacks = nil, &block)
- traverse_sequences(self, other, callbacks || Diff::LCS::YieldingCallbacks,
- &block)
- end
-
- # Traverses the discovered longest common subsequences between +self+ and
- # +other+ using the alternate, balanced algorithm. See
- # Diff::LCS#traverse_balanced.
- def traverse_balanced(other, callbacks = nil, &block)
- traverse_balanced(self, other, callbacks || Diff::LCS::YieldingCallbacks,
- &block)
- end
-
- # Attempts to patch a copy of +self+ with the provided +patchset+. See
- # Diff::LCS#patch.
- def patch(patchset)
- Diff::LCS::patch(self.dup, patchset)
- end
-
- # Attempts to unpatch a copy of +self+ with the provided +patchset+.
- # See Diff::LCS#patch.
- def unpatch(patchset)
- Diff::LCS::unpatch(self.dup, patchset)
- end
-
- # Attempts to patch +self+ with the provided +patchset+. See
- # Diff::LCS#patch!. Does no autodiscovery.
- def patch!(patchset)
- Diff::LCS::patch!(self, patchset)
- end
-
- # Attempts to unpatch +self+ with the provided +patchset+. See
- # Diff::LCS#unpatch. Does no autodiscovery.
- def unpatch!(patchset)
- Diff::LCS::unpatch!(self, patchset)
- end
-end
-
-module Diff::LCS
- class << self
- # Given two sequenced Enumerables, LCS returns an Array containing their
- # longest common subsequences.
- #
- # lcs = Diff::LCS.LCS(seq1, seq2)
- #
- # This array whose contents is such that:
- #
- # lcs.each_with_index do |ee, ii|
- # assert(ee.nil? || (seq1[ii] == seq2[ee]))
- # end
- #
- # If a block is provided, the matching subsequences will be yielded from
- # +seq1+ in turn and may be modified before they are placed into the
- # returned Array of subsequences.
- def LCS(seq1, seq2, &block) #:yields seq1[ii] for each matched:
- matches = Diff::LCS.__lcs(seq1, seq2)
- ret = []
- matches.each_with_index do |ee, ii|
- unless matches[ii].nil?
- if block_given?
- ret << (yield seq1[ii])
- else
- ret << seq1[ii]
- end
- end
- end
- ret
- end
-
- # Diff::LCS.diff computes the smallest set of additions and deletions
- # necessary to turn the first sequence into the second, and returns a
- # description of these changes.
- #
- # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate
- # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks.
- # If a Class argument is provided for +callbacks+, #diff will attempt
- # to initialise it. If the +callbacks+ object (possibly initialised)
- # responds to #finish, it will be called.
- def diff(seq1, seq2, callbacks = nil, &block) # :yields diff changes:
- callbacks ||= Diff::LCS::DiffCallbacks
- if callbacks.kind_of?(Class)
- cb = callbacks.new rescue callbacks
- callbacks = cb
- end
- traverse_sequences(seq1, seq2, callbacks)
- callbacks.finish if callbacks.respond_to?(:finish)
-
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.sdiff computes all necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix
- # utility <em>sdiff</em> does:
- #
- # old < -
- # same same
- # before | after
- # - > new
- #
- # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate
- # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If
- # a Class argument is provided for +callbacks+, #diff will attempt to
- # initialise it. If the +callbacks+ object (possibly initialised)
- # responds to #finish, it will be called.
- def sdiff(seq1, seq2, callbacks = nil, &block) #:yields diff changes:
- callbacks ||= Diff::LCS::SDiffCallbacks
- if callbacks.kind_of?(Class)
- cb = callbacks.new rescue callbacks
- callbacks = cb
- end
- traverse_balanced(seq1, seq2, callbacks)
- callbacks.finish if callbacks.respond_to?(:finish)
-
- if block_given?
- res = callbacks.diffs.map do |hunk|
- if hunk.kind_of?(Array)
- hunk = hunk.map { |block| yield block }
- else
- yield hunk
- end
- end
- res
- else
- callbacks.diffs
- end
- end
-
- # Diff::LCS.traverse_sequences is the most general facility provided by this
- # module; +diff+ and +LCS+ are implemented as calls to it.
- #
- # The arguments to #traverse_sequences are the two sequences to
- # traverse, and a callback object, like this:
- #
- # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
- #
- # #diff is implemented with #traverse_sequences.
- #
- # == Callback Methods
- # Optional callback methods are <em>emphasized</em>.
- #
- # callbacks#match:: Called when +a+ and +b+ are pointing
- # to common elements in +A+ and +B+.
- # callbacks#discard_a:: Called when +a+ is pointing to an
- # element not in +B+.
- # callbacks#discard_b:: Called when +b+ is pointing to an
- # element not in +A+.
- # <em>callbacks#finished_a</em>:: Called when +a+ has reached the end of
- # sequence +A+.
- # <em>callbacks#finished_b</em>:: Called when +b+ has reached the end of
- # sequence +B+.
- #
- # == Algorithm
- # a---+
- # v
- # A = a b c e h j l m n p
- # B = b c d e f j k l m r s t
- # ^
- # b---+
- #
- # If there are two arrows (+a+ and +b+) pointing to elements of
- # sequences +A+ and +B+, the arrows will initially point to the first
- # elements of their respective sequences. #traverse_sequences will
- # advance the arrows through the sequences one element at a time,
- # calling a method on the user-specified callback object before each
- # advance. It will advance the arrows in such a way that if there are
- # elements <tt>A[ii]</tt> and <tt>B[jj]</tt> which are both equal and
- # part of the longest common subsequence, there will be some moment
- # during the execution of #traverse_sequences when arrow +a+ is pointing
- # to <tt>A[ii]</tt> and arrow +b+ is pointing to <tt>B[jj]</tt>. When
- # this happens, #traverse_sequences will call <tt>callbacks#match</tt>
- # and then it will advance both arrows.
- #
- # Otherwise, one of the arrows is pointing to an element of its sequence
- # that is not part of the longest common subsequence.
- # #traverse_sequences will advance that arrow and will call
- # <tt>callbacks#discard_a</tt> or <tt>callbacks#discard_b</tt>, depending
- # on which arrow it advanced. If both arrows point to elements that are
- # not part of the longest common subsequence, then #traverse_sequences
- # will advance one of them and call the appropriate callback, but it is
- # not specified which it will call.
- #
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
- # and <tt>callbacks#discard_b</tt> are invoked with an event comprising
- # the action ("=", "+", or "-", respectively), the indicies +ii+ and
- # +jj+, and the elements <tt>A[ii]</tt> and <tt>B[jj]</tt>. Return
- # values are discarded by #traverse_sequences.
- #
- # === End of Sequences
- # If arrow +a+ reaches the end of its sequence before arrow +b+ does,
- # #traverse_sequence try to call <tt>callbacks#finished_a</tt> with the
- # last index and element of +A+ (<tt>A[-1]</tt>) and the current index
- # and element of +B+ (<tt>B[jj]</tt>). If <tt>callbacks#finished_a</tt>
- # does not exist, then <tt>callbacks#discard_b</tt> will be called on
- # each element of +B+ until the end of the sequence is reached (the call
- # will be done with <tt>A[-1]</tt> and <tt>B[jj]</tt> for each element).
- #
- # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+,
- # <tt>callbacks#finished_b</tt> will be called with the current index
- # and element of +A+ (<tt>A[ii]</tt>) and the last index and element of
- # +B+ (<tt>A[-1]</tt>). Again, if <tt>callbacks#finished_b</tt> does not
- # exist on the callback object, then <tt>callbacks#discard_a</tt> will
- # be called on each element of +A+ until the end of the sequence is
- # reached (<tt>A[ii]</tt> and <tt>B[-1]</tt>).
- #
- # There is a chance that one additional <tt>callbacks#discard_a</tt> or
- # <tt>callbacks#discard_b</tt> will be called after the end of the
- # sequence is reached, if +a+ has not yet reached the end of +A+ or +b+
- # has not yet reached the end of +B+.
- def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks, &block) #:yields change events:
- matches = Diff::LCS.__lcs(seq1, seq2)
-
- run_finished_a = run_finished_b = false
- string = seq1.kind_of?(String)
-
- a_size = seq1.size
- b_size = seq2.size
- ai = bj = 0
-
- (0 .. matches.size).each do |ii|
- b_line = matches[ii]
-
- ax = string ? seq1[ii, 1] : seq1[ii]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- if b_line.nil?
- unless ax.nil?
- event = Diff::LCS::ContextChange.new('-', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- end
- else
- loop do
- break unless bj < b_line
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('=', ii, ax, bj, bx)
- event = yield event if block_given?
- callbacks.match(event)
- bj += 1
- end
- ai = ii
- end
- ai += 1
-
- # The last entry (if any) processed was a match. +ai+ and +bj+ point
- # just past the last matching lines in their sequences.
- while (ai < a_size) or (bj < b_size)
- # last A?
- if ai == a_size and bj < b_size
- if callbacks.respond_to?(:finished_a) and not run_finished_a
- ax = string ? seq1[-1, 1] : seq1[-1]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
- event = yield event if block_given?
- callbacks.finished_a(event)
- run_finished_a = true
- else
- ax = string ? seq1[ai, 1] : seq1[ai]
- loop do
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- break unless bj < b_size
- end
- end
- end
-
- # last B?
- if bj == b_size and ai < a_size
- if callbacks.respond_to?(:finished_b) and not run_finished_b
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[-1, 1] : seq2[-1]
- event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
- event = yield event if block_given?
- callbacks.finished_b(event)
- run_finished_b = true
- else
- bx = string ? seq2[bj, 1] : seq2[bj]
- loop do
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- break unless bj < b_size
- end
- end
- end
-
- if ai < a_size
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- end
-
- if bj < b_size
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- # #traverse_balanced is an alternative to #traverse_sequences. It
- # uses a different algorithm to iterate through the entries in the
- # computed longest common subsequence. Instead of viewing the changes as
- # insertions or deletions from one of the sequences, #traverse_balanced
- # will report <em>changes</em> between the sequences. To represent a
- #
- # The arguments to #traverse_balanced are the two sequences to traverse
- # and a callback object, like this:
- #
- # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new)
- #
- # #sdiff is implemented with #traverse_balanced.
- #
- # == Callback Methods
- # Optional callback methods are <em>emphasized</em>.
- #
- # callbacks#match:: Called when +a+ and +b+ are pointing
- # to common elements in +A+ and +B+.
- # callbacks#discard_a:: Called when +a+ is pointing to an
- # element not in +B+.
- # callbacks#discard_b:: Called when +b+ is pointing to an
- # element not in +A+.
- # <em>callbacks#change</em>:: Called when +a+ and +b+ are pointing
- # to the same relative position, but
- # <tt>A[a]</tt> and <tt>B[b]</tt> are
- # not the same; a <em>change</em> has
- # occurred.
- #
- # #traverse_balanced might be a bit slower than #traverse_sequences,
- # noticable only while processing huge amounts of data.
- #
- # The +sdiff+ function of this module is implemented as call to
- # #traverse_balanced.
- #
- # == Algorithm
- # a---+
- # v
- # A = a b c e h j l m n p
- # B = b c d e f j k l m r s t
- # ^
- # b---+
- #
- # === Matches
- # If there are two arrows (+a+ and +b+) pointing to elements of
- # sequences +A+ and +B+, the arrows will initially point to the first
- # elements of their respective sequences. #traverse_sequences will
- # advance the arrows through the sequences one element at a time,
- # calling a method on the user-specified callback object before each
- # advance. It will advance the arrows in such a way that if there are
- # elements <tt>A[ii]</tt> and <tt>B[jj]</tt> which are both equal and
- # part of the longest common subsequence, there will be some moment
- # during the execution of #traverse_sequences when arrow +a+ is pointing
- # to <tt>A[ii]</tt> and arrow +b+ is pointing to <tt>B[jj]</tt>. When
- # this happens, #traverse_sequences will call <tt>callbacks#match</tt>
- # and then it will advance both arrows.
- #
- # === Discards
- # Otherwise, one of the arrows is pointing to an element of its sequence
- # that is not part of the longest common subsequence.
- # #traverse_sequences will advance that arrow and will call
- # <tt>callbacks#discard_a</tt> or <tt>callbacks#discard_b</tt>,
- # depending on which arrow it advanced.
- #
- # === Changes
- # If both +a+ and +b+ point to elements that are not part of the longest
- # common subsequence, then #traverse_sequences will try to call
- # <tt>callbacks#change</tt> and advance both arrows. If
- # <tt>callbacks#change</tt> is not implemented, then
- # <tt>callbacks#discard_a</tt> and <tt>callbacks#discard_b</tt> will be
- # called in turn.
- #
- # The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>,
- # <tt>callbacks#discard_b</tt>, and <tt>callbacks#change</tt> are
- # invoked with an event comprising the action ("=", "+", "-", or "!",
- # respectively), the indicies +ii+ and +jj+, and the elements
- # <tt>A[ii]</tt> and <tt>B[jj]</tt>. Return values are discarded by
- # #traverse_balanced.
- #
- # === Context
- # Note that +ii+ and +jj+ may not be the same index position, even if
- # +a+ and +b+ are considered to be pointing to matching or changed
- # elements.
- def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
- matches = Diff::LCS.__lcs(seq1, seq2)
- a_size = seq1.size
- b_size = seq2.size
- ai = bj = mb = 0
- ma = -1
- string = seq1.kind_of?(String)
-
- # Process all the lines in the match vector.
- loop do
- # Find next match indices +ma+ and +mb+
- loop do
- ma += 1
- break unless ma < matches.size and matches[ma].nil?
- end
-
- break if ma >= matches.size # end of matches?
- mb = matches[ma]
-
- # Change(seq2)
- while (ai < ma) or (bj < mb)
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- case [(ai < ma), (bj < mb)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
-
- # Match
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
- event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.match(event)
- ai += 1
- bj += 1
- end
-
- while (ai < a_size) or (bj < b_size)
- ax = string ? seq1[ai, 1] : seq1[ai]
- bx = string ? seq2[bj, 1] : seq2[bj]
-
- case [(ai < a_size), (bj < b_size)]
- when [true, true]
- if callbacks.respond_to?(:change)
- event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.change(event)
- ai += 1
- bj += 1
- else
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- ax = string ? seq1[ai, 1] : seq1[ai]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- when [true, false]
- event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_a(event)
- ai += 1
- when [false, true]
- event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
- event = yield event if block_given?
- callbacks.discard_b(event)
- bj += 1
- end
- end
- end
-
- PATCH_MAP = { #:nodoc:
- :patch => { '+' => '+', '-' => '-', '!' => '!', '=' => '=' },
- :unpatch => { '+' => '-', '-' => '+', '!' => '!', '=' => '=' }
- }
-
- # Given a patchset, convert the current version to the new
- # version. If +direction+ is not specified (must be
- # <tt>:patch</tt> or <tt>:unpatch</tt>), then discovery of the
- # direction of the patch will be attempted.
- def patch(src, patchset, direction = nil)
- string = src.kind_of?(String)
- # Start with a new empty type of the source's class
- res = src.class.new
-
- # Normalize the patchset.
- patchset = __normalize_patchset(patchset)
-
- direction ||= Diff::LCS.__diff_direction(src, patchset)
- direction ||= :patch
-
- ai = bj = 0
-
- patchset.each do |change|
- # Both Change and ContextChange support #action
- action = PATCH_MAP[direction][change.action]
-
- case change
- when Diff::LCS::ContextChange
- case direction
- when :patch
- el = change.new_element
- op = change.old_position
- np = change.new_position
- when :unpatch
- el = change.old_element
- op = change.new_position
- np = change.old_position
- end
-
- case action
- when '-' # Remove details from the old string
- while ai < op
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += 1
- when '+'
- while bj < np
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- res << el
- bj += 1
- when '='
- # This only appears in sdiff output with the SDiff callback.
- # Therefore, we only need to worry about dealing with a single
- # element.
- res << el
-
- ai += 1
- bj += 1
- when '!'
- while ai < op
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- bj += 1
- ai += 1
-
- res << el
- end
- when Diff::LCS::Change
- case action
- when '-'
- while ai < change.position
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
- ai += 1
- when '+'
- while bj < change.position
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- bj += 1
-
- res << change.element
- end
- end
- end
-
- while ai < src.size
- res << (string ? src[ai, 1] : src[ai])
- ai += 1
- bj += 1
- end
-
- res
- end
-
- # Given a set of patchset, convert the current version to the prior
- # version. Does no auto-discovery.
- def unpatch!(src, patchset)
- Diff::LCS.patch(src, patchset, :unpatch)
- end
-
- # Given a set of patchset, convert the current version to the next
- # version. Does no auto-discovery.
- def patch!(src, patchset)
- Diff::LCS.patch(src, patchset, :patch)
- end
-
-# private
- # Compute the longest common subsequence between the sequenced Enumerables
- # +a+ and +b+. The result is an array whose contents is such that
- #
- # result = Diff::LCS.__lcs(a, b)
- # result.each_with_index do |e, ii|
- # assert_equal(a[ii], b[e]) unless e.nil?
- # end
- def __lcs(a, b)
- a_start = b_start = 0
- a_finish = a.size - 1
- b_finish = b.size - 1
- vector = []
-
- # Prune off any common elements at the beginning...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_start] == b[b_start])
- vector[a_start] = b_start
- a_start += 1
- b_start += 1
- end
-
- # Now the end...
- while (a_start <= a_finish) and
- (b_start <= b_finish) and
- (a[a_finish] == b[b_finish])
- vector[a_finish] = b_finish
- a_finish -= 1
- b_finish -= 1
- end
-
- # Now, compute the equivalence classes of positions of elements.
- b_matches = Diff::LCS.__position_hash(b, b_start .. b_finish)
-
- thresh = []
- links = []
-
- (a_start .. a_finish).each do |ii|
- ai = a.kind_of?(String) ? a[ii, 1] : a[ii]
- bm = b_matches[ai]
- kk = nil
- bm.reverse_each do |jj|
- if kk and (thresh[kk] > jj) and (thresh[kk - 1] < jj)
- thresh[kk] = jj
- else
- kk = Diff::LCS.__replace_next_larger(thresh, jj, kk)
- end
- links[kk] = [ (kk > 0) ? links[kk - 1] : nil, ii, jj ] unless kk.nil?
- end
- end
-
- unless thresh.empty?
- link = links[thresh.size - 1]
- while not link.nil?
- vector[link[1]] = link[2]
- link = link[0]
- end
- end
-
- vector
- end
-
- # Find the place at which +value+ would normally be inserted into the
- # Enumerable. If that place is already occupied by +value+, do nothing
- # and return +nil+. If the place does not exist (i.e., it is off the end
- # of the Enumerable), add it to the end. Otherwise, replace the element
- # at that point with +value+. It is assumed that the Enumerable's values
- # are numeric.
- #
- # This operation preserves the sort order.
- def __replace_next_larger(enum, value, last_index = nil)
- # Off the end?
- if enum.empty? or (value > enum[-1])
- enum << value
- return enum.size - 1
- end
-
- # Binary search for the insertion point
- last_index ||= enum.size
- first_index = 0
- while (first_index <= last_index)
- ii = (first_index + last_index) >> 1
-
- found = enum[ii]
-
- if value == found
- return nil
- elsif value > found
- first_index = ii + 1
- else
- last_index = ii - 1
- end
- end
-
- # The insertion point is in first_index; overwrite the next larger
- # value.
- enum[first_index] = value
- return first_index
- end
-
- # If +vector+ maps the matching elements of another collection onto this
- # Enumerable, compute the inverse +vector+ that maps this Enumerable
- # onto the collection. (Currently unused.)
- def __inverse_vector(a, vector)
- inverse = a.dup
- (0 ... vector.size).each do |ii|
- inverse[vector[ii]] = ii unless vector[ii].nil?
- end
- inverse
- end
-
- # Returns a hash mapping each element of an Enumerable to the set of
- # positions it occupies in the Enumerable, optionally restricted to the
- # elements specified in the range of indexes specified by +interval+.
- def __position_hash(enum, interval = 0 .. -1)
- hash = Hash.new { |hh, kk| hh[kk] = [] }
- interval.each do |ii|
- kk = enum.kind_of?(String) ? enum[ii, 1] : enum[ii]
- hash[kk] << ii
- end
- hash
- end
-
- # Examine the patchset and the source to see in which direction the
- # patch should be applied.
- #
- # WARNING: By default, this examines the whole patch, so this could take
- # some time. This also works better with Diff::LCS::ContextChange or
- # Diff::LCS::Change as its source, as an array will cause the creation
- # of one of the above.
- def __diff_direction(src, patchset, limit = nil)
- count = left = left_miss = right = right_miss = 0
- string = src.kind_of?(String)
-
- patchset.each do |change|
- count += 1
-
- case change
- when Diff::LCS::Change
- # With a simplistic change, we can't tell the difference between
- # the left and right on '!' actions, so we ignore those. On '='
- # actions, if there's a miss, we miss both left and right.
- element = string ? src[change.position, 1] : src[change.position]
-
- case change.action
- when '-'
- if element == change.element
- left += 1
- else
- left_miss += 1
- end
- when '+'
- if element == change.element
- right += 1
- else
- right_miss += 1
- end
- when '='
- if element != change.element
- left_miss += 1
- right_miss += 1
- end
- end
- when Diff::LCS::ContextChange
- case change.action
- when '-' # Remove details from the old string
- element = string ? src[change.old_position, 1] : src[change.old_position]
- if element == change.old_element
- left += 1
- else
- left_miss += 1
- end
- when '+'
- element = string ? src[change.new_position, 1] : src[change.new_position]
- if element == change.new_element
- right += 1
- else
- right_miss += 1
- end
- when '='
- le = string ? src[change.old_position, 1] : src[change.old_position]
- re = string ? src[change.new_position, 1] : src[change.new_position]
-
- left_miss += 1 if le != change.old_element
- right_miss += 1 if re != change.new_element
- when '!'
- element = string ? src[change.old_position, 1] : src[change.old_position]
- if element == change.old_element
- left += 1
- else
- element = string ? src[change.new_position, 1] : src[change.new_position]
- if element == change.new_element
- right += 1
- else
- left_miss += 1
- right_miss += 1
- end
- end
- end
- end
-
- break if not limit.nil? and count > limit
- end
-
- no_left = (left == 0) and (left_miss >= 0)
- no_right = (right == 0) and (right_miss >= 0)
-
- case [no_left, no_right]
- when [false, true]
- return :patch
- when [true, false]
- return :unpatch
- else
- raise "The provided patchset does not appear to apply to the provided value as either source or destination value."
- end
- end
-
- # Normalize the patchset. A patchset is always a sequence of changes, but
- # how those changes are represented may vary, depending on how they were
- # generated. In all cases we support, we also support the array
- # representation of the changes. The formats are:
- #
- # [ # patchset <- Diff::LCS.diff(a, b)
- # [ # one or more hunks
- # Diff::LCS::Change # one or more changes
- # ] ]
- #
- # [ # patchset, equivalent to the above
- # [ # one or more hunks
- # [ action, line, value ] # one or more changes
- # ] ]
- #
- # [ # patchset <- Diff::LCS.diff(a, b, Diff::LCS::ContextDiffCallbacks)
- # # OR <- Diff::LCS.sdiff(a, b, Diff::LCS::ContextDiffCallbacks)
- # [ # one or more hunks
- # Diff::LCS::ContextChange # one or more changes
- # ] ]
- #
- # [ # patchset, equivalent to the above
- # [ # one or more hunks
- # [ action, [ old line, old value ], [ new line, new value ] ]
- # # one or more changes
- # ] ]
- #
- # [ # patchset <- Diff::LCS.sdiff(a, b)
- # # OR <- Diff::LCS.diff(a, b, Diff::LCS::SDiffCallbacks)
- # Diff::LCS::ContextChange # one or more changes
- # ]
- #
- # [ # patchset, equivalent to the above
- # [ action, [ old line, old value ], [ new line, new value ] ]
- # # one or more changes
- # ]
- #
- # The result of this will be either of the following.
- #
- # [ # patchset
- # Diff::LCS::ContextChange # one or more changes
- # ]
- #
- # [ # patchset
- # Diff::LCS::Change # one or more changes
- # ]
- #
- # If either of the above is provided, it will be returned as such.
- #
- def __normalize_patchset(patchset)
- patchset.map do |hunk|
- case hunk
- when Diff::LCS::ContextChange, Diff::LCS::Change
- hunk
- when Array
- if (not hunk[0].kind_of?(Array)) and hunk[1].kind_of?(Array) and hunk[2].kind_of?(Array)
- Diff::LCS::ContextChange.from_a(hunk)
- else
- hunk.map do |change|
- case change
- when Diff::LCS::ContextChange, Diff::LCS::Change
- change
- when Array
- # change[1] will ONLY be an array in a ContextChange#to_a call.
- # In Change#to_a, it represents the line (singular).
- if change[1].kind_of?(Array)
- Diff::LCS::ContextChange.from_a(change)
- else
- Diff::LCS::Change.from_a(change)
- end
- end
- end
- end
- else
- raise ArgumentError, "Cannot normalise a hunk of class #{hunk.class}."
- end
- end.flatten
- end
- end
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/array.rb b/diff-lcs/trunk/lib/diff/lcs/array.rb
deleted file mode 100644
index e07f8aa..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/array.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Includes Diff::LCS into the Array built-in class.
-
-require 'diff/lcs'
-
-class Array
- include Diff::LCS
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/block.rb b/diff-lcs/trunk/lib/diff/lcs/block.rb
deleted file mode 100644
index 7dceb48..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/block.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains Diff::LCS::Block for bin/ldiff.
-
- # A block is an operation removing, adding, or changing a group of items.
- # Basically, this is just a list of changes, where each change adds or
- # deletes a single item. Used by bin/ldiff.
-class Diff::LCS::Block
- attr_reader :changes, :insert, :remove
-
- def initialize(chunk)
- @changes = []
- @insert = []
- @remove = []
-
- chunk.each do |item|
- @changes << item
- @remove << item if item.deleting?
- @insert << item if item.adding?
- end
- end
-
- def diff_size
- @insert.size - @remove.size
- end
-
- def op
- case [@remove.empty?, @insert.empty?]
- when [false, false]
- '!'
- when [false, true]
- '-'
- when [true, false]
- '+'
- else # [true, true]
- '^'
- end
- end
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/callbacks.rb b/diff-lcs/trunk/lib/diff/lcs/callbacks.rb
deleted file mode 100644
index 74a1cdc..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/callbacks.rb
+++ /dev/null
@@ -1,322 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains definitions for all default callback objects.
-
-require 'diff/lcs/change'
-
-module Diff::LCS
- # This callback object implements the default set of callback events, which
- # only returns the event itself. Note that #finished_a and #finished_b are
- # not implemented -- I haven't yet figured out where they would be useful.
- #
- # Note that this is intended to be called as is, e.g.,
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks)
- class DefaultCallbacks
- class << self
- # Called when two items match.
- def match(event)
- event
- end
- # Called when the old value is discarded in favour of the new value.
- def discard_a(event)
- event
- end
- # Called when the new value is discarded in favour of the old value.
- def discard_b(event)
- event
- end
- # Called when both the old and new values have changed.
- def change(event)
- event
- end
-
- private :new
- end
- end
-
- # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_sequences.
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks)
- SequenceCallbacks = DefaultCallbacks
- # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_balanced.
- #
- # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks)
- BalancedCallbacks = DefaultCallbacks
-end
-
- # This will produce a compound array of simple diff change objects. Each
- # element in the #diffs array is a +hunk+ or +hunk+ array, where each
- # element in each +hunk+ array is a single Change object representing the
- # addition or removal of a single element from one of the two tested
- # sequences. The +hunk+ provides the full context for the changes.
- #
- # diffs = Diff::LCS.diff(seq1, seq2)
- # # This example shows a simplified array format.
- # # [ [ [ '-', 0, 'a' ] ], # 1
- # # [ [ '+', 2, 'd' ] ], # 2
- # # [ [ '-', 4, 'h' ], # 3
- # # [ '+', 4, 'f' ] ],
- # # [ [ '+', 6, 'k' ] ], # 4
- # # [ [ '-', 8, 'n' ], # 5
- # # [ '-', 9, 'p' ],
- # # [ '+', 9, 'r' ],
- # # [ '+', 10, 's' ],
- # # [ '+', 11, 't' ] ] ]
- #
- # There are five hunks here. The first hunk says that the +a+ at position 0
- # of the first sequence should be deleted (<tt>'-'</tt>). The second hunk
- # says that the +d+ at position 2 of the second sequence should be inserted
- # (<tt>'+'</tt>). The third hunk says that the +h+ at position 4 of the
- # first sequence should be removed and replaced with the +f+ from position 4
- # of the second sequence. The other two hunks are described similarly.
- #
- # === Use
- # This callback object must be initialised and is used by the Diff::LCS#diff
- # method.
- #
- # cbo = Diff::LCS::DiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- # cbo.finish
- #
- # Note that the call to #finish is absolutely necessary, or the last set of
- # changes will not be visible. Alternatively, can be used as:
- #
- # cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # The necessary #finish call will be made.
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.map { |f| f.to_a } }
-class Diff::LCS::DiffCallbacks
- # Returns the difference set collected during the diff process.
- attr_reader :diffs
-
- def initialize # :yields self:
- @hunk = []
- @diffs = []
-
- if block_given?
- begin
- yield self
- ensure
- self.finish
- end
- end
- end
-
- # Finalizes the diff process. If an unprocessed hunk still exists, then it
- # is appended to the diff list.
- def finish
- add_nonempty_hunk
- end
-
- def match(event)
- add_nonempty_hunk
- end
-
- def discard_a(event)
- @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element)
- end
-
-private
- def add_nonempty_hunk
- @diffs << @hunk unless @hunk.empty?
- @hunk = []
- end
-end
-
- # This will produce a compound array of contextual diff change objects. Each
- # element in the #diffs array is a "hunk" array, where each element in each
- # "hunk" array is a single change. Each change is a Diff::LCS::ContextChange
- # that contains both the old index and new index values for the change. The
- # "hunk" provides the full context for the changes. Both old and new objects
- # will be presented for changed objects. +nil+ will be substituted for a
- # discarded object.
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks)
- # # This example shows a simplified array format.
- # # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1
- # # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2
- # # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3
- # # [ '+', [ 5, nil ], [ 4, 'f' ] ] ],
- # # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4
- # # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5
- # # [ '+', [ 9, nil ], [ 9, 'r' ] ],
- # # [ '-', [ 9, 'p' ], [ 10, nil ] ],
- # # [ '+', [ 10, nil ], [ 10, 's' ] ],
- # # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ]
- #
- # The five hunks shown are comprised of individual changes; if there is a
- # related set of changes, they are still shown individually.
- #
- # This callback can also be used with Diff::LCS#sdiff, which will produce
- # results like:
- #
- # diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks)
- # # This example shows a simplified array format.
- # # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1
- # # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2
- # # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3
- # # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4
- # # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5
- # # [ "!", [ 9, "p" ], [ 10, "s" ] ],
- # # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ]
- #
- # The five hunks are still present, but are significantly shorter in total
- # presentation, because changed items are shown as changes ("!") instead of
- # potentially "mismatched" pairs of additions and deletions.
- #
- # The result of this operation is similar to that of
- # Diff::LCS::SDiffCallbacks. They may be compared as:
- #
- # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
- #
- # s == c # -> true
- #
- # === Use
- # This callback object must be initialised and can be used by the
- # Diff::LCS#diff or Diff::LCS#sdiff methods.
- #
- # cbo = Diff::LCS::ContextDiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- # cbo.finish
- #
- # Note that the call to #finish is absolutely necessary, or the last set of
- # changes will not be visible. Alternatively, can be used as:
- #
- # cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # The necessary #finish call will be made.
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.map { |f| f.to_a } }
-class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks
- def discard_a(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_b(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-
- def change(event)
- @hunk << Diff::LCS::ContextChange.simplify(event)
- end
-end
-
- # This will produce a simple array of diff change objects. Each element in
- # the #diffs array is a single ContextChange. In the set of #diffs provided
- # by SDiffCallbacks, both old and new objects will be presented for both
- # changed <strong>and unchanged</strong> objects. +nil+ will be substituted
- # for a discarded object.
- #
- # The diffset produced by this callback, when provided to Diff::LCS#sdiff,
- # will compute and display the necessary components to show two sequences
- # and their minimized differences side by side, just like the Unix utility
- # +sdiff+.
- #
- # same same
- # before | after
- # old < -
- # - > new
- #
- # seq1 = %w(a b c e h j l m n p)
- # seq2 = %w(b c d e f j k l m r s t)
- #
- # diffs = Diff::LCS.sdiff(seq1, seq2)
- # # This example shows a simplified array format.
- # # [ [ "-", [ 0, "a"], [ 0, nil ] ],
- # # [ "=", [ 1, "b"], [ 0, "b" ] ],
- # # [ "=", [ 2, "c"], [ 1, "c" ] ],
- # # [ "+", [ 3, nil], [ 2, "d" ] ],
- # # [ "=", [ 3, "e"], [ 3, "e" ] ],
- # # [ "!", [ 4, "h"], [ 4, "f" ] ],
- # # [ "=", [ 5, "j"], [ 5, "j" ] ],
- # # [ "+", [ 6, nil], [ 6, "k" ] ],
- # # [ "=", [ 6, "l"], [ 7, "l" ] ],
- # # [ "=", [ 7, "m"], [ 8, "m" ] ],
- # # [ "!", [ 8, "n"], [ 9, "r" ] ],
- # # [ "!", [ 9, "p"], [ 10, "s" ] ],
- # # [ "+", [ 10, nil], [ 11, "t" ] ] ]
- #
- # The result of this operation is similar to that of
- # Diff::LCS::ContextDiffCallbacks. They may be compared as:
- #
- # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
- #
- # s == c # -> true
- #
- # === Use
- # This callback object must be initialised and is used by the Diff::LCS#sdiff
- # method.
- #
- # cbo = Diff::LCS::SDiffCallbacks.new
- # Diff::LCS.LCS(seq1, seq2, cbo)
- #
- # As with the other initialisable callback objects, Diff::LCS::SDiffCallbacks
- # can be initialised with a block. As there is no "fininishing" to be done,
- # this has no effect on the state of the object.
- #
- # cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) }
- #
- # === Simplified Array Format
- # The simplified array format used in the example above can be obtained
- # with:
- #
- # require 'pp'
- # pp diffs.map { |e| e.to_a }
-class Diff::LCS::SDiffCallbacks
- # Returns the difference set collected during the diff process.
- attr_reader :diffs
-
- def initialize #:yields self:
- @diffs = []
- yield self if block_given?
- end
-
- def match(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_a(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def discard_b(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-
- def change(event)
- @diffs << Diff::LCS::ContextChange.simplify(event)
- end
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/change.rb b/diff-lcs/trunk/lib/diff/lcs/change.rb
deleted file mode 100644
index 6ecdf7e..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/change.rb
+++ /dev/null
@@ -1,169 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Provides Diff::LCS::Change and Diff::LCS::ContextChange.
-
- # Centralises the change test code in Diff::LCS::Change and
- # Diff::LCS::ContextChange, since it's the same for both classes.
-module Diff::LCS::ChangeTypeTests
- def deleting?
- @action == '-'
- end
-
- def adding?
- @action == '+'
- end
-
- def unchanged?
- @action == '='
- end
-
- def changed?
- @changed == '!'
- end
-
- def finished_a?
- @changed == '>'
- end
-
- def finished_b?
- @changed == '<'
- end
-end
-
- # Represents a simplistic (non-contextual) change. Represents the removal or
- # addition of an element from either the old or the new sequenced enumerable.
-class Diff::LCS::Change
- # Returns the action this Change represents. Can be '+' (#adding?), '-'
- # (#deleting?), '=' (#unchanged?), # or '!' (#changed?). When created by
- # Diff::LCS#diff or Diff::LCS#sdiff, it may also be '>' (#finished_a?) or
- # '<' (#finished_b?).
- attr_reader :action
- attr_reader :position
- attr_reader :element
-
- include Comparable
- def ==(other)
- (self.action == other.action) and
- (self.position == other.position) and
- (self.element == other.element)
- end
-
- def <=>(other)
- r = self.action <=> other.action
- r = self.position <=> other.position if r.zero?
- r = self.element <=> other.element if r.zero?
- r
- end
-
- def initialize(action, position, element)
- @action = action
- @position = position
- @element = element
- end
-
- # Creates a Change from an array produced by Change#to_a.
- def to_a
- [@action, @position, @element]
- end
-
- def self.from_a(arr)
- Diff::LCS::Change.new(arr[0], arr[1], arr[2])
- end
-
- include Diff::LCS::ChangeTypeTests
-end
-
- # Represents a contextual change. Contains the position and values of the
- # elements in the old and the new sequenced enumerables as well as the action
- # taken.
-class Diff::LCS::ContextChange
- # Returns the action this Change represents. Can be '+' (#adding?), '-'
- # (#deleting?), '=' (#unchanged?), # or '!' (#changed?). When
- # created by Diff::LCS#diff or Diff::LCS#sdiff, it may also be '>'
- # (#finished_a?) or '<' (#finished_b?).
- attr_reader :action
- attr_reader :old_position
- attr_reader :old_element
- attr_reader :new_position
- attr_reader :new_element
-
- include Comparable
-
- def ==(other)
- (@action == other.action) and
- (@old_position == other.old_position) and
- (@new_position == other.new_position) and
- (@old_element == other.old_element) and
- (@new_element == other.new_element)
- end
-
- def inspect(*args)
- %Q(#<#{self.class.name}:#{__id__} @action=#{action} positions=#{old_position},#{new_position} elements=#{old_element.inspect},#{new_element.inspect}>)
- end
-
- def <=>(other)
- r = @action <=> other.action
- r = @old_position <=> other.old_position if r.zero?
- r = @new_position <=> other.new_position if r.zero?
- r = @old_element <=> other.old_element if r.zero?
- r = @new_element <=> other.new_element if r.zero?
- r
- end
-
- def initialize(action, old_position, old_element, new_position, new_element)
- @action = action
- @old_position = old_position
- @old_element = old_element
- @new_position = new_position
- @new_element = new_element
- end
-
- def to_a
- [@action, [@old_position, @old_element], [@new_position, @new_element]]
- end
-
- # Creates a ContextChange from an array produced by ContextChange#to_a.
- def self.from_a(arr)
- if arr.size == 5
- Diff::LCS::ContextChange.new(arr[0], arr[1], arr[2], arr[3], arr[4])
- else
- Diff::LCS::ContextChange.new(arr[0], arr[1][0], arr[1][1], arr[2][0],
- arr[2][1])
- end
- end
-
- # Simplifies a context change for use in some diff callbacks. '<' actions
- # are converted to '-' and '>' actions are converted to '+'.
- def self.simplify(event)
- ea = event.to_a
-
- case ea[0]
- when '-'
- ea[2][1] = nil
- when '<'
- ea[0] = '-'
- ea[2][1] = nil
- when '+'
- ea[1][1] = nil
- when '>'
- ea[0] = '+'
- ea[1][1] = nil
- end
-
- Diff::LCS::ContextChange.from_a(ea)
- end
-
- include Diff::LCS::ChangeTypeTests
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/hunk.rb b/diff-lcs/trunk/lib/diff/lcs/hunk.rb
deleted file mode 100644
index 58fac9f..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/hunk.rb
+++ /dev/null
@@ -1,257 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Contains Diff::LCS::Hunk for bin/ldiff.
-
-require 'diff/lcs/block'
-
- # A Hunk is a group of Blocks which overlap because of the context
- # surrounding each block. (So if we're not using context, every hunk will
- # contain one block.) Used in the diff program (bin/diff).
-class Diff::LCS::Hunk
- # Create a hunk using references to both the old and new data, as well as
- # the piece of data
- def initialize(data_old, data_new, piece, context, file_length_difference)
- # At first, a hunk will have just one Block in it
- @blocks = [ Diff::LCS::Block.new(piece) ]
- @data_old = data_old
- @data_new = data_new
-
- before = after = file_length_difference
- after += @blocks[0].diff_size
- @file_length_difference = after # The caller must get this manually
-
- # Save the start & end of each array. If the array doesn't exist
- # (e.g., we're only adding items in this block), then figure out the
- # line number based on the line number of the other file and the
- # current difference in file lengths.
- if @blocks[0].remove.empty?
- a1 = a2 = nil
- else
- a1 = @blocks[0].remove[0].position
- a2 = @blocks[0].remove[-1].position
- end
-
- if @blocks[0].insert.empty?
- b1 = b2 = nil
- else
- b1 = @blocks[0].insert[0].position
- b2 = @blocks[0].insert[-1].position
- end
-
- @start_old = a1 || (b1 - before)
- @start_new = b1 || (a1 + before)
- @end_old = a2 || (b2 - after)
- @end_new = b2 || (a2 + after)
-
- self.flag_context = context
- end
-
- attr_reader :blocks
- attr_reader :start_old, :start_new
- attr_reader :end_old, :end_new
- attr_reader :file_length_difference
-
- # Change the "start" and "end" fields to note that context should be added
- # to this hunk
- attr_accessor :flag_context
- def flag_context=(context) #:nodoc:
- return if context.nil? or context.zero?
-
- add_start = (context > @start_old) ? @start_old : context
- @start_old -= add_start
- @start_new -= add_start
-
- if (@end_old + context) > @data_old.size
- add_end = @data_old.size - @end_old
- else
- add_end = context
- end
- @end_old += add_end
- @end_new += add_end
- end
-
- def unshift(hunk)
- @start_old = hunk.start_old
- @start_new = hunk.start_new
- blocks.unshift(*hunk.blocks)
- end
-
- # Is there an overlap between hunk arg0 and old hunk arg1? Note: if end
- # of old hunk is one less than beginning of second, they overlap
- def overlaps?(hunk = nil)
- return nil if hunk.nil?
-
- a = (@start_old - hunk.end_old) <= 1
- b = (@start_new - hunk.end_new) <= 1
- return (a or b)
- end
-
- def diff(format)
- case format
- when :old
- old_diff
- when :unified
- unified_diff
- when :context
- context_diff
- when :ed
- self
- when :reverse_ed, :ed_finish
- ed_diff(format)
- else
- raise "Unknown diff format #{format}."
- end
- end
-
- def each_old(block)
- @data_old[@start_old .. @end_old].each { |e| yield e }
- end
-
- private
- # Note that an old diff can't have any context. Therefore, we know that
- # there's only one block in the hunk.
- def old_diff
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
-
- block = @blocks[0]
-
- # Calculate item number range. Old diff range is just like a context
- # diff range, except the ranges are on one line with the action between
- # them.
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
- # If removing anything, just print out all the remove lines in the hunk
- # which is just all the remove lines in the block.
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
- s << "---\n" if block.op == "!"
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
- s
- end
-
- def unified_diff
- # Calculate item number range.
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
-
- # Outlist starts containing the hunk of the old file. Removing an item
- # just means putting a '-' in front of it. Inserting an item requires
- # getting it from the new file and splicing it in. We splice in
- # +num_added+ items. Remove blocks use +num_added+ because splicing
- # changed the length of outlist.
- #
- # We remove +num_removed+ items. Insert blocks use +num_removed+
- # because their item numbers -- corresponding to positions in the NEW
- # file -- don't take removed items into account.
- lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
-
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
-
- @blocks.each do |block|
- block.remove.each do |item|
- op = item.action.to_s # -
- offset = item.position - lo + num_added
- outlist[offset].gsub!(/^ /, op.to_s)
- num_removed += 1
- end
- block.insert.each do |item|
- op = item.action.to_s # +
- offset = item.position - @start_new + num_removed
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
- num_added += 1
- end
- end
-
- s << outlist.join("\n")
- end
-
- def context_diff
- s = "***************\n"
- s << "*** #{context_range(:old)} ****\n"
- r = context_range(:new)
-
- # Print out file 1 part for each block in context diff format if there
- # are any blocks that remove items
- lo, hi = @start_old, @end_old
- removes = @blocks.select { |e| not e.remove.empty? }
- if removes
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- removes.each do |block|
- block.remove.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
- end
- end
- s << outlist.join("\n")
- end
-
- s << "\n--- #{r} ----\n"
- lo, hi = @start_new, @end_new
- inserts = @blocks.select { |e| not e.insert.empty? }
- if inserts
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
- inserts.each do |block|
- block.insert.each do |item|
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
- end
- end
- s << outlist.join("\n")
- end
- s
- end
-
- def ed_diff(format)
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
-
- if format == :reverse_ed
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
- else
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
- end
-
- unless @blocks[0].insert.empty?
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
- s << ".\n"
- end
- s
- end
-
- # Generate a range of item numbers to print. Only print 1 number if the
- # range has only one item in it. Otherwise, it's 'start,end'
- def context_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- (s < e) ? "#{s},#{e}" : "#{e}"
- end
-
- # Generate a range of item numbers to print for unified diff. Print
- # number where block starts, followed by number of lines in the block
- # (don't print number of lines if it's 1)
- def unified_range(mode)
- case mode
- when :old
- s, e = (@start_old + 1), (@end_old + 1)
- when :new
- s, e = (@start_new + 1), (@end_new + 1)
- end
-
- length = e - s + 1
- first = (length < 2) ? e : s # "strange, but correct"
- (length == 1) ? "#{first}" : "#{first},#{length}"
- end
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/ldiff.rb b/diff-lcs/trunk/lib/diff/lcs/ldiff.rb
deleted file mode 100644
index 61abc47..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/ldiff.rb
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'optparse'
-require 'ostruct'
-require 'diff/lcs/hunk'
-
- # == ldiff Usage
- # ldiff [options] oldfile newfile
- #
- # -c:: Displays a context diff with 3 lines of context.
- # -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
- # -u:: Displays a unified diff with 3 lines of context.
- # -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
- # -e:: Creates an 'ed' script to change oldfile to newfile.
- # -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
- # -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
- # --binary:: Treats the files as binary.
- # -q, --brief:: Reports only whether or not the files differ, not the details.
- # --help:: Shows the command-line help.
- # --version:: Shows the version of Diff::LCS.
- #
- # By default, runs produces an "old-style" diff, with output like UNIX diff.
- #
- # == Copyright
- # Copyright &copy; 2004 Austin Ziegler
- #
- # Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
- # Austin Ziegler <diff-lcs@halostatue.ca>
- #
- # This program is free software. It may be redistributed and/or modified under
- # the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- # Ruby licence.
-module Diff::LCS::Ldiff
- BANNER = <<-COPYRIGHT
-ldiff #{Diff::LCS::VERSION}
- Copyright © 2004 Austin Ziegler
-
- Part of Diff::LCS.
- http://rubyforge.org/projects/ruwiki/
-
- Austin Ziegler <diff-lcs@halostatue.ca>
-
- This program is free software. It may be redistributed and/or modified under
- the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
- Ruby licence.
-
-$Id$
- COPYRIGHT
-
- class << self
- attr_reader :format, :lines #:nodoc:
- attr_reader :file_old, :file_new #:nodoc:
- attr_reader :data_old, :data_new #:nodoc:
-
- def run(args, input = $stdin, output = $stdout, error = $stderr) #:nodoc:
- args.options do |o|
- o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
- o.separator ""
- o.on('-c',
- 'Displays a context diff with 3 lines of',
- 'context.') do |ctx|
- @format = :context
- @lines = 3
- end
- o.on('-C', '--context [LINES]', Numeric,
- 'Displays a context diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :context
- @lines = ctx || 3
- end
- o.on('-u',
- 'Displays a unified diff with 3 lines of',
- 'context.') do |ctx|
- @format = :unified
- @lines = 3
- end
- o.on('-U', '--unified [LINES]', Numeric,
- 'Displays a unified diff with LINES lines',
- 'of context. Default 3 lines.') do |ctx|
- @format = :unified
- @lines = ctx || 3
- end
- o.on('-e',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile.') do |ctx|
- @format = :ed
- end
- o.on('-f',
- 'Creates an \'ed\' script to change',
- 'oldfile to newfile in reverse order.') do |ctx|
- @format = :reverse_ed
- end
- o.on('-a', '--text',
- 'Treat the files as text and compare them',
- 'line-by-line, even if they do not seem',
- 'to be text.') do |txt|
- @binary = false
- end
- o.on('--binary',
- 'Treats the files as binary.') do |bin|
- @binary = true
- end
- o.on('-q', '--brief',
- 'Report only whether or not the files',
- 'differ, not the details.') do |ctx|
- @format = :report
- end
- o.on_tail('--help', 'Shows this text.') do
- error << o
- return 0
- end
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
- error << BANNER
- return 0
- end
- o.on_tail ""
- o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
- o.parse!
- end
-
- unless args.size == 2
- error << args.options
- return 127
- end
-
- # Defaults are for old-style diff
- @format ||= :old
- @lines ||= 0
-
- file_old, file_new = *ARGV
-
- case @format
- when :context
- char_old = '*' * 3
- char_new = '-' * 3
- when :unified
- char_old = '-' * 3
- char_new = '+' * 3
- end
-
- # After we've read up to a certain point in each file, the number of
- # items we've read from each file will differ by FLD (could be 0).
- file_length_difference = 0
-
- if @binary.nil? or @binary
- data_old = IO::read(file_old)
- data_new = IO::read(file_new)
-
- # Test binary status
- if @binary.nil?
- old_txt = data_old[0...4096].grep(/\0/).empty?
- new_txt = data_new[0...4096].grep(/\0/).empty?
- @binary = (not old_txt) or (not new_txt)
- old_txt = new_txt = nil
- end
-
- unless @binary
- data_old = data_old.split(/\n/).map! { |e| e.chomp }
- data_new = data_new.split(/\n/).map! { |e| e.chomp }
- end
- else
- data_old = IO::readlines(file_old).map! { |e| e.chomp }
- data_new = IO::readlines(file_new).map! { |e| e.chomp }
- end
-
- # diff yields lots of pieces, each of which is basically a Block object
- if @binary
- diffs = (data_old == data_new)
- else
- diffs = Diff::LCS.diff(data_old, data_new)
- diffs = nil if diffs.empty?
- end
-
- return 0 unless diffs
-
- if (@format == :report) and diffs
- output << "Files #{file_old} and #{file_new} differ\n"
- return 1
- end
-
- if (@format == :unified) or (@format == :context)
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_old} #{file_old}\t#{ft}"
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S %z')
- puts "#{char_new} #{file_new}\t#{ft}"
- end
-
- # Loop over hunks. If a hunk overlaps with the last hunk, join them.
- # Otherwise, print out the old one.
- oldhunk = hunk = nil
-
- if @format == :ed
- real_output = output
- output = []
- end
-
- diffs.each do |piece|
- begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines,
- file_length_difference)
- file_length_difference = hunk.file_length_difference
-
- next unless oldhunk
-
- if (@lines > 0) and hunk.overlaps?(oldhunk)
- hunk.unshift(oldhunk)
- else
- output << oldhunk.diff(@format)
- end
- ensure
- oldhunk = hunk
- output << "\n"
- end
- end
-
- output << oldhunk.diff(@format)
- output << "\n"
-
- if @format == :ed
- output.reverse_each { |e| real_output << e.diff(:ed_finish) }
- end
-
- return 1
- end
- end
-end
diff --git a/diff-lcs/trunk/lib/diff/lcs/string.rb b/diff-lcs/trunk/lib/diff/lcs/string.rb
deleted file mode 100644
index 2de7d1f..0000000
--- a/diff-lcs/trunk/lib/diff/lcs/string.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /usr/env/bin ruby
-#--
-# Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
-# adapted from:
-# Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
-# Smalltalk by Mario I. Wolczko <mario@wolczko.com>
-# implements McIlroy-Hunt diff algorithm
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
-# Ruby licence.
-#
-# $Id$
-#++
-# Includes Diff::LCS into String.
-
-class String
- include Diff::LCS
-end
diff --git a/diff-lcs/trunk/tests/00test.rb b/diff-lcs/trunk/tests/00test.rb
deleted file mode 100644
index 8872dfd..0000000
--- a/diff-lcs/trunk/tests/00test.rb
+++ /dev/null
@@ -1,626 +0,0 @@
-#! /usr/bin/env ruby
-#
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
-
-require 'diff/lcs'
-require 'test/unit'
-require 'pp'
-require 'diff/lcs/array'
-
-module Diff::LCS::Tests
- def __format_diffs(diffs)
- diffs.map do |e|
- if e.kind_of?(Array)
- e.map { |f| f.to_a.join }.join(", ")
- else
- e.to_a.join
- end
- end.join("; ")
- end
-
- def __map_diffs(diffs, klass = Diff::LCS::ContextChange)
- diffs.map do |chunks|
- if klass == Diff::LCS::ContextChange
- klass.from_a(chunks)
- else
- chunks.map { |changes| klass.from_a(changes) }
- end
- end
- end
-
- def __simple_callbacks
- callbacks = Object.new
- class << callbacks
- attr_reader :matched_a
- attr_reader :matched_b
- attr_reader :discards_a
- attr_reader :discards_b
- attr_reader :done_a
- attr_reader :done_b
-
- def reset
- @matched_a = []
- @matched_b = []
- @discards_a = []
- @discards_b = []
- @done_a = []
- @done_b = []
- end
-
- def match(event)
- @matched_a << event.old_element
- @matched_b << event.new_element
- end
-
- def discard_b(event)
- @discards_b << event.new_element
- end
-
- def discard_a(event)
- @discards_a << event.old_element
- end
-
- def finished_a(event)
- @done_a << [event.old_element, event.old_position]
- end
-
- def finished_b(event)
- @done_b << [event.new_element, event.new_position]
- end
- end
- callbacks.reset
- callbacks
- end
-
- def __balanced_callback
- cb = Object.new
- class << cb
- attr_reader :result
-
- def reset
- @result = ""
- end
-
- def match(event)
- @result << "M#{event.old_position}#{event.new_position} "
- end
-
- def discard_a(event)
- @result << "DA#{event.old_position}#{event.new_position} "
- end
-
- def discard_b(event)
- @result << "DB#{event.old_position}#{event.new_position} "
- end
-
- def change(event)
- @result << "C#{event.old_position}#{event.new_position} "
- end
- end
- cb.reset
- cb
- end
-
- def setup
- @seq1 = %w(a b c e h j l m n p)
- @seq2 = %w(b c d e f j k l m r s t)
-
- @correct_lcs = %w(b c e j l m)
-
- @skipped_seq1 = 'a h n p'
- @skipped_seq2 = 'd f k r s t'
-
- correct_diff = [
- [ [ '-', 0, 'a' ] ],
- [ [ '+', 2, 'd' ] ],
- [ [ '-', 4, 'h' ],
- [ '+', 4, 'f' ] ],
- [ [ '+', 6, 'k' ] ],
- [ [ '-', 8, 'n' ],
- [ '-', 9, 'p' ],
- [ '+', 9, 'r' ],
- [ '+', 10, 's' ],
- [ '+', 11, 't' ] ] ]
- @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
- end
-end
-
-class TestLCS < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_lcs
- res = ares = bres = nil
- assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
- # The result of the LCS (less the +nil+ values) must be as long as the
- # correct result.
- assert_equal(res.compact.size, @correct_lcs.size)
- res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
- assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
- assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
- assert_equal(@correct_lcs, ares.compact)
- assert_equal(@correct_lcs, bres.compact)
- assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
- assert_equal(res.compact, @correct_lcs)
- end
-end
-
-class TestSequences < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sequences
- callbacks = nil
- assert_nothing_raised do
- callbacks = __simple_callbacks
- class << callbacks
- undef :finished_a
- undef :finished_b
- end
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_nothing_raised do
- callbacks = __simple_callbacks
- Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
- end
- assert_equal(@correct_lcs.size, callbacks.matched_a.size)
- assert_equal(@correct_lcs.size, callbacks.matched_b.size)
- assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
- assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
- assert_equal(9, callbacks.done_a[0][1])
- assert_nil(callbacks.done_b[0])
-
-# seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
-# assert_nothing_raised do
-# callbacks = __simple_callbacks
-# class << callbacks
-# undef :finished_a
-# undef :finished_b
-# end
-# Diff::LCS.traverse_sequences(seqw, [], callbacks)
-# end
- end
-
- def test_diff
- diff = nil
- assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
- assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
- assert_equal(@correct_diff, diff)
- end
-
- def test_diff_empty
- seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
- correct_diff = [
- [ [ '-', 0, 'abcd' ],
- [ '-', 1, 'efgh' ],
- [ '-', 2, 'ijkl' ],
- [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
- diff = nil
-
- assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
-
- correct_diff = [
- [ [ '+', 0, 'abcd' ],
- [ '+', 1, 'efgh' ],
- [ '+', 2, 'ijkl' ],
- [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
- assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
- assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
- end
-end
-
-class TestBalanced < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_sdiff_a
- sdiff = nil
- seq1 = %w(abc def yyy xxx ghi jkl)
- seq2 = %w(abc dxf xxx ghi jkl)
- correct_sdiff = [
- [ '=', [ 0, 'abc' ], [ 0, 'abc' ] ],
- [ '!', [ 1, 'def' ], [ 1, 'dxf' ] ],
- [ '-', [ 2, 'yyy' ], [ 2, nil ] ],
- [ '=', [ 3, 'xxx' ], [ 2, 'xxx' ] ],
- [ '=', [ 4, 'ghi' ], [ 3, 'ghi' ] ],
- [ '=', [ 5, 'jkl' ], [ 4, 'jkl' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_b
- sdiff = nil
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '=', [ 1, 'b' ], [ 0, 'b' ] ],
- [ '=', [ 2, 'c' ], [ 1, 'c' ] ],
- [ '+', [ 3, nil ], [ 2, 'd' ] ],
- [ '=', [ 3, 'e' ], [ 3, 'e' ] ],
- [ '!', [ 4, 'h' ], [ 4, 'f' ] ],
- [ '=', [ 5, 'j' ], [ 5, 'j' ] ],
- [ '+', [ 6, nil ], [ 6, 'k' ] ],
- [ '=', [ 6, 'l' ], [ 7, 'l' ] ],
- [ '=', [ 7, 'm' ], [ 8, 'm' ] ],
- [ '!', [ 8, 'n' ], [ 9, 'r' ] ],
- [ '!', [ 9, 'p' ], [ 10, 's' ] ],
- [ '+', [ 10, nil ], [ 11, 't' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_c
- sdiff = nil
- seq1 = %w(a b c d e)
- seq2 = %w(a e)
- correct_sdiff = [
- [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
- [ '-', [ 1, 'b' ], [ 1, nil ] ],
- [ '-', [ 2, 'c' ], [ 1, nil ] ],
- [ '-', [ 3, 'd' ], [ 1, nil ] ],
- [ '=', [ 4, 'e' ], [ 1, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_d
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
- [ '+', [ 1, nil ], [ 1, 'b' ] ],
- [ '+', [ 1, nil ], [ 2, 'c' ] ],
- [ '+', [ 1, nil ], [ 3, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 4, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_e
- sdiff = nil
- seq1 = %w(v x a e)
- seq2 = %w(w y a b c d e)
- correct_sdiff = [
- [ '!', [ 0, 'v' ], [ 0, 'w' ] ],
- [ '!', [ 1, 'x' ], [ 1, 'y' ] ],
- [ '=', [ 2, 'a' ], [ 2, 'a' ] ],
- [ '+', [ 3, nil ], [ 3, 'b' ] ],
- [ '+', [ 3, nil ], [ 4, 'c' ] ],
- [ '+', [ 3, nil ], [ 5, 'd' ] ],
- [ '=', [ 3, 'e' ], [ 6, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_f
- sdiff = nil
- seq1 = %w(x a e)
- seq2 = %w(a b c d e)
- correct_sdiff = [
- [ '-', [ 0, 'x' ], [ 0, nil ] ],
- [ '=', [ 1, 'a' ], [ 0, 'a' ] ],
- [ '+', [ 2, nil ], [ 1, 'b' ] ],
- [ '+', [ 2, nil ], [ 2, 'c' ] ],
- [ '+', [ 2, nil ], [ 3, 'd' ] ],
- [ '=', [ 2, 'e' ], [ 4, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_g
- sdiff = nil
- seq1 = %w(a e)
- seq2 = %w(x a b c d e)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'x' ] ],
- [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
- [ '+', [ 1, nil ], [ 2, 'b' ] ],
- [ '+', [ 1, nil ], [ 3, 'c' ] ],
- [ '+', [ 1, nil ], [ 4, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 5, 'e' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_h
- sdiff = nil
- seq1 = %w(a e v)
- seq2 = %w(x a b c d e w x)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'x' ] ],
- [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
- [ '+', [ 1, nil ], [ 2, 'b' ] ],
- [ '+', [ 1, nil ], [ 3, 'c' ] ],
- [ '+', [ 1, nil ], [ 4, 'd' ] ],
- [ '=', [ 1, 'e' ], [ 5, 'e' ] ],
- [ '!', [ 2, 'v' ], [ 6, 'w' ] ],
- [ '+', [ 3, nil ], [ 7, 'x' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_i
- sdiff = nil
- seq1 = %w()
- seq2 = %w(a b c)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'a' ] ],
- [ '+', [ 0, nil ], [ 1, 'b' ] ],
- [ '+', [ 0, nil ], [ 2, 'c' ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_j
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w()
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '-', [ 1, 'b' ], [ 0, nil ] ],
- [ '-', [ 2, 'c' ], [ 0, nil ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_k
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(1)
- correct_sdiff = [
- [ '!', [ 0, 'a' ], [ 0, '1' ] ],
- [ '-', [ 1, 'b' ], [ 1, nil ] ],
- [ '-', [ 2, 'c' ], [ 1, nil ] ] ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_l
- sdiff = nil
- seq1 = %w(a b c)
- seq2 = %w(c)
- correct_sdiff = [
- [ '-', [ 0, 'a' ], [ 0, nil ] ],
- [ '-', [ 1, 'b' ], [ 0, nil ] ],
- [ '=', [ 2, 'c' ], [ 0, 'c' ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_m
- sdiff = nil
- seq1 = %w(abcd efgh ijkl mnop)
- seq2 = []
- correct_sdiff = [
- [ '-', [ 0, 'abcd' ], [ 0, nil ] ],
- [ '-', [ 1, 'efgh' ], [ 0, nil ] ],
- [ '-', [ 2, 'ijkl' ], [ 0, nil ] ],
- [ '-', [ 3, 'mnop' ], [ 0, nil ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_sdiff_n
- sdiff = nil
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnop)
- correct_sdiff = [
- [ '+', [ 0, nil ], [ 0, 'abcd' ] ],
- [ '+', [ 0, nil ], [ 1, 'efgh' ] ],
- [ '+', [ 0, nil ], [ 2, 'ijkl' ] ],
- [ '+', [ 0, nil ], [ 3, 'mnop' ] ]
- ]
- correct_sdiff = __map_diffs(correct_sdiff)
- assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
- assert_equal(correct_sdiff, sdiff)
- end
-
- def test_balanced_a
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 M22 ", callback.result)
- end
-
- def test_balanced_b
- seq1 = %w(a b c)
- seq2 = %w(a x c)
- callback = nil
- assert_nothing_raised do
- callback = __balanced_callback
- class << callback
- undef change
- end
- end
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 DB21 M22 ", callback.result)
- end
-
- def test_balanced_c
- seq1 = %w(a x y c)
- seq2 = %w(a v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 C11 C22 M33 ", callback.result)
- end
-
- def test_balanced_d
- seq1 = %w(x y c)
- seq2 = %w(v w c)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 M22 ", callback.result)
- end
-
- def test_balanced_e
- seq1 = %w(a x y z)
- seq2 = %w(b v w)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 DA33 ", callback.result)
- end
-
- def test_balanced_f
- seq1 = %w(a z)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("M00 DA11 ", callback.result)
- end
-
- def test_balanced_g
- seq1 = %w(z a)
- seq2 = %w(a)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 M10 ", callback.result)
- end
-
- def test_balanced_h
- seq1 = %w(a b c)
- seq2 = %w(x y z)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("C00 C11 C22 ", callback.result)
- end
-
- def test_balanced_i
- seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- seq2 = []
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
- end
-
- def test_balanced_j
- seq1 = []
- seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
- callback = nil
- assert_nothing_raised { callback = __balanced_callback }
- assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
- assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
- end
-end
-
-class TestPatching < Test::Unit::TestCase
- include Diff::LCS::Tests
-
- def test_patch_diff
- ps = ms1 = ms2 = ms3 = nil
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms2 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::SDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- end
-
- # Tests patch bug #891:
- # http://rubyforge.org/tracker/?func=detail&atid=407&aid=891&group_id=84
- def test_patch_bug891
- s1 = s2 = s3 = s4 = s5 = ps = nil
- assert_nothing_raised do
- s1 = %w{a b c d e f g h i j k }
- s2 = %w{a b c d D e f g h i j k }
- ps = Diff::LCS::diff(s1, s2)
- s3 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::ContextDiffCallbacks)
- s4 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::SDiffCallbacks)
- s5 = Diff::LCS.patch(s1, ps, :patch)
- end
- assert_equal(s2, s3)
- assert_equal(s2, s4)
- assert_equal(s2, s5)
-
- assert_nothing_raised do
- ps = Diff::LCS::sdiff(s1, s2)
- s3 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::ContextDiffCallbacks)
- s4 = Diff::LCS.patch(s1, ps, :patch)
- ps = Diff::LCS::diff(s1, s2, Diff::LCS::DiffCallbacks)
- s5 = Diff::LCS.patch(s1, ps, :patch)
- end
- assert_equal(s2, s3)
- assert_equal(s2, s4)
- assert_equal(s2, s5)
- end
-
- def test_patch_sdiff
- ps = ms1 = ms2 = ms3 = nil
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- assert_nothing_raised do
- ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::DiffCallbacks)
- ms1 = Diff::LCS.patch(@seq1, ps)
- ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
- ms3 = Diff::LCS.patch(@seq2, ps)
- end
- assert_equal(@seq2, ms1)
- assert_equal(@seq1, ms2)
- assert_equal(@seq1, ms3)
- end
-end
diff --git a/diff-lcs/tags/release-1.1.1/install.rb b/install.rb
index 4bd3d7a..4bd3d7a 100644
--- a/diff-lcs/tags/release-1.1.1/install.rb
+++ b/install.rb
diff --git a/diff-lcs/tags/release-1.1.2/lib/diff/lcs.rb b/lib/diff/lcs.rb
index b74b2d3..b74b2d3 100644
--- a/diff-lcs/tags/release-1.1.2/lib/diff/lcs.rb
+++ b/lib/diff/lcs.rb
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/array.rb b/lib/diff/lcs/array.rb
index e07f8aa..e07f8aa 100644
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/array.rb
+++ b/lib/diff/lcs/array.rb
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/block.rb b/lib/diff/lcs/block.rb
index 7dceb48..7dceb48 100644
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/block.rb
+++ b/lib/diff/lcs/block.rb
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/callbacks.rb b/lib/diff/lcs/callbacks.rb
index 74a1cdc..74a1cdc 100644
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/callbacks.rb
+++ b/lib/diff/lcs/callbacks.rb
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/change.rb b/lib/diff/lcs/change.rb
index 6ecdf7e..6ecdf7e 100644
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/change.rb
+++ b/lib/diff/lcs/change.rb
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/hunk.rb b/lib/diff/lcs/hunk.rb
index 58fac9f..58fac9f 100644
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/hunk.rb
+++ b/lib/diff/lcs/hunk.rb
diff --git a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/ldiff.rb b/lib/diff/lcs/ldiff.rb
index 61abc47..61abc47 100644
--- a/diff-lcs/tags/release-1.1.1/lib/diff/lcs/ldiff.rb
+++ b/lib/diff/lcs/ldiff.rb
diff --git a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/string.rb b/lib/diff/lcs/string.rb
index 2de7d1f..2de7d1f 100644
--- a/diff-lcs/tags/release-1.1.0/lib/diff/lcs/string.rb
+++ b/lib/diff/lcs/string.rb
diff --git a/diff-lcs/tags/release-1.1.1/tests/00test.rb b/tests/00test.rb
index 8872dfd..8872dfd 100644
--- a/diff-lcs/tags/release-1.1.1/tests/00test.rb
+++ b/tests/00test.rb