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 + -
显示快捷键?