dfline.c

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

C
537
字号
    unsigned_16     rem;
    unsigned_16     seg_last;
    cue_info       *info_last;
    seg_cue        *ctl;
    line_state      state;
    dfline_find     ret;

    switch( what ){ /* init state */
    case LOOK_LOW:
        state = ST_START_LOW;
        break;
    case LOOK_HIGH:
        state = ST_START_HIGH;
        break;
    case LOOK_CLOSEST:
        state = ST_START_CLOSEST;
        break;
    case LOOK_FILE:
        state = ST_START_FILE;
        break;
    }
    ctl = list->head;
    while( ctl != NULL ){
        blk = ctl->head;
        while( blk != NULL ){
            info =  &blk->info[0];
            if( blk->next == NULL ){ /* last blk */
                rem = ctl->count % CUES_PER_BLK;
                if( rem == 0 ){
                    rem = CUES_PER_BLK; /* never have empty blocks */
                }
            }else{
                rem = CUES_PER_BLK;
            }
            while( rem > 0 ){
                if( info->fno == item->fno ){
                    switch( state ){
                    case ST_START_FILE:
                        info_last = info;
                        seg_last = ctl->seg;
                        ret = LINE_FOUND;
                        goto found;
                    case ST_START_LOW:
                        info_last = info;
                        seg_last = ctl->seg;
                        if( item->line > info->line ){
                            state = ST_SQUEEZE_LOW;
                        }else{
                            state = ST_WRAP_LOW;
                        }
                        break;
                    case ST_START_HIGH:
                        info_last = info;
                        seg_last = ctl->seg;
                        if( item->line < info->line ){
                            state = ST_SQUEEZE_HIGH;
                        }else{
                            state = ST_WRAP_HIGH;
                        }
                        break;
                    case ST_WRAP_LOW:
                        if( item->line  > info->line ){
                            info_last = info;
                            seg_last = ctl->seg;
                            state = ST_SQUEEZE_LOW;
                        }else if( info_last->line < info->line ){
                            info_last = info;
                            seg_last = ctl->seg;
                        }
                        break;
                    case ST_WRAP_HIGH:
                        if( item->line < info->line ){
                            info_last = info;
                            seg_last = ctl->seg;
                            state = ST_SQUEEZE_HIGH;
                        }else if( info_last->line > info->line ){
                            info_last = info;
                            seg_last = ctl->seg;
                        }
                        break;
                    case ST_SQUEEZE_HIGH:
                        if( item->line < info->line ){
                            if( info_last->line > info->line ){
                                info_last = info;
                                seg_last = ctl->seg;
                            }
                        }
                        break;
                    case ST_START_CLOSEST:
                        if( item->line < info->line ){
                            break; //continue on
                        }
                        info_last = info;
                        seg_last = ctl->seg;
                        state = ST_FOUND_CLOSEST;
                        //drop through
                    case ST_FOUND_CLOSEST:
                        if( item->line == info->line ){
                            info_last = info;
                            seg_last = ctl->seg;
                            ret = LINE_FOUND;
                            goto found;
                        }// else drop through
                    case ST_SQUEEZE_LOW:
                        if( item->line > info->line ){
                            if( info_last->line < info->line ){
                                info_last = info;
                                seg_last = ctl->seg;
                            }
                        }
                        break;
                    }
                }
                ++info;
                --rem;
            }
            blk = blk->next;
        }
        ctl = ctl->next;
    }
    switch( state  ){
    case ST_START_LOW:
    case ST_START_HIGH:
    case ST_START_CLOSEST:
    case ST_START_FILE:
        ret = LINE_NOT;
        goto not_found;
        break;
    case ST_WRAP_LOW:
    case ST_WRAP_HIGH:
        ret = LINE_WRAPPED;
        break;
    case ST_SQUEEZE_LOW:
    case ST_SQUEEZE_HIGH:
        ret = LINE_FOUND;
        break;
    case ST_FOUND_CLOSEST:
        ret = LINE_CLOSEST;
        break;
    }
found:
    item->mach.offset = info_last->offset;
    item->mach.segment = seg_last;
    item->next_offset = 0;
    item->line = info_last->line;
//  item->col = info_last->col;
    item->fno = info_last->fno;
not_found:
    return( ret );
}

static void FreeSegCue(  seg_cue *curr ){
/***********************************************/
// Free all offset blocks for a segment
    cue_blk    *blk, *old;

    blk = curr->head;
    while( blk != NULL ){
        old = blk;
        blk = blk->next;
        DCFree( old );
    }
}

extern void  FiniCueInfo( cue_list *list ){
/*****************************************/
//Free all offset blocks for a line segment
//Free all line segments
    seg_cue   *ctl;
    seg_cue   *next;

    ctl = list->head;
    while( ctl != NULL ){
        next = ctl->next;
        FreeSegCue( ctl );
        DCFree( ctl );
        ctl = next;
    }
    list->head = NULL;
}
#ifdef DEBUG
#include <stdarg.h>
extern void myprintf( char *ctl, ... ){
/** my printf ************************/
    va_list argument;
    char buff[100];
    long val;
    char *curr;
    char form;

    curr = buff;
    va_start( argument, ctl );
    while( *ctl != '\0' ){
        if( *ctl == '%' ){
            ++ctl;
            if( *ctl == 'l' ){
                ++ctl;
                form = 'l';
            }else{
                form = ' ';
            }
            switch( *ctl ){
            case 'x':
                if( form == 'l' ){
                    val = va_arg( argument, long );
                }else{
                    val = va_arg( argument, int );
                }
                ultoa( val, curr, 16 );
                break;
            case 'd':
                if( form == 'l' ){
                    val = va_arg( argument, long );
                }else{
                    val = va_arg( argument, int );
                }
                ltoa( val, curr, 10 );
                break;
            default:
                curr[0] = '%';
                curr[1] = *ctl;
                curr[2] ='\0';
                break;
            }
            ++ctl;
            while( *curr != '\0' ) ++curr;
        }else{
            *curr = *ctl;
            ++curr;
            ++ctl;
        }
    }
    va_end( argument );
    DCWrite( 1, buff, curr-buff );

}

extern  void DmpCueOffset( cue_list *list ){
/****************************************************/
    cue_blk    *blk;
    cue_info   *info;
    unsigned_16 rem;
    seg_cue   *ctl;

    ctl = list->head;
    while( ctl != NULL ){
        myprintf( "seg %x:%x\n", ctl->seg, ctl->low );
        blk = ctl->head;
        while( blk != NULL ){
            info = &blk->info[0];
            if( blk->next == NULL ){ /* last blk */
                rem = ctl->count % CUES_PER_BLK;
                if( rem == 0 ){
                    rem = CUES_PER_BLK; /* never have empty blocks */
                }
            }
            while( rem > 0 ){
               myprintf( "    %lx f%d.%d\n", info->offset, info->fno, info->line );
                ++info;
                --rem;
            }
            blk = blk->next;
        }
        ctl = ctl->next;
    }
}
#endif

⌨️ 快捷键说明

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