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