⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdiff.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                            TestOld += size;    \
                            TestNew += size;


    /* check boundary conditions */

    if( OldCurr < OldFile + backup_amt ) return( 0 );
    if( NewCurr < NewFile + backup_amt ) return( 0 );
    TestOld = OldCurr - backup_amt;
    TestNew = NewCurr - backup_amt;
    TestNew -= adjust;
    if( TestOld < OldFile || TestOld >= OldCurr ) return( 0 );
    if( TestNew < NewFile || TestNew >= NewCurr ) return( 0 );
    if( TheSameIgnoringHoles() ) {

        if( TestOld >= OldCurr ) return( 0 );
        if( TestNew >= NewCurr ) return( 0 );

        lastold = TestOld;
        lastnew = TestNew;

        /* Move forward as long as two files are similar */

        for(;;) {
            if( *TestOld == *TestNew ) {
                lastold = TestOld;
                lastnew = TestNew;
                AddAndCheck( 1 );
                continue;
            }
            if( TestOld[sizeof(hole)] == TestNew[sizeof(hole)] ) {
                AddAndCheck( sizeof( hole ) );
                continue;
            }
            if( TestOld[2*sizeof(hole)] == TestNew[2*sizeof(hole)] ) {
                AddAndCheck( 2*sizeof( hole ) );
                continue;
            }
            if( TestOld[3*sizeof(hole)] == TestNew[3*sizeof(hole)] ) {
                AddAndCheck( 3*sizeof( hole ) );
                continue;
            }
            break;
        }

        OldCurr = lastold;
        NewCurr = lastnew;

        return( 1 );
    }
    return( 0 );
}


static void CheckSyncPoint( void )
{
    if( SyncOld == (foff)-1 ) return;
    if( SaveOld >= OldFile+SyncOld && OldCurr < OldFile+SyncOld ||
        SaveNew >= NewFile+SyncNew && NewCurr < NewFile+SyncNew ) {
        OldCurr = OldFile+SyncOld;
        NewCurr = NewFile+SyncNew;
        stats( "\r\nJumped SyncPoint\r\n" );
    }
}

int ReSync( void )
{

    /* Try to resync the two file pointer by finding similar areas */

    foff_diff   i;
    foff_diff   backup;
    char        j;
    char        *spin = "-\\|/";

    SaveOld = OldCurr; SaveNew = NewCurr;
    j = 0;
    for( backup = MIN_DIFF; backup <= MAX_DIFF; backup += backup ) {
        if( backup > OldCurr-OldFile || backup > NewCurr-NewFile ) return( 0 );
        stats( "\rResync %8.8lx:%8.8lx %c ", OldCurr-OldFile, NewCurr-NewFile, spin[j] );
        ++j; j &= 3;
        for( i = 0; i <= backup; ++i ) {
            if( AreasAreSimilar( i, backup ) ) {
                CheckSyncPoint();
                return( 1 );
            }
        }
        for( i = -1; i >= -backup; --i ) {
            if( AreasAreSimilar( i, backup ) ) {
                CheckSyncPoint();
                return( 1 );
            }
        }
    }
    return( 0 );
}


int TryBackingUp( int backup )
{
    int         i;

    if( OldCurr-backup < OldFile ) return( 0 );
    if( NewCurr-backup < NewFile ) return( 0 );
    for( i = 0; ; ++i ) {
        if( i == sizeof( hole ) ) {
            return( 0 );
        }
        if( *(OldCurr-backup-i) == *(NewCurr-backup-i) ) break;
    }
    ++OldCurr;
    ++NewCurr;
    while( backup >= sizeof( hole ) ) {
        OldCurr -= sizeof( hole );
        NewCurr -= sizeof( hole );
        AddHole( OldCurr - OldFile, NewCurr - NewFile );
        backup -= sizeof( hole );
    }
    if( backup != 0 ) {
        OldCurr -= backup;
        NewCurr -= backup;
        AddDiff( NewCurr - NewFile, backup );
    }
    return( 1 );
}


