linkutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 617 行 · 第 1/2 页
C
617 行
/*********************************/
/* Free a list of nodes. */
{
node *curr = _curr;
node *next_node;
while( curr ) {
next_node = curr->next;
_LnkFree( curr );
curr = next_node;
}
}
extern name_list * AddNameTable( char *name, unsigned len, bool is_mod,
name_list **owner )
/*************************************************************************/
{
name_list * imp;
unsigned_32 off;
unsigned_16 index;
index = 1;
off = 1;
for( ;; ) {
imp = *owner;
if( imp == NULL ) {
_PermAlloc( imp, sizeof( name_list ) );
imp->next = NULL;
imp->len = len;
ReserveStringTable( &PermStrings, len + 1 );
imp->name = AddStringTable( &PermStrings, name, len );
CharStringTable( &PermStrings, '\0' );
imp->num = is_mod ? index : off;
*owner = imp;
break;
}
if( len == imp->len && memcmp( imp->name, name, len ) == 0 )
break;
off += imp->len + 1;
owner = &imp->next;
++index;
}
return( imp );
}
extern unsigned_16 binary_log( unsigned_16 value )
/************************************************/
// This calculates the binary log of value, truncating decimals.
{
unsigned_16 log;
if( value == 0 ) {
return( 0 );
}
log = 15;
for( ; ; ) {
if( value & 0x8000 ) { // done if high bit on
break;
}
value <<= 1; // shift left and decrease possible log.
log--;
}
return( log );
}
extern unsigned_16 blog_32( unsigned_32 value )
/*********************************************/
// This calculates the binary log of a 32-bit value, truncating decimals.
{
unsigned_16 log;
if( value == 0 ) {
return( 0 );
}
log = 31;
for( ; ; ) {
if( value & 0x80000000 ) { // done if high bit on
break;
}
value <<= 1; // shift left and decrease possible log.
log--;
}
return( log );
}
extern char * RemovePath( char *name, int *len )
/**********************************************/
/* parse name as a filename, "removing" the path and the extension */
/* returns a pointer to the "base" of the filename, and a length without
* the extension */
{
char * dotpoint;
char * namestart;
char * string;
char ch;
dotpoint = NULL;
string = namestart = name;
while( *string != '\0' ) { // ignore path & extension in module name.
ch = *string;
if( ch == '.' ) {
dotpoint = string;
}
if( IS_PATH_SEP( ch ) ) {
namestart = string + 1;
dotpoint = NULL;
}
string++;
}
if( dotpoint != NULL ) {
*len = dotpoint - namestart;
} else {
*len = string - namestart;
}
return( namestart );
}
#define MAXDEPTH ( sizeof( unsigned ) * 8 )
extern void VMemQSort( virt_mem base, unsigned n, unsigned width,
void (*swapfn)( virt_mem, virt_mem ),
int (*cmpfn)( virt_mem, virt_mem ) )
/***************************************************************/
// qsort stolen from clib, and suitably modified since we need to be able
// to swap parallel arrays.
{
virt_mem p1;
virt_mem p2;
virt_mem mid;
int comparison;
int last_non_equal_count;
unsigned i;
unsigned count;
unsigned sp;
auto virt_mem base_stack[MAXDEPTH];
auto unsigned n_stack[MAXDEPTH];
sp = 0;
for( ; ; ) {
while( n > 1 ) {
p1 = base + width;
if( n == 2 ) {
if( cmpfn( base, p1 ) > 0 ) {
swapfn( base, p1 );
}
break;
} else {
/* store mid element at base for pivot */
/* this will speed up sorting of a sorted list */
mid = base + ( n >> 1 ) * width;
swapfn( base, mid );
p2 = base;
count = 0;
last_non_equal_count = 0;
for( i = 1; i < n; ++i ) {
comparison = cmpfn( p1, base );
if( comparison <= 0 ) {
p2 += width;
count++;
if( i != count ) { /* p1 != p2 */
swapfn( p1, p2 );
}
}
if( comparison != 0 )
last_non_equal_count = count;
p1 += width;
}
/* special check to see if all values compared are equal */
if( ( count == n-1 ) && ( last_non_equal_count == 0 ) )
break;
if( count != 0 ) { /* store pivot in right spot */
swapfn( base, p2 );
}
#if 0
qsort( base, count, size, cmp );
qsort( p2 + size, n - count - 1, size, cmp );
#endif
n = n - count - 1; /* calc. size of right part */
/* The pivot is at p2. It is in its final position.
There are count items to the left of the pivot.
There are n items to the right of the pivot.
*/
if( count != last_non_equal_count ) { /* 18-jul-90 */
/*
There are last_non_equal_count+1 items to the left
of the pivot that still need to be checked.
There are (count - (last_non_equal_count+1)) items
immediately to the left of the pivot that are
equal to the pivot. They are in their final position.
*/
count = last_non_equal_count + 1;
}
if( count < n ) { /* if left part is shorter */
base_stack[sp] = p2 + width; /* - stack right part */
n_stack[sp] = n;
n = count;
} else { /* right part is shorter */
base_stack[sp] = base; /* - stack left part */
n_stack[sp] = count;
base = p2 + width;
}
++sp;
}
}
if( sp == 0 )
break;
--sp;
base = base_stack[sp];
n = n_stack[sp];
}
}
static void *SpawnStack;
extern int Spawn( void (*fn)() )
/******************************/
{
void * save_env;
jmp_buf env;
int status;
save_env = SpawnStack;
SpawnStack = env;
status = setjmp( env );
if( status == 0 ) {
(*fn)();
}
SpawnStack = save_env; /* unwind */
return( status );
}
extern void Suicide( void )
/*************************/
{
if( SpawnStack != NULL ) {
longjmp( SpawnStack, 1 );
}
}
extern f_handle SearchPath( char *name )
/**************************************/
{
char * path;
f_handle file;
char fullpath[PATH_MAX];
file = QObjOpen( name );
if( file != NIL_HANDLE ) {
return( file );
}
#if defined( __QNX__ )
path = "/usr/watcom";
#else
path = GetEnvString( "PATH" );
#endif
if( path != NULL ) {
while( QMakeFileName( &path, name, fullpath ) ) {
file = QObjOpen( fullpath );
if( file != NIL_HANDLE ) {
return( file );
}
}
}
return( NIL_HANDLE );
}
extern group_entry *FindGroup( segment seg )
/******************************************/
{
group_entry *group;
group = Groups;
for( ;; ) {
if( group == NULL )
break;
if( group->grp_addr.seg == seg )
break;
group = group->next_group;
}
return( group );
}
extern offset FindLinearAddr( targ_addr *addr )
/*********************************************/
{
group_entry *group;
group = FindGroup( addr->seg );
if( group != NULL ) {
return( addr->off + ( group->linear - group->grp_addr.off ) );
}
return( addr->off );
}
extern offset FindLinearAddr2( targ_addr *addr )
/*********************************************/
{
group_entry *group;
group = FindGroup( addr->seg );
if( group != NULL ) {
return( addr->off + group->linear + FmtData.base );
}
return( addr->off );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?