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

📄 pchdr.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    int         index;
    struct array_info *array;
    union parmtype {
        TYPEPTR parm_typ;
        int     type_index;
    } *parm_list;

    InitTypeHashTables();
    typ = (TYPEPTR)p;
    TypeArray = typ - 1;
    while( type_count != 0 ) {
        if( typ->decl_type == TYPE_FUNCTION )  break;
        if( typ->object_index != 0 ) {
            typ->object = &TypeArray[ typ->object_index ];
        }
        if( typ->decl_type == TYPE_ARRAY ) {
            array = (struct array_info *)CMemAlloc(sizeof(struct array_info));
            array->dimension = typ->u.array_dimension;
            typ->u.array = array;
        }
        AddTypeHash( typ );
        ++typ;
        --type_count;
    }
    parm_list = (union parmtype *)(typ + type_count);
    while( type_count != 0 ) {
        index = typ->u.parm_index;
        typ->next_type = FuncTypeHead[ index ];
        FuncTypeHead[ index ] = typ;
        if( typ->object_index != 0 ) {
            typ->object = &TypeArray[ typ->object_index ];
        }
        if( parm_list->type_index == -1 ) {
            typ->u.parms = NULL;
        } else {
            typ->u.parms = (TYPEPTR *)parm_list;
            for(;;) {
                index = parm_list->type_index;
                if( index == -1 ) break;
                parm_list->parm_typ = TypeArray + index;
                parm_list++;
            }
            parm_list->parm_typ = NULL;
        }
        parm_list++;
        ++typ;
        --type_count;
    }
    FixupTypeIndexes( (struct type_indices *)parm_list );
    return( (char *)parm_list + sizeof(struct type_indices) );
}

static char *FixupEnums( char *p, TAGPTR parent )
{
    ENUMPTR     ep;

    for(;;) {
        ep = (ENUMPTR)p;
        p += ep->enum_len;
        ep->parent = parent;            // parent is union'ed with enum_len
        ep->next_enum = EnumTable[ ep->hash ];
        EnumTable[ ep->hash ] = ep;
        if( ep->thread == NULL ) break;
        ep->thread = (ENUMPTR)p;
    }
    return( p );
}

static char *FixupFields( char *p )
{
    FIELDPTR    field;
    int         len;

    for(;;) {
        field = (FIELDPTR)p;
        field->field_type = TypeArray + field->field_type_index;
        len = field->field_len;
        p += len;
        field->next_field = (FIELDPTR)p;
        if( len < 0 ) break;
    }
    field->next_field = NULL;
    p -= len + len;
    return( p );
}

static void FixupTag( TYPEPTR typ )
{
    switch( typ->decl_type ) {
    case TYPE_STRUCT:
    case TYPE_UNION:
    case TYPE_ENUM:
        typ->u.tag = TagArray[ typ->u.tag_index ];
        break;
    default:
        break;
    }
}

static void FixupTagPointers()
{
    WalkTypeList( FixupTag );
}

static char *FixupTags( char *p, unsigned tag_count )
{
    TAGPTR      tag;
    TAGPTR      prevtag;
    TAGPTR      nexttag;
    TYPEPTR     typ;
    unsigned    len;

    if( tag_count != 0 ) {
        TagArray = (TAGPTR *)CMemAlloc( tag_count * sizeof(TAGPTR) );
    }
    tag = NULL;
    prevtag = NULL;
    while( tag_count != 0 ) {
        tag = (TAGPTR)p;
        TagArray[ tag->tag_index ] = tag;
        typ = TypeArray + tag->sym_type_index;
        tag->sym_type = typ;
        len = strlen( tag->name ) + sizeof(TAGDEFN);
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        p += len;
        if( typ->decl_type == TYPE_ENUM ) {
            if( tag->u.enum_list != NULL ) {
                tag->u.enum_list = (ENUMPTR)p;
                p = FixupEnums( p, tag );
            }
        } else {
            if( tag->u.field_list != NULL ) {
                tag->u.field_list = (FIELDPTR)p;
                p = FixupFields( p );
            }
        }
        tag->next_tag = prevtag;
        prevtag = tag;
        --tag_count;
    }
    for( tag = prevtag; tag; tag = nexttag ) {
        nexttag = tag->next_tag;
        tag->next_tag = TagHash[ tag->hash ];
        TagHash[ tag->hash ] = tag;
    }
    FixupTagPointers();
    return( p );
}

#if _MACHINE == _PC
static char *FixupAuxInfo( char *p, struct aux_info *info )
{
    unsigned            len;
    unsigned            codelen;

    p += sizeof( struct aux_info );
    len = info->parms_size;
    if( len != 0 ) {
        info->parms = (hw_reg_set *)p;
        p += len;
    }
    len = info->objname_size;
    if( len != 0 ) {
        info->objname = (char *)p;
        p += len;
    }
    codelen = info->code_size;
    if( codelen != 0 ) {
        info->code = (byte_seq *)p;
        p += codelen;
    }
    len += codelen;
    p += ((len + (sizeof(int) - 1)) & - sizeof(int)) - len;
    return( p );
}

static char *FixupPragmaInfo( char *p, unsigned pragma_count )
{
    struct aux_entry    *ent;
    struct aux_info     *info;
    struct aux_info     **info_array;
    int                 index;
    unsigned            len;

    for( index = 0; (info = BuiltinInfos[index]); ++index ) {
        memcpy( info, p, sizeof(struct aux_info) );
        p = FixupAuxInfo( p, info );
    }
    if( pragma_count == 0 )  return( p );
    info_array = (struct aux_info **)
                        CMemAlloc( pragma_count * sizeof(struct aux_info *) );
    index = 0;
    while( pragma_count != 0 ) {
        info = (struct aux_info *)p;
        info_array[index++] = info;
        p = FixupAuxInfo( p, info );
        --pragma_count;
    }
    AuxList = (struct aux_entry *)p;
    for(;;) {
        ent = (struct aux_entry *)p;
        len = sizeof( struct aux_entry ) + strlen( ent->name );
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        p += len;
        ent->info = info_array[ ent->aux_info_index ];
        if( ent->next == NULL ) break;
        ent->next = (struct aux_entry *)p;
    }
    CMemFree( info_array );
    return( p );
}
#endif

void FixupFNames( void ){
    FNAMEPTR    *lnk;
    FNAMEPTR    flist;

    lnk = &FNames;
    while( (flist = *lnk) != NULL ){
        lnk  = &flist->next;
    }
    *lnk = FNameList;
}

int ValidHeader( struct pheader *pch )
{
    if( pch->signature      == PCH_SIGNATURE  &&
        pch->version        == PCH_VERSION    &&
        pch->size_of_header == sizeof(struct pheader)  &&
        pch->size_of_int    == TARGET_INT       &&
        pch->specialsyms_count    == SpecialSyms      &&
        pch->pack_amount    == PackAmount ) {
        return( 1 );
    }
    return( 0 );                // indicate unusable pre-compiled header
}

int LoadPreCompiledHeader( char *p, struct pheader *pch )
{
    int                 rc;

    rc = FixupDataStructures( p, pch );
    CMemFree( TagArray );
    CMemFree( TextSegArray );
    CMemFree( PCHMacroHash );
    return( rc );
}

static int FixupDataStructures( char *p, struct pheader *pch )
{
    p = FixupLibrarys( p, pch->library_count );
    p = FixupSegInfo( p, pch->seg_count );
    p = FixupTypes( p, pch->type_count );
    p = FixupTags( p, pch->tag_count );
#if _MACHINE == _PC
    p = FixupPragmaInfo( p, pch->pragma_count );
#endif
    p = FixupSymHashTable( p, pch->symhash_count );
    p = FixupSymbols( p, pch->symbol_count );
    if( pch->msgflags_len != 0 ) {                      /* 06-jul-94 */
        MsgFlags = p;
        p += pch->msgflags_len;
    }
    PCH_MaxSymHandle = pch->symbol_count;
    NextSymHandle = pch->symbol_count - 1;
    IncLineCount = pch->incline_count;
    Toggles = pch->toggles;
    FixupFNames();
    InitDebugTypes();
    InitDebugTags();
    return( 0 );
}

int SameCWD( char *p )
{
    char        *cwd;
    int         same;
    char        buf[_MAX_PATH];

    cwd = getcwd( buf, _MAX_PATH );
    same = strcmp( cwd, p );
    return( same == 0 );
}

void FreePreCompiledHeader( void ){
    FEfree( PCH_Start );
    FEfree( PCH_Macros );
    FEfree( PCH_SymArray );
}

void AbortPreCompiledHeader( void )
{
    FreePreCompiledHeader();
    CMemFree( TagArray );
    CMemFree( TextSegArray );
    CMemFree( PCHMacroHash );
    PCH_Start = NULL;
    PCH_End = NULL;
    PCH_Macros = NULL;
    PCH_SymArray = NULL;
    PCH_MaxSymHandle = 0;
    TagArray = NULL;
    TextSegArray = NULL;
    FNameList = NULL;
    IncFileList = NULL;
    PCHMacroHash = NULL;
    CompFlags.make_precompiled_header = 1;      // force new PCH to be created
}

//========================================================================
//      This portion of the code checks to see if we can use the
//      existing pre-compiled header.
//      - all the predefined macros have the same definition
//      - all the include files are the same and have not been modified
//========================================================================

int UsePreCompiledHeader( char *filename )
{
    int                 handle;
    unsigned            len;
    char                *p;
    struct pheader      pch;

    handle = sopen( PCH_FileName, O_RDONLY|O_BINARY, SH_DENYWR );
    if( handle == -1 ) {
        CompFlags.make_precompiled_header = 1;
        return( -1 );
    }
    PCH_Start = NULL;
    TextSegArray = NULL;
    TagArray = NULL;
    PCHMacroHash = NULL;
    len = read( handle, &pch, sizeof(struct pheader) );
    if( len != sizeof(struct pheader) ) {
        close( handle );
        PCHNote( PCHDR_READ_ERROR );
        AbortPreCompiledHeader();
        return( -1 );
    }
    if( !ValidHeader( &pch ) ) {
        close( handle );
        PCHNote( PCHDR_INVALID_HEADER );
        AbortPreCompiledHeader();
        return( -1 );
    }
    if( pch.gen_switches != GenSwitches  ||
        pch.target_switches != TargetSwitches ) {
        close( handle );
        PCHNote( PCHDR_DIFFERENT_OPTIONS );
        AbortPreCompiledHeader();
        return( -1 );
    }
    p = FEmalloc( pch.size );                   // allocate big memory block
    PCH_Start = p;
    PCH_End = p + pch.size;
    PH_size = read( handle, p, pch.size );      // read rest of the file
    PCH_Macros = FEmalloc( pch.macro_size );
    len = read( handle, PCH_Macros, pch.macro_size );
    close( handle );
    PCH_SymArray = (SYMPTR *)FEmalloc( pch.symbol_count * sizeof(SYMPTR) );
    if( PH_size != pch.size  ||  len != pch.macro_size ) {
        PCHNote( PCHDR_READ_ERROR );
        AbortPreCompiledHeader();
        return( -1 );
    }
    if( ! SameCWD( p ) ) {
        PCHNote( PCHDR_DIFFERENT_CWD );
        AbortPreCompiledHeader();
        return( -1 );
    }
    p = FixupIncludes( p + pch.cwd_len, pch.file_count );
    p = FixupRoDirList( p, pch.rdir_count );
    if( VerifyIncludes() ){
        AbortPreCompiledHeader();
        return( -1 );
    }
    len = strlen( p ) + 1;              // get length of saved HFileList
    len = (len + sizeof(int) - 1) & - sizeof(int);
    if((( HFileList == NULL ) && ( strlen( p ) > 0 ))
        || (( HFileList != NULL ) && ( strcmp( p, HFileList ) != 0 ))) {
        PCHNote( PCHDR_INCFILE_DIFFERENT );
        AbortPreCompiledHeader();
        return( -1 );
    }
    p = FixupIncFileList( p + len, pch.incfile_count );
    if( strcmp( filename, IncFileList->filename ) != 0 ) {
        PCHNote( PCHDR_INCPATH_CHANGED );
        AbortPreCompiledHeader();
        return( -1 );                           // can't use PCH
    }
    if( VerifyMacros(PCH_Macros,pch.macro_count,pch.undef_macro_count) != 0) {
        PCHNote( PCHDR_MACRO_CHANGED );
        AbortPreCompiledHeader();
        return( -1 );
    }
    LoadPreCompiledHeader( p, &pch );
    PCH_FileName = NULL;
    return( 0 );
}

void SetDebugType( TYPEPTR typ )
{
    typ->debug_type = DBG_NIL_TYPE;
}

void SetFuncDebugType( TYPEPTR typ, int index )
{
    // index;      /* unused */
    typ->debug_type = DBG_NIL_TYPE;
}

void InitDebugTypes( void )
{
    WalkTypeList( SetDebugType );
    WalkFuncTypeList( SetFuncDebugType );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -