namelist.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 274 行
C
274 行
/****************************************************************************
*
* 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 "dbgdefn.h"
#include "dbginfo.h"
//#include "dbgwind.h"
#include "dbgerr.h"
#include "namelist.h"
#include "sortlist.h"
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
extern char *TxtBuff;
extern address NilAddr;
extern char *DupStr(char*);
extern int AddrComp( address a, address b );
extern unsigned QualifiedSymName( sym_handle *sh, char *name, unsigned max, bool );
typedef struct a_symbol {
struct a_symbol *next;
unsigned long key;
char __hdl[1]; // Variable size
} a_symbol;
#define ASymHdl( s ) ((sym_handle*)((s)->__hdl))
static void SetKey( a_symbol *sym )
{
unsigned char b[4];
b[0] = 0;
b[1] = 0;
b[2] = 0;
b[3] = 0;
SymName( ASymHdl( sym ), NULL, SN_SOURCE, b, sizeof( b ) );
sym->key = ((unsigned long)tolower(b[0])<<24)+
((unsigned long)tolower(b[1])<<16)+
(tolower(b[2])<< 8)+
tolower(b[3]);
}
OVL_EXTERN int SymCompare( void **pa, void **pb )
{
char *cmpa,*cmpb;
a_symbol *a = *pa;
a_symbol *b = *pb;
if( a->key == 0 ) SetKey( a );
if( b->key == 0 ) SetKey( b );
if( a->key > b->key ) return( +1 );
if( a->key < b->key ) return( -1 );
cmpa = TxtBuff;
cmpb = cmpa + SymName( ASymHdl( a ), NULL, SN_SOURCE, cmpa, TXT_LEN/2 ) + 1;
SymName( ASymHdl( b ), NULL, SN_SOURCE, cmpb, TXT_LEN/2-1 );
return( stricmp( cmpa, cmpb ) );
}
static bool CheckType( sym_handle *sym, name_list *name )
{
sym_info sinfo;
mod_handle mod;
if( name->d2_only ) {
mod = SymMod( sym );
if( mod == NO_MOD ) return( FALSE );
if( ModHasInfo( mod, HK_TYPE ) != DS_OK ) return( FALSE );
}
SymInfo( sym, NULL, &sinfo );
switch( sinfo.kind ) {
case SK_CODE:
case SK_PROCEDURE:
if( sinfo.compiler ) return( FALSE );
if( name->type & WF_CODE ) return( TRUE );
break;
case SK_DATA:
if( name->type & WF_DATA ) return( TRUE );
break;
case SK_NONE:
return( TRUE );
}
return( FALSE );
}
static SYM_WALKER StickEmIn;
static walk_result StickEmIn( sym_walk_info swi, sym_handle *sym, void *_name )
{
name_list *name = _name;
char *p;
a_symbol *curr;
if( swi != SWI_SYMBOL ) return( WR_CONTINUE );
if( !CheckType( sym, name ) ) return( WR_CONTINUE );
p = TxtBuff;
curr = DbgAlloc( sizeof( a_symbol ) + sym_SIZE - 1 );
if( curr == NULL ) return( WR_STOP );
HDLAssign( sym, ASymHdl( curr ), sym );
curr->key = 0;
curr->next = name->list;
name->numrows++;
name->list = curr;
return( WR_CONTINUE );
}
static address NameSymAddr( a_symbol *s )
{
location_list ll;
if( SymLocation( ASymHdl( s ), NULL, &ll ) != DS_OK ) {
return( NilAddr );
}
return( ll.e[0].u.addr );
}
static a_symbol *NameGetRow( name_list *name, int i )
{
int idx;
a_symbol *curr;
if( name->skip ) {
idx = i / SKIP_ENTRIES;
curr = name->skip[ idx ];
i -= idx * SKIP_ENTRIES;
} else {
curr = name->list;
}
while( --i >= 0 ) {
curr = curr->next;
}
return( curr );
}
static void UniqList( name_list *name, bool dup_ok )
{
a_symbol **owner, *next;
address addr, next_addr;
owner = &name->list;
for( ;; ) {
next = *owner;
if( next == NULL ) break;
if( next->next == NULL ) break;
addr = NameSymAddr( next );
next_addr = NameSymAddr( next->next );
if( ( AddrComp( addr, next_addr ) == 0 &&
SymCompare( &next, &next->next ) == 0 ) ||
( !dup_ok && SymCompare( &next, &next->next ) == 0 ) ) {
*owner = next->next;
DbgFree( next );
name->numrows--;
} else {
owner = &next->next;
}
}
}
void NameListAddModules( name_list *name, mod_handle mod, bool d2_only, bool dup_ok )
{
a_symbol *curr;
int i;
name->numrows = 0;
name->list = NULL;
name->d2_only = d2_only;
WalkSymList( SS_MODULE, &mod, StickEmIn, name );
name->list = SortLinkedList( name->list, offsetof( a_symbol, next ),
SymCompare, DbgAlloc, DbgFree );
UniqList( name, dup_ok );
if( name->numrows > SKIP_ENTRIES ) {
name->skip = DbgAlloc( (name->numrows/SKIP_ENTRIES + 1)*sizeof(a_symbol*) );
} else {
name->skip = NULL;
}
if( name->skip ) {
i = 0;
for( curr = name->list; curr != NULL; curr = curr->next ) {
if( i % SKIP_ENTRIES == 0 ) {
name->skip[ i / SKIP_ENTRIES ] = curr;
}
++i;
}
}
}
void NameListInit( name_list *name, walk_find type )
{
name->list = NULL;
name->skip = NULL;
name->type = type;
}
void NameListFree( name_list *name )
{
a_symbol *curr, *next;
DbgFree( name->skip );
for( curr = name->list; curr != NULL; curr = next ) {
next = curr->next;
DbgFree( curr );
}
name->list = NULL;
name->numrows = 0;
}
int NameListNumRows( name_list *name )
{
if( name->list == NULL ) return( 0 );
return( name->numrows );
}
unsigned NameListName( name_list *name, int i, char *buff, symbol_name type )
{
unsigned rc;
sym_handle *sh;
buff[0] = '\0';
if( i >= name->numrows || name->list == NULL ) return( 0 );
sh = ASymHdl( NameGetRow( name, i ) );
if( type == SN_PARSEABLE ) {
rc = QualifiedSymName( sh, buff, TXT_LEN, TRUE );
} else if( type == SN_QUALIFIED ) {
rc = QualifiedSymName( sh, buff, TXT_LEN, FALSE );
} else {
rc = SymName( sh, NULL, type, buff, TXT_LEN );
}
return( rc );
}
address NameListAddr( name_list *name, int i )
{
if( i >= name->numrows || name->list == NULL ) return( NilAddr );
return( NameSymAddr( NameGetRow( name, i ) ) );
}
sym_handle *NameListHandle( name_list *name, int i )
{
return( ASymHdl( NameGetRow( name, i ) ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?