dfline.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 537 行 · 第 1/2 页
C
537 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdlib.h>
#include "dfdip.h"
#include "dfline.h"
typedef struct {
dword offset;
dword line;
unsigned_16 fno;
}cue_info;
enum {
CUES_PER_BLK = 256,
};
typedef struct cue_blk{
struct cue_blk *next;
cue_info info[CUES_PER_BLK]; /*variable*/
}cue_blk;
struct seg_cue{
struct seg_cue *next;
addr_seg seg;
dword low;
dword high;
unsigned_16 count; /*#entries collected by head */
cue_blk *head; /* list of cues */
};
extern void InitCueList( cue_list *ctl ){
/*********************************/
ctl->head = NULL;
}
extern seg_cue *InitSegCue( cue_list *ctl, addr_seg seg, dword offset ){
/************************************************************************/
/* Keep in asending order seg:offset */
seg_cue *curr;
seg_cue **lnk;
lnk = &ctl->head;
while( (curr = *lnk) != NULL ){
if( seg < curr->seg )break;
if( seg == curr->seg && offset < curr->low )break;
lnk = &curr->next;
}
curr = DCAlloc( sizeof( *curr ) );
curr->seg = seg;
curr->low = offset;
curr->high = offset;
curr->count = 0;
curr->head = NULL;
curr->next = *lnk;
*lnk = curr;
return( curr );
}
extern void AddCue( seg_cue *ctl, dr_line_data *new ){
/************************************************************/
// Add a new offset to the last block if full alloc a new one
// bump the item count
cue_blk *blk, **lnk;
cue_info *next;
unsigned_16 rem; /*#entries in last blk */
rem = ctl->count % CUES_PER_BLK;
blk = ctl->head;
if( blk != NULL ){
while( blk->next != NULL ){
blk = blk->next;
}
lnk = &blk->next;
}else{
lnk = &ctl->head;
}
if( rem == 0 ){
blk = DCAlloc( sizeof( *blk ) );
blk->next = NULL;
*lnk = blk;
}
next = &blk->info[rem];
next->offset = new->offset;
next->line = new->line;
next->fno = new->file;
if( new->offset > ctl->high ){
ctl->high = new->offset;
}
++ctl->count;
}
typedef struct{
unsigned_16 hi;
cue_info *base;
addr_off key;
unsigned_16 last;
}off_cmp;
static long BlkOffSearch( off_cmp *cmp ){
/****************************************/
// Do a B-search on the blk
cue_info *curr;
cue_info *base;
addr_off key;
unsigned_16 lo;
unsigned_16 mid;
unsigned_16 hi;
long diff;
key = cmp->key;
base = cmp->base;
hi = cmp->hi;
lo = 0;
for(;;){
mid = (lo + hi)/2;
curr = &base[mid];
diff = (long)key - (long)curr->offset;
if( mid == lo ){ /* fix up last cmp */
break;
}
if( diff < 0 ){ // key < mid
hi = mid;
}else{ // key > mid
lo = mid;
}
}
cmp->last = mid;
cmp->base = curr;
return( diff );
}
static seg_cue *FindSegCue( cue_list *list, addr_ptr *mach ){
/************************************************************/
seg_cue *ctl;
seg_cue *last;
last = NULL;
ctl = list->head;
while( ctl != NULL ){
if( mach->segment == ctl->seg ){
if( mach->offset < ctl->low )break;
last = ctl;
}
ctl = ctl->next;
}
return( last );
}
extern int FindCueOffset( cue_list *list, addr_ptr *mach, cue_item *ret ){
/****************************************************/
cue_blk *blk;
cue_info *info;
off_cmp cmp;
unsigned_16 rem;
seg_cue *ctl;
long diff;
dword next_off;
info = NULL;
ctl = FindSegCue( list, mach );
if( ctl != NULL ){
rem = CUES_PER_BLK;
blk = ctl->head;
while( blk != NULL ){
if( blk->next == NULL ){ /* last blk */
rem = ctl->count % CUES_PER_BLK;
if( rem == 0 ){
rem = CUES_PER_BLK; /* never have empty blocks */
}
}
info = &blk->info[rem-1];
cmp.last = rem-1;
cmp.hi = rem;
if( info->offset >= mach->offset ){
cmp.key = mach->offset;
cmp.base = &blk->info[0];
diff = BlkOffSearch( &cmp );
if( diff >= 0 ){
info = cmp.base;
break;
}else{
//shouldn't happen an error
return( FALSE );
}
}
blk = blk->next;
}
ret->fno = info->fno;
ret->line = info->line;
ret->mach.offset = info->offset;
ret->mach.segment = ctl->seg;
ret->col = 0;
if( cmp.last+1 < cmp.hi ){
++info;
next_off = info->offset;
}else{
if( blk != NULL ){
blk = blk->next;
}
if( blk == NULL ){
next_off = 0xffffffff; /* high value */
if( (ctl = ctl->next ) != NULL ){
if( ctl->seg == ret->mach.segment ){
next_off = ctl->low;
}
}
}else{
next_off= blk->info[0].offset;
}
}
ret->next_offset = next_off;
return( TRUE );
}
return( FALSE );
}
typedef enum{
ST_START_LOW, // look for next lower than cue
ST_START_HIGH, // look for next higher than cue
ST_START_CLOSEST, // look for lower or equal to cue
ST_START_FILE, // look for any cue with file
ST_WRAP_LOW, // found wrapped past low
ST_WRAP_HIGH, // found wrapped past high
ST_SQUEEZE_LOW, // found next lower
ST_FOUND_CLOSEST, // found next lower
ST_SQUEEZE_HIGH, // found next higher
}line_state;
extern dfline_find FindCue( cue_list *list,
cue_item *item,
dfline_search what ){
/****************************************************/
cue_blk *blk;
cue_info *info;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?