home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / COMPARE.PEL < prev    next >
Text File  |  1995-02-03  |  8KB  |  265 lines

  1. # $Header:   P:\source\wmacros\compare.pev   1.4   03 Feb 1995 16:01:06   PFHJXM0  $
  2.  
  3. ##############################################################################
  4. #
  5. #       Compuware Corporation
  6. #         31440 Northwestern Highway
  7. #           Farmington Hills, Michigan 48334-2564
  8. #
  9. #   This source code listing contains information that is
  10. #   proprietary to Compuware Corporation and may not be copied
  11. #   duplicated, translated, transmitted, stored, retrieved
  12. #   or in any manner or by any method conveyed or disclosed
  13. #   to a third party or parties without express written
  14. #   permission from Compuware Corporation.
  15. #
  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.       {
  66.          #         buf1 = edit_file( buf1 )
  67.          #         buf2 = edit_file( buf2 )
  68.          create_buf_and_win( buf1 )
  69.          buf1 = current_buffer;
  70.  
  71.          create_buf_and_win( buf2 )
  72.          buf2 = current_buffer;
  73.       }
  74.    } else {
  75.       # use current and next buffer
  76.       buf1 = current_buffer
  77.       buf2 = next_buffer("", 0, 1)
  78.    }
  79.  
  80.    # check validity of buffer ids
  81.    if ( (0 + buf1) == 0 || (0 + buf2) == 0      \
  82.          || typeof(buf1) != "bufid" \
  83.          || typeof(buf2) != "bufid" ) {
  84.       current_buffer = prevBuffer
  85.       return FALSE
  86.    }
  87.  
  88.    current_buffer = buf1
  89.    return _compare( buf1, buf2 )
  90. }
  91.  
  92.  
  93. ## compare_windows()
  94. #
  95. # Compare the buffers attached to two windows.
  96. #
  97. # Usage -
  98. #  create two windows (e.g. using the "split_window" function)
  99. #  containing the two buffers to be compared.  Position the cursor on
  100. #  the "same" line in each buffer, then invoke this function without
  101. #  arguments.  The cursor will advance to the line and column where
  102. #  the next mismatch is found.
  103. #
  104. # return value is FALSE if an error occured
  105. #
  106. global function compare_windows() {          # PUBLIC
  107.    local buf1, buf2
  108.    local w1, w2
  109.    local test
  110.    local status
  111.  
  112.    # If exactly two windows are present, use the buffers attached 
  113.    # to the two windows.
  114.  
  115.    w1 = current_window
  116.    buf1 = current_buffer
  117.  
  118.    w2 = next_window()
  119.    buf2 = current_buffer
  120.  
  121.    if ( w1 == w2 ) {
  122.       warning( "compare_windows requires two windows" )
  123.       return
  124.    }
  125.  
  126.    test = next_window()
  127.    current_window = w1
  128.    if ( test != w1 && test != w2 ) {
  129.       warning( "to many windows - compare requires two windows" )
  130.       return
  131.    }
  132.  
  133.    status = _compare( buf1, buf2 )
  134.    center_cursor()
  135.  
  136.    if ( w2 ) {
  137.       # locate the cursor in the second window if necessary
  138.       current_buffer = buf2
  139.       save_position()
  140.       current_buffer = buf1
  141.  
  142.       current_window = w2
  143.       restore_position( 1 )
  144.       center_cursor()
  145.       current_window = w1
  146.    }
  147.  
  148.    return status
  149. }
  150.  
  151.  
  152. # compare two buffers given two distinct buffer ids.
  153. # return value is FALSE if the input arguments are invalid.
  154. #
  155. global function _compare( buf1, buf2 ) {
  156.    local priorWindow = current_window
  157.    local s1, s2
  158.    local nlines1, nlines2
  159.    local eof1, eof2
  160.    local maxcol
  161.    local line, col
  162.    local more
  163.  
  164.    if ( 0+buf1 == 0 || 0+buf2 == 0 || buf1 == buf2 ) {
  165.       warning( "compare requires different buffers" )
  166.       return FALSE
  167.    }
  168.  
  169.    # make the dialog window current to avoid changing the rest of
  170.    # the screen when status messages are displayed
  171.    message( "Comparing..." )
  172.  
  173.    # optimize by precomputing buffer sizes
  174.    current_buffer = buf2
  175.    nlines2 = buffer_last_line
  176.  
  177.    current_buffer = buf1
  178.    nlines1 = buffer_last_line
  179.  
  180.    # are we comparing the whole buffer?
  181.    more = (current_line == 1) ? "" : "more "
  182.  
  183.    # do the compare
  184.    do {
  185.       # read the current lines
  186.  
  187.       current_buffer = buf1
  188.       s1 = read_buffer()
  189.  
  190.       current_buffer = buf2
  191.       s2 = read_buffer()
  192.  
  193.       if ( s1 != s2 ) { # difference found
  194.  
  195.          # find the first column where a difference occurs
  196.          maxcol = length( s1 ) > length( s2 )   \
  197.                ? length( s1 )    \
  198.                : length( s2 )
  199.  
  200.          for ( col=1; maxcol; col++ ) {
  201.             if ( substr(s1,1,col) != substr(s2,1,col )) {
  202.  
  203.                # buffer 2
  204.                col--
  205.                if ( col ) {
  206.                   next_char( col )
  207.                }
  208.  
  209.                # buffer 1
  210.                current_buffer = buf1
  211.                if ( col ) {
  212.                   next_char( col )
  213.                }
  214.  
  215.                # place the cursor in the window
  216.                if ( priorWindow ) {
  217.                   save_position()
  218.                   current_window = priorWindow
  219.                   restore_position( 1 )
  220.                }
  221.                message( "difference found in column %d", \
  222.                   current_column )
  223.                break
  224.             }
  225.          }
  226.          return TRUE
  227.       }
  228.  
  229.       # advance to the next line
  230.  
  231.       current_column = 1
  232.       eof2 = ( current_line++ == nlines2 )
  233.       current_buffer = buf1
  234.       current_column = 1
  235.       eof1 = ( current_line++ == nlines1 )
  236.       if ( (line = current_line) % 50 == 0 ) {
  237.          # update status message without updating display
  238.          message( "Comparing... %d%%", line * 100 / nlines1 )
  239.       }
  240.  
  241.    } while ( !eof1 && !eof2 )
  242.  
  243.    if ( priorWindow ) {
  244.       save_position()
  245.       current_window = priorWindow
  246.       restore_position( 1 )
  247.    }
  248.  
  249.    if ( xor( eof1, eof2 )) {
  250.       if ( eof2 ) {
  251.          current_buffer = buf2
  252.       } else {
  253.          current_buffer = buf1
  254.       }
  255.       notify( "premature end of file in buffer %s",   \
  256.             buffer_filename )
  257.  
  258.       current_buffer = buf1
  259.  
  260.    } else {
  261.       notify( "no " more "differences found" )
  262.    }
  263.    return TRUE
  264. }
  265.