diff options
author | Austin Ziegler <austin@zieglers.ca> | 2014-05-06 00:08:02 -0400 |
---|---|---|
committer | Austin Ziegler <austin@zieglers.ca> | 2017-01-18 18:16:14 -0500 |
commit | 06ee20e929656d41c301f61fd447105c3840e410 (patch) | |
tree | 7325cd8e3279b71e5bc18302112e47cad3000a40 /lib | |
parent | 32727d6d0beb48672a1ee2d4a5c20bb81f7e301d (diff) | |
download | diff-lcs-06ee20e929656d41c301f61fd447105c3840e410.tar.gz |
diff-lcs 1.3
- Updated testing and gem infrastructure.
- Cleaning up documentation.
- Modernizing specs.
- Silence Ruby 2.4 Fixnum deprecation warnings. Fixes #36, #38.
- Ensure test dependencies are loaded. Fixes #33, #34 so that specs can be run
independently.
- Fix issue #1 with incorrect intuition of patch direction. Tentative fix, but
the failure cases pass now.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/diff/lcs.rb | 86 | ||||
-rw-r--r-- | lib/diff/lcs/change.rb | 8 | ||||
-rw-r--r-- | lib/diff/lcs/internals.rb | 22 | ||||
-rw-r--r-- | lib/diff/lcs/ldiff.rb | 52 |
4 files changed, 35 insertions, 133 deletions
diff --git a/lib/diff/lcs.rb b/lib/diff/lcs.rb index b51c1bc..34ddf0f 100644 --- a/lib/diff/lcs.rb +++ b/lib/diff/lcs.rb @@ -1,57 +1,7 @@ # -*- ruby encoding: utf-8 -*- module Diff; end unless defined? Diff -# 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 Smalltalk version (1.2, 1993) and Ned Konz's -# Perl version (Algorithm::Diff 1.15). -# -# == 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>. +# == How Diff Works (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 @@ -98,34 +48,6 @@ module Diff; end unless defined? Diff # # 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 <austin@rubyforge.org>. -# -# It is based on the Perl Algorithm::Diff (1.15) by Ned Konz , copyright -# © 2000–2002 and the Smalltalk diff version by Mario I. -# Wolczko, copyright © 1993. Documentation includes work by -# Mark-Jason Dominus. -# -# == Licence -# Copyright © 2004–2013 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 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 Diff::LCS VERSION = '1.3' end @@ -765,7 +687,7 @@ class << Diff::LCS ai += 1 bj += 1 end - ai += 1 + ai += 1 when '+' while bj < change.position res << (string ? src[ai, 1] : src[ai]) @@ -773,9 +695,9 @@ class << Diff::LCS bj += 1 end - bj += 1 + bj += 1 - res << change.element + res << change.element end end end diff --git a/lib/diff/lcs/change.rb b/lib/diff/lcs/change.rb index 3104a51..9229069 100644 --- a/lib/diff/lcs/change.rb +++ b/lib/diff/lcs/change.rb @@ -4,6 +4,8 @@ # addition of an element from either the old or the new sequenced # enumerable. class Diff::LCS::Change + IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 + # The only actions valid for changes are '+' (add), '-' (delete), '=' # (no change), '!' (changed), '<' (tail changes from first sequence), or # '>' (tail changes from second sequence). The last two ('<>') are only @@ -28,7 +30,7 @@ class Diff::LCS::Change unless Diff::LCS::Change.valid_action?(@action) raise "Invalid Change Action '#{@action}'" end - raise "Invalid Position Type" unless @position.kind_of? Fixnum + raise "Invalid Position Type" unless @position.kind_of? IntClass end def inspect @@ -115,10 +117,10 @@ class Diff::LCS::ContextChange < Diff::LCS::Change unless Diff::LCS::Change.valid_action?(@action) raise "Invalid Change Action '#{@action}'" end - unless @old_position.nil? or @old_position.kind_of? Fixnum + unless @old_position.nil? or @old_position.kind_of? IntClass raise "Invalid (Old) Position Type" end - unless @new_position.nil? or @new_position.kind_of? Fixnum + unless @new_position.nil? or @new_position.kind_of? IntClass raise "Invalid (New) Position Type" end end diff --git a/lib/diff/lcs/internals.rb b/lib/diff/lcs/internals.rb index 9d9e3f3..17d1d06 100644 --- a/lib/diff/lcs/internals.rb +++ b/lib/diff/lcs/internals.rb @@ -142,8 +142,6 @@ class << Diff::LCS::Internals # 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. - # - # Note: This will be deprecated as a public function in a future release. def intuit_diff_direction(src, patchset, limit = nil) string = src.kind_of?(String) count = left_match = left_miss = right_match = right_miss = 0 @@ -217,19 +215,27 @@ class << Diff::LCS::Internals no_left = (left_match == 0) && (left_miss > 0) no_right = (right_match == 0) && (right_miss > 0) - case [no_left, no_right] - when [false, true] + case [ no_left, no_right ] + when [ false, true ] :patch - when [true, false] + when [ true, false ] :unpatch else case left_match <=> right_match when 1 - :patch + if left_miss.zero? + :patch + else + :unpatch + end when -1 - :unpatch + if right_miss.zero? + :unpatch + else + :patch + end else - raise "The provided patchset does not appear to apply to the provided value as either source or destination value." + raise "The provided patchset does not appear to apply to the provided enumerable as either source or destination value." end end end diff --git a/lib/diff/lcs/ldiff.rb b/lib/diff/lcs/ldiff.rb index 75d890f..c789f46 100644 --- a/lib/diff/lcs/ldiff.rb +++ b/lib/diff/lcs/ldiff.rb @@ -4,46 +4,18 @@ 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 © 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 +module Diff::LCS::Ldiff #:nodoc: BANNER = <<-COPYRIGHT ldiff #{Diff::LCS::VERSION} - Copyright 2004-2013 Austin Ziegler + Copyright 2004-2014 Austin Ziegler Part of Diff::LCS. - http://rubyforge.org/projects/ruwiki/ - - Austin Ziegler <diff-lcs@halostatue.ca> + https://github.com/halostatue/diff-lcs 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 MIT licence. - COPYRIGHT +COPYRIGHT end class << Diff::LCS::Ldiff @@ -118,13 +90,13 @@ class << Diff::LCS::Ldiff file_length_difference = 0 if @binary.nil? or @binary - data_old = IO::read(file_old) - data_new = IO::read(file_new) + data_old = IO.read(file_old) + data_new = IO.read(file_new) # Test binary status if @binary.nil? - old_txt = data_old[0...4096].scan(/\0/).empty? - new_txt = data_new[0...4096].scan(/\0/).empty? + old_txt = data_old[0, 4096].scan(/\0/).empty? + new_txt = data_new[0, 4096].scan(/\0/).empty? @binary = (not old_txt) or (not new_txt) old_txt = new_txt = nil end @@ -134,8 +106,8 @@ class << Diff::LCS::Ldiff data_new = data_new.split($/).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 } + 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 @@ -155,9 +127,9 @@ class << Diff::LCS::Ldiff if (@format == :unified) or (@format == :context) ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z') - puts "#{char_old} #{file_old}\t#{ft}" + output << "#{char_old} #{file_old}\t#{ft}\n" ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z') - puts "#{char_new} #{file_new}\t#{ft}" + output << "#{char_new} #{file_new}\t#{ft}\n" end # Loop over hunks. If a hunk overlaps with the last hunk, join them. |