dbgwvar.c

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

C
979
字号
/****************************************************************************
*
*                            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:  Variables window (Locals/Watches).
*
****************************************************************************/



#include "dbgdefn.h"
#include "dbgtoken.h"
#include "dbginfo.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbgwind.h"//
#include "dbgadget.h"
#include "dbgitem.h"
#include "dbgtoggl.h"
#include "dlgvarx.h"
#include "dbgvar.h"
#include "spawn.h"
#include <limits.h>
#include <string.h>

extern char             *ScanPos( void );
extern void             ReqEOC( void );
extern void             ChkExpr( void );
extern void             StartPrintBuff( char *buff, int len );
extern void             EndPrintBuff( void );
extern void             PrintChar( void );
extern void             PrintString( void );
extern void             ForcePrintString( void );
extern char             *ReScan( char * );
extern void             NormalExpr( void );
extern void             EvalLValExpr( int );
extern void             ExprValue( stack_entry * );
extern void             PopEntry( void );
extern void             DupStack( void );
extern void             SwapStack( int entry );
extern void             ExprPurge( void );
extern bool             TokenName( unsigned int, char **, unsigned int * );
extern void             SetTokens( bool );
extern void             DoPlus( void );
extern void             DoPoints( type_kind );
extern void             DoAssign( void );
extern char             *CnvLongDec( long, char * );
extern void             Scan( void );
extern bool             ScanEOC( void );
extern int              AddrComp( address, address );
extern bool             DlgVarExpand( dlg_var_expand * );
extern bool             DlgAnyExpr( char *, char *, unsigned );
extern WNDOPEN          WndVarOpen;
extern void             WndVarNewWindow( char * );
extern void             WndVarInspect( char * );
extern void             DlgNewWithSym( char *title, char *buff, int len );
extern char             *StrCopy( char *, char * );
extern void             BreakOnExprSP( char * );
extern unsigned         NewCurrRadix( unsigned int );
extern void             FreezeInpStack( void );
extern void             PopInpStack( void );
extern void             FreezeStack( void );
extern void             UnFreezeStack( bool );
extern void             PrintValue( void );
extern char             *DupStr( char * );
extern void             WndInspectExprSP( char *item );
extern char             *CnvNearestAddr( address, char *, unsigned );
extern char             *GetCmdName( int );
extern void             Warn( char * );
extern void             InitMappableAddr( mappable_addr *loc );
extern void             FiniMappableAddr( mappable_addr *loc );
extern void             DUIMsgBox( char *text );

extern tokens           CurrToken;
extern unsigned char    CurrRadix;

extern char             *TxtBuff;
extern stack_entry      *ExprSP;
extern address          NilAddr;

typedef struct {
    var_info            i;
    gui_ord             last_width;     // how wide were we last resize?
    gui_ord             name_end;       // the length of the longest name
    var_type            vtype;          // type of window : locals, expression, etc
    unsigned            initialized : 1;        // is it just opened
    unsigned            show_whole_expr : 1;// show foo->bar versus just .bar
} var_window;

#define scroll( s ) s->wnd_data[0]
#define curr_piece( s ) s->wnd_data[1]
#define curr_row( s ) s->wnd_data[2]

#include "menudef.h"
static gui_menu_struct VarTypeMenu[] = {
    #include "mvartype.h"
};

static gui_menu_struct VarClassMenu[] = {
    #include "mvarclas.h"
};

static gui_menu_struct VarShowMenu[] = {
    #include "mvarshow.h"
};

static gui_menu_struct VarOptMenu[] = {
    #include "mvaropt.h"
};

static gui_menu_struct VarMenu[] = {
    #include "menuvar.h"
};


#define WndVar( wnd ) ( (var_window*)WndExtra( wnd ) )
#define WndVarInfo( wnd ) ( &WndVar( wnd )->i )

#define INDENT_AMOUNT           2
#define REASONABLE_NAME_WIDTH   30

static char **VarNames[] = { LITREF( Empty ), LITREF( WindowWatches ), LITREF( Empty ), LITREF( WindowFile_Variables ) };
static wnd_class VarClass[] = { WND_VARIABLE, WND_WATCH, WND_LOCALS, WND_FILESCOPE };
static gui_resource *VarIcons[] = { &VarIcon, &WatIcon, &LocIcon, &VarIcon };

static void     VarSetWidth( a_window *wnd )
/*
    Always leave room for a vertical scroll bar. It's most annoying
    having the window repaint whenever it appears/disappears.
 */
{
    var_window  *var = WndVar( wnd );

    var->last_width = WndWidth( wnd );
    if( VarRowTotal( &var->i ) <= WndRows( wnd ) ) {
        var->last_width -= WndVScrollWidth( wnd );
    }
    var->last_width -= WndAvgCharX( wnd ) / 2;

}

static  void    VarRepaint( a_window *wnd )
{
    var_window  *var = WndVar( wnd );

    VarAllNodesInvalid( &var->i );
    VarKillExprSPCache( &var->i );
    WndSetThumb( wnd );
    WndNoSelect( wnd );
    WndRepaint( wnd );
    WndResetScroll( wnd );
}


extern  bool    WndVarAdd( a_window *wnd, char *name,
                             unsigned len, bool expand )
{
    var_node    *v;

    v = VarAdd1( WndVarInfo( wnd ), name, len, expand, FALSE );
    VarRepaint( wnd );
    return( v != NULL );
}


static WNDNUMROWS VarNumRows;
static int VarNumRows( a_window *wnd )
{
    return( VarRowTotal( WndVarInfo( wnd ) ) );
}

static void     VarMenuItem( a_window *wnd, unsigned id, int row, int piece );

static  WNDMODIFY VarModify;
static  void    VarModify( a_window *wnd, int row, int piece )
{
    var_node            *v;
    type_kind           class;
    var_window          *var = WndVar( wnd );
    bool                ok;
    bool                followable;
    unsigned            old;

    if( row < 0 ) {
        if( var->vtype == VAR_WATCH || var->vtype == VAR_VARIABLE ) {
            VarMenuItem( wnd, MENU_VAR_NEW_EXPRESSION, row, piece );
        }
        return;
    }
    VarErrState();
    VarKillExprSPCache( &var->i );
    v = VarFindRow( &var->i, row );
    if( v == NULL ) {
        v = VarFindRowNode( &var->i, row );
        if( v == NULL ) return;
        if( piece != VAR_PIECE_GADGET && piece != VAR_PIECE_NAME ) return;
        if( v->expand != NULL || v->node_type == NODE_INHERIT ) {
            VarExpandRow( &var->i, v, row );
            WndNewCurrent( wnd, row, VAR_PIECE_NAME );
            VarRepaint( wnd );
        }
        return;
    }
    followable = VarGetStackClass( &class );
    switch( piece ) {
    case VAR_PIECE_GADGET:
    case VAR_PIECE_NAME:
        if( VarExpandable( class ) || followable || v->expand != NULL ) {
            VarExpandRow( &var->i, v, row );
            WndNewCurrent( wnd, row, VAR_PIECE_NAME );
            VarRepaint( wnd );
        }
        break;
    case VAR_PIECE_VALUE:
        if( !VarExpandable( class ) ) {
            char *value = DbgAlloc( TXT_LEN );
            char *name = DbgAlloc( TXT_LEN );
            old = VarNewCurrRadix( v );
            ExprValue( ExprSP );
            VarBuildName( &var->i, v, FALSE );
            StrCopy( TxtBuff, name );
            VarPrintText( &var->i, value, PrintValue, TXT_LEN );
            VarKillExprSPCache( &var->i );
            v = VarFindRow( &var->i, row );
            FreezeStack();
            ok = DlgAnyExpr( name, value, TXT_LEN );
            UnFreezeStack( FALSE );
            if( ok ) VarDoAssign( &var->i, v, value );
            NewCurrRadix( old );
            WndRowDirty( wnd, row );
            DbgFree( value );
            DbgFree( name );
        }
        break;
    }
    VarDoneRow( &var->i );
    VarOldErrState();
}


static bool VarEdit( a_window *wnd, var_node *v )
{
    var_window  *var = WndVar( wnd );

    if( v == NULL ) {
        TxtBuff[0] = '\0';
    } else {
        strcpy( TxtBuff, VarNodeExpr( v ) );
    }
    VarRepaint( wnd );
    DlgNewWithSym( LIT( New_Expression ), TxtBuff, TXT_LEN );
    if( TxtBuff[0] == '\0' ) return( FALSE );
    VarAddNodeToScope( &var->i, v, TxtBuff );
    VarRepaint( wnd );
    return( TRUE );
}

#if 0
static void VarMoveToRoot( a_window *wnd, int row, var_node *v )
{
    var_window  *var = WndVar( wnd );
    int         new_row;

    new_row = VarFindRootRow( &var->i, v, row );
    if( new_row == row ) return;
    WndMoveCurrent( wnd, new_row, VAR_PIECE_NAME );
}
#endif


static void VarSetOptions( var_window *var )
{
    var->show_whole_expr = _IsOn( SW_VAR_WHOLE_EXPR );
    VarDisplaySetMembers( &var->i, _IsOn( SW_VAR_SHOW_MEMBERS ) );
}

static void VarInitPopup( a_window *wnd, var_window *var, var_node *v )
{
    type_kind           class;
    bool                pointer;
    bool                noedit;

    WndMenuGrayAll( wnd );
    WndMenuEnable( wnd, MENU_VAR_OPTIONS, TRUE );
    WndMenuEnable( wnd, MENU_VAR_CLASS, TRUE );
    WndMenuEnable( wnd, MENU_VAR_TYPE, TRUE );
    WndMenuEnable( wnd, MENU_VAR_SHOW_MEMBER, TRUE );
    WndMenuEnable( wnd, MENU_VAR_SHOW_WHOLE_EXPR, TRUE );
    noedit = ( var->vtype == VAR_LOCALS || var->vtype == VAR_FILESCOPE );
    WndMenuIgnore( wnd, MENU_VAR_EDIT_EXPRESSION, noedit );
    WndMenuIgnore( wnd, MENU_VAR_NEW_EXPRESSION, noedit );
    WndMenuIgnore( wnd, MENU_VAR_DELETE, noedit );
    if( !noedit ) {
        WndMenuEnable( wnd, MENU_VAR_EDIT_EXPRESSION, v != NULL && v->parent == NULL );
        WndMenuEnable( wnd, MENU_VAR_NEW_EXPRESSION, TRUE );
        WndMenuEnable( wnd, MENU_VAR_DELETE, v != NULL && v->parent == NULL );
    }
    WndMenuEnable( wnd, MENU_VAR_WATCH, v != NULL );
    WndMenuEnable( wnd, MENU_VAR_INSPECT, v != NULL );

    if( v != NULL && !VarError ) {
        VarGetStackClass( &class );
        pointer = VarIsPointer( class );
        WndMenuEnable( wnd, MENU_VAR_TYPE, TRUE );
        WndMenuEnable( wnd, MENU_VAR_SHOW, TRUE );

⌨️ 快捷键说明

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