📄 diff.c
字号:
#include "tdestr.h"
#include "common.h"
#include "define.h"
#include "tdefunc.h"
/*
* Name: define_diff
* Purpose: get info needed to initialize diff
* Date: October 31, 1992
* Passed: window: pointer to current window
* Notes: allow the user to start the diff at the beginning of the
* file or at the current cursor location. once the diff
* has been defined, the user may press one key to diff again.
* user may diff any two visible windows on the screen.
*/
int define_diff( WINDOW *window )
{
int rc;
char temp[MAX_COLS];
int num1;
int let1;
int num2;
int let2;
int start;
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */
char buff[MAX_COLS*2]; /* buffer for char and attribute */
/*
* get window number and letter of the first diff window. then,
* verify that window - does it exit? is it visible?
*/
*temp = '\0';
rc = get_name( diff_prompt1, window->bottom_line, temp,
g_display.message_color );
if (rc == OK) {
rc = verify_number( temp, &num1 );
if (rc == OK)
rc = verify_letter( temp, &let1, &diff.w1 );
} else
return( ERROR );
if (rc == ERROR) {
combine_strings( buff, diff_prompt6a, temp, diff_prompt6b );
error( WARNING, window->bottom_line, buff );
return( ERROR );
}
/*
* get and verify the next window number and letter to diff.
*/
*temp = '\0';
rc = get_name( diff_prompt2, window->bottom_line, temp,
g_display.message_color );
if (rc == OK) {
rc = verify_number( temp, &num2 );
if (rc == OK)
rc = verify_letter( temp, &let2, &diff.w2 );
} else
return( ERROR );
if (rc == ERROR) {
combine_strings( buff, diff_prompt6a, temp, diff_prompt6b );
error( WARNING, window->bottom_line, buff );
return( ERROR );
}
/*
* are leading spaces significant?
*/
save_screen_line( 0, window->bottom_line, line_buff );
set_prompt( diff_prompt7a, window->bottom_line );
start = get_yn( );
restore_screen_line( 0, window->bottom_line, line_buff );
if (start != ERROR)
diff.leading = start == A_YES ? TRUE : FALSE;
else
return( ERROR );
/*
* are all spaces significant?
*/
save_screen_line( 0, window->bottom_line, line_buff );
set_prompt( diff_prompt7b, window->bottom_line );
start = get_yn( );
restore_screen_line( 0, window->bottom_line, line_buff );
if (start != ERROR) {
if (start == A_YES)
diff.leading = diff.all_space = TRUE;
else
diff.all_space = FALSE;
} else
return( ERROR );
/*
* are blank lines significant?
*/
save_screen_line( 0, window->bottom_line, line_buff );
set_prompt( diff_prompt7c, window->bottom_line );
start = get_yn( );
restore_screen_line( 0, window->bottom_line, line_buff );
if (start != ERROR)
diff.blank_lines = start == A_YES ? TRUE : FALSE;
else
return( ERROR );
/*
* is end of line significant?
*/
save_screen_line( 0, window->bottom_line, line_buff );
set_prompt( diff_prompt7d, window->bottom_line );
start = get_yn( );
restore_screen_line( 0, window->bottom_line, line_buff );
if (start != ERROR)
diff.ignore_eol = start == A_YES ? TRUE : FALSE;
else
return( ERROR );
/*
* now, find out were to start the diff -- beginning of file or
* current cursor location.
*/
save_screen_line( 0, window->bottom_line, line_buff );
set_prompt( diff_prompt3, window->bottom_line );
start = get_bc( );
restore_screen_line( 0, window->bottom_line, line_buff );
if (start != ERROR) {
entab_linebuff( );
if (un_copy_line( window->ll, window, TRUE ) == ERROR)
return( ERROR );
/*
* if everything is everything, initialize the diff pointers.
*/
diff.defined = TRUE;
if (start == BEGINNING) {
diff.d1 = diff.w1->file_info->line_list;
diff.d2 = diff.w2->file_info->line_list;
diff.rline1 = 1L;
diff.rline2 = 1L;
diff.bin_offset1 = 0;
diff.bin_offset2 = 0;
rc = differ( 0, 0, window->bottom_line );
} else {
diff.d1 = diff.w1->ll;
diff.d2 = diff.w2->ll;
diff.rline1 = diff.w1->rline;
diff.rline2 = diff.w2->rline;
diff.bin_offset1 = diff.w1->bin_offset;
diff.bin_offset2 = diff.w2->bin_offset;
rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
}
}
return( rc );
}
/*
* Name: repeat_diff
* Purpose: compare two cursor positions
* Date: October 31, 1992
* Passed: window: pointer to current window
* Notes: user may press this key at any time once the diff has been
* defined.
*/
int repeat_diff( WINDOW *window )
{
register int rc = ERROR;
if (diff.defined) {
entab_linebuff( );
if (un_copy_line( window->ll, window, TRUE ) == ERROR)
return( ERROR );
/*
* initialize the diff pointers.
*/
diff.d1 = diff.w1->ll;
diff.d2 = diff.w2->ll;
diff.rline1 = diff.w1->rline;
diff.rline2 = diff.w2->rline;
diff.bin_offset1 = diff.w1->bin_offset;
diff.bin_offset2 = diff.w2->bin_offset;
rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
} else
error( WARNING, window->bottom_line, diff_prompt5 );
return( rc );
}
/*
* Name: differ
* Purpose: diff text pointers
* Date: October 31, 1992
* Passed: initial_rcol1: beginning column to begin diff in window1
* initial_rcol2: beginning column to begin diff in window2
* bottom: line to display diagnostics
* Notes: a straight diff on text pointers is simple; however, diffing
* with leading spaces and tabs is kinda messy. let's do the
* messy diff.
*/
int differ( int initial_rcol1, int initial_rcol2, int bottom )
{
int rcol1; /* virtual real column on diff window 1 */
int rcol2; /* virtual real column on diff window 2 */
int r1; /* real real column rcol1 - needed for tabs */
int r2; /* real real column rcol2 - needed for tabs */
char c1; /* character under r1 */
char c2; /* character under r2 */
int leading1; /* adjustment for leading space in window 1 */
int leading2; /* adjustment for leading space in window 2 */
int len1; /* length of diff1 line */
int len2; /* length of diff2 line */
line_list_ptr node1; /* scratch node in window 1 */
line_list_ptr node2; /* scratch node in window 2 */
text_ptr diff1; /* scratch text ptr in window 1 */
text_ptr diff2; /* scratch text ptr in window 2 */
long rline1; /* real line number of diff pointer 1 */
long rline2; /* real line number of diff pointer 2 */
long bin_offset1; /* binary offset of diff pointer 1 */
long bin_offset2; /* binary offset of diff pointer 2 */
int len; /* line length variable */
register int tabs; /* local variable for mode.inflate_tabs, T or F */
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */
/*
* initialize the text pointers and the initial column. skip any
* initial blank lines.
*/
rline1 = diff.rline1;
rline2 = diff.rline2;
node1 = diff.d1;
node2 = diff.d2;
bin_offset1 = diff.bin_offset1;
bin_offset2 = diff.bin_offset2;
tabs = mode.inflate_tabs;
if (diff.blank_lines) {
while (node1->len != EOF && is_line_blank( node1->line, node1->len )) {
bin_offset1 += node1->len;
node1 = node1->next;
++rline1;
initial_rcol1 = 0;
}
while (node2->len != EOF && is_line_blank( node2->line , node2->len)) {
bin_offset2 += node2->len;
node2 = node2->next;
++rline2;
initial_rcol2 = 0;
}
}
/*
* if everything is everything, initialize the diff variables and diff.
*/
if (node1->len != EOF && node2->len != EOF) {
diff1 = node1->line;
diff2 = node2->line;
rcol1 = initial_rcol1;
rcol2 = initial_rcol2;
len1 = node1->len;
len2 = node2->len;
assert( rcol1 >= 0 );
assert( rcol1 < MAX_LINE_LENGTH );
assert( rcol2 >= 0 );
assert( rcol2 < MAX_LINE_LENGTH );
assert( len1 >= 0 );
assert( len1 < MAX_LINE_LENGTH );
assert( len2 >= 0 );
assert( len2 < MAX_LINE_LENGTH );
/*
* if cursors are past EOL, move them back to EOL.
*/
len = find_end( diff1, len1 );
if (rcol1 > len)
rcol1 = len;
len = find_end( diff2, len2 );
if (rcol2 > len)
rcol2 = len;
/*
* if skip leading space, make sure our cursors start on first non-space.
*/
if (diff.leading) {
leading1 = skip_leading_space( diff1, len1 );
leading2 = skip_leading_space( diff2, len2 );
if (tabs) {
leading1 = detab_adjust_rcol( diff1, leading1 );
leading2 = detab_adjust_rcol( diff2, leading2 );
}
if (rcol1 < leading1)
rcol1 = leading1;
if (rcol2 < leading2)
rcol2 = leading2;
}
/*
* we now have a valid rcol for the diff start, we may need to adjust
* for tabs, though.
*/
assert( rcol1 >= 0 );
assert( rcol1 < MAX_LINE_LENGTH );
assert( rcol2 >= 0 );
assert( rcol2 < MAX_LINE_LENGTH );
r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
assert( r1 >= 0 );
assert( r1 <= len1 );
assert( r2 >= 0 );
assert( r2 <= len2 );
assert( r1 <= rcol1 );
assert( r2 <= rcol2 );
s_output( diff_message, g_display.mode_line, 67, g_display.diag_color );
while (node1->len != EOF && node2->len != EOF &&
!g_status.control_break) {
/*
* look at each character in each diff window
*/
c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0);
c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0);
/*
* tabs == space
*/
if (tabs) {
if (c1 == '\t')
c1 = ' ';
if (c2 == '\t')
c2 = ' ';
}
/*
* skip spaces, if needed
*/
if (diff.all_space) {
while (c1 == ' ' && r1 < len1) {
++rcol1;
r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
c1 = (char)(r1 < len1 ? *(diff1 + r1) : 0);
if (c1 == '\t' && tabs)
c1 = ' ';
}
while (c2 == ' ' && r2 < len2) {
++rcol2;
r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
c2 = (char)(r2 < len2 ? *(diff2 + r2) : 0);
if (c2 == '\t' && tabs)
c2 = ' ';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -