direct.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,214 行 · 第 1/5 页
C
2,214 行
one word */
{
char *ptrhead;
char *ptrend;
/* strip the space in the front */
for( ptrhead = *token; ; ptrhead++ ) {
if( ( *ptrhead != ' ' ) && ( *ptrhead != '\t' ) ) {
break;
}
}
/* Then search for the first ending space */
ptrend = strchr( ptrhead, ' ' );
if( ptrend == NULL ) {
ptrend = strchr( ptrhead, '\t' );
}
if( ptrend == NULL ) {
ptrend = strchr( ptrhead, '\n' );
}
/* Check if there is any letters following that ending space */
if( ptrend != NULL ) {
*ptrend = '\0';
ptrend++;
while( *ptrend != '\0' ) {
if( ( *ptrend != ' ' ) && ( *ptrend != '\t' ) && ( *ptrend != '\n' ) ) {
return( ERROR );
}
ptrend++;
}
}
*token = ptrhead;
return( NOT_ERROR );
}
uint GetExtIdx( struct asm_sym *sym )
/***********************************/
{
dir_node *dir;
dir = (dir_node *)sym;
/**/myassert( dir != NULL );
return( dir->e.extinfo->idx );
}
uint_32 GetCurrAddr( void )
/*************************/
{
if( CurrSeg == NULL )
return( 0 );
return( CurrSeg->seg->e.seginfo->current_loc );
}
dir_node *GetCurrSeg( void )
/**************************/
{
if( CurrSeg == NULL )
return( 0 );
return( CurrSeg->seg );
}
uint_32 GetCurrSegAlign( void )
/*****************************/
{
if( CurrSeg == NULL )
return( 0 );
switch( CurrSeg->seg->e.seginfo->segrec->d.segdef.align ) {
case ALIGN_ABS: // same as byte aligned ?
case ALIGN_BYTE:
return( 1 );
case ALIGN_WORD:
return( 2 );
case ALIGN_DWORD:
return( 4 );
case ALIGN_PARA:
return( 16 );
case ALIGN_PAGE:
return( 256 );
case ALIGN_4KPAGE:
return( 4096 );
default:
return( 0 );
}
}
uint_32 GetCurrSegStart( void )
/*****************************/
{
if( CurrSeg == NULL )
return( 0 );
/**/myassert( !write_to_file
|| ( CurrSeg->seg->e.seginfo->current_loc - BufSize )
== CurrSeg->seg->e.seginfo->start_loc );
return( CurrSeg->seg->e.seginfo->start_loc );
}
static int GetLangType( int i )
/*****************************/
{
if( AsmBuffer[i]->token != T_RES_ID)
return( LANG_NONE );
switch( AsmBuffer[i]->value ) {
case T_C:
return( LANG_C );
case T_BASIC:
return( LANG_BASIC );
case T_FORTRAN:
return( LANG_FORTRAN );
case T_PASCAL:
return( LANG_PASCAL );
case T_WATCOM_C:
return( LANG_WATCOM_C );
case T_STDCALL:
return( LANG_STDCALL );
case T_SYSCALL:
return( LANG_SYSCALL );
default:
return( LANG_NONE );
}
}
int GlobalDef( int i )
/********************/
{
char *token;
char *mangle_type = NULL;
char *typetoken;
int type;
struct asm_sym *sym;
dir_node *dir;
int lang_type;
mangle_type = Check4Mangler( &i );
for( ; i < Token_Count; i++ ) {
lang_type = GetLangType( i );
if( lang_type != LANG_NONE )
i++;
/* get the symbol name */
token = AsmBuffer[i++]->string_ptr;
/* go past the colon */
if( AsmBuffer[i]->token != T_COLON ) {
AsmError( COLON_EXPECTED );
return( ERROR );
}
i++;
typetoken = AsmBuffer[i]->string_ptr;
type = token_cmp( &typetoken, TOK_EXT_NEAR, TOK_EXT_ABS );
if( type == ERROR ) {
AsmError( INVALID_QUALIFIED_TYPE );
return( ERROR );
}
for( ; i< Token_Count && AsmBuffer[i]->token != T_COMMA; i++ ) ;
sym = AsmGetSymbol( token );
if( ( sym != NULL ) && ( sym->state != SYM_UNDEFINED ) ) {
return( PubDef( 0 ) ); // it is defined here, so make a pubdef
}
if( sym == NULL ) {
dir = dir_insert( token, TAB_GLOBAL );
sym = &dir->sym;
} else {
dir = (dir_node *)sym;
}
if( dir == NULL )
return( ERROR );
GetSymInfo( sym );
sym->offset = 0;
sym->state = SYM_UNDEFINED;
// FIXME !! symbol can have different type
sym->mem_type = TypeInfo[type].value;
// FIXME !! symbol can have different language type
SetMangler( sym, mangle_type, lang_type );
/* put the symbol in the globaldef table */
AddGlobalData( dir );
}
return( NOT_ERROR );
}
asm_sym *MakeExtern( char *name, memtype mem_type, bool already_defd )
/********************************************************************/
{
dir_node *ext;
struct asm_sym *sym;
sym = AsmGetSymbol( name );
if( ( sym != NULL ) && already_defd ) {
ext = (dir_node *)sym;
dir_change( ext, TAB_EXT );
} else {
ext = dir_insert( name, TAB_EXT );
if( ext == NULL ) {
return( NULL );
}
sym = &ext->sym;
}
GetSymInfo( sym );
sym->offset = 0;
sym->mem_type = mem_type;
return( sym );
}
int ExtDef( int i )
/*****************/
{
char *token;
char *mangle_type = NULL;
char *typetoken;
int type;
memtype mem_type;
struct asm_sym *sym;
int lang_type;
mangle_type = Check4Mangler( &i );
for( ; i < Token_Count; i++ ) {
lang_type = GetLangType( i );
if( lang_type != LANG_NONE )
i++;
/* get the symbol name */
token = AsmBuffer[i++]->string_ptr;
/* go past the colon */
if( AsmBuffer[i]->token != T_COLON ) {
AsmError( COLON_EXPECTED );
return( ERROR );
}
i++;
typetoken = AsmBuffer[i]->string_ptr;
type = token_cmp( &typetoken, TOK_EXT_NEAR, TOK_EXT_ABS );
if( type == ERROR ) {
if( !IsLabelStruct( AsmBuffer[i]->string_ptr ) ) {
AsmError( INVALID_QUALIFIED_TYPE );
return( ERROR );
}
mem_type = MT_STRUCT;
} else {
mem_type = TypeInfo[type].value;
}
for( ; i< Token_Count && AsmBuffer[i]->token != T_COMMA; i++ );
sym = AsmGetSymbol( token );
if( sym != NULL ) {
if( sym->state == SYM_UNDEFINED ) {
if( MakeExtern( token, mem_type, TRUE ) == NULL ) {
return( ERROR );
}
} else if( sym->mem_type != mem_type ) {
AsmError( EXT_DEF_DIFF );
return( ERROR );
}
} else {
sym = MakeExtern( token, mem_type, FALSE );
if( sym == NULL ) {
return( ERROR );
}
}
SetMangler( sym, mangle_type, lang_type );
}
return( NOT_ERROR );
}
static char *Check4Mangler( int *i )
/**********************************/
{
char *mangle_type = NULL;
if( AsmBuffer[*i]->token == T_STRING ) {
mangle_type = AsmBuffer[*i]->string_ptr;
(*i)++;
if( AsmBuffer[*i]->token != T_COMMA ) {
AsmWarn( 2, EXPECTING_COMMA );
} else {
(*i)++;
}
}
return( mangle_type );
}
int PubDef( int i )
/*****************/
{
char *mangle_type = NULL;
char *token;
struct asm_sym *sym;
dir_node *node;
int lang_type;
mangle_type = Check4Mangler( &i );
for( ; i < Token_Count; i+=2 ) {
lang_type = GetLangType( i );
if( lang_type != LANG_NONE )
i++;
token = AsmBuffer[i]->string_ptr;
/* Add the public name */
if( checkword( &token ) == ERROR ) {
AsmError( EXPECTING_COMMA );
return( ERROR );
}
sym = AsmGetSymbol( token );
if( sym != NULL ) {
node = (dir_node *)sym;
if( sym->state == SYM_CONST ) {
/* check if the symbol expands to another symbol,
* and if so, expand it */
if( node->e.constinfo->data[0].token == T_ID ) {
ExpandTheWorld( i, FALSE, TRUE );
return( PubDef( i ) );
}
}
/* make the existing symbol public */
switch( sym->state ) {
case SYM_UNDEFINED:
case SYM_INTERNAL:
case SYM_EXTERNAL:
case SYM_STACK:
case SYM_CONST:
break;
case SYM_PROC:
if( node->e.procinfo->visibility != VIS_EXPORT ) {
node->e.procinfo->visibility = VIS_PUBLIC;
}
default:
break;
}
} else {
node = dir_insert( token, TAB_PUB );
AddPublicData( node );
sym = &node->sym;
}
SetMangler( sym, mangle_type, lang_type );
if( !sym->public ) {
/* put it into the pub table */
sym->public = TRUE;
AddPublicData( node );
}
}
return( NOT_ERROR );
}
static dir_node *CreateGroup( char *name )
/****************************************/
{
dir_node *grp;
grp = (dir_node *)AsmGetSymbol( name );
if( grp == NULL ) {
grp = dir_insert( name, TAB_GRP );
LnameInsert( name );
} else if( grp->sym.state == SYM_UNDEFINED ) {
dir_change( grp, TAB_GRP );
LnameInsert( name );
} else if( grp->sym.state != SYM_GRP ) {
AsmErr( SYMBOL_PREVIOUSLY_DEFINED, name );
grp = NULL;
}
return( grp );
}
int GrpDef( int i )
/*****************/
{
char *name;
dir_node *grp;
seg_list *new;
seg_list *curr;
dir_node *seg;
if( i < 0 ) {
AsmError( GRP_NAME_MISSING );
return( ERROR );
}
name = AsmBuffer[i]->string_ptr;
grp = CreateGroup( name );
if( grp == NULL )
return( ERROR );
for( i+=2; // skip over the GROUP directive
i < Token_Count; // stop at the end of the line
i+=2 ) { // skip over commas
name = AsmBuffer[i]->string_ptr;
/* Add the segment name */
if( checkword( &name ) == ERROR ) {
AsmError( EXPECTING_COMMA );
return( ERROR );
}
seg = (dir_node *)AsmGetSymbol( name );
if( seg == NULL ) {
seg = dir_insert( name, TAB_SEG );
} else if( seg->sym.state == SYM_UNDEFINED ) {
dir_change( seg, TAB_SEG );
} else if( seg->sym.state != SYM_SEG ) {
AsmErr( SYMBOL_PREVIOUSLY_DEFINED, name );
return( ERROR );
}
if( seg->e.seginfo->group == &grp->sym ) // segment is in group already
continue;
if( seg->e.seginfo->group != NULL ) { // segment is in another group
AsmError( SEGMENT_IN_GROUP );
return( ERROR );
}
/* set the grp index of the segment */
seg->e.seginfo->group = &grp->sym;
new = AsmAlloc( sizeof(seg_list) );
new->seg = seg;
new->next = NULL;
grp->e.grpinfo->numseg++;
/* insert the segment at the end of linked list */
if( grp->e.grpinfo->seglist == NULL ) {
grp->e.grpinfo->seglist = new;
} else {
curr = grp->e.grpinfo->seglist;
while( curr->next != NULL ) {
curr = curr->next;
}
curr->next = new;
}
}
return( NOT_ERROR );
}
static int SetUse32( void )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?