diff.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,393 行 · 第 1/3 页
C
1,393 行
*/
for( aend = lenA; aend >= 1; aend = astart - 1 ) {
while( aend >= 1 && match[aend] == ( match[aend + 1] - 1 )
&& match[aend] != 0 ) {
aend--;
}
bend = match[aend + 1] - 1;
astart = aend + 1;
while( astart > 1 && match[astart - 1] == 0 ) {
astart--;
}
bstart = match[astart - 1] + 1;
match[astart] = bstart;
change( astart, aend, bstart, bend );
}
}
if( lenA == 0 ) {
change( 1, 0, 1, lenB );
}
}
/*
* Output a change entry: fileA[astart..aend] changed to fileB[bstart..bend]
*/
void change( SLONG astart, SLONG aend, SLONG bstart, SLONG bend )
{
char c;
/*
* This catches a "dummy" last entry
*/
if( astart > aend && bstart > bend )
return;
havediffs = TRUE;
c = ( astart > aend ) ? 'a' : ( bstart > bend ) ? 'd' : 'c';
if( nflag ) {
if( c == 'a' ) {
printf( "a%ld %ld\n", astart - 1, bend - bstart + 1 );
fetch( newseek, bstart, bend, lenB, infd[1], "" );
} else if( c == 'd' ) {
printf( "d%ld %ld\n", astart, aend - astart + 1 );
} else {
printf( "d%ld %ld\n", astart, aend - astart + 1 );
printf( "a%ld %ld\n", aend, bend - bstart + 1 );
fetch( newseek, bstart, bend, lenB, infd[1], "" );
}
return;
}
if( cflag ) {
fputs( "**************\n*** ", stdout );
}
if( c == 'a' && !cflag ) {
range( astart - 1, astart - 1, 0 ); /* Addition: just print one
* odd # */
} else {
range( astart, aend, 0 ); /* Print both, if different */
}
if( !cflag ) {
putchar( c );
if( !eflag ) {
if( c == 'd' ) {
range( bstart - 1, bstart - 1, 1 ); /* Deletion: just print
* one odd # */
} else {
range( bstart, bend, 1 ); /* Print both, if different */
}
}
}
putchar( '\n' );
if( ( !eflag && c != 'a' ) || cflag ) {
fetch( oldseek, astart, aend, lenA, infd[0],
cflag ? ( c == 'd' ? "- " : "! " ) : "< " );
if( cflag ) {
fputs( "--- ", stdout );
range( bstart, bend, 1 );
fputs( " -----\n", stdout );
} else if( astart <= aend && bstart <= bend ) {
printf( "---\n" );
}
}
if( bstart <= bend ) {
fetch( newseek, bstart, bend, lenB, infd[1],
cflag ? ( c == 'a' ? "+ " : "! " ) : ( eflag ? "" : "> " ) );
if( eflag )
printf( ".\n" );
}
}
/*
* Print a range
*/
void range( SLONG from, SLONG to, SLONG w )
{
if( cflag ) {
if( ( from -= cflag ) <= 0 ) {
from = 1;
}
if( ( to += cflag ) > len[w] ) {
to = len[w];
}
}
if( to > from ) {
printf( "%ld,%ld", from, to );
} else if( to < from ) {
printf( "%ld,%ld", to, from );
} else {
printf( "%ld", from );
}
}
/*
* Print the appropriate text
*/
void fetch( long *seekvec, SLONG start, SLONG end, SLONG trueend, FILE *fd, char *pfx )
{
SLONG i;
SLONG first;
SLONG last;
if( cflag ) {
if( ( first = start - cflag ) <= 0 ) {
first = 1;
}
if( ( last = end + cflag ) > trueend ) {
last = trueend;
}
} else {
first = start;
last = end;
}
if( fseek( fd, seekvec[first], 0 ) != 0 ) {
fatal( "?Can't read line %d at %08lx (hex) in file%c\n", start,
seekvec[first], ( fd == infd[0] ) ? 'A' : 'B' );
} else {
for( i = first; i <= last; i++ ) {
if( fgetss( text, sizeof text, fd ) == NULL ) {
fatal( "** Unexpected end of file\n" );
break;
}
#ifdef DEBUG
printf( "%5d: %s%s\n", i, pfx, text );
#else
fputs( ( cflag && ( i < start || i > end ) ) ? " " : pfx, stdout );
fputs( text, stdout );
putchar( '\n' );
#endif
}
}
}
/*
* Input routine, read one line to buffer[], return TRUE on eof, else FALSE.
* The terminating newline is always removed. If "-b" was given, trailing
* whitespace (blanks and tabs) are removed and strings of blanks and
* tabs are replaced by a single blank. Getline() does all hacking for
* redirected input files.
*/
INT getline( FILE *fd, char *buffer )
{
char *top;
char *fromp;
char c;
if( fgetss( buffer, sizeof text, fd ) == NULL ) {
*buffer = EOS;
return( TRUE );
}
if( fd == stdin ) {
fputss( buffer, tempfd );
}
if( bflag || iflag ) {
top = buffer;
fromp = buffer;
while( ( c = *fromp++ ) != EOS ) {
if( bflag && ( c == ' ' || c == '\t' ) ) {
c = ' ';
while( *fromp == ' ' || *fromp == '\t' )
fromp++;
}
if( iflag ) {
c = tolower( c );
}
*top++ = c;
}
if( bflag && top[ -1] == ' ' ) {
top--;
}
*top = EOS;
}
return( FALSE );
}
static USHORT crc16a[] = {
0000000, 0140301, 0140601, 0000500,
0141401, 0001700, 0001200, 0141101,
0143001, 0003300, 0003600, 0143501,
0002400, 0142701, 0142201, 0002100,
};
static USHORT crc16b[] = {
0000000, 0146001, 0154001, 0012000,
0170001, 0036000, 0024000, 0162001,
0120001, 0066000, 0074000, 0132001,
0050000, 0116001, 0104001, 0043000,
};
/*
* Return the CRC16 hash code for the buffer
* Algorithm from Stu Wecker (Digital memo 130-959-002-00).
*/
USHORT hash( char *buffer )
{
USHORT crc;
char *tp;
short temp;
crc = 0;
for( tp = buffer; *tp != EOS; ) {
temp = *tp++ ^ crc; /* XOR crc with new char */
crc = ( crc >> 8 ) ^ crc16a[ ( temp & 0017 )]
^ crc16b[ ( temp & 0360 ) >> 4];
}
return( ( crc == 0 ) ? ( USHORT ) 1 : crc );
}
/*
* Allocate or crash.
*/
char *myalloc( ULONG amount, char *why )
{
char *pointer;
#if defined( M_I86 )
if( amount > UINT_MAX )
noroom( why );
#endif
if( ( pointer = malloc( amount ) ) == NULL )
noroom( why );
return( pointer );
}
void myfree( void *what )
{
free( *( char **) what );
*( char **) what = NULL;
}
char *compact( char *pointer, ULONG new_amount, char *why )
{
char *new_pointer;
#if defined( M_I86 )
if( new_amount > UINT_MAX )
noroom( why );
#endif
// if (new_pointer = (char *)realloc((void *)pointer, (size_t)new_amount) == NULL)
if( new_pointer = realloc( pointer, ( size_t ) new_amount ),
new_pointer == NULL )
noroom( why );
#ifdef DEBUG
if( new_pointer != pointer ) {
fprintf( stderr, "moved from %06o to %06o\n",
pointer, new_pointer );
}
#endif
return( new_pointer );
}
void noroom( char *why )
{
if( tflag ) {
exit( xflag + DIFF_NO_MEMORY );
} else if( Hflag ) {
#define freeup( x ) if( x ) myfree( &x );
freeup( klist );
freeup( clist );
freeup( match );
freeup( oldseek );
freeup( newseek );
freeup( fileA );
freeup( fileB );
printf( "d1 %ld\n", lenA );
printf( "a1 %ld\n", lenB );
fseek( infd[1], 0, 0 );
while( fgetss( text, sizeof text, infd[1] ) != NULL )
printf( "%s\n", text );
exit( xflag + DIFF_HAVE_DIFFS );
} else {
error( "Out of memory when %s\n", why );
exit( xflag + DIFF_NOT_COMPARED );
}
}
#ifdef DEBUG
/*
* Dump memory block
*/
void rdump( SLONG *pointer, char *why )
{
SLONG *last;
SLONG count;
last = ( ( SLONG **) pointer )[ -1];
fprintf( stderr, "dump %s of %06o -> %06o, %d words",
why, pointer, last, last - pointer );
last = ( SLONG *) ( ( ( SLONG ) last ) & ~1 );
for( count = 0; pointer < last; ++count ) {
if( ( count & 07 ) == 0 ) {
fprintf( stderr, "\n%06o", pointer );
}
fprintf( stderr, "\t%06o", *pointer );
pointer++;
}
fprintf( stderr, "\n" );
}
#endif
#ifdef DEBUG
void dump( LINE *d_linep, SLONG d_len, SLONG d_which )
{
SLONG i;
printf( "Dump of file%c, %d elements\n", "AB"[d_which], d_len );
printf( "linep @ %06o\n", d_linep );
for( i = 0; i <= d_len; i++ ) {
printf( "%3d %6d %06o\n", i,
d_linep[i].serial, d_linep[i].hash );
}
}
/*
* Dump klist
*/
void dumpklist( SLONG kmax, char *why )
{
SLONG i;
CANDIDATE *cp;
SLONG count;
printf( "\nklist[0..%d] %s, clength = %d\n", kmax, why, clength );
for( i = 0; i <= kmax; i++ ) {
cp = &clist[klist[i]];
printf( "%2d %2d", i, klist[i] );
if( cp >= &clist[0] && cp < &clist[clength] )
printf( " (%2d %2d -> %2d)\n", cp->a, cp->b, cp->link );
else if( klist[i] == -1 )
printf( " End of chain\n" );
else
printf( " illegal klist element\n" );
}
for( i = 0; i <= kmax; i++ ) {
count = -1;
for( cp = ( CANDIDATE * ) klist[i]; cp > &clist[0];
cp = ( CANDIDATE * ) & cp->link ) {
if( ++count >= 6 ) {
printf( "\n " );
count = 0;
}
printf( " (%2d: %2d,%2d -> %d)",
cp - clist, cp->a, cp->b, cp->link );
}
printf( "\n" );
}
printf( "*\n" );
}
#endif
/*
* TRUE if strings are identical
*/
INT streq( char *s1, char *s2 )
{
while( *s1++ == *s2 ) {
if( *s2++ == EOS )
return( TRUE );
}
return( FALSE );
}
/*
* Can't open file message
*/
void cant( char *filename, char *what, SLONG fatalflag )
{
fprintf( stderr, "Can't open %s file \"%s\": ", what, filename );
perror( ( char *) NULL );
if( fatalflag ) {
exit( xflag + DIFF_NOT_COMPARED );
}
}
void fatal( char *format, ... )
{
va_list args;
va_start( args, format );
fprintf( stderr, "Internal error: " );
vfprintf( stderr, format, args );
va_end( args );
putc( '\n', stderr );
exit( xflag + DIFF_NOT_COMPARED );
}
/*
* Error message before retiring.
*/
void error( char *format, ... )
{
va_list args;
va_start( args, format );
vfprintf( stderr, format, args );
va_end( args );
putc( '\n', stderr );
fflush( stderr );
}
/*
* Like fput() except that it puts a newline at the end of the line.
*/
void fputss( char *s, FILE *iop )
{
fputs( s, iop );
putc( '\n', iop );
}
/*
* Fgetss() is like fgets() except that the terminating newline
* is removed.
*/
char *fgetss( char *s, SLONG n, FILE *iop )
{
char *cs;
int len;
if( fgets( s, n, iop ) == NULL )
return( ( char *) NULL );
len = strlen( s );
cs = s + len - 1;
if( *cs == '\n' ) {
*cs = '\0';
}
--cs;
if( len > 1 && *cs == '\r' ) {
*cs = '\0';
}
return( s );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?