dbgvar.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,356 行 · 第 1/5 页
C
2,356 行
/****************************************************************************
*
* 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: Evaluation and formatting of program variables.
*
****************************************************************************/
#include "dbgdefn.h"
#include "dbgtoken.h"
#include "dbginfo.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbglit.h"
#include "dbgitem.h"
#include "dbgtoggl.h"
#include "dlgvarx.h"
#define DBGVAR_C
#include "dbgvar.h"
#include "dbgmem.h"
#include "spawn.h"
#include "dui.h"
#include <limits.h>
#include <string.h>
extern image_entry *ImageEntry( mod_handle mh );
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 PushNum( long );
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 void WndVarNewWindow( char *);
extern void WndVarInspect( char *);
extern void DlgNewWithSym( char * title, char * buff, int len );
extern void BreakOnExprSP( void * );
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 void DoGivenField( sym_handle *member );
extern void StartSubscript( void );
extern void AddSubscript( void );
extern void EndSubscript( void );
extern void PushSymHandle( sym_handle * );
extern void SetUpExpr( unsigned addr_depth );
extern bool UnMapAddress( mappable_addr *loc, image_entry *image );
extern remap_return ReMapImageAddress( mappable_addr *loc, image_entry *image );
extern char *DupStr( char * );
extern void WndInspectExprSP( char *item );
extern void CollapseMachState( void );
extern char *CnvNearestAddr( address, char *, unsigned );
extern char *GetCmdName( int );
extern void RecordEvent( char * );
extern void Warn( char * );
extern void InitMappableAddr( mappable_addr *loc );
extern void FiniMappableAddr( mappable_addr *loc );
extern void DbgUpdate( update_list );
extern char *StrCopy( char*, char* );
extern bool AdvMachState( int );
extern void LValue( stack_entry * );
extern tokens CurrToken;
extern mod_handle ContextMod;
extern unsigned char CurrRadix;
extern char *TxtBuff;
extern stack_entry *ExprSP;
extern address NilAddr;
static int TargRow;
static long ExprStackTimeStamp;
static int CurrRow;
static var_node *VarFound;
static var_info *TargVar;
static long ScopeTimeStamp = 0;
static bool FindField( sym_handle *field, var_node *vfield );
bool VarError;
static var_type_bits Hide;
/*
* This is all junk to remember how we display fields/structs
*/
type_display *TypeDisplay;
static void VarNodeDisplayUpdate( var_node *v )
/*********************************************/
{
var_node *e;
if( v->display_type != NULL ) {
v->display = v->display_type->display;
}
VarNodeInvalid( v );
for( e = v->expand; e != NULL; e = e->next ) {
VarNodeDisplayUpdate( e );
}
for( e = v->old_expand; e != NULL; e = e->next ) {
VarNodeDisplayUpdate( e );
}
}
bool VarDisplayIsStruct( var_node *v )
/************************************/
{
return( v->display_type != NULL && v->display_type->is_struct );
}
static var_type_bits *VarHidePtr( var_node *v )
/*********************************************/
{
if( v != NULL && v->display_type != NULL ) {
return( &v->display_type->hide );
} else {
return( &Hide );
}
}
bool VarDisplayIsHidden( var_node *v, var_type_bits bit )
/********************************************************************/
{
return( ( *VarHidePtr( v ) & bit ) != 0 );
}
void VarDisplaySetHidden( var_node *v, var_type_bits bit, bool on )
/*****************************************************************/
{
if( on ) {
*VarHidePtr( v ) |= bit;
} else {
*VarHidePtr( v ) &= ~bit;
}
DbgUpdate( UP_VAR_DISPLAY );
}
void VarDisplayFlipHide( var_node *v, var_type_bits bit )
/*******************************************************/
{
var_type_bits *hide = VarHidePtr( v );
type_display *alias;
if( ( *hide & bit ) != 0 ) {
*hide &= ~bit;
} else {
*hide |= bit;
}
if( v->display_type != NULL ) {
alias = v->display_type;
do {
alias->hide = *hide;
VarDisplayDirty( alias );
alias = alias->alias;
} while( alias != v->display_type );
}
DbgUpdate( UP_VAR_DISPLAY );
}
void VarDisplayUpdate( var_info *i )
/**********************************/
{
scope_state *s;
var_node *v;
for( s = i->s; s != NULL; s = s->outer ) {
for( v = s->v; v != NULL; v = v->next ) {
VarNodeDisplayUpdate( v );
}
}
}
bool VarDisplayShowMembers( var_info *i )
/***************************************/
{
return( i->members );
}
void VarDisplaySetMembers( var_info *i, bool on )
/***********************************************/
{
i->members = on;
}
void VarDisplaySetBits( var_node *v )
/***********************************/
{
if( v->display_type != NULL ) {
v->display = v->display_type->display;
}
}
type_display *VarDisplayFindParent( type_display *curr )
/******************************************************/
{
type_display *alias;
if( curr->parent != NULL ) return( curr->parent );
for( alias = curr->alias; alias != curr; alias = alias->alias ) {
if( alias->parent != NULL ) return( alias->parent );
}
return( NULL );
}
void VarDisplayDirty( type_display *curr )
/****************************************/
{
while( curr != NULL ) {
if( curr->dirty ) return;
curr->dirty = TRUE;
curr = VarDisplayFindParent( curr );
}
}
extern void VarDisplayInit( void )
/********************************/
{
TypeDisplay = NULL;
}
bool VarDisplayedOnTop( var_node *v )
/***********************************/
{
if( v->display_type == NULL ) return( FALSE );
return( v->display_type->on_top );
}
void VarDisplayOnTop( var_node *v, bool on )
/******************************************/
{
type_display *type = v->display_type;
type_display *parent;
type_display *alias;
bool has_top;
if( type != NULL ) {
VarDisplayDirty( type );
type->on_top = on;
parent = type->parent;
if( parent != NULL ) {
has_top = FALSE;
for( type = parent->fields; type != NULL; type = type->next ) {
if( type->on_top ) {
has_top = TRUE;
}
}
parent->has_top = has_top;
for( alias = parent->alias; alias != parent; alias = alias->alias ) {
alias->has_top = has_top;
}
}
}
DbgUpdate( UP_VAR_DISPLAY );
}
static void VarDisplayFree( type_display *junk )
/**********************************************/
{
type_display *prev;
for( prev = junk; prev->alias != junk; prev = prev->alias ) ;
prev->alias = junk->alias;
DbgFree( junk );
}
extern void VarDisplayFini( void )
/********************************/
{
type_display *curr, *next, *alias;
type_display *fcurr, *fnext;
for( curr = TypeDisplay; curr != NULL; curr = next ) {
next = curr->next;
for( fcurr = curr->fields; fcurr != NULL; fcurr = fnext ) {
fnext = fcurr->next;
VarDisplayFree( fcurr );
}
for( alias = curr->alias; alias != curr; alias = alias->alias ) {
alias->fields = NULL; // so we don't free twice
}
VarDisplayFree( curr );
}
TypeDisplay = NULL;
}
static type_display *VarDisplayAddType( type_display **owner, char *name )
/*****************************************************************/
{
type_display *new;
new = DbgAlloc( sizeof( *new ) + strlen( name ) );
memset( new, 0, sizeof( *new ) );
strcpy( new->name, name );
while( *owner != NULL ) owner = &((*owner)->next);
*owner = new;
new->alias = new;
new->hide = Hide;
return( new );
}
type_display *VarDisplayAddStruct( char *name )
/*********************************************/
{
type_display *new;
for( new = TypeDisplay; new != NULL; new = new->next ) {
if( strcmp( new->name, name ) == 0 ) return( new );
}
new = VarDisplayAddType( &TypeDisplay, name );
new->is_struct = TRUE;
return( new );
}
static char *TagName( symbol_type tag )
/*************************************/
{
switch( tag ) {
case ST_STRUCT_TAG:
return( "struct" );
case ST_CLASS_TAG:
return( "class" );
case ST_UNION_TAG:
return( "union" );
case ST_ENUM_TAG:
return( "enum" );
default:
return( NULL );
}
}
static type_display *VarDisplayAddStructType( type_handle *th )
/*************************************************************/
{
symbol_type tag;
int len;
len = TypeName( th, 0, &tag, TxtBuff, TXT_LEN );
if( len == 0 ) {
return( NULL );
}
return( VarDisplayAddStruct( TxtBuff ) );
}
type_display *VarDisplayAddField( type_display *parent, char *name )
/******************************************************************/
{
type_display *new;
type_display *alias;
for( new = parent->fields; new != NULL; new = new->next ) {
if( strcmp( new->name, name ) == 0 ) return( new );
}
new = VarDisplayAddType( &parent->fields, name );
for( alias = parent->alias; alias != parent; alias = alias->alias ) {
alias->fields = parent->fields;
}
new->parent = parent;
new->is_field = TRUE;
return( new );
}
static type_display *VarDisplayAddFieldSym( type_display *parent, sym_handle *field )
/***********************************************************************************/
{
int len;
len = SymName( field, NULL, SN_SOURCE, TxtBuff, TXT_LEN );
if( len == 0 ) return( NULL );
return( VarDisplayAddField( parent, TxtBuff ) );
}
void VarDisplayAlias( type_display *type, type_display *to )
/**********************************************************/
{
type_display *curr;
// if already there, do nothing
if( to == type || to == NULL ) return;
for( curr = type->alias; curr != type; curr = curr->alias ) {
if( curr == to ) return;
}
// ok, it's a new one - hook it in
curr = type->alias;
type->alias = to->alias;
to->alias = curr;
type->fields = to->fields;
type->has_top = to->has_top;
type->is_struct = TRUE;
}
static void VarDisplayAliasNode( var_node *v, type_display *to )
/**************************************************************/
{
if( v->display_type == NULL ) {
v->display_type = to;
} else {
VarDisplayAlias( v->display_type, to );
}
}
char *VarDisplayType( var_node *v, char *buff, int max_len )
/**********************************************************/
{
int len;
int tag_len;
symbol_type tag;
char *tag_name;
if( v->node_type == NODE_INHERIT ) {
if( VarNodeExpr( v )[0] != '\0' ) {
return( StrCopy( VarNodeExpr( v ), buff ) );
} else {
StrCopy( LIT( Unknown_type ), buff );
return( NULL );
}
}
if( !v->have_type || ( len = TypeName( v->th, 0, &tag, buff, max_len ) ) == 0 ) {
StrCopy( LIT( Unknown_type ), buff );
return( NULL );
}
tag_name = TagName( tag );
if( tag_name != NULL ) {
tag_len = strlen( tag_name );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?