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