watlnum.c

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

C
654
字号
    ic->entry = save_entry;
    UnlockLine();
    return( close.have );
}

static void ScanSection( struct search_info *close, unsigned file_id,
                        unsigned line )
{
    line_info           *curr;
    line_segment        *ptr;
    void                *next;
    unsigned            num;
    cue_state           spec;

    close->found = 0;
    for( ptr = LinStart; ptr < LinEnd; ptr = next ) {
        next = NEXT_SEG( ptr );
        if( line == 0 ) {
            line = LINE_LINE( ptr )[0].line_number;
        }
        for( curr = LINE_LINE( ptr ); curr < next; ++curr ) {
            spec.fno = 1;
            num = curr->line_number;
            if( num >= PRIMARY_RANGE ) {
                if( !CueFind( close->special_table, num, &spec ) ) {
                    continue;
                }
                num = spec.line;
            }
            if( spec.fno != file_id ) continue;
            if( num > line ) continue;
            if( num <= close->num ) continue;
            close->found = 1;
            close->ic.seg_bias = BIAS( ptr );
            close->ic.info_bias = BIAS( curr );
            close->num = num;
            if( num == line ) {
                close->have = SR_EXACT;
                return;
            }
            close->have = SR_CLOSEST;
        }
    }
}

search_result DIPENTRY DIPImpLineCue( imp_image_handle *ii, imp_mod_handle im,
                        cue_file_id file, unsigned long line, unsigned col,
                        imp_cue_handle *ic )
{
    struct search_info  close;
    unsigned            save_entry;
    void                *base;

    col = col;
    if( file == 0 ) file = 1;
    close.ic.im = im;
    close.have = SR_NONE;
    close.num = 0;
    close.ic.entry = 0;
    close.special_table = FindSpecCueTable( ii, im, &base );
    for( ;; ) {
        if( GetLineInfo( ii, im, close.ic.entry ) != DS_OK ) break;
        ScanSection( &close, file, line );
        if( close.found ) save_entry = close.ic.entry;
        if( close.have == SR_EXACT ) break;
        ++close.ic.entry;
    }
    *ic = close.ic;
    ic->entry = save_entry;
    UnlockLine();
    if( base != NULL ) InfoSpecUnlock( base );
    return( close.have );
}

unsigned long DIPENTRY DIPImpCueLine( imp_image_handle *ii, imp_cue_handle *ic )
{
    line_info   *info;
    unsigned    num;

    LinStart = NULL;
    num = 0;
    if( ic->entry != NO_LINE && GetLineInfo( ii, ic->im, ic->entry ) == DS_OK ) {
        info = UNBIAS( ic->info_bias );
        num = info->line_number;
        UnlockLine();
        if( num >= PRIMARY_RANGE ) {
            return( SpecCueLine( ii, ic, num ) );
        }
    }
    return( num );
}

unsigned DIPENTRY DIPImpCueColumn( imp_image_handle *ii, imp_cue_handle *ic )
{
    ii = ii; ic = ic;
    return( 0 );
}

address DIPENTRY DIPImpCueAddr( imp_image_handle *ii, imp_cue_handle *ic )
{
    address             addr;
    line_info           *info;
    line_segment        *seg;

    LinStart = NULL;
    addr = NilAddr;
    if( ic->entry != NO_LINE && GetLineInfo( ii, ic->im, ic->entry ) == DS_OK ) {
        seg = UNBIAS( ic->seg_bias );
        addr = FindSegBlock( ii, ic->im, LINE_SEG( seg ) ).start;
        info = UNBIAS( ic->info_bias );
        addr.mach.offset += info->code_offset;
        UnlockLine();
    }
    return( addr );
}


walk_result DIPENTRY DIPImpWalkFileList( imp_image_handle *ii, imp_mod_handle im,
            IMP_CUE_WKR *wk, imp_cue_handle *ic, void *d )
{
    line_info           *curr;
    line_segment        *ptr;
    void                *next;
    walk_result         wr;

    //NYI: handle special cues
    ic->im = im;
    ic->entry = 0;
    for( ;; ) {
        if( GetLineInfo( ii, im, ic->entry ) != DS_OK ) break;
        for( ptr = LinStart; ptr < LinEnd; ptr = next ) {
            next = NEXT_SEG( ptr );
            ic->seg_bias = BIAS( ptr );
            for( curr = LINE_LINE( ptr ); curr < next; ++curr ) {
                ic->info_bias = BIAS( curr );
                if( curr->line_number < PRIMARY_RANGE ) {
                    wr = wk( ii, ic, d );
                    UnlockLine();
                    return( wr );
                }
            }
        }
        UnlockLine();
        ++ic->entry;
    }
    if( ic->entry == 0 ) {
        /* Module with no line cues. Fake one up. */
        ic->entry = NO_LINE;
        return( wk( ii, ic, d ) );
    }
    return( WR_CONTINUE );
}

imp_mod_handle DIPENTRY DIPImpCueMod( imp_image_handle *ii, imp_cue_handle *ic )
{
    ii = ii;
    return( ic->im );
}

cue_file_id DIPENTRY DIPImpCueFileId( imp_image_handle *ii, imp_cue_handle *ic )
{
    line_info   *info;
    unsigned    num;

    LinStart = NULL;
    if( ic->entry != NO_LINE && GetLineInfo( ii, ic->im, ic->entry ) == DS_OK ) {
        info = UNBIAS( ic->info_bias );
        num = info->line_number;
        UnlockLine();
        if( num >= PRIMARY_RANGE ) {
            return( SpecCueFileId( ii, ic, num ) );
        }
    }
    return( 1 );
}

unsigned DIPENTRY DIPImpCueFile( imp_image_handle *ii, imp_cue_handle *ic,
                        char *buff, unsigned max )
{
    cue_file_id         id;

    id = ImpInterface.cue_fyle_id( ii, ic );
    switch( id ) {
    case 0:
        return( 0 );
    case 1:
        return( PrimaryCueFile( ii, ic, buff, max ) );
    default:
        return( SpecCueFile( ii, ic, id, buff, max ) );
    }
}


static dip_status AdjForward( imp_image_handle *ii, imp_cue_handle *ic )
{
    line_info           *info;
    line_segment        *seg;
    unsigned            num_entries;
    dip_status          status;

    status = DS_OK;
    num_entries = ModPointer( ii, ic->im )->di[DMND_LINES].u.entries;
    for( ;; ) {
        status = GetLineInfo( ii, ic->im, ic->entry );
        if( status != DS_OK ) return( status );
        seg = UNBIAS( ic->seg_bias );
        info = UNBIAS( ic->info_bias );
        ++info;
        for( ;; ) {
            if( (void *)info < NEXT_SEG( seg ) ) {
                ic->seg_bias = BIAS( seg );
                ic->info_bias = BIAS( info );
                UnlockLine();
                return( DS_OK );
            }
            seg = NEXT_SEG( seg );
            if( seg >= LinEnd ) break;
            info = LINE_LINE( seg );
        }
        ic->entry++;
        if( ic->entry >= num_entries ) {
            ic->entry = 0;
            ic->seg_bias = BIAS( LinStart );
            info = LINE_LINE( (line_segment *)LinStart );
            ic->info_bias = BIAS( info );
            UnlockLine();
            return( DS_WRAPPED );
        }
        ic->seg_bias = BIAS( seg );
        ic->info_bias = BIAS( info );
    }
}

static line_segment *FindPrevSeg( line_segment *seg )
{
    line_segment        *curr;
    line_segment        *next;

    curr = LinStart;
    for( ;; ) {
        next = NEXT_SEG( curr );
        if( next >= seg ) return( curr );
        curr = next;
    }
}

static dip_status AdjBackward( imp_image_handle *ii, imp_cue_handle *ic )
{
    line_info           *info;
    line_segment        *seg;
    unsigned            num_entries;
    dip_status          status;

    LinStart = NULL;
    for( ;; ) {
        status = GetLineInfo( ii, ic->im, ic->entry );
        if( status != DS_OK ) return( status );
        seg = UNBIAS( ic->seg_bias );
        info = UNBIAS( ic->info_bias );
        --info;
        for( ;; ) {
            if( info >= LINE_LINE( seg ) ) {
                ic->seg_bias = BIAS( seg );
                ic->info_bias = BIAS( info );
                UnlockLine();
                return( DS_OK );
            }
            if( seg == LinStart ) break;
            seg = FindPrevSeg( seg );
            info = &LINE_LINE( seg )[ LINE_NUM( seg ) - 1 ];
        }
        if( ic->entry == 0 ) {
            num_entries = ModPointer( ii, ic->im )->di[DMND_LINES].u.entries;
            ic->entry = num_entries - 1;
            status = GetLineInfo( ii, ic->im, ic->entry );
            if( status != DS_OK ) return( status );
            seg = FindPrevSeg( seg );
            info = &LINE_LINE( seg )[ LINE_NUM( seg ) - 1 ];
            ic->seg_bias = BIAS( seg );
            ic->info_bias = BIAS( info );
            UnlockLine();
            return( DS_WRAPPED );
        }
        ic->entry--;
        if( ic->entry == 0 ) {
            /* special handling since we're walking backwards */
            UnlockLine();
        }
        ic->seg_bias = BIAS( seg );
        ic->info_bias = BIAS( info );
    }
}

dip_status DIPENTRY DIPImpCueAdjust( imp_image_handle *ii, imp_cue_handle *ic,
                        int adj, imp_cue_handle *aic )
{
    dip_status  status;
    dip_status  ok;

    if( ic->entry == NO_LINE ) return( DS_BAD_PARM );
    //NYI: handle special cues
    *aic = *ic;
    ok = DS_OK;
    while( adj > 0 ) {
        status = AdjForward( ii, aic );
        if( status & DS_ERR ) return( status );
        if( status != DS_OK ) ok = status;
        --adj;
    }
    while( adj < 0 ) {
        status = AdjBackward( ii, aic );
        if( status & DS_ERR ) return( status );
        if( status != DS_OK ) ok = status;
        ++adj;
    }
    return( ok );
}

int DIPENTRY DIPImpCueCmp( imp_image_handle *ii, imp_cue_handle *ic1,
                                imp_cue_handle *ic2 )
{
    ii = ii;
    if( ic1->im != ic2->im ) return( ic1->im - ic2->im );
    if( ic1->entry != ic2->entry ) return( ic1->entry - ic2->entry );
    return( ic1->info_bias - ic2->info_bias );
}

⌨️ 快捷键说明

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