void FindRegions( void )
{
    /*
     * classify the differences between the two files into regions;
     * similar, different, and hole
     */

    byte        *old_hi;

    OldCurr = OldFile + EndOld + 1;
    NewCurr = NewFile + EndNew + 1;
    AddSimilarDiff( EndOld + 1, EndNew + 1, 0 );
    OldCurr = OldFile + (EndOld-1);
    NewCurr = NewFile + (EndNew-1);
    old_hi = OldCurr;
    for(;;) {
        if( *OldCurr != *NewCurr ) {
            if( !TryBackingUp(sizeof(hole))
             && !TryBackingUp(2*sizeof(hole))
             && !TryBackingUp(3*sizeof(hole)) ) {
                ++OldCurr;
                ++NewCurr;
                AddSimilarDiff(OldCurr-OldFile, NewCurr-NewFile,
                           (old_hi-OldCurr)+1);
                if( !ReSync() ) break;
                stats( "%8.8lx:%8.8lx\n", OldCurr-OldFile, NewCurr-NewFile );
                old_hi = OldCurr;
                continue;
            }
        }
        if( OldCurr == OldFile || NewCurr == NewFile ) {
            AddSimilarDiff( OldCurr - OldFile,
                        NewCurr - NewFile, (old_hi-OldCurr) + 1 );
            break;
        }
        --OldCurr;
        --NewCurr;
    }
    OldCurr = OldFile;
    NewCurr = NewFile;
    if( SimilarRegions->new_start != 0 ) {
        AddSimilarDiff( 0, 0, 0 );
    }
    putchar( '\n' );
}

/***************************************************************
  Routines that use debugging information to guide the analysis
 ***************************************************************/

void printd( char *p )
{
    int i;

    for( i = *(p++); i != 0; --i ) {
        stats( "%c", *(p++) );
    }
}

void fatal( int p )
{
    char msgbuf[80];

    GetMsg( msgbuf, p );
    puts( msgbuf );
    MsgFini();
    exit( EXIT_FAILURE );
}

void IOError( char *file )
{
    char msgbuf[80];

    GetMsg( msgbuf, MSG_IO_ERROR );
    printf( msgbuf, file );
    MsgFini();
    exit( EXIT_FAILURE );
}

void xseek( int fd, fpos_t pos, int how )
{
    if( lseek( fd, pos, how ) < 0 ) {
        fatal( MSG_IO_ERR );
    }
}

void xread( int fd, void *p, size_t size )
{
    if( read( fd, p, size ) != size ) {
        fatal( MSG_IO_ERR );
    }
}

int cmp_blk( exe_blk *b1, exe_blk *b2 )
{
    if( b1->start == b2->start ) {
        return( 0 );
    } else if( b1->start < b2->start ) {
        return( -1 );
    }
    return( 1 );
}

int cmp_mod_offset( exe_mod *m1, exe_mod *m2 )
{
    if( m1->mod_offset == m2->mod_offset ) {
        return( 0 );
    } else if( m1->mod_offset < m2->mod_offset ) {
        return( -1 );
    }
    return( 1 );
}

int cmp_mod_name( exe_mod *m1, exe_mod *m2 )
{
    int comp;

    if( m1->name[0] == m2->name[0] ) {
        return( memcmp( &(m1->name[1]), &(m2->name[1]), m2->name[0] ) );
    } else if( m1->name[0] < m2->name[0] ) {
        comp = memcmp( &(m1->name[1]), &(m2->name[1]), m1->name[0] );
        if( comp == 0 ) {
            comp = -1;
        }
    } else {
        comp = memcmp( &(m1->name[1]), &(m2->name[1]), m2->name[0] );
        if( comp == 0 ) {
            comp = 1;
        }
    }
    return( comp );
}

int TestBlock( foff old_off, foff new_off, foff len )
{
    byte *pold;
    byte *pnew;
    byte *o;
    byte *n;
    byte *old_stop;
    byte *new_stop;
    foff matches;
    foff holes;

    pold = &OldFile[ old_off ];
    pnew = &NewFile[ new_off ];
    matches = 0;
    holes = 0;
    o = pold;
    n = pnew;
    old_stop = &pold[ len ];
    new_stop = &pnew[ len ];
    for(;;) {
        if( o >= old_stop || n >= new_stop ) break;
        if( *o == *n ) {
            ++o;
            ++n;
            ++matches;
            continue;
        }
        o += sizeof( hole );
        n += sizeof( hole );
        if( o >= old_stop || n >= new_stop ) break;
        if( *o == *n ) {
            ++holes;
        }
    }
    if( matches + holes * sizeof( hole ) > len / 2 ) {
        AddSimilar( old_off, new_off, len );
        o = pold;
        n = pnew;
        for(;;) {
            if( o >= old_stop || n >= new_stop ) break;
            if( *o == *n ) {
                ++o;
                ++n;
                continue;
            }
            o += sizeof( hole );
            n += sizeof( hole );
            if( o >= old_stop || n >= new_stop ) {
                n -= sizeof( hole );
                AddDiff( n - NewFile, new_stop - n );
                break;
            }
            AddHole( (o-sizeof(hole)) - OldFile, (n-sizeof(hole)) - NewFile );
        }
        return( 1 );
    }
    return( 0 );
}

