annotate lib/redmine/.svn/text-base/unified_diff.rb.svn-base @ 865:49a3585c24b1 bug_133

Close obsolete branch bug_133
author Chris Cannam
date Wed, 11 May 2011 11:39:27 +0100
parents 513646585e45
children 051f544170fe
rev   line source
Chris@0 1 # redMine - project management software
Chris@0 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 module Redmine
Chris@0 19 # Class used to parse unified diffs
Chris@0 20 class UnifiedDiff < Array
Chris@0 21 def initialize(diff, options={})
Chris@0 22 options.assert_valid_keys(:type, :max_lines)
Chris@0 23 diff = diff.split("\n") if diff.is_a?(String)
Chris@0 24 diff_type = options[:type] || 'inline'
Chris@0 25
Chris@0 26 lines = 0
Chris@0 27 @truncated = false
Chris@0 28 diff_table = DiffTable.new(diff_type)
Chris@0 29 diff.each do |line|
Chris@0 30 unless diff_table.add_line line
Chris@0 31 self << diff_table if diff_table.length > 1
Chris@0 32 diff_table = DiffTable.new(diff_type)
Chris@0 33 end
Chris@0 34 lines += 1
Chris@0 35 if options[:max_lines] && lines > options[:max_lines]
Chris@0 36 @truncated = true
Chris@0 37 break
Chris@0 38 end
Chris@0 39 end
Chris@0 40 self << diff_table unless diff_table.empty?
Chris@0 41 self
Chris@0 42 end
Chris@0 43
Chris@0 44 def truncated?; @truncated; end
Chris@0 45 end
Chris@0 46
Chris@0 47 # Class that represents a file diff
Chris@0 48 class DiffTable < Hash
Chris@0 49 attr_reader :file_name, :line_num_l, :line_num_r
Chris@0 50
Chris@0 51 # Initialize with a Diff file and the type of Diff View
Chris@0 52 # The type view must be inline or sbs (side_by_side)
Chris@0 53 def initialize(type="inline")
Chris@0 54 @parsing = false
Chris@0 55 @nb_line = 1
Chris@0 56 @start = false
Chris@0 57 @before = 'same'
Chris@0 58 @second = true
Chris@0 59 @type = type
Chris@0 60 end
Chris@0 61
Chris@0 62 # Function for add a line of this Diff
Chris@0 63 # Returns false when the diff ends
Chris@0 64 def add_line(line)
Chris@0 65 unless @parsing
Chris@0 66 if line =~ /^(---|\+\+\+) (.*)$/
Chris@0 67 @file_name = $2
Chris@0 68 elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
Chris@0 69 @line_num_l = $2.to_i
Chris@0 70 @line_num_r = $5.to_i
Chris@0 71 @parsing = true
Chris@0 72 end
Chris@0 73 else
Chris@0 74 if line =~ /^[^\+\-\s@\\]/
Chris@0 75 @parsing = false
Chris@0 76 return false
Chris@0 77 elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
Chris@0 78 @line_num_l = $2.to_i
Chris@0 79 @line_num_r = $5.to_i
Chris@0 80 else
Chris@0 81 @nb_line += 1 if parse_line(line, @type)
Chris@0 82 end
Chris@0 83 end
Chris@0 84 return true
Chris@0 85 end
Chris@0 86
Chris@0 87 def inspect
Chris@0 88 puts '### DIFF TABLE ###'
Chris@0 89 puts "file : #{file_name}"
Chris@0 90 self.each do |d|
Chris@0 91 d.inspect
Chris@0 92 end
Chris@0 93 end
Chris@0 94
Chris@0 95 private
Chris@0 96 # Test if is a Side By Side type
Chris@0 97 def sbs?(type, func)
Chris@0 98 if @start and type == "sbs"
Chris@0 99 if @before == func and @second
Chris@0 100 tmp_nb_line = @nb_line
Chris@0 101 self[tmp_nb_line] = Diff.new
Chris@0 102 else
Chris@0 103 @second = false
Chris@0 104 tmp_nb_line = @start
Chris@0 105 @start += 1
Chris@0 106 @nb_line -= 1
Chris@0 107 end
Chris@0 108 else
Chris@0 109 tmp_nb_line = @nb_line
Chris@0 110 @start = @nb_line
Chris@0 111 self[tmp_nb_line] = Diff.new
Chris@0 112 @second = true
Chris@0 113 end
Chris@0 114 unless self[tmp_nb_line]
Chris@0 115 @nb_line += 1
Chris@0 116 self[tmp_nb_line] = Diff.new
Chris@0 117 else
Chris@0 118 self[tmp_nb_line]
Chris@0 119 end
Chris@0 120 end
Chris@0 121
Chris@0 122 # Escape the HTML for the diff
Chris@0 123 def escapeHTML(line)
Chris@0 124 CGI.escapeHTML(line)
Chris@0 125 end
Chris@0 126
Chris@0 127 def parse_line(line, type="inline")
Chris@0 128 if line[0, 1] == "+"
Chris@0 129 diff = sbs? type, 'add'
Chris@0 130 @before = 'add'
Chris@0 131 diff.line_right = escapeHTML line[1..-1]
Chris@0 132 diff.nb_line_right = @line_num_r
Chris@0 133 diff.type_diff_right = 'diff_in'
Chris@0 134 @line_num_r += 1
Chris@0 135 true
Chris@0 136 elsif line[0, 1] == "-"
Chris@0 137 diff = sbs? type, 'remove'
Chris@0 138 @before = 'remove'
Chris@0 139 diff.line_left = escapeHTML line[1..-1]
Chris@0 140 diff.nb_line_left = @line_num_l
Chris@0 141 diff.type_diff_left = 'diff_out'
Chris@0 142 @line_num_l += 1
Chris@0 143 true
Chris@0 144 elsif line[0, 1] =~ /\s/
Chris@0 145 @before = 'same'
Chris@0 146 @start = false
Chris@0 147 diff = Diff.new
Chris@0 148 diff.line_right = escapeHTML line[1..-1]
Chris@0 149 diff.nb_line_right = @line_num_r
Chris@0 150 diff.line_left = escapeHTML line[1..-1]
Chris@0 151 diff.nb_line_left = @line_num_l
Chris@0 152 self[@nb_line] = diff
Chris@0 153 @line_num_l += 1
Chris@0 154 @line_num_r += 1
Chris@0 155 true
Chris@0 156 elsif line[0, 1] = "\\"
Chris@0 157 true
Chris@0 158 else
Chris@0 159 false
Chris@0 160 end
Chris@0 161 end
Chris@0 162 end
Chris@0 163
Chris@0 164 # A line of diff
Chris@0 165 class Diff
Chris@0 166 attr_accessor :nb_line_left
Chris@0 167 attr_accessor :line_left
Chris@0 168 attr_accessor :nb_line_right
Chris@0 169 attr_accessor :line_right
Chris@0 170 attr_accessor :type_diff_right
Chris@0 171 attr_accessor :type_diff_left
Chris@0 172
Chris@0 173 def initialize()
Chris@0 174 self.nb_line_left = ''
Chris@0 175 self.nb_line_right = ''
Chris@0 176 self.line_left = ''
Chris@0 177 self.line_right = ''
Chris@0 178 self.type_diff_right = ''
Chris@0 179 self.type_diff_left = ''
Chris@0 180 end
Chris@0 181
Chris@0 182 def inspect
Chris@0 183 puts '### Start Line Diff ###'
Chris@0 184 puts self.nb_line_left
Chris@0 185 puts self.line_left
Chris@0 186 puts self.nb_line_right
Chris@0 187 puts self.line_right
Chris@0 188 end
Chris@0 189 end
Chris@0 190 end