Returns the index of the smallest item for which the item > the given value This is a min binary search. Although written in Ruby it is only slightly slower than the corresponding method in C in Ruby 2.0.0 - the main benefit to use this method over the Ruby C version is that it returns the index (not the value) which means there is not need to have an additional structure to get the index (or record the index in the structure). This saves both memory and CPU. It also does not require passing a block that is called since this method is specialized to search the line index.
# File lib/puppet/pops/parser/locator.rb, line 189 def ary_bsearch_i(ary, value) low = 0 high = ary.length mid = nil smaller = false satisfied = false v = nil while low < high do mid = low + ((high - low) / 2) v = (ary[mid] > value) if v == true satisfied = true smaller = true elsif !v smaller = false else raise TypeError, "wrong argument, must be boolean or nil, got '#{v.class}'" end if smaller high = mid else low = mid + 1; end end return nil if low == ary.length return nil if !satisfied return low end
Common impl for 18 and 19 since scanner is byte based
# File lib/puppet/pops/parser/locator.rb, line 222 def compute_line_index scanner = StringScanner.new(string) result = [0] # first line starts at 0 while scanner.scan_until(/\n/) result << scanner.pos end self.line_index = result.freeze end
Returns the line number (first line is 1) for the given offset
# File lib/puppet/pops/parser/locator.rb, line 232 def line_for_offset(offset) if prev_offset == offset # use cache return prev_line end if line_nbr = ary_bsearch_i(line_index, offset) # cache prev_offset = offset prev_line = line_nbr return line_nbr end # If not found it is after last # clear cache prev_offset = prev_line = nil return line_index.size end
Returns the position on line (first position on a line is 1)
# File lib/puppet/pops/parser/locator.rb, line 169 def pos_on_line(offset) offset_on_line(offset) +1 end
# File lib/puppet/pops/parser/locator.rb, line 173 def to_location_hash(reported_offset, end_offset) pos = pos_on_line(reported_offset) offset = char_offset(reported_offset) length = char_length(reported_offset, end_offset) start_line = line_for_offset(reported_offset) { :line => start_line, :pos => pos, :offset => offset, :length => length} end
Create a locator based on a content string, and a boolean indicating if ruby version support multi-byte strings or not.
# File lib/puppet/pops/parser/locator.rb, line 159 def initialize(string, file, index = nil) @string = string.freeze @file = file.freeze @prev_offset = nil @prev_line = nil @line_index = index compute_line_index unless !index.nil? end