class Origen::Utility::Diff
Diff
provides an easy way to diff the contents of two files while optionally ignoring any differences in file comments.
differ = Origen::Utility::Diff.new(:ignore_blank_lines => true, :comment_char => "//") differ.file_a = "#{Origen.root}/my/file1.v" differ.file_b = "#{Origen.root}/my/file2.v" if differ.diffs? puts "You've changed something!" end
Attributes
Set this attribute to the comment char used by the given file and comments will be ignored by the diff. An array of strings can be passed in to mask multiple comment identifiers.
Full path to File A, this attribute must be set before calling any diff actions
Full path to File B, this attribute must be set before calling any diff actions
When true the diff will ignore blank lines, or lines that contain only whitespace
Public Class Methods
Create a new diff, attributes can be initialized via the options, or can be set later.
# File lib/origen/utility/diff.rb, line 28 def initialize(options = {}) @file_a = options[:file_a] @file_b = options[:file_b] @ignore_blank_lines = options[:ignore_blank_lines] @comment_char = options[:comment_char] @suspend_string = options[:suspend_string] # permits suspending diff check based on a string @resume_string = options[:resume_string] # permits resuming diff check based on a string @suspend_diff = false @resume_diff = false end
Public Instance Methods
Returns true if there are differences between the two files based on the current configuration
# File lib/origen/utility/diff.rb, line 41 def diffs? initialize_counters result = false content_a = File.readlines(@file_a) content_b = File.readlines(@file_b) changes = false lines_remaining = true while lines_remaining a = get_next_line_a(content_a) # Get the next vectors b = get_next_line_b(content_b) if !a && !b # If both patterns finished lines_remaining = false elsif !a || !b # If only 1 pattern finished lines_remaining = false changes = true unless @suspend_diff # There are extra vectors in one of the patterns elsif a != b # If the vectors don't match changes = true unless @suspend_diff end if @resume_diff # resume checking diffs for subsequent lines @suspend_diff = false @resume_diff = false end end changes end
Private Instance Methods
Fetches the line from the given array and does some pre-processing
# File lib/origen/utility/diff.rb, line 97 def get_line(array, ix) line = array[ix] if line set_suspend_diff(line) if @comment_char # Screen off any inline comments at the end of line begin [@comment_char].flatten.each do |comchar| unless line =~ /^\s*#{comchar}/ if line =~ /(.*)\s*#{comchar}.*/ return Regexp.last_match[1].strip else return line.strip end end end # This rescue is a crude way to guard against non-ASCII files that find # their way in here rescue line end else line.strip end end end
# File lib/origen/utility/diff.rb, line 91 def get_next_line_a(array) @a_ix = next_index(array, @a_ix) get_line(array, @a_ix) end
# File lib/origen/utility/diff.rb, line 86 def get_next_line_b(array) @b_ix = next_index(array, @b_ix) get_line(array, @b_ix) end
# File lib/origen/utility/diff.rb, line 156 def initialize_counters @a_ix = nil @b_ix = nil end
Find the next line in the given array and return the new index pointer
# File lib/origen/utility/diff.rb, line 125 def next_index(array, ix = nil) ix = ix ? ix + 1 : 0 matched = false while !matched && ix < array.size begin comment_matched = false # Skip comment lines if @comment_char [@comment_char].flatten.each do |char| if array[ix] =~ /^\s*#{char}.*/ comment_matched = true end end end # Skip blank lines if comment_matched ix += 1 elsif @ignore_blank_lines && array[ix] =~ /^\s*$/ ix += 1 else matched = true end # This rescue is a crude way to guard against non-ASCII files that find # there way in here rescue matched = true end end ix end
# File lib/origen/utility/diff.rb, line 72 def set_suspend_diff(line) if line.valid_encoding? if @suspend_string && !@suspend_diff if line =~ /#{@suspend_string}/ @suspend_diff = true end elsif @resume_string && @suspend_diff if line =~ /#{@resume_string}/ @resume_diff = true end end end end