wf77info.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,181 行 · 第 1/5 页

C
2,181
字号
    size = GetComBlkSize( cb );
    while( size > MaxSegSize ) {
        BESetSeg( segment );
        SegBytes( MaxSegSize );
        size -= MaxSegSize;
        segment++;
    }
    BESetSeg( segment );
    SegBytes( size );
}


static  void    SegBytes( unsigned_32 size ) {
//============================================

#if _CPU == 386
    DGUBytes( size );
#else
    if( size == MaxSegSize ) {
        DGUBytes( size - 1 ); // back end can't handle value of 64k
        DGUBytes( 1 );
    } else {
        DGUBytes( size );
    }
#endif
}


static  void            DefineGlobalSeg( global_seg *seg ) {
//==========================================================

// Define a global segment.

    int         private;
    char        g_name[G_DATA_LEN+3];

    seg->segment = AllocSegId();
    memcpy( g_name, GData, G_DATA_LEN );
    itoa( seg->segment - GlobalSeg->segment, &g_name[ G_DATA_LEN ], 10 );

#if _CPU == 386 || _CPU == 8086
    if( _SmallDataModel( CGOpts ) ) {
        if( seg->initialized ) {
            private = INIT; // so segment doesn't get put in BSS class
        } else {
            private = 0;
        }
    } else {
        private = PRIVATE;
    }
#else
    if( seg->initialized ) {
        private = INIT; // so segment doesn't get put in BSS class
    } else {
        private = 0;
    }
#endif

    BEDefSeg( seg->segment, private, g_name, ALIGN_SEGMENT );
}


static  void    DefineGlobalSegs( void ) {
//==================================

// Define global segments.

    global_seg  *g_seg;

    g_seg = GlobalSeg;
    while( g_seg != NULL ) {
        DefineGlobalSeg( g_seg );
        g_seg = g_seg->link;
    }
}


static  void    AllocGlobalSegs( void ) {
//=================================

// Allocate global segments.

    global_seg  *g_seg;

    g_seg = GlobalSeg;
    while( g_seg != NULL ) {
        BESetSeg( g_seg->segment );
        SegBytes( g_seg->size );
        g_seg = g_seg->link;
    }
}


static  global_seg      *GSegDesc( unsigned_32 g_offset ) {
//=========================================================

// Find global segment descriptor for given offset.

    global_seg  *g_seg;
    unsigned_32 g_size;

    g_seg = GlobalSeg;
    g_size = 0;
    for(;;) {
        if( g_size + g_seg->size > g_offset ) break;
        g_size += g_seg->size;
        g_seg = g_seg->link;
    }
    return( g_seg );
}


void    DtInit( segment_id seg, seg_offset offset ) {
//===================================================

// Set to do DATA initialization.

    if( DtOffset >= MaxSegSize - offset ) {
        seg++;
        DtSegOffset = DtOffset - (MaxSegSize - offset);
        while( DtSegOffset >= MaxSegSize ) {
            seg++;
            DtSegOffset -= MaxSegSize;
        }
    } else {
        DtSegOffset = offset + DtOffset;
    }
    DtSegment = seg;
}


struct {
    int         seg;
    seg_offset  offset;
    uint        size;
    char        byte_value;
} CurrDt;


static  void    InitBytes( unsigned long size, byte value ) {
//===========================================================

#if _CPU == 386
    DGIBytes( size, value );
#else
    if( size == MaxSegSize ) {
        // back end can't handle size of 64k
        DGIBytes( MaxSegSize / 2, value );
        DGIBytes( MaxSegSize / 2, value );
    } else {
        DGIBytes( size, value );
    }
#endif
}


static  void    UndefBytes( unsigned long size, byte *data ) {
//============================================================

#if _CPU == 386
    DGBytes( size, data );
#else
    if( size == MaxSegSize ) {
        // back end can't handle size of 64k
        DGBytes( MaxSegSize / 2, data );
        DGBytes( MaxSegSize / 2, data );
    } else {
        DGBytes( size, data );
    }
#endif
}


static  void    FlushCurrDt( void ) {
//=============================

    if( CurrDt.seg != WF77_NULLSEGID ) {
        BESetSeg( CurrDt.seg );
        DGSeek( CurrDt.offset );
        InitBytes( CurrDt.size, CurrDt.byte_value );
    }
}


static  void    InitCurrDt( void ) {
//============================

    CurrDt.seg = WF77_NULLSEGID;
    CurrDt.offset = 0;
    CurrDt.byte_value = 0;
    CurrDt.size = 0;
}


void    DtIBytes( byte data, int size ) {
//=======================================

// Initialize with specified data.

    if( (DtSegment == CurrDt.seg) &&
        (DtSegOffset == CurrDt.offset + CurrDt.size) &&
        (data == CurrDt.byte_value) &&
        ((MaxSegSize - (CurrDt.offset + CurrDt.size)) >= size ) ) {
        // We are continuing where we left off
        CurrDt.size += size;
        DtSegOffset += size;
    } else {
        FlushCurrDt();
        if( MaxSegSize - DtSegOffset > size ) {
            CurrDt.seg = DtSegment;
            CurrDt.offset = DtSegOffset;
            CurrDt.byte_value = data;
            CurrDt.size = size;
            DtSegOffset += size;
        } else {
            BESetSeg( DtSegment );
            DGSeek( DtSegOffset );
            DGIBytes( MaxSegSize - DtSegOffset, data );
            size -= MaxSegSize - DtSegOffset;
            DtSegment++;
            DtSegOffset = size;
            CurrDt.seg = DtSegment;
            CurrDt.offset = DtSegOffset;
            CurrDt.byte_value = data;
            CurrDt.size = size;
        }
    }
}


void    DtStreamBytes( byte *data, int size ) {
//=============================================

// Initialize with specified data.

    FlushCurrDt();
    InitCurrDt();
    BESetSeg( DtSegment );
    DGSeek( DtSegOffset );
    if( MaxSegSize - DtSegOffset > size ) {
        UndefBytes( size, data );
        DtSegOffset += size;
    } else {
        UndefBytes( MaxSegSize - DtSegOffset, data );
        size -= MaxSegSize - DtSegOffset;
        DtSegment++;
        if( size != 0 ) {
            BESetSeg( DtSegment );
            DGSeek( 0 );
            UndefBytes( size, data + MaxSegSize - DtSegOffset );
            DtSegOffset = size;
        } else {
            DtSegOffset = 0;
        }
    }
}


void    DtBytes( byte *data, int size ) {
//=======================================

// Initialize with specified data.

    byte        byte_value;
    int         i;

    byte_value = *data;
    for( i = 1; i < size; ++i ) {
        if( data[i] != byte_value ) {
            DtStreamBytes( data, size );
            return;
        }
    }
    DtIBytes( byte_value, size );
}


void    DtStartSequence( void ) {
//=========================

    InitCurrDt();
}


void    DtFiniSequence( void ) {
//========================

    FlushCurrDt();
}


segment_id      GetComSeg( sym_id sym, unsigned_32 offset ) {
//===========================================================

// Get segment id of common block for variable in common.

    int segment;

    offset += sym->ns.si.va.vi.ec_ext->offset;
    segment = sym->ns.si.va.vi.ec_ext->com_blk->ns.si.cb.seg_id;
    while( offset > MaxSegSize ) {
        segment++;
        offset -= MaxSegSize;
    }
    return( segment );
}


segment_id      GetDataSegId( sym_id sym ) {
//==========================================

// Get segment containing data for given variable.

    segment_id  id;
    unsigned_32 offset;
    com_eq      *ce_ext;

    if( sym->ns.flags & SY_IN_EQUIV ) {
        offset = 0;
        for(;;) {
            ce_ext = sym->ns.si.va.vi.ec_ext;
            if( ce_ext->ec_flags & LEADER ) break;
            offset += ce_ext->offset;
            sym = ce_ext->link_eqv;
        }
        if( ce_ext->ec_flags & MEMBER_IN_COMMON ) {
            id = GetComSeg( sym, offset );
        } else {
            id = GetGlobalSeg( ce_ext->offset + offset );
        }
    } else if( sym->ns.flags & SY_IN_COMMON ) {
        id = GetComSeg( sym, 0 );
    } else if( sym->ns.flags & SY_SUBSCRIPTED ) {
        id = sym->ns.si.va.vi.seg_id;
    } else if( sym->ns.typ == TY_CHAR ) {
        id = sym->ns.si.va.vi.seg_id;
    } else if( sym->ns.typ == TY_STRUCTURE ) {
        id = sym->ns.si.va.vi.seg_id;
    } else if( sym->ns.flags & SY_DATA_INIT ) {
        id = WF77_LDATA;
    } else {
        id = WF77_UDATA;
    }
    return( id );
}


seg_offset      GetGlobalOffset( unsigned_32 g_offset ) {
//=======================================================

// Find offset in the global segment containing data at given offset.

    global_seg  *g_seg;
    unsigned_32 g_size;

    g_seg = GlobalSeg;
    g_size = 0;
    for(;;) {
        if( g_size + g_seg->size > g_offset ) break;
        g_size += g_seg->size;
        g_seg = g_seg->link;
    }
    return( g_offset - g_size );
}


seg_offset      GetComOffset( unsigned_32 offset ) {
//==================================================

// Get segment offset in common block for variable in common.

    while( offset >= MaxSegSize ) {
        offset -= MaxSegSize;
    }
    return( offset );
}


void    *FEBack( sym_id sym ) {
//=============================

// Return the back handle for the given symbol.

    void        *back_handle;

    if( ( sym->ns.flags & SY_CLASS ) == SY_COMMON ) {
        back_handle = sym->ns.address;
    } else {
        if( sym->ns.address == NULL ) {
            sym->ns.address = BENewBack( sym );
        }
        back_handle = sym->ns.address;
    }
    return( back_handle );
}


seg_offset      GetDataOffset( sym_id sym ) {
//===========================================

// Get offset in segment containing data for given variable.

    seg_offset  seg_offset;
    unsigned_32 offset;
    com_eq      *ce_ext;

    if( sym->ns.flags & SY_IN_EQUIV ) {
        offset = 0;
        for(;;) {
            ce_ext = sym->ns.si.va.vi.ec_ext;
            if( ce_ext->ec_flags & LEADER ) break;
            offset += ce_ext->offset;
            sym = ce_ext->link_eqv;
        }
        if( ce_ext->ec_flags & MEMBER_IN_COMMON ) {
            seg_offset = GetComOffset( ce_ext->offset + offset );
        } else {
            seg_offset = GetGlobalOffset( ce_ext->offset + offset );
        }
    } else if( sym->ns.flags & SY_IN_COMMON ) {
        seg_offset = GetComOffset( sym->ns.si.va.vi.ec_ext->offset );
    } else if( sym->ns.flags & SY_SUBSCRIPTED ) {
        seg_offset = DGBackTell( FEBack( sym ) );
    } else if( sym->ns.typ == TY_CHAR ) {
        seg_offset = DGBackTell( sym->ns.si.va.bck_hdl );
    } else {
        seg_offset = DGBackTell( FEBack( sym ) );
    }
    return( seg_offset );
}


segment_id  GetGlobalSeg( unsigned_32 g_offset ) {
//================================================

// Find global segment containing data at given offset.

⌨️ 快捷键说明

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