📄 fuzzy.c
字号:
/****************************************************************************
*
* 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 <ctype.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <string.h>
#include "demangle.h" /* from lib_misc project */
#include "dlltool.h"
#include "error.h"
#include "fuzzy.h"
#include "hash.h"
#include "memory.h"
#include "orl.h" /* from riscdev project */
#define HASH_TABLE_SIZE 2111
#define MAX_SYMBOL_LEN 512
#define MATCH_MODE_EXACT 1
#define MATCH_MODE_UNDERBAR_SYMBOL 2
#define MATCH_MODE_SYMBOL_UNDERBAR 3
#define MATCH_MODE_UNDERBAR_SYMBOL_AT_NUMBER 4
/*
* Types.
*/
typedef struct _ListElem {
struct _ListElem * next;
char buff[1];
} ListElem;
typedef struct _MatchingInfo {
char * basename;
int findmode;
ListElem * found;
} MatchingInfo;
/*
* Static data.
*/
static HashTable hashtable = NULL;
static ListElem * bufflist = NULL;
static void * dllhandle = NULL;
/*
* Determine if a symbol's name is mangled.
*/
static int is_name_mangled( const char *symbol )
/**********************************************/
{
if( __is_mangled( symbol, strlen( symbol ) ) ) {
return( 1 );
}
/* what about MS mangling? */
return( 0 );
}
/*
* Hash comparison callback function.
*/
static int hash_compare( const void *item1, const void *item2 )
/*************************************************************/
{
return( !strcmp( (const char*)item1, (const char*)item2 ) );
}
/*
* Hash a symbol name.
*/
static unsigned hash_symbol_name( const void *symbol )
/****************************************************/
{
char * namecopy;
char * namestart;
char * p;
unsigned * s;
size_t len;
unsigned mask;
unsigned c;
unsigned g;
unsigned h;
unsigned const namecmpmask[5] = {
0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF, 0xFFFFFFFF
};
/*
* We want 'foo', '_foo', 'foo_', '_foo@8', and so on all to hash to
* the same value, so strip off stuff from each end if necessary to
* get the root name.
*/
namecopy = DupStrMem( symbol );
namestart = namecopy;
while( *namestart == '_' ) namestart++;
len = strlen( namestart );
if( len > 0 ) {
p = namestart + len - 1;
while( p >= namestart && ( isdigit(*p) || *p=='@' || *p=='_' ) ) {
*p = '\0';
p--;
}
}
/*
* Ok, now do the actual hashing.
*/
s = (unsigned*) namestart;
len = strlen( namestart );
h = len;
c = len;
if( len > sizeof( unsigned ) ) {
do {
c ^= *s;
h = ( h << 4 ) + c;
g = h & ~0x00FFFFFF;
h ^= g;
h ^= g >> (4+4+4+4+4);
++s;
len -= sizeof( unsigned );
} while( len > sizeof( unsigned ) );
}
mask = namecmpmask[ len ];
c ^= *s & mask;
h = ( h << 4 ) + c;
g = h & ~0x00FFFFFF;
h ^= g;
h ^= g >> (4+4+4+4+4);
g = h & ~0x0FFF;
h ^= g;
h ^= g >> (4+4+4);
h ^= h >> (2+4);
FreeMem( namecopy );
return( h );
}
/*
* Used by ORL.
*/
static void *obj_read( void *hdl, size_t len )
/*****************************************/
{
ListElem * newelem;
newelem = AllocMem( sizeof( ListElem ) + len - 1 );
newelem->next = bufflist;
bufflist = newelem;
if( read( (int)hdl, newelem->buff, len ) != len ) {
FreeMem( newelem );
return( NULL );
}
return( newelem->buff );
}
/*
* Used by ORL.
*/
static long obj_seek( void *hdl, long pos, int where )
/****************************************************/
{
return( lseek( (int)hdl, pos, where ) );
}
/*
* Free a list of ListElem's.
*/
static void free_list( ListElem *liststart )
/******************************************/
{
ListElem * curelem;
ListElem * nextelem;
curelem = liststart;
while( curelem != NULL ) {
nextelem = curelem->next;
FreeMem( curelem );
curelem = nextelem;
}
bufflist = NULL;
}
/*
* Add one more symbol.
*/
static orl_return do_orl_symbol( orl_symbol_handle o_symbol )
/***********************************************************/
{
char * name;
char * namecopy;
name = ORLSymbolGetName( o_symbol );
if( !is_name_mangled( name ) ) {
namecopy = DupStrMem( name );
InsertHash( hashtable, namecopy );
}
return( ORL_OKAY );
}
/*
* Collect all external symbols from an object file. Returns 0 on error.
*/
static int handle_obj_file( const char *filename, orl_handle o_hnd )
/******************************************************************/
{
orl_file_handle o_fhnd;
orl_file_format o_format;
orl_file_type o_filetype;
orl_sec_handle o_symtab;
orl_return o_rc;
int fileh;
/*** Make ORL interested in the file ***/
fileh = open( filename, O_BINARY | O_RDONLY );
if( fileh == -1 ) {
return( 0 );
}
o_format = ORLFileIdentify( o_hnd, (void*)fileh );
if( o_format == ORL_UNRECOGNIZED_FORMAT ) {
close( fileh );
return( 0 );
}
o_fhnd = ORLFileInit( o_hnd, (void*)fileh, o_format );
if( o_fhnd == NULL ) {
close( fileh );
return( 0 );
}
o_filetype = ORLFileGetType( o_fhnd );
if( o_filetype != ORL_FILE_TYPE_OBJECT ) {
close( fileh );
return( 0 );
}
/*** Scan the file's symbol table ***/
o_symtab = ORLFileGetSymbolTable( o_fhnd );
if( o_symtab == NULL ) {
close( fileh );
return( 0 );
}
o_rc = ORLSymbolSecScan( o_symtab, &do_orl_symbol );
if( o_rc != ORL_OKAY ) {
close( fileh );
return( 0 );
}
o_rc = ORLFileFini( o_fhnd );
if( o_rc != ORL_OKAY ) {
close( fileh );
return( 0 );
}
close( fileh );
return( 1 );
}
/*
* Returns the actual name of 'filename', searching 'libpaths' if necessary.
* The caller is responsible for freeing the returned memory. If the file
* cannot be found, NULL is returned.
*/
static char *find_file( const char *filename, const char *libpaths[] )
/********************************************************************/
{
int rc;
unsigned count;
char * tryme;
size_t len;
const char * p;
int hasbackslash;
/*** We might not have to go searching for it ***/
rc = access( filename, F_OK );
if( rc == 0 ) {
return( DupStrMem( filename ) );
}
/*** Not found, so check any directories in 'libpaths' ***/
if( libpaths != NULL ) {
for( count=0; libpaths[count]!=NULL; count++ ) {
/*** Determine if we need to add a backslash to the path ***/
len = strlen( libpaths[count] );
if( len == 0 ) Zoinks();
p = libpaths[count] + len - 1;
if( *p == '\\' ) {
hasbackslash = 1;
} else {
hasbackslash = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -