home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w055 / 4.ddi / SOURCES.LIF / COMPARE.PEL < prev    next >
Encoding:
Text File  |  1990-09-27  |  6.7 KB  |  262 lines

  1. # $Header:   P:/source/ppee/macros/compare.pev   1.5   26 Sep 1990 16:33:04   skipr  $
  2.  
  3. ##############################################################################
  4. #
  5. #           Sage Software - POLYTRON Division
  6. #             1700 NW 167th Place
  7. #               Beaverton, OR 97006
  8. #
  9. #   Copyright 1990, Sage Software, Inc.
  10. #
  11. #   Permission is hereby granted for licensed users of Sage Professional
  12. #   Editor and PolyAwk to copy and modify this source code for their own
  13. #   personal use.  These derivative works may be distributed only to other
  14. #   licensed Sage Professional Editor and PolyAwk users.  All other usage
  15. #   is prohibited without express written permission from Sage Software.
  16. #
  17. ##############################################################################
  18.  
  19. #### $Workfile:   compare.pel  $: file comparision utility
  20.  
  21. ## buffer comparison functions
  22. #
  23. # Usage -
  24. #    Given two buffers to be compared, position the cursor on the 
  25. #    "same" line in each buffer, then invoke either "compare_buffers"
  26. #    or "compare_windows" depending on whether the buffers are in
  27. #    separate windows.  The cursor will advance to the line and column 
  28. #    where the next mismatch is found.
  29. #
  30. ## compare_buffers( [buf1, buf2] )
  31. #    Performs a character by character comparison of two buffers given 
  32. #    their buffer_id numbers or filenames.  If no arguments are given, 
  33. #    this function compares the "current_buffer" with the "next_buffer()".  
  34. #    The compare begins at the current cursor line within each buffer.  
  35. #    If a difference is found, the cursor is placed on the first 
  36. #    character which differs.
  37. #
  38. ## compare_windows()
  39. #    Differs from compare_buffers in that the buffers to be compared are
  40. #    those attached to the "current_window" and the "next_window()".
  41. #
  42. #############################################################################
  43.  
  44.  
  45. ## compare_buffers( [buf1, buf2] )
  46. #
  47. # Compare two buffers, line by line.  The buffers may be specified either
  48. # by filename or buffer id.
  49. #
  50. # Usage -
  51. #    Position the cursor on the "same" line in each buffer, then invoke 
  52. #    this function.  It is convenient to have this function bound to a
  53. #    key.  The cursor will advance to the line and column where the next 
  54. #    mismatch is found.
  55. #
  56. # return value is FALSE if an error occured
  57. #
  58. global function compare_buffers( buf1, buf2 ) {            # PUBLIC
  59.     local    prevBuffer = current_buffer
  60.  
  61.     if ( argcount() == 2 ){
  62.         # check for file name arguments
  63.         if ( typeof(buf1) == "string"    \
  64.           && typeof(buf2) == "string" ) {
  65.             buf1 = edit_file( buf1 )
  66.             buf2 = edit_file( buf2 )
  67.         }
  68.     } else {
  69.         # use current and next buffer
  70.         buf1 = current_buffer
  71.         buf2 = next_buffer()
  72.     }
  73.  
  74.     # check validity of buffer ids
  75.     if ( (0 + buf1) == 0 || (0 + buf2) == 0        \
  76.             || typeof(buf1) != "bufid"    \
  77.             || typeof(buf2) != "bufid" ) {
  78.         current_buffer = prevBuffer
  79.         return FALSE
  80.     }
  81.  
  82.     current_buffer = buf1
  83.     return _compare( buf1, buf2 )
  84. }
  85.  
  86.  
  87. ## compare_windows()
  88. #
  89. # Compare the buffers attached to two windows.
  90. #
  91. # Usage -
  92. #    create two windows (e.g. using the "split_window" function)
  93. #    containing the two buffers to be compared.  Position the cursor on
  94. #    the "same" line in each buffer, then invoke this function without
  95. #    arguments.  The cursor will advance to the line and column where
  96. #    the next mismatch is found.
  97. #
  98. # return value is FALSE if an error occured
  99. #
  100. global function compare_windows() {                # PUBLIC
  101.     local    buf1, buf2
  102.     local    w1, w2
  103.     local    test
  104.     local    status
  105.  
  106.     # If exactly two windows are present, use the buffers attached 
  107.     # to the two windows.
  108.  
  109.     w1 = current_window
  110.     buf1 = current_buffer
  111.  
  112.     w2 = next_window()
  113.     buf2 = current_buffer
  114.  
  115.     if ( w1 == w2 ) {
  116.         warning( "compare_windows requires two windows" )
  117.         return
  118.     }
  119.  
  120.     test = next_window()
  121.     current_window = w1
  122.     if ( test != w1 && test != w2 ) {
  123.         warning( "to many windows - compare requires two windows" )
  124.         return
  125.     }
  126.  
  127.     status = _compare( buf1, buf2 )
  128.     center_cursor()
  129.  
  130.     if ( w2 ) {
  131.         # locate the cursor in the second window if necessary
  132.         current_buffer = buf2
  133.         save_position()
  134.         current_buffer = buf1
  135.  
  136.         current_window = w2
  137.         restore_position( 1 )
  138.         center_cursor()
  139.         current_window = w1
  140.     }
  141.  
  142.     return status
  143. }
  144.  
  145.  
  146. # compare two buffers given two distinct buffer ids.
  147. # return value is FALSE if the input arguments are invalid.
  148. #
  149. global function _compare( buf1, buf2 ) {
  150.     local    priorWindow = current_window
  151.     local    s1, s2
  152.     local    nlines1, nlines2
  153.     local    eof1, eof2
  154.     local    maxcol
  155.     local    line, col
  156.     local    more
  157.  
  158.     if ( 0+buf1 == 0 || 0+buf2 == 0 || buf1 == buf2 ) {
  159.         warning( "compare requires different buffers" )
  160.         return FALSE
  161.     }
  162.  
  163.     # make the dialog window current to avoid changing the rest of
  164.     # the screen when status messages are displayed
  165.     if ( dialog_window ) {
  166.         current_window = dialog_window
  167.         message( "Comparing..."    )
  168.     }
  169.  
  170.     # optimize by precomputing buffer sizes
  171.     current_buffer = buf2
  172.     nlines2 = buffer_last_line
  173.  
  174.     current_buffer = buf1
  175.     nlines1 = buffer_last_line
  176.  
  177.     # are we comparing the whole buffer?
  178.     more = (current_line == 1) ? "" : "more "
  179.  
  180.     # do the compare
  181.     do {
  182.         # read the current lines
  183.  
  184.         current_buffer = buf1
  185.         current_column = 1
  186.         s1 = read_buffer()
  187.  
  188.         current_buffer = buf2
  189.         current_column = 1
  190.         s2 = read_buffer()
  191.  
  192.         if ( s1 != s2 ) {    # difference found
  193.  
  194.             # find the first column where a difference occurs
  195.             maxcol = length( s1 ) > length( s2 )    \
  196.                     ? length( s1 )        \
  197.                     : length( s2 )
  198.  
  199.             for ( col=1; maxcol; col++ ) {
  200.                 if ( substr(s1,1,col) != substr(s2,1,col )) {
  201.  
  202.                     # buffer 2
  203.                     col--
  204.                     if ( col ) {
  205.                         next_char( col )
  206.                     }
  207.  
  208.                     # buffer 1
  209.                     current_buffer = buf1
  210.                     if ( col ) {
  211.                         next_char( col )
  212.                     }
  213.  
  214.                     # place the cursor in the window
  215.                     if ( priorWindow ) {
  216.                         save_position()
  217.                         current_window = priorWindow
  218.                         restore_position( 1 )
  219.                     }
  220.                     message( "difference found in column %d", \
  221.                         current_column )
  222.                     break
  223.                 }
  224.             }
  225.             return TRUE
  226.         }
  227.  
  228.         # advance to the next line
  229.  
  230.         eof2 = ( current_line++ == nlines2 )
  231.         current_buffer = buf1
  232.         eof1 = ( current_line++ == nlines1 )
  233.         if ( dialog_window && (line = current_line) % 50 == 0 ) {
  234.             # update status message without updating display
  235.             message( "Comparing... %d%%", line * 100 / nlines1 )
  236.         }
  237.  
  238.     } while ( !eof1 && !eof2 )
  239.  
  240.     if ( priorWindow ) {
  241.         save_position()
  242.         current_window = priorWindow
  243.         restore_position( 1 )
  244.     }
  245.  
  246.     if ( xor( eof1, eof2 )) {
  247.         if ( eof2 ) {
  248.             current_buffer = buf2
  249.         } else {
  250.             current_buffer = buf1
  251.         }
  252.         notify( "premature end of file in buffer %s",    \
  253.                 buffer_filename )
  254.  
  255.         current_buffer = buf1
  256.  
  257.     } else {
  258.         notify( "no " more "differences found" )
  259.     }
  260.     return TRUE
  261. }
  262.