diff-lcs 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +491 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +74 -0
- data/CONTRIBUTORS.md +48 -0
- data/Contributing.md +45 -90
- data/{License.md → LICENCE.md} +6 -4
- data/Manifest.txt +7 -4
- data/README.md +92 -0
- data/Rakefile +43 -66
- data/SECURITY.md +41 -0
- data/bin/htmldiff +4 -4
- data/docs/artistic.txt +1 -1
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +2 -2
- data/lib/diff/lcs/block.rb +4 -4
- data/lib/diff/lcs/callbacks.rb +9 -7
- data/lib/diff/lcs/change.rb +20 -20
- data/lib/diff/lcs/htmldiff.rb +26 -16
- data/lib/diff/lcs/hunk.rb +66 -45
- data/lib/diff/lcs/internals.rb +17 -17
- data/lib/diff/lcs/ldiff.rb +86 -74
- data/lib/diff/lcs.rb +66 -63
- data/lib/diff-lcs.rb +1 -1
- data/spec/change_spec.rb +50 -50
- data/spec/diff_spec.rb +14 -14
- data/spec/hunk_spec.rb +20 -20
- data/spec/issues_spec.rb +76 -70
- data/spec/lcs_spec.rb +11 -11
- data/spec/ldiff_spec.rb +30 -17
- data/spec/patch_spec.rb +84 -84
- data/spec/sdiff_spec.rb +111 -109
- data/spec/spec_helper.rb +76 -74
- data/spec/traverse_balanced_spec.rb +191 -189
- data/spec/traverse_sequences_spec.rb +31 -31
- metadata +55 -30
- data/Code-of-Conduct.md +0 -74
- data/History.md +0 -400
- data/README.rdoc +0 -84
data/lib/diff/lcs/backports.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
unless 0.respond_to?(:positive?)
|
4
|
-
class Fixnum #
|
4
|
+
class Fixnum # standard:disable Lint/UnifiedInteger
|
5
5
|
def positive?
|
6
|
-
self > 0
|
6
|
+
self > 0
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/diff/lcs/block.rb
CHANGED
@@ -25,13 +25,13 @@ class Diff::LCS::Block
|
|
25
25
|
def op
|
26
26
|
case [@remove.empty?, @insert.empty?]
|
27
27
|
when [false, false]
|
28
|
-
|
28
|
+
"!"
|
29
29
|
when [false, true]
|
30
|
-
|
30
|
+
"-"
|
31
31
|
when [true, false]
|
32
|
-
|
32
|
+
"+"
|
33
33
|
else # [true, true]
|
34
|
-
|
34
|
+
"^"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/diff/lcs/callbacks.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "diff/lcs/change"
|
4
4
|
|
5
|
-
module Diff::LCS
|
5
|
+
module Diff::LCS
|
6
6
|
# This callback object implements the default set of callback events,
|
7
7
|
# which only returns the event itself. Note that #finished_a and
|
8
8
|
# #finished_b are not implemented -- I haven't yet figured out where they
|
@@ -50,7 +50,9 @@ module Diff::LCS # rubocop:disable Style/Documentation
|
|
50
50
|
BalancedCallbacks = DefaultCallbacks
|
51
51
|
|
52
52
|
def self.callbacks_for(callbacks)
|
53
|
-
callbacks.new
|
53
|
+
callbacks.new
|
54
|
+
rescue
|
55
|
+
callbacks
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
@@ -107,7 +109,7 @@ class Diff::LCS::DiffCallbacks
|
|
107
109
|
# Returns the difference set collected during the diff process.
|
108
110
|
attr_reader :diffs
|
109
111
|
|
110
|
-
def initialize # :yields self
|
112
|
+
def initialize # :yields: self
|
111
113
|
@hunk = []
|
112
114
|
@diffs = []
|
113
115
|
|
@@ -131,11 +133,11 @@ class Diff::LCS::DiffCallbacks
|
|
131
133
|
end
|
132
134
|
|
133
135
|
def discard_a(event)
|
134
|
-
@hunk << Diff::LCS::Change.new(
|
136
|
+
@hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element)
|
135
137
|
end
|
136
138
|
|
137
139
|
def discard_b(event)
|
138
|
-
@hunk << Diff::LCS::Change.new(
|
140
|
+
@hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element)
|
139
141
|
end
|
140
142
|
|
141
143
|
def finish_hunk
|
@@ -302,7 +304,7 @@ class Diff::LCS::SDiffCallbacks
|
|
302
304
|
# Returns the difference set collected during the diff process.
|
303
305
|
attr_reader :diffs
|
304
306
|
|
305
|
-
def initialize
|
307
|
+
def initialize # :yields: self
|
306
308
|
@diffs = []
|
307
309
|
yield self if block_given?
|
308
310
|
end
|
data/lib/diff/lcs/change.rb
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
# addition of an element from either the old or the new sequenced
|
5
5
|
# enumerable.
|
6
6
|
class Diff::LCS::Change
|
7
|
-
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 #
|
7
|
+
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName
|
8
8
|
|
9
9
|
# The only actions valid for changes are '+' (add), '-' (delete), '='
|
10
10
|
# (no change), '!' (changed), '<' (tail changes from first sequence), or
|
11
11
|
# '>' (tail changes from second sequence). The last two ('<>') are only
|
12
12
|
# found with Diff::LCS::diff and Diff::LCS::sdiff.
|
13
|
-
VALID_ACTIONS = %w
|
13
|
+
VALID_ACTIONS = %w[+ - = ! > <].freeze
|
14
14
|
|
15
15
|
def self.valid_action?(action)
|
16
16
|
VALID_ACTIONS.include? action
|
@@ -28,7 +28,7 @@ class Diff::LCS::Change
|
|
28
28
|
@action, @position, @element = *args
|
29
29
|
|
30
30
|
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
31
|
-
fail
|
31
|
+
fail "Invalid Position Type" unless @position.is_a? IntClass
|
32
32
|
end
|
33
33
|
|
34
34
|
def inspect(*_args)
|
@@ -39,7 +39,7 @@ class Diff::LCS::Change
|
|
39
39
|
[@action, @position, @element]
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
alias_method :to_ary, :to_a
|
43
43
|
|
44
44
|
def self.from_a(arr)
|
45
45
|
arr = arr.flatten(1)
|
@@ -49,7 +49,7 @@ class Diff::LCS::Change
|
|
49
49
|
when 3
|
50
50
|
Diff::LCS::Change.new(*(arr[0...3]))
|
51
51
|
else
|
52
|
-
fail
|
52
|
+
fail "Invalid change array format provided."
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -70,27 +70,27 @@ class Diff::LCS::Change
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def adding?
|
73
|
-
@action ==
|
73
|
+
@action == "+"
|
74
74
|
end
|
75
75
|
|
76
76
|
def deleting?
|
77
|
-
@action ==
|
77
|
+
@action == "-"
|
78
78
|
end
|
79
79
|
|
80
80
|
def unchanged?
|
81
|
-
@action ==
|
81
|
+
@action == "="
|
82
82
|
end
|
83
83
|
|
84
84
|
def changed?
|
85
|
-
@action ==
|
85
|
+
@action == "!"
|
86
86
|
end
|
87
87
|
|
88
88
|
def finished_a?
|
89
|
-
@action ==
|
89
|
+
@action == ">"
|
90
90
|
end
|
91
91
|
|
92
92
|
def finished_b?
|
93
|
-
@action ==
|
93
|
+
@action == "<"
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
@@ -115,8 +115,8 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
115
115
|
@action, @old_position, @old_element, @new_position, @new_element = *args
|
116
116
|
|
117
117
|
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
118
|
-
fail
|
119
|
-
fail
|
118
|
+
fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass)
|
119
|
+
fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass)
|
120
120
|
end
|
121
121
|
|
122
122
|
def to_a
|
@@ -127,7 +127,7 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
127
127
|
]
|
128
128
|
end
|
129
129
|
|
130
|
-
|
130
|
+
alias_method :to_ary, :to_a
|
131
131
|
|
132
132
|
def self.from_a(arr)
|
133
133
|
Diff::LCS::Change.from_a(arr)
|
@@ -139,15 +139,15 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
139
139
|
ea = event.to_a
|
140
140
|
|
141
141
|
case ea[0]
|
142
|
-
when
|
142
|
+
when "-"
|
143
143
|
ea[2][1] = nil
|
144
|
-
when
|
145
|
-
ea[0] =
|
144
|
+
when "<"
|
145
|
+
ea[0] = "-"
|
146
146
|
ea[2][1] = nil
|
147
|
-
when
|
147
|
+
when "+"
|
148
148
|
ea[1][1] = nil
|
149
|
-
when
|
150
|
-
ea[0] =
|
149
|
+
when ">"
|
150
|
+
ea[0] = "+"
|
151
151
|
ea[1][1] = nil
|
152
152
|
end
|
153
153
|
|
data/lib/diff/lcs/htmldiff.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cgi"
|
4
4
|
|
5
5
|
# Produce a simple HTML diff view.
|
6
6
|
class Diff::LCS::HTMLDiff
|
7
7
|
class << self
|
8
|
-
|
8
|
+
# standard:disable ThreadSafety/ClassAndModuleAttributes
|
9
|
+
attr_accessor :can_expand_tabs # :nodoc:
|
10
|
+
# standard:enable ThreadSafety/ClassAndModuleAttributes
|
9
11
|
end
|
10
12
|
self.can_expand_tabs = true
|
11
13
|
|
12
|
-
class Callbacks
|
14
|
+
class Callbacks # :nodoc:
|
13
15
|
attr_accessor :output
|
14
16
|
attr_accessor :match_class
|
15
17
|
attr_accessor :only_a_class
|
@@ -19,14 +21,14 @@ class Diff::LCS::HTMLDiff
|
|
19
21
|
@output = output
|
20
22
|
options ||= {}
|
21
23
|
|
22
|
-
@match_class = options[:match_class] ||
|
23
|
-
@only_a_class = options[:only_a_class] ||
|
24
|
-
@only_b_class = options[:only_b_class] ||
|
24
|
+
@match_class = options[:match_class] || "match"
|
25
|
+
@only_a_class = options[:only_a_class] || "only_a"
|
26
|
+
@only_b_class = options[:only_b_class] || "only_b"
|
25
27
|
end
|
26
28
|
|
27
29
|
def htmlize(element, css_class)
|
28
|
-
element =
|
29
|
-
%
|
30
|
+
element = " " if element.empty?
|
31
|
+
%(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
|
30
32
|
end
|
31
33
|
private :htmlize
|
32
34
|
|
@@ -46,13 +48,16 @@ class Diff::LCS::HTMLDiff
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
51
|
+
# standard:disable Style/HashSyntax
|
49
52
|
DEFAULT_OPTIONS = {
|
50
53
|
:expand_tabs => nil,
|
51
54
|
:output => nil,
|
52
55
|
:css => nil,
|
53
56
|
:title => nil
|
54
57
|
}.freeze
|
58
|
+
# standard:enable Style/HashSyntax
|
55
59
|
|
60
|
+
# standard:disable Layout/HeredocIndentation
|
56
61
|
DEFAULT_CSS = <<-CSS
|
57
62
|
body { margin: 0; }
|
58
63
|
.diff
|
@@ -86,11 +91,12 @@ pre
|
|
86
91
|
}
|
87
92
|
h1 { margin-left: 2em; }
|
88
93
|
CSS
|
94
|
+
# standard:enable Layout/HeredocIndentation
|
89
95
|
|
90
96
|
def initialize(left, right, options = nil)
|
91
|
-
@left
|
92
|
-
@right
|
93
|
-
@options
|
97
|
+
@left = left
|
98
|
+
@right = right
|
99
|
+
@options = options
|
94
100
|
|
95
101
|
@options = DEFAULT_OPTIONS.dup if @options.nil?
|
96
102
|
end
|
@@ -103,7 +109,7 @@ h1 { margin-left: 2em; }
|
|
103
109
|
|
104
110
|
@options[:css] ||= DEFAULT_CSS.dup
|
105
111
|
|
106
|
-
@options[:title] ||=
|
112
|
+
@options[:title] ||= "diff"
|
107
113
|
end
|
108
114
|
private :verify_options
|
109
115
|
|
@@ -116,13 +122,14 @@ h1 { margin-left: 2em; }
|
|
116
122
|
formatter = Text::Format.new
|
117
123
|
formatter.tabstop = @options[:expand_tabs]
|
118
124
|
|
119
|
-
@left.map!
|
120
|
-
@right.map!
|
125
|
+
@left.map! { |line| formatter.expand(line.chomp) }
|
126
|
+
@right.map! { |line| formatter.expand(line.chomp) }
|
121
127
|
end
|
122
128
|
|
123
|
-
@left.map!
|
124
|
-
@right.map!
|
129
|
+
@left.map! { |line| CGI.escapeHTML(line.chomp) }
|
130
|
+
@right.map! { |line| CGI.escapeHTML(line.chomp) }
|
125
131
|
|
132
|
+
# standard:disable Layout/HeredocIndentation
|
126
133
|
@options[:output] << <<-OUTPUT
|
127
134
|
<html>
|
128
135
|
<head>
|
@@ -137,14 +144,17 @@ h1 { margin-left: 2em; }
|
|
137
144
|
<span class="only_b">Only in New</span></p>
|
138
145
|
<div class="diff">
|
139
146
|
OUTPUT
|
147
|
+
# standard:enable Layout/HeredocIndentation
|
140
148
|
|
141
149
|
callbacks = Callbacks.new(@options[:output])
|
142
150
|
Diff::LCS.traverse_sequences(@left, @right, callbacks)
|
143
151
|
|
152
|
+
# standard:disable Layout/HeredocIndentation
|
144
153
|
@options[:output] << <<-OUTPUT
|
145
154
|
</div>
|
146
155
|
</body>
|
147
156
|
</html>
|
148
157
|
OUTPUT
|
158
|
+
# standard:enable Layout/HeredocIndentation
|
149
159
|
end
|
150
160
|
end
|
data/lib/diff/lcs/hunk.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "diff/lcs/block"
|
4
4
|
|
5
5
|
# A Hunk is a group of Blocks which overlap because of the context surrounding
|
6
6
|
# each block. (So if we're not using context, every hunk will contain one
|
7
7
|
# block.) Used in the diff program (bin/ldiff).
|
8
8
|
class Diff::LCS::Hunk
|
9
|
-
OLD_DIFF_OP_ACTION = {
|
10
|
-
ED_DIFF_OP_ACTION = {
|
9
|
+
OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
10
|
+
ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
11
11
|
|
12
12
|
private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant)
|
13
13
|
|
@@ -22,18 +22,19 @@ class Diff::LCS::Hunk
|
|
22
22
|
end
|
23
23
|
|
24
24
|
if String.method_defined?(:encoding)
|
25
|
-
@preferred_data_encoding = data_old.fetch(0
|
25
|
+
@preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding
|
26
26
|
end
|
27
27
|
|
28
28
|
@data_old = data_old
|
29
29
|
@data_new = data_new
|
30
|
+
@old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?)
|
31
|
+
@new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?)
|
30
32
|
|
31
33
|
before = after = file_length_difference
|
32
34
|
after += @blocks[0].diff_size
|
33
35
|
@file_length_difference = after # The caller must get this manually
|
34
36
|
@max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
|
35
37
|
|
36
|
-
|
37
38
|
# Save the start & end of each array. If the array doesn't exist (e.g.,
|
38
39
|
# we're only adding items in this block), then figure out the line number
|
39
40
|
# based on the line number of the other file and the current difference in
|
@@ -54,8 +55,8 @@ class Diff::LCS::Hunk
|
|
54
55
|
|
55
56
|
@start_old = a1 || (b1 - before)
|
56
57
|
@start_new = b1 || (a1 + before)
|
57
|
-
@end_old
|
58
|
-
@end_new
|
58
|
+
@end_old = a2 || (b2 - after)
|
59
|
+
@end_new = b2 || (a2 + after)
|
59
60
|
|
60
61
|
self.flag_context = flag_context
|
61
62
|
end
|
@@ -67,12 +68,12 @@ class Diff::LCS::Hunk
|
|
67
68
|
|
68
69
|
# Change the "start" and "end" fields to note that context should be added
|
69
70
|
# to this hunk.
|
70
|
-
attr_accessor :flag_context
|
71
|
+
attr_accessor :flag_context
|
71
72
|
undef :flag_context=
|
72
|
-
def flag_context=(context)
|
73
|
-
return if context.nil?
|
73
|
+
def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods
|
74
|
+
return if context.nil? || context.zero?
|
74
75
|
|
75
|
-
add_start = context > @start_old ? @start_old : context
|
76
|
+
add_start = (context > @start_old) ? @start_old : context
|
76
77
|
|
77
78
|
@start_old -= add_start
|
78
79
|
@start_new -= add_start
|
@@ -80,14 +81,12 @@ class Diff::LCS::Hunk
|
|
80
81
|
old_size = @data_old.size
|
81
82
|
|
82
83
|
add_end =
|
83
|
-
if (@end_old + context)
|
84
|
-
old_size - @end_old
|
84
|
+
if (@end_old + context) >= old_size
|
85
|
+
old_size - @end_old - 1
|
85
86
|
else
|
86
87
|
context
|
87
88
|
end
|
88
89
|
|
89
|
-
add_end = @max_diff_size if add_end >= old_size
|
90
|
-
|
91
90
|
@end_old += add_end
|
92
91
|
@end_new += add_end
|
93
92
|
end
|
@@ -102,7 +101,7 @@ class Diff::LCS::Hunk
|
|
102
101
|
@start_new = hunk.start_new
|
103
102
|
blocks.unshift(*hunk.blocks)
|
104
103
|
end
|
105
|
-
|
104
|
+
alias_method :unshift, :merge
|
106
105
|
|
107
106
|
# Determines whether there is an overlap between this hunk and the
|
108
107
|
# provided hunk. This will be true if the difference between the two hunks
|
@@ -132,34 +131,42 @@ class Diff::LCS::Hunk
|
|
132
131
|
|
133
132
|
# Note that an old diff can't have any context. Therefore, we know that
|
134
133
|
# there's only one block in the hunk.
|
135
|
-
def old_diff(
|
136
|
-
warn
|
134
|
+
def old_diff(last = false)
|
135
|
+
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
137
136
|
|
138
137
|
block = @blocks[0]
|
139
138
|
|
139
|
+
if last
|
140
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
141
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
142
|
+
end
|
143
|
+
|
140
144
|
# Calculate item number range. Old diff range is just like a context
|
141
145
|
# diff range, except the ranges are on one line with the action between
|
142
146
|
# them.
|
143
|
-
s = encode("#{context_range(:old,
|
147
|
+
s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n")
|
144
148
|
# If removing anything, just print out all the remove lines in the hunk
|
145
149
|
# which is just all the remove lines in the block.
|
146
150
|
unless block.remove.empty?
|
147
|
-
@data_old[@start_old..@end_old].each { |e| s << encode(
|
151
|
+
@data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") }
|
148
152
|
end
|
149
153
|
|
150
|
-
s << encode("
|
154
|
+
s << encode("\\n") if old_missing_newline && !new_missing_newline
|
155
|
+
s << encode("---\n") if block.op == "!"
|
151
156
|
|
152
157
|
unless block.insert.empty?
|
153
|
-
@data_new[@start_new..@end_new].each { |e| s << encode(
|
158
|
+
@data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") }
|
154
159
|
end
|
155
160
|
|
161
|
+
s << encode("\\n") if new_missing_newline && !old_missing_newline
|
162
|
+
|
156
163
|
s
|
157
164
|
end
|
158
165
|
private :old_diff
|
159
166
|
|
160
167
|
def unified_diff(last = false)
|
161
168
|
# Calculate item number range.
|
162
|
-
s = encode("@@ -#{unified_range(:old
|
169
|
+
s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n")
|
163
170
|
|
164
171
|
# Outlist starts containing the hunk of the old file. Removing an item
|
165
172
|
# just means putting a '-' in front of it. Inserting an item requires
|
@@ -172,18 +179,20 @@ class Diff::LCS::Hunk
|
|
172
179
|
# file -- don't take removed items into account.
|
173
180
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
174
181
|
|
175
|
-
|
182
|
+
# standard:disable Performance/UnfreezeString
|
183
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
184
|
+
# standard:enable Performance/UnfreezeString
|
176
185
|
|
177
186
|
last_block = blocks[-1]
|
178
187
|
|
179
188
|
if last
|
180
|
-
old_missing_newline = missing_last_newline?(@data_old)
|
181
|
-
new_missing_newline = missing_last_newline?(@data_new)
|
189
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
190
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
182
191
|
end
|
183
192
|
|
184
193
|
@blocks.each do |block|
|
185
194
|
block.remove.each do |item|
|
186
|
-
op
|
195
|
+
op = item.action.to_s # -
|
187
196
|
offset = item.position - lo + num_added
|
188
197
|
outlist[offset][0, 1] = encode(op)
|
189
198
|
num_removed += 1
|
@@ -195,7 +204,7 @@ class Diff::LCS::Hunk
|
|
195
204
|
end
|
196
205
|
|
197
206
|
block.insert.each do |item|
|
198
|
-
op
|
207
|
+
op = item.action.to_s # +
|
199
208
|
offset = item.position - @start_new + num_removed
|
200
209
|
outlist[offset, 0] = encode(op) + @data_new[item.position].chomp
|
201
210
|
num_added += 1
|
@@ -212,8 +221,8 @@ class Diff::LCS::Hunk
|
|
212
221
|
|
213
222
|
def context_diff(last = false)
|
214
223
|
s = encode("***************\n")
|
215
|
-
s << encode("*** #{context_range(:old,
|
216
|
-
r = context_range(:new,
|
224
|
+
s << encode("*** #{context_range(:old, ",")} ****\n")
|
225
|
+
r = context_range(:new, ",")
|
217
226
|
|
218
227
|
if last
|
219
228
|
old_missing_newline = missing_last_newline?(@data_old)
|
@@ -226,7 +235,9 @@ class Diff::LCS::Hunk
|
|
226
235
|
removes = @blocks.reject { |e| e.remove.empty? }
|
227
236
|
|
228
237
|
unless removes.empty?
|
229
|
-
|
238
|
+
# standard:disable Performance/UnfreezeString
|
239
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
240
|
+
# standard:enable Performance/UnfreezeString
|
230
241
|
|
231
242
|
last_block = removes[-1]
|
232
243
|
|
@@ -248,7 +259,9 @@ class Diff::LCS::Hunk
|
|
248
259
|
inserts = @blocks.reject { |e| e.insert.empty? }
|
249
260
|
|
250
261
|
unless inserts.empty?
|
251
|
-
|
262
|
+
# standard:disable Performance/UnfreezeString
|
263
|
+
outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
264
|
+
# standard:enable Performance/UnfreezeString
|
252
265
|
|
253
266
|
last_block = inserts[-1]
|
254
267
|
|
@@ -268,14 +281,24 @@ class Diff::LCS::Hunk
|
|
268
281
|
end
|
269
282
|
private :context_diff
|
270
283
|
|
271
|
-
def ed_diff(format,
|
272
|
-
warn
|
284
|
+
def ed_diff(format, last)
|
285
|
+
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
286
|
+
if last
|
287
|
+
# ed script doesn't support well incomplete lines
|
288
|
+
warn "<old_file>: No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old)
|
289
|
+
warn "<new_file>: No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new)
|
290
|
+
|
291
|
+
if @blocks[0].op == "!"
|
292
|
+
return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n"
|
293
|
+
return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element
|
294
|
+
end
|
295
|
+
end
|
273
296
|
|
274
297
|
s =
|
275
298
|
if format == :reverse_ed
|
276
|
-
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old,
|
299
|
+
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n")
|
277
300
|
else
|
278
|
-
encode("#{context_range(:old,
|
301
|
+
encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
|
279
302
|
end
|
280
303
|
|
281
304
|
unless @blocks[0].insert.empty?
|
@@ -290,7 +313,7 @@ class Diff::LCS::Hunk
|
|
290
313
|
|
291
314
|
# Generate a range of item numbers to print. Only print 1 number if the
|
292
315
|
# range has only one item in it. Otherwise, it's 'start,end'
|
293
|
-
def context_range(mode, op
|
316
|
+
def context_range(mode, op)
|
294
317
|
case mode
|
295
318
|
when :old
|
296
319
|
s, e = (@start_old + 1), (@end_old + 1)
|
@@ -298,28 +321,26 @@ class Diff::LCS::Hunk
|
|
298
321
|
s, e = (@start_new + 1), (@end_new + 1)
|
299
322
|
end
|
300
323
|
|
301
|
-
e
|
302
|
-
e = 1 if e.zero?
|
303
|
-
|
304
|
-
s < e ? "#{s}#{op}#{e}" : e.to_s
|
324
|
+
(s < e) ? "#{s}#{op}#{e}" : e.to_s
|
305
325
|
end
|
306
326
|
private :context_range
|
307
327
|
|
308
328
|
# Generate a range of item numbers to print for unified diff. Print number
|
309
329
|
# where block starts, followed by number of lines in the block
|
310
330
|
# (don't print number of lines if it's 1)
|
311
|
-
def unified_range(mode
|
331
|
+
def unified_range(mode)
|
312
332
|
case mode
|
313
333
|
when :old
|
334
|
+
return "0,0" if @old_empty
|
314
335
|
s, e = (@start_old + 1), (@end_old + 1)
|
315
336
|
when :new
|
337
|
+
return "0,0" if @new_empty
|
316
338
|
s, e = (@start_new + 1), (@end_new + 1)
|
317
339
|
end
|
318
340
|
|
319
|
-
length = e - s +
|
341
|
+
length = e - s + 1
|
320
342
|
|
321
|
-
|
322
|
-
length <= 1 ? first.to_s : "#{first},#{length}"
|
343
|
+
(length <= 1) ? e.to_s : "#{s},#{length}"
|
323
344
|
end
|
324
345
|
private :unified_range
|
325
346
|
|