home *** CD-ROM | disk | FTP | other *** search
- # $Header: P:/source/ppee/macros/compare.pev 1.5 26 Sep 1990 16:33:04 skipr $
-
- ##############################################################################
- #
- # Sage Software - POLYTRON Division
- # 1700 NW 167th Place
- # Beaverton, OR 97006
- #
- # Copyright 1990, Sage Software, Inc.
- #
- # Permission is hereby granted for licensed users of Sage Professional
- # Editor and PolyAwk to copy and modify this source code for their own
- # personal use. These derivative works may be distributed only to other
- # licensed Sage Professional Editor and PolyAwk users. All other usage
- # is prohibited without express written permission from Sage Software.
- #
- ##############################################################################
-
- #### $Workfile: compare.pel $: file comparision utility
-
- ## buffer comparison functions
- #
- # Usage -
- # Given two buffers to be compared, position the cursor on the
- # "same" line in each buffer, then invoke either "compare_buffers"
- # or "compare_windows" depending on whether the buffers are in
- # separate windows. The cursor will advance to the line and column
- # where the next mismatch is found.
- #
- ## compare_buffers( [buf1, buf2] )
- # Performs a character by character comparison of two buffers given
- # their buffer_id numbers or filenames. If no arguments are given,
- # this function compares the "current_buffer" with the "next_buffer()".
- # The compare begins at the current cursor line within each buffer.
- # If a difference is found, the cursor is placed on the first
- # character which differs.
- #
- ## compare_windows()
- # Differs from compare_buffers in that the buffers to be compared are
- # those attached to the "current_window" and the "next_window()".
- #
- #############################################################################
-
-
- ## compare_buffers( [buf1, buf2] )
- #
- # Compare two buffers, line by line. The buffers may be specified either
- # by filename or buffer id.
- #
- # Usage -
- # Position the cursor on the "same" line in each buffer, then invoke
- # this function. It is convenient to have this function bound to a
- # key. The cursor will advance to the line and column where the next
- # mismatch is found.
- #
- # return value is FALSE if an error occured
- #
- global function compare_buffers( buf1, buf2 ) { # PUBLIC
- local prevBuffer = current_buffer
-
- if ( argcount() == 2 ){
- # check for file name arguments
- if ( typeof(buf1) == "string" \
- && typeof(buf2) == "string" ) {
- buf1 = edit_file( buf1 )
- buf2 = edit_file( buf2 )
- }
- } else {
- # use current and next buffer
- buf1 = current_buffer
- buf2 = next_buffer()
- }
-
- # check validity of buffer ids
- if ( (0 + buf1) == 0 || (0 + buf2) == 0 \
- || typeof(buf1) != "bufid" \
- || typeof(buf2) != "bufid" ) {
- current_buffer = prevBuffer
- return FALSE
- }
-
- current_buffer = buf1
- return _compare( buf1, buf2 )
- }
-
-
- ## compare_windows()
- #
- # Compare the buffers attached to two windows.
- #
- # Usage -
- # create two windows (e.g. using the "split_window" function)
- # containing the two buffers to be compared. Position the cursor on
- # the "same" line in each buffer, then invoke this function without
- # arguments. The cursor will advance to the line and column where
- # the next mismatch is found.
- #
- # return value is FALSE if an error occured
- #
- global function compare_windows() { # PUBLIC
- local buf1, buf2
- local w1, w2
- local test
- local status
-
- # If exactly two windows are present, use the buffers attached
- # to the two windows.
-
- w1 = current_window
- buf1 = current_buffer
-
- w2 = next_window()
- buf2 = current_buffer
-
- if ( w1 == w2 ) {
- warning( "compare_windows requires two windows" )
- return
- }
-
- test = next_window()
- current_window = w1
- if ( test != w1 && test != w2 ) {
- warning( "to many windows - compare requires two windows" )
- return
- }
-
- status = _compare( buf1, buf2 )
- center_cursor()
-
- if ( w2 ) {
- # locate the cursor in the second window if necessary
- current_buffer = buf2
- save_position()
- current_buffer = buf1
-
- current_window = w2
- restore_position( 1 )
- center_cursor()
- current_window = w1
- }
-
- return status
- }
-
-
- # compare two buffers given two distinct buffer ids.
- # return value is FALSE if the input arguments are invalid.
- #
- global function _compare( buf1, buf2 ) {
- local priorWindow = current_window
- local s1, s2
- local nlines1, nlines2
- local eof1, eof2
- local maxcol
- local line, col
- local more
-
- if ( 0+buf1 == 0 || 0+buf2 == 0 || buf1 == buf2 ) {
- warning( "compare requires different buffers" )
- return FALSE
- }
-
- # make the dialog window current to avoid changing the rest of
- # the screen when status messages are displayed
- if ( dialog_window ) {
- current_window = dialog_window
- message( "Comparing..." )
- }
-
- # optimize by precomputing buffer sizes
- current_buffer = buf2
- nlines2 = buffer_last_line
-
- current_buffer = buf1
- nlines1 = buffer_last_line
-
- # are we comparing the whole buffer?
- more = (current_line == 1) ? "" : "more "
-
- # do the compare
- do {
- # read the current lines
-
- current_buffer = buf1
- current_column = 1
- s1 = read_buffer()
-
- current_buffer = buf2
- current_column = 1
- s2 = read_buffer()
-
- if ( s1 != s2 ) { # difference found
-
- # find the first column where a difference occurs
- maxcol = length( s1 ) > length( s2 ) \
- ? length( s1 ) \
- : length( s2 )
-
- for ( col=1; maxcol; col++ ) {
- if ( substr(s1,1,col) != substr(s2,1,col )) {
-
- # buffer 2
- col--
- if ( col ) {
- next_char( col )
- }
-
- # buffer 1
- current_buffer = buf1
- if ( col ) {
- next_char( col )
- }
-
- # place the cursor in the window
- if ( priorWindow ) {
- save_position()
- current_window = priorWindow
- restore_position( 1 )
- }
- message( "difference found in column %d", \
- current_column )
- break
- }
- }
- return TRUE
- }
-
- # advance to the next line
-
- eof2 = ( current_line++ == nlines2 )
- current_buffer = buf1
- eof1 = ( current_line++ == nlines1 )
- if ( dialog_window && (line = current_line) % 50 == 0 ) {
- # update status message without updating display
- message( "Comparing... %d%%", line * 100 / nlines1 )
- }
-
- } while ( !eof1 && !eof2 )
-
- if ( priorWindow ) {
- save_position()
- current_window = priorWindow
- restore_position( 1 )
- }
-
- if ( xor( eof1, eof2 )) {
- if ( eof2 ) {
- current_buffer = buf2
- } else {
- current_buffer = buf1
- }
- notify( "premature end of file in buffer %s", \
- buffer_filename )
-
- current_buffer = buf1
-
- } else {
- notify( "no " more "differences found" )
- }
- return TRUE
- }
-