int FindBlockInOld( foff new_off, foff len )
{
    byte *pold;
    byte *pnew;
    byte *o;
    byte *n;
    byte *old_stop;
    byte *new_stop;

    pnew = &NewFile[ new_off ];
    new_stop = &pnew[ len ];
    pold = &OldFile[ 0 ];
    old_stop = &OldFile[ EndOld ];
    for(;;) {
        if( pold >= old_stop ) break;
        o = memchr( pold, *pnew, old_stop - pold );
        if( o == NULL ) break;
        pold = o + 1;
        n = pnew;
        for(;;) {
            if( o >= old_stop || n >= new_stop ) {
                if( TestBlock( ( pold - 1 ) - OldFile, new_off, len ) ) {
                    return( 1 );
                }
                break;
            }
            if( *o == *n ) {
                ++o;
                ++n;
                continue;
            }
            o += sizeof( hole );
            n += sizeof( hole );
            if( o >= old_stop || n >= new_stop ) {
                if( TestBlock( ( pold - 1 ) - OldFile, new_off, len ) ) {
                    return( 1 );
                }
                break;
            }
            if( *o != *n ) break;
        }
    }
    AddDiff( new_off, len );
    return( 0 );
}

#ifdef USE_DBGINFO
int both_walker( exe_blk *new_blk, void *parm )
{
    fpos_t len;
    walker_data *last;
    exe_blk *old_blk;
    exe_mod *old_mod;
    exe_mod *new_mod;
    auto exe_mod tmp_mod;

    last = parm;
    tmp_mod.mod_offset = new_blk->mod_offset;
    new_mod = SymFind( new.mods_by_offset, &tmp_mod );
    if( new_mod == NULL ) {
        fatal( MSG_DEBUG_INFO );
    }
    if( last->last_offset != new_blk->start ) {
        len = new_blk->start - last->last_offset;
        stats( "[%lx-%lx) ???",last->last_offset, last->last_offset + len );
        if( FindBlockInOld( last->last_offset, len ) ) {
            stats( "\n" );
        } else {
            stats( " (NOT found)\n" );
        }
    }
    last->last_offset = new_blk->start + new_blk->length;
    stats( "[%lx-%lx) ", new_blk->start, last->last_offset );
    printd( new_mod->name );
    if( new_blk->start >= EndNew ) {
        stats( " (BSS block ignored)\n" );
        return( 0 );
    }
    old_mod = SymFind( old.mods_by_name, new_mod );
    if( old_mod == NULL ) {
        stats( " (NOT found)\n" );
        AddDiff( new_blk->start, new_blk->length );
        return( 0 );
    }
    /* find an exact match in length if possible */
    for( old_blk = old_mod->blocks; old_blk; old_blk = old_blk->next ) {
        if( old_blk->length == -1 ) {
            continue;
        }
        if( old_blk->length == new_blk->length ) {
            if( TestBlock( old_blk->start, new_blk->start, old_blk->length ) ) {
                old_blk->length = -1;   /* don't test this one again */
                stats( "\n" );
                return( 0 );
            }
        }
    }
    for( old_blk = old_mod->blocks; old_blk; old_blk = old_blk->next ) {
        if( old_blk->length == -1 || old_blk->length == new_blk->length ) {
            continue;
        }
        if( old_blk->length > new_blk->length ) {
            if( TestBlock( old_blk->start, new_blk->start, new_blk->length ) ) {
                AddDiff( new_blk->start + new_blk->length,
                         old_blk->length - new_blk->length );
                old_blk->length = -1;   /* don't test this one again */
                stats( "\n" );
                return( 0 );
            }
        } else {        /* old_blk->length < new_blk->length */
            if( TestBlock( old_blk->start, new_blk->start, old_blk->length ) ) {
                AddDiff( new_blk->start + old_blk->length,
                         new_blk->length - old_blk->length );
                old_blk->length = -1;   /* don't test this one again */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -