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

📄 pchdr.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

    while( field != NULL ) {
        len = strlen( field->name ) + sizeof(FIELD_ENTRY);
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        next_field = field->next_field;         // save pointer
        field->field_len = len;                 // replace with length
        if( next_field == NULL ) {
            field->field_len = - len;           // marker for end of list
        }
        typ = field->field_type;                // save type pointer
        field->field_type_index = typ->type_index;// replace with type index
        rc = WritePHeader( field, len );
        field->next_field = next_field;         // restore pointer
        field->field_type = typ;                // restore type pointer
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        field = next_field;
    }
}

static void OutPutATag( TAGPTR tag )
{
    int         rc;
    TYPEPTR     typ;
    unsigned    len;

    typ = tag->sym_type;
    tag->sym_type_index = typ->type_index;
    len = strlen( tag->name ) + sizeof(TAGDEFN);
    len = (len + (sizeof(int) - 1)) & - sizeof(int);
    rc = WritePHeader( tag, len );
    tag->sym_type = typ;
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
    if( typ->decl_type == TYPE_ENUM ) {
        OutPutEnums( tag->u.enum_list, tag );
    } else {
        OutPutFields( tag->u.field_list );
    }
}

static void OutPutTags()
{
    WalkTagList( OutPutATag );
}

void SetTypeIndex( TYPEPTR typ )
{
    ++PH_TypeCount;
    typ->type_index = PH_TypeCount;
}

static void SetFuncTypeIndex( TYPEPTR typ, int index )
{
    // index;      /* unused */
    SetTypeIndex( typ );
}

static void NumberTypes()
{
    PH_TypeCount = 0;
    WalkTypeList( SetTypeIndex );
    WalkFuncTypeList( SetFuncTypeIndex );
}

static void SetTagIndex( TAGPTR tag )
{
    tag->tag_index = PH_TagCount;
    ++PH_TagCount;
}

static void SetDebugTag( TAGPTR tag )
{
    tag->refno = 0;
}

static void NumberTags()
{
    PH_TagCount = 0;
    WalkTagList( SetTagIndex );
}

static void InitDebugTags()
{
    WalkTagList( SetDebugTag );
}

static int WriteType( TYPEPTR typ )
{
    int         rc;
    TYPEPTR     object;

    object = typ->object;
    if( object != NULL ) {
        typ->object_index = object->type_index;
        rc = WritePHeader( typ, sizeof(TYPEDEFN) );
        typ->object = object;
    } else {
        rc = WritePHeader( typ, sizeof(TYPEDEFN) );
    }
    return( rc );
}

struct type_indices {
        int     basetype_index[TYPE_LAST_ENTRY];
        int     stringtype_index;
        int     constchartype_index;
};

static void OutPutTypeIndexes()                         /* 02-jan-95 */
{
    TYPEPTR     typ;
    int         rc;
    int         i;
    struct type_indices typ_index;

    for( i = TYPE_CHAR; i < TYPE_LAST_ENTRY; i++ ) {
        typ = BaseTypes[i];
        if( typ == NULL ) {
            typ_index.basetype_index[i] = 0;
        } else {
            typ_index.basetype_index[i] = typ->type_index;
        }
    }
    typ_index.stringtype_index = StringType->type_index;
    typ_index.constchartype_index = ConstCharType->type_index;
    rc = WritePHeader( &typ_index, sizeof(struct type_indices) );
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutAType( TYPEPTR typ )
{
    TAGPTR      tag;
    int         rc;
    struct array_info *array;

    rc = 0;
    switch( typ->decl_type ) {
    case TYPE_ARRAY:
        array = typ->u.array;                   // save pointer
        typ->u.array_dimension = array->dimension;      // replace with dim
        rc = WriteType( typ );
        typ->u.array = array;                   // restore pointer
        break;
    case TYPE_STRUCT:
    case TYPE_UNION:
    case TYPE_ENUM:
        tag = typ->u.tag;                               // save tag
        typ->u.tag_index = tag->tag_index;              // replace with index
        rc = WriteType( typ );
        typ->u.tag = tag;                               // restore tag pointer
        break;
    default:
        if( typ->decl_type != TYPE_FUNCTION ) {
            rc = WriteType( typ );
        }
        break;
    }
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutAFuncType( TYPEPTR typ, int index )
{
    TYPEPTR     *parm_list;
    int         rc;

    parm_list = typ->u.parms;                   // save pointer
    typ->u.parm_index = index;                  // replace with index
    rc = WriteType( typ );
    typ->u.parms = parm_list;                   // restore pointer
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutFuncParmList( TYPEPTR typ, int index )
{
    TYPEPTR     *parm_list;
    int         rc;
    union parmtype {
        TYPEPTR parm_typ;
        int     type_index;
    } parm;

    // index;      /* unused */
    parm_list = typ->u.parms;
    if( parm_list != NULL ) {
        for( ; *parm_list; ++parm_list ) {
            parm.type_index = (*parm_list)->type_index;
            rc = WritePHeader( &parm, sizeof(union parmtype) );
            if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        }
    }
    parm.type_index = -1;
    rc = WritePHeader( &parm, sizeof(union parmtype) );
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutTypes()
{
    NumberTypes();
    NumberTags();
    WalkTypeList( OutPutAType );
    WalkFuncTypeList( OutPutAFuncType );
    WalkFuncTypeList( OutPutFuncParmList );
    OutPutTypeIndexes();
}

#if _MACHINE == _PC
static void OutPutAuxInfo( struct aux_info *info )
{
    hw_reg_set          *regs;
    hw_reg_set          *save_parms;
    char                *save_objname;
    byte_seq            *save_code;
    int                 rc;
    unsigned            len;
    unsigned            padding;

    save_parms = info->parms;
    save_objname = info->objname;
    save_code = info->code;
    len = sizeof( struct aux_info );
    if( save_parms != NULL ) {
        info->parms_size = 0;
        regs = save_parms;
        for(;;) {
            info->parms_size += sizeof( hw_reg_set );
            if( HW_CEqual( *regs, HW_EMPTY ) ) break;
            ++regs;
        }
    }
    if( save_objname != NULL ) {
        info->objname_size = strlen( save_objname ) + 1;
        len += info->objname_size;
    }
    if( save_code != NULL ) {
        info->code_size = (save_code->length & MAX_BYTE_SEQ_LEN)
                                + sizeof(byte_seq);
        len += info->code_size;
    }
    padding = ((len + (sizeof(int) - 1)) & - sizeof(int)) - len;
    rc = WritePHeader( info, sizeof( struct aux_info ) );
    if( save_parms != NULL ) {
        regs = save_parms;
        for(;;) {
            rc |= WritePHeader( regs, sizeof( hw_reg_set ) );
            if( HW_CEqual( *regs, HW_EMPTY ) ) break;
            ++regs;
        }
    }
    if( save_objname != NULL ) {
        len = strlen( save_objname ) + 1;
        rc |= WritePHeader( save_objname, len );
    }
    if( save_code != NULL ) {
        len = (save_code->length & MAX_BYTE_SEQ_LEN)
                        + sizeof(byte_seq);
        rc |= WritePHeader( save_code, len );
    }
    rc |= WritePHeader( "    ", padding );
    info->parms = save_parms;
    info->objname = save_objname;
    info->code = save_code;
    if( rc != 0 )  longjmp( PH_jmpbuf, rc );
}

static void OutPutPragmaInfo()
{
    struct aux_entry    *ent;
    struct aux_info     *info;
    int                 index;
    int                 rc;
    unsigned            len;

    for( index = 0; (info = BuiltinInfos[index]); ++index ) {
        OutPutAuxInfo( info );          // write out the aux_info struct
    }
    PH_PragmaCount = 0;
    for( ent = AuxList; ent; ent = ent->next ) {
        info = ent->info;
        info->aux_info_index = -1;
    }
    index = 0;
    for( ent = AuxList; ent; ent = ent->next ) {
        info = ent->info;
        if( info->aux_info_index == -1 ) {
            info->aux_info_index = index;
            index++;
            OutPutAuxInfo( info );      // write out the aux_info struct
            ++PH_PragmaCount;
        }
    }
    for( ent = AuxList; ent; ent = ent->next ) {
        info = ent->info;
        ent->aux_info_index = info->aux_info_index;
        // write out aux_entry
        len = sizeof( struct aux_entry ) + strlen( ent->name );
        len = (len + (sizeof(int) - 1)) & - sizeof(int);
        rc = WritePHeader( ent, len );
        ent->info = info;                       // restore pointer
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
    }
}
#endif

static void OutPutMacros()
{
    int         i;
    int         rc;
    MEPTR       mentry;
    MEPTR       next_macro;
    unsigned    mentry_len;

    PH_MacroCount = 0;
    PH_MacroSize = PH_size;
    for( i = 0; i < MACRO_HASH_SIZE; ++i ) {
        for( mentry = MacHash[i]; mentry; mentry = mentry->next_macro ) {
            mentry_len = mentry->macro_len;
            next_macro = mentry->next_macro;        // save pointer
            mentry->macro_index = i;        // replace with hash index
            rc = WritePHeader( mentry, mentry_len );
            mentry->next_macro = next_macro;        // restore pointer
            mentry_len = ((mentry_len + (sizeof(int) - 1)) & -sizeof(int))
                                - mentry_len;
            rc |= WritePHeader( "    ", mentry_len );
            if( rc != 0 )  longjmp( PH_jmpbuf, rc );
            ++PH_MacroCount;
        }
    }
    /* write out undefined macro list.  26-may-94 */
    PH_UndefMacroCount = 0;
    for( mentry = UndefMacroList; mentry; mentry = mentry->next_macro ) {
        mentry_len = mentry->macro_len;
        rc = WritePHeader( mentry, mentry_len );
        mentry_len = ((mentry_len + (sizeof(int) - 1)) & - sizeof(int))
                            - mentry_len;
        rc |= WritePHeader( "    ", mentry_len );
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        ++PH_UndefMacroCount;
    }
    PH_MacroSize = PH_size - PH_MacroSize;
}

static void OutPutSymHashTable()
{
    SYM_HASHPTR hsym;
    SYM_HASHPTR next_hsymptr;
    SYM_HASHPTR sym_list;
    TYPEPTR     typ;
    int         i;
    int         rc;
    unsigned    len;

    for( i=0; i < SYM_HASH_SIZE; i++ ) {
        // reverse the list
        sym_list = NULL;
        for( hsym = HashTab[i]; hsym; hsym = next_hsymptr ) {
            next_hsymptr = hsym->next_sym;
            hsym->next_sym = sym_list;
            sym_list = hsym;
            ++PH_SymHashCount;
        }
        HashTab[i] = NULL;
        rc = 0;
        for( hsym = sym_list; hsym; hsym = next_hsymptr ) {
            next_hsymptr = hsym->next_sym;
            hsym->hash_index = i;
            typ = hsym->sym_type;               // save type pointer
            if( typ != NULL ) {
                hsym->sym_type_index = typ->type_index; // replace with index
            }
            len = strlen( hsym->name ) + sizeof(struct sym_hash_entry);
            len = (len + (sizeof(int) - 1)) & - sizeof(int);
            rc |= WritePHeader( hsym, len );
            hsym->sym_type = typ;               // restore type pointer
            hsym->next_sym = HashTab[i];
            HashTab[i] = hsym;
        }
        if( rc != 0 )  longjmp( PH_jmpbuf, rc );
    }
}

static void OutPutSymbols()
{
    SYM_ENTRY   sym;
    SYM_HANDLE  sym_handle;
    int         rc;

    if( PH_computing_size ) {
        PH_size += (NextSymHandle+1) * sizeof(SYM_ENTRY);
    } else {
        for( sym_handle = 0; sym_handle <= NextSymHandle; sym_handle++ ) {
            SymGet( &sym, sym_handle );
            if( sym.sym_type != NULL ) {
                sym.sym_type_index = sym.sym_type->type_index;
            }
            if( sym.seginfo != NULL ) {
                sym.seginfo_index = sym.seginfo->index;
            }
            sym.name = NULL; // can't carry a name across
            rc = WritePHeader( &sym, sizeof(SYM_ENTRY) );
            if( rc != 0 )  longjmp( PH_jmpbuf, rc );
        }
    }
}

void OutPutEverything()
{
    PH_SymHashCount = 0;
    PH_FileCount = 0;
    PH_RDirCount=0;
    PH_SegCount = 0;
    OutPutIncludes();
    OutPutRoDirList();
    OutPutHFileList();
    OutPutIncFileList();
    OutPutLibrarys();
    OutPutSegInfo();
    OutPutTypes();
    OutPutTags();
#if _MACHINE == _PC
    OutPutPragmaInfo();

⌨️ 快捷键说明

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