⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fuzzy.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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 + -