dbgwmadr.c

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

C
500
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <string.h>
#include "dbgdefn.h"
#include "dbgwind.h"
#include "dbgreg.h"
#include "dbgtoggl.h"
#include "dbginfo.h"
#include "dbgitem.h"
#include "madcli.h"
#include "mad.h"

extern char             *DupStr( char *str );
extern address          AddrRegIP( machine_state *regs );
extern unsigned         GetInsSize( address addr );
extern unsigned         NewCurrRadix( unsigned );
extern void             WndInspect( char *item );
extern char             *GetCmdName( int index );
extern char             *Format( char *buff, char *fmt, ... );
extern void             RecordEvent( char *p );
extern void             GetMADTypeDefault( mad_type_kind, mad_type_handle );
extern void             PushAddr( address val );
extern bool             DlgMadTypeExpr( char *title, item_mach *value, mad_type_handle );
extern gui_menu_struct *WndAppendToggles( mad_toggle_strings const *toggles, unsigned *pnum_toggles,
                                   gui_menu_struct *old, unsigned num_old, int id );
extern void             WndDeleteToggles( gui_menu_struct *popup, unsigned num_old, unsigned num_toggles );
extern unsigned         GetMADMaxFormatWidth( mad_type_handle th );
extern void             WndInspectExprSP( char *item );
extern void             RegFindData( mad_type_kind kind, mad_reg_set_data **pdata );
extern void             RegValue( item_mach *value, const mad_reg_info *reginfo, machine_state *mach );
extern void             RegNewValue( const mad_reg_info *, item_mach const *, mad_type_handle  );

extern machine_state    *DbgRegs;
extern machine_state    *PrevRegs;
extern char             *TxtBuff;
extern unsigned char    CurrRadix;

#include "menudef.h"
static gui_menu_struct RegMenu[] = {
    #include "menureg.h"
};

typedef struct {
        char                    standout;
        mad_reg_info  const     *info;
        gui_ord                 max_extent;
        gui_ord                 max_descript;
        char                    max_value;
} a_reg_info;

typedef struct {
    gui_ord     descript;
    gui_ord     value;
} reg_indent;

typedef struct {
        mad_reg_set_data        *data;
        char                    up;
        char                    rows;
        char                    count;
        a_reg_info              *info;
        reg_indent              *indents;
        gui_menu_struct         *popup;
        unsigned                num_toggles;
        mad_type_kind           kind;
} reg_window;
#define WndReg( wnd ) ( (reg_window*)WndExtra( wnd ) )


typedef struct {
    char                *descript;
    unsigned            max_descript;
    const mad_reg_info  *reginfo;
    mad_type_handle     disp_type;
    unsigned            max_value;
} reg_display_piece;

static bool GetDisplayPiece( reg_display_piece *disp, reg_window *reg, machine_state *mach, int i )
{
    return( MADRegSetDisplayGetPiece( reg->data, &mach->mr, i, &disp->descript,
                                  &disp->max_descript, &disp->reginfo,
                                  &disp->disp_type, &disp->max_value ) == MS_OK );
}

static bool RegResize( a_window *wnd )
{
    reg_window          *reg = WndReg( wnd );
    gui_ord             space;
    int                 old_up;
    int                 i,j;
    reg_display_piece   disp;
    gui_ord             max_extent;
    gui_ord             max_descript;
    a_reg_info          *info;
    gui_ord             indent;
    gui_ord             value,descript;
    char                *p;
    unsigned            len;

    old_up = reg->up;
    reg->up = 1;

    RegFindData( reg->kind, &reg->data );
    reg->count = 0;
    for( ;; ) {
        if( !GetDisplayPiece( &disp, reg, DbgRegs, reg->count ) ) break;
        reg->count++;
    }

    WndFree( reg->info );
    reg->info = WndMustAlloc( reg->count * sizeof( *reg->info ) );
    space = WndAvgCharX( wnd );

    max_extent = 0;
    max_descript = 0;
    for( i = 0; i < reg->count; ++i ) {
        GetDisplayPiece( &disp, reg, DbgRegs, i );
        if( disp.max_value == 0 && disp.reginfo != NULL ) {
            disp.max_value = GetMADMaxFormatWidth( disp.disp_type );
        }
        info = &reg->info[i];
        info->max_value = disp.max_value;
        info->info = disp.reginfo;
        if( disp.max_descript > strlen( disp.descript ) ) {
            info->max_descript = space + disp.max_descript * WndAvgCharX( wnd );
        } else {
            info->max_descript = space + WndExtentX( wnd, disp.descript );
        }
        info->max_extent = space + disp.max_value * WndAvgCharX( wnd );
        info->standout = FALSE;
        if( info->max_extent > max_extent ) {
            max_extent = info->max_extent;
        }
        if( info->max_descript > max_descript ) {
            max_descript = info->max_descript;
        }
    }

    reg->up = MADRegSetDisplayGrouping( reg->data );
    if( reg->up == 0 ) {
        reg->up = WndWidth( wnd ) / ( max_extent + max_descript );
        if( reg->up < 1 ) reg->up = 1;
        if( reg->up > reg->count ) reg->up = reg->count;
    }
    reg->rows = ( reg->count + reg->up - 1 ) / reg->up;

    // calculate the indents

    WndFree( reg->indents );
    reg->indents = WndMustAlloc( reg->count * sizeof( *reg->indents ) );

    for( i = 0; i < reg->up; ++i ) {
        reg->indents[i].descript = 0;
        reg->indents[i].value = 0;
        for( j = i; j < reg->count; j += reg->up ) {
            if( reg->info[j].max_extent > reg->indents[i].value ) {
                reg->indents[i].value = reg->info[j].max_extent;
            }
            if( reg->info[j].max_descript > reg->indents[i].descript ) {
                reg->indents[i].descript = reg->info[j].max_descript;
            }
        }
    }
    indent = 0;
    value = 0;
    descript = 0;
    for( i = 0; i < reg->up; ++i ) {
        value = reg->indents[i].value;
        descript = reg->indents[i].descript;
        reg->indents[i].descript = indent;
        reg->indents[i].value = indent + descript;
        indent += value + descript;
    }
    for( i = reg->up; i < reg->count; ++i ) {
        reg->indents[i] = reg->indents[i % reg->up];
    }

    if( reg->up != old_up ) {
        WndScrollAbs( wnd, 0 );
        WndNoCurrent( wnd );
    }

    p = TxtBuff + MADCliString( MADRegSetName( reg->data ), TXT_LEN, TxtBuff );
    *p++ = ' ';
    *p++ = '(';
    len = MADRegSetLevel( reg->data, TXT_LEN - ( p - TxtBuff ), p );
    if( len == 0 ) {
        p -= 2;
    } else {
        p += len;
        *p++ = ')';
    }
    *p++ = '\0';
    WndSetTitle( wnd, TxtBuff );

    return( TRUE );
}


static WNDNUMROWS RegNumRows;
static int RegNumRows( a_window *wnd )
{
    return( WndReg( wnd )->rows );
}


static int GetRegIdx( reg_window *reg, int row, int piece )
{
    int         i;

    if( row == WND_NO_ROW ) return( -1 );
    i = row * reg->up + piece;
    if( i >= reg->count ) i = -1;
    return( i );
}


static DLGPICKTEXT RegValueName;
static char *RegValueName( void *_possible, int i )
{

⌨️ 快捷键说明

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