traverse_sequences (Diff::LCS)

         # File lib/diff/lcs.rb, line 395
    395:     def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks, &block) #:yields change events:
    396:       matches = Diff::LCS.__lcs(seq1, seq2)
    397:
    398:       run_finished_a = run_finished_b = false
    399:       string = seq1.kind_of?(String)
    400:
    401:       a_size = seq1.size
    402:       b_size = seq2.size
    403:       ai = bj = 0
    404:
    405:       (0 .. matches.size).each do |ii|
    406:         b_line = matches[ii]
    407:
    408:         ax = string ? seq1[ii, 1] : seq1[ii]
    409:         bx = string ? seq2[bj, 1] : seq2[bj]
    410:
    411:         if b_line.nil?
    412:           unless ax.nil?
    413:             event = Diff::LCS::ContextChange.new('-', ii, ax, bj, bx)
    414:             event = yield event if block_given?
    415:             callbacks.discard_a(event)
    416:           end
    417:         else
    418:           loop do
    419:             break unless bj < b_line
    420:             bx = string ? seq2[bj, 1] : seq2[bj]
    421:             event = Diff::LCS::ContextChange.new('+', ii, ax, bj, bx)
    422:             event = yield event if block_given?
    423:             callbacks.discard_b(event)
    424:             bj += 1
    425:           end
    426:           bx = string ? seq2[bj, 1] : seq2[bj]
    427:           event = Diff::LCS::ContextChange.new('=', ii, ax, bj, bx)
    428:           event = yield event if block_given?
    429:           callbacks.match(event)
    430:           bj += 1
    431:         end
    432:         ai = ii
    433:       end
    434:       ai += 1
    435:
    436:         # The last entry (if any) processed was a match. +ai+ and +bj+ point
    437:         # just past the last matching lines in their sequences.
    438:       while (ai < a_size) or (bj < b_size)
    439:           # last A?
    440:         if ai == a_size and bj < b_size
    441:           if callbacks.respond_to?(:finished_a) and not run_finished_a
    442:             ax = string ? seq1[-1, 1] : seq1[-1]
    443:             bx = string ? seq2[bj, 1] : seq2[bj]
    444:             event = Diff::LCS::ContextChange.new('>', (a_size - 1), ax, bj, bx)
    445:             event = yield event if block_given?
    446:             callbacks.finished_a(event)
    447:             run_finished_a = true
    448:           else
    449:             ax = string ? seq1[ai, 1] : seq1[ai]
    450:             loop do
    451:               bx = string ? seq2[bj, 1] : seq2[bj]
    452:               event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
    453:               event = yield event if block_given?
    454:               callbacks.discard_b(event)
    455:               bj += 1
    456:               break unless bj < b_size
    457:             end
    458:           end
    459:         end
    460:
    461:           # last B?
    462:         if bj == b_size and ai < a_size
    463:           if callbacks.respond_to?(:finished_b) and not run_finished_b
    464:             ax = string ? seq1[ai, 1] : seq1[ai]
    465:             bx = string ? seq2[-1, 1] : seq2[-1]
    466:             event = Diff::LCS::ContextChange.new('<', ai, ax, (b_size - 1), bx)
    467:             event = yield event if block_given?
    468:             callbacks.finished_b(event)
    469:             run_finished_b = true
    470:           else
    471:             bx = string ? seq2[bj, 1] : seq2[bj]
    472:             loop do
    473:               ax = string ? seq1[ai, 1] : seq1[ai]
    474:               event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
    475:               event = yield event if block_given?
    476:               callbacks.discard_a(event)
    477:               ai += 1
    478:               break unless bj < b_size
    479:             end
    480:           end
    481:         end
    482:
    483:         if ai < a_size
    484:           ax = string ? seq1[ai, 1] : seq1[ai]
    485:           bx = string ? seq2[bj, 1] : seq2[bj]
    486:           event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
    487:           event = yield event if block_given?
    488:           callbacks.discard_a(event)
    489:           ai += 1
    490:         end
    491:
    492:         if bj < b_size
    493:           ax = string ? seq1[ai, 1] : seq1[ai]
    494:           bx = string ? seq2[bj, 1] : seq2[bj]
    495:           event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
    496:           event = yield event if block_given?
    497:           callbacks.discard_b(event)
    498:           bj += 1
    499:         end
    500:       end
    501:     end