dbgwmem.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,074 行 · 第 1/3 页

C
1,074
字号
    mem_window  *mem = WndMem( wnd );

    if( !mem->file ) {
        SetDataDot( AddrAddWrap( mem->u.m.addr, MemCurrOffset( wnd ) ) );
    }
}

static  void    MemUpdateCursor( a_window *wnd )
{
    mem_window  *mem = WndMem( wnd );
    wnd_row     cursor_row;
    int         cursor_piece;
    int         shadow_piece;

    WndGetCurrent( wnd, &cursor_row, &cursor_piece );
    if( cursor_piece > mem->items_per_line ) {
        shadow_piece = cursor_piece - mem->items_per_line;
    } else {
        shadow_piece = cursor_piece + mem->items_per_line;
    }

    if( cursor_row != WND_NO_ROW ) {
        WndRowDirty( wnd, -TITLE_SIZE );
    }
    if( cursor_row == mem->cursor_row && cursor_piece == mem->cursor_piece ) return;
    if( mem->piece_type == MemByteType ) {
        if( mem->cursor_row != WND_NO_ROW ) {
            WndPieceDirty( wnd, mem->cursor_row, mem->shadow_piece );
        }
        if( cursor_row != WND_NO_ROW ) {
            WndPieceDirty( wnd, cursor_row, shadow_piece );
        }
    }
    SetNewDataDot( wnd );
    mem->cursor_row = cursor_row;
    mem->cursor_piece = cursor_piece;
    mem->shadow_piece = shadow_piece;
}


static  WNDMODIFY MemModify;
static  void    MemModify( a_window *wnd, int row, int piece )
{
    address     addr;
    union {
        item_mach i;
        char      str[TXT_LEN];
    } item;
    bool        is_char;
    unsigned    old;
    unsigned    item_size;
    mem_window  *mem = WndMem( wnd );

    --piece;
    if( !CanModify( wnd, row, piece ) ) return;
    if( piece >= mem->items_per_line ) {
        is_char = TRUE;
        piece -= mem->items_per_line;
    } else {
        is_char = FALSE;
    }
    addr = AddrAddWrap( mem->u.m.addr,
                        (row*mem->items_per_line+piece)*mem->item_size );
    StrAddr( &addr, TxtBuff, TXT_LEN );
    ProgPeekWrap( addr, (void*)&item, mem->item_size );
    old = NewCurrRadix( MemData.info[ mem->piece_type ].piece_radix );
    item_size = mem->item_size;
    if( is_char ) {
        if( DlgString( TxtBuff, &item.str ) ) {
            ChangeMemUndoable( addr, &item, strlen( item.str ) );
        }
    } else {
        if( DlgMadTypeExpr( TxtBuff, &item.i, MemData.info[ mem->piece_type ].type ) ) {
            ChangeMemUndoable( addr, &item, item_size );
        }
    }
    NewCurrRadix( old );
}


static bool MemScrollBytes( a_window *wnd, int tomove, bool new_home )
{
    address     addr;
    char        ch;
    mem_window  *mem = WndMem( wnd );

    addr = AddrAddWrap( mem->u.m.addr, tomove );
    if( ProgPeekWrap( addr, &ch, 1 ) != 1 ) return( FALSE );
    MemSetStartAddr( wnd, addr, new_home );
    SetNewDataDot( wnd );
//    SetDataDot( addr );
    WndFixedThumb( wnd );
    return( TRUE );
}

static void MemFreeBackout( mem_window *mem )
{
    mem_backout *junk;

    junk = mem->u.m.backout;
    mem->u.m.backout = junk->next;
    WndFree( junk->follow );
    WndFree( junk );
}

static void MemSetCurrent( a_window *wnd, unsigned offset )
{
    wnd_row     row;
    int         line_size;
    int         piece;
    mem_window  *mem = WndMem( wnd );

    line_size = mem->items_per_line * mem->item_size;
    row = offset / line_size;
    piece = ( offset - row * line_size ) / mem->item_size;
    WndNewCurrent( wnd, row, piece+1 );
}

static void MemBackout( a_window *wnd )
{
    mem_backout *backout;
    mem_window  *mem = WndMem( wnd );

    backout = mem->u.m.backout;
    if( backout == NULL ) return;
    MemSetStartAddr( wnd, backout->home, TRUE );
    MemSetStartAddr( wnd, backout->addr, FALSE );
    if( backout->has_current ) {
        MemSetCurrent( wnd, backout->curr_offset );
    } else {
        WndNoCurrent( wnd );
    }
    mem->total_size = backout->total_size;
    if( backout->follow ) {
        WndFree( mem->u.m.follow );
        mem->u.m.follow = backout->follow;
        backout->follow = NULL;
    }
    MemFreeBackout( mem );
    WndSetTitle( wnd, MemGetTitle( mem ) );
    SetNewDataDot( wnd );
//    SetDataDot( mem->u.m.home );
    WndNoSelect( wnd );
    WndRepaint( wnd );
}

static void MemNewBackout( a_window *wnd )
{
    mem_backout *backout;
    mem_window  *mem = WndMem( wnd );

    backout = WndAlloc( sizeof( *backout ) );
    if( backout == NULL ) return;
    backout->next = mem->u.m.backout;
    backout->home = mem->u.m.home;
    backout->addr = mem->u.m.addr;
    backout->curr_offset = MemCurrOffset( wnd );
    backout->total_size = mem->total_size;
    backout->has_current = WndHasCurrent( wnd );
    if( mem->u.m.follow ) {
        backout->follow = DupStr( mem->u.m.follow );
    } else {
        backout->follow = NULL;
    }
    mem->u.m.backout = backout;
    for( backout = backout->next; backout != NULL; backout = backout->next ) {
        if( AddrComp( mem->u.m.backout->home, backout->home ) == 0 ) {
            Warn( LIT( WARN_Cycle_Detected ) );
            return;
        }
    }
}

static void MemFollow( a_window *wnd )
{
    address     new_addr;
    mem_window  *mem = WndMem( wnd );
    char        ch;

    if( mem->u.m.follow != NULL ) {
        new_addr = mem->u.m.home;
        SetDataDot( new_addr );
        if( !DlgScanGivenAddr( mem->u.m.follow, &new_addr ) ) {
            Warn( TxtBuff ); /* stashed here */
            MemBackout( wnd );
        } else {
            mem->total_size = 0;
            if( ProgPeekWrap( new_addr, &ch, 1 ) != 1 ) {
                MemBackout( wnd );
                Error( ERR_NONE, LIT( ERR_NO_READ_MEM ), new_addr );
            }
            MemSetStartAddr( wnd, new_addr, TRUE );
        }
    } else {
        new_addr = AddrAddWrap( mem->u.m.addr, mem->total_size );
        mem->u.m.home = mem->u.m.addr;
        if( !MemScrollBytes( wnd, mem->total_size, TRUE ) ) {
            MemBackout( wnd );
        } else {
            WndNoCurrent( wnd );
        }
    }
    WndSetTitle( wnd, MemGetTitle( mem ) );
    SetNewDataDot( wnd );
//  SetDataDot( mem->u.m.home );
    WndNoSelect( wnd );
    WndRepaint( wnd );
}


static void DoFollow( a_window *wnd, char *fmt )
{
    mem_window  *mem = WndMem( wnd );

    MemNewBackout( wnd );
    WndFree( mem->u.m.follow );
    Format( TxtBuff, fmt, AddrDiff( mem->u.m.addr, mem->u.m.home ) + MemCurrOffset( wnd ) );
    mem->u.m.follow = DupStr( TxtBuff );
    MemFollow( wnd );
}

static void SetBreakWrite( a_window *wnd )
{
    mem_window  *mem = WndMem( wnd );
    char        buff[TXT_LEN];
    address     addr;

    addr = AddrAddWrap( mem->u.m.addr, MemCurrOffset( wnd ) );
    StrAddr( &addr, buff, TXT_LEN );
    if( !BreakWrite( addr, MemData.info[ mem->piece_type ].type, buff ) ) {
        Error( ERR_NONE, LIT( ERR_NOT_WATCH_SIZE ) );
    }
}

static bool GetBuff( mem_window *mem,
                     unsigned long offset, char *buff, int size )
{
    unsigned long new;
    int         len;

    if( mem->file ) {
        offset += mem->u.f.offset;
        new = SeekStream( mem->u.f.filehndl,
                          offset, DIO_SEEK_ORG );
        if( new != offset ) return( FALSE );
        len = ReadStream( mem->u.f.filehndl, buff, size );
        return( len >= size );
    } else {
        if( mem->u.m.contents == NULL ) return( FALSE );
        if( offset + size > mem->u.m.size ) return( FALSE );
        memcpy( buff, (char*)mem->u.m.contents + offset, size );
        return( TRUE );
    }
}

static WNDGETLINE MemGetLine;
static  bool    MemGetLine( a_window *wnd, int row, int piece,
                            wnd_line_piece *line )
{
    char        buff[16];
    unsigned long offset;
    mem_window  *mem = WndMem( wnd );
    address     addr;
    char        *p;
    unsigned    old,new;
    unsigned    max;
    char        ch;

    line->text = TxtBuff;
    if( row < 0 ) {
        row += TITLE_SIZE;
        switch( row ) {
        case 0:
            line->tabstop = FALSE;
            line->indent = HeadTab[ mem->file ]( wnd, piece );
            line->attr = WND_STANDOUT;
            if( line->indent == (gui_ord)-1 ) return( FALSE );
            return( TRUE );
#if 0
        case 1:
            if( piece != 0 ) return( FALSE );
            SetUnderLine( wnd, line );
            return( TRUE );
#endif
        default:
            return( FALSE );
        }
    }
    if( row >= WndRows( wnd ) ) return( FALSE );
    TxtBuff[0] = '\0';
    offset = row * mem->items_per_line;
    if( piece == 0 ) {
        line->tabstop = FALSE;
        offset *= mem->item_size;
        if( mem->file ) {
            p = CnvULong( mem->u.f.offset + offset, TxtBuff );
            StrCopy( ":", p );
            return( TRUE );
        }
        if( mem->stack ) {
            if( offset == mem->sp_offset ) {
                MADRegSpecialName( MSR_SP, &DbgRegs->mr, MAF_OFFSET, TXT_LEN, TxtBuff );
                line->text = TxtBuff;
                line->attr = WND_STANDOUT;
                return( TRUE );
            } else if( offset == mem->bp_offset ) {
                MADRegSpecialName( MSR_FP, &DbgRegs->mr, MAF_OFFSET, TXT_LEN, TxtBuff );
                line->text = TxtBuff;
                line->attr = WND_STANDOUT;
                return( TRUE );
            }
        }
        addr = AddrAddWrap( mem->u.m.addr, offset );
        p = AddrToString( &addr, MAF_OFFSET, TxtBuff, TXT_LEN );
        StrCopy( ":", p );
        return( TRUE );
    }
    if( row == mem->cursor_row && piece == mem->shadow_piece ) {
        line->attr = WND_STANDOUT;
    }
    --piece;
    if( piece >= mem->items_per_line ) {
        if( mem->piece_type != MemByteType ) return( FALSE );
        if( piece >= 2 * mem->items_per_line ) return( FALSE );
        if( mem->item_width <= 2 ) {
            line->indent = ( mem->item_width * WndAvgCharX(wnd) );
        } else {
            line->indent = ( mem->item_width * WndMidCharX(wnd) );
        }
        line->indent += WndMidCharX( wnd );
        line->indent *= mem->items_per_line;
        line->indent += ( piece - mem->items_per_line + 1 ) * WndMaxCharX(wnd);
        offset += piece - mem->items_per_line;
    } else {
        line->indent = ( piece * mem->item_width );
        if( mem->item_width <= 2 ) {
            line->indent *= WndAvgCharX( wnd );
        } else {
            line->indent *= WndMidCharX( wnd );
        }
        line->indent += piece * WndMidCharX( wnd );
        offset += piece;
    }
    line->indent += mem->address_end + WndAvgCharX( wnd );
    offset *= mem->item_size;
    if( mem->total_size != 0 && offset >= mem->total_size ) return( FALSE );
    if( !GetBuff( mem, offset, buff, mem->item_size ) ) return( FALSE );
    if( piece >= mem->items_per_line ) {
        ch = buff[0];
        if( !isprint( ch ) ) ch = '.';
        TxtBuff[0] = ch;
        TxtBuff[1] = '\0';
    } else {
        new = MemData.info[ mem->piece_type ].piece_radix;
        old = NewCurrRadix( new );
        max = TXT_LEN;
        MADTypeHandleToString( new, MemData.info[ mem->piece_type ].type, &buff, &max, TxtBuff );
        NewCurrRadix( old );

⌨️ 快捷键说明

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