direct.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,214 行 · 第 1/5 页
C
2,214 行
/*************************/
{
if( CurrSeg == NULL ) {
Use32 = ModuleInfo.defUse32;
} else {
Globals.code_seg = SEGISCODE( CurrSeg );
Use32 = CurrSeg->seg->e.seginfo->segrec->d.segdef.use_32;
if( Use32 && ( ( Code->info.cpu & P_CPU_MASK ) < P_386 ) ) {
AsmError( WRONG_CPU_FOR_32BIT_SEGMENT );
return( ERROR );
}
}
return( NOT_ERROR );
}
int SetUse32Def( bool flag )
/**************************/
{
if( ( CurrSeg == NULL ) // outside any segments
&& ( !ModuleInfo.init // model not defined
|| ModuleInfo.cmdline ) ) { // model defined on cmdline by -m?
ModuleInfo.defUse32 = flag;
}
return( SetUse32() );
}
int SetCurrSeg( int i )
/**********************/
{
char *name;
struct asm_sym *sym;
name = AsmBuffer[i]->string_ptr;
switch( AsmBuffer[i+1]->value ) {
case T_SEGMENT:
FlushCurrSeg();
sym = AsmGetSymbol( name );
/**/ myassert( sym != NULL );
push_seg( (dir_node *)sym );
break;
case T_ENDS:
FlushCurrSeg();
pop_seg();
break;
default:
break;
}
return( SetUse32() );
}
static int token_cmp( char **token, int start, int end )
/******************************************************/
/* compare token against those specified in TypeInfo[ start...end ] */
{
int i;
char *str;
char *tkn;
str = *token;
for( i = start; i <= end; i++ ) {
tkn = TypeInfo[i].string;
if( tkn == NULL )
continue;
if( stricmp( tkn, str ) == 0 ) {
// type is found
return( i );
}
}
return( ERROR ); // No type is found
}
static seg_type ClassNameType( char *name )
/*****************************************/
{
int slen;
char uname[257];
if( name == NULL )
return( SEGTYPE_UNDEF );
if( ModuleInfo.init ) {
if( stricmp( name, Options.code_class ) == 0 ) {
return( SEGTYPE_ISCODE );
}
}
slen = strlen( name );
strcpy( uname, name );
strupr( uname );
switch( slen ) {
default:
case 5:
// 'CONST'
if( memcmp( uname, "CONST", 6 ) == 0 )
return( SEGTYPE_ISDATA );
// 'STACK'
if( memcmp( uname, "STACK", 6 ) == 0 )
return( SEGTYPE_ISDATA );
// 'DBTYP'
if( memcmp( uname, "DBTYP", 6 ) == 0 )
return( SEGTYPE_ISDATA );
// 'DBSYM'
if( memcmp( uname, "DBSYM", 6 ) == 0 )
return( SEGTYPE_ISDATA );
case 4:
// 'CODE'
if( memcmp( uname , "CODE", 5 ) == 0 )
return( SEGTYPE_ISCODE );
// '...DATA'
if( memcmp( uname + slen - 4, "DATA", 4 ) == 0 )
return( SEGTYPE_ISDATA );
case 3:
// '...BSS'
if( memcmp( uname + slen - 3, "BSS", 3 ) == 0 )
return( SEGTYPE_ISDATA );
case 2:
case 1:
case 0:
return( SEGTYPE_UNDEF );
}
}
static seg_type SegmentNameType( char *name )
/*******************************************/
{
int slen;
char uname[257];
slen = strlen( name );
strcpy( uname, name );
strupr( uname );
switch( slen ) {
default:
case 5:
// '..._TEXT'
if( memcmp( uname + slen - 5, DEFAULT_CODE_NAME, 5 ) == 0 )
return( SEGTYPE_ISCODE );
// '..._DATA'
if( memcmp( uname + slen - 5, DEFAULT_DATA_NAME, 5 ) == 0 )
return( SEGTYPE_ISDATA );
// 'CONST'
if( memcmp( uname, "CONST", 5 ) == 0 )
return( SEGTYPE_ISDATA );
case 4:
// '..._BSS'
if( memcmp( uname + slen - 4, "_BSS", 4 ) == 0 )
return( SEGTYPE_ISDATA );
case 3:
case 2:
case 1:
case 0:
return( SEGTYPE_UNDEF );
}
}
int SegDef( int i )
/*****************/
{
char defined;
char *token;
obj_rec *seg;
obj_rec *oldobj;
direct_idx classidx;
uint type; // type of option
uint initstate = 0; // to show if a field is initialized
char oldreadonly; // readonly value of a defined segment
char oldiscode; // iscode value of a defined segment
bool ignore;
dir_node *dirnode;
char *name;
struct asm_sym *sym;
if( i < 0 ) {
AsmError( SEG_NAME_MISSING );
return( ERROR );
}
name = AsmBuffer[i]->string_ptr;
switch( AsmBuffer[i+1]->value ) {
case T_SEGMENT:
seg = ObjNewRec( CMD_SEGDEF );
/* Check to see if the segment is already defined */
sym = AsmGetSymbol( name );
if( sym != NULL ) {
dirnode = (dir_node *)sym;
if ( sym->state == SYM_SEG ) {
// segment already defined
defined = TRUE;
oldreadonly = dirnode->e.seginfo->readonly;
oldiscode = dirnode->e.seginfo->iscode;
ignore = dirnode->e.seginfo->ignore;
if( dirnode->e.seginfo->lname_idx == 0 ) {
// segment was mentioned in a group statement, but not really set up
defined = FALSE;
seg->d.segdef.idx = ++segdefidx;
}
} else {
// symbol is different kind, change to segment
dir_change( dirnode, TAB_SEG );
seg->d.segdef.idx = ++segdefidx;
defined = FALSE;
ignore = FALSE;
}
} else {
// segment is not defined
dirnode = dir_insert( name, TAB_SEG );
seg->d.segdef.idx = ++segdefidx;
defined = FALSE;
ignore = FALSE;
}
/* Setting up default values */
if( !defined ) {
seg->d.segdef.align = ALIGN_PARA;
seg->d.segdef.combine = COMB_INVALID;
seg->d.segdef.use_32 = ModuleInfo.defUse32;
seg->d.segdef.class_name_idx = 1;
/* null class name, in case none is mentioned */
dirnode->e.seginfo->readonly = FALSE;
dirnode->e.seginfo->iscode = SEGTYPE_UNDEF;
} else {
oldobj = dirnode->e.seginfo->segrec;
dirnode->e.seginfo->readonly = oldreadonly;
dirnode->e.seginfo->iscode = oldiscode;
seg->d.segdef.align = oldobj->d.segdef.align;
seg->d.segdef.combine = oldobj->d.segdef.combine;
if( !ignore ) {
seg->d.segdef.use_32 = oldobj->d.segdef.use_32;
} else {
seg->d.segdef.use_32 = ModuleInfo.defUse32;
}
seg->d.segdef.class_name_idx = oldobj->d.segdef.class_name_idx;
}
dirnode->e.seginfo->ignore = FALSE; // always false unless set explicitly
seg->d.segdef.access_valid = FALSE;
seg->d.segdef.seg_length = 0;
if( lastseg.stack_size > 0 ) {
seg->d.segdef.seg_length = lastseg.stack_size;
lastseg.stack_size = 0;
}
i+=2; /* go past segment name and "SEGMENT " */
for( ; i < Token_Count; i ++ ) {
if( AsmBuffer[i]->token == T_STRING ) {
/* the class name - the only token which is of type STRING */
token = AsmBuffer[i]->string_ptr;
classidx = FindLnameIdx( token );
if( classidx == LNAME_NULL ) {
classidx = InsertClassLname( token );
if( classidx == LNAME_NULL ) {
return( ERROR );
}
}
seg->d.segdef.class_name_idx = classidx;
continue;
}
/* go through all tokens EXCEPT the class name */
token = AsmBuffer[i]->string_ptr;
// look up the type of token
type = token_cmp( &token, TOK_READONLY, TOK_AT );
if( type == ERROR ) {
AsmError( UNDEFINED_SEGMENT_OPTION );
return( ERROR );
}
/* initstate is used to check if any field is already
initialized */
if( initstate & TypeInfo[type].init ) {
AsmError( SEGMENT_PARA_DEFINED ); // initialized already
return( ERROR );
} else {
initstate |= TypeInfo[type].init; // mark it initialized
}
switch( type ) {
case TOK_READONLY:
dirnode->e.seginfo->readonly = TRUE;
break;
case TOK_BYTE:
case TOK_WORD:
case TOK_DWORD:
case TOK_PARA:
case TOK_PAGE:
seg->d.segdef.align = TypeInfo[type].value;
break;
case TOK_PRIVATE:
case TOK_PUBLIC:
case TOK_STACK:
case TOK_COMMON:
case TOK_MEMORY:
seg->d.segdef.combine = TypeInfo[type].value;
break;
case TOK_USE16:
case TOK_USE32:
seg->d.segdef.use_32 = TypeInfo[type].value;
break;
case TOK_IGNORE:
dirnode->e.seginfo->ignore = TRUE;
break;
case TOK_AT:
seg->d.segdef.align = SEGDEF_ALIGN_ABS;
ExpandTheWorld( i + 1, FALSE, TRUE);
if( AsmBuffer[i+1]->token == T_NUM ) {
i++;
seg->d.segdef.abs.frame = AsmBuffer[i]->value;
seg->d.segdef.abs.offset = 0;
} else {
AsmError( UNDEFINED_SEGMENT_OPTION );
return( ERROR );
}
break;
default:
AsmError( UNDEFINED_SEGMENT_OPTION );
return( ERROR );
}
}
token = GetLname( seg->d.segdef.class_name_idx );
if( dirnode->e.seginfo->iscode != SEGTYPE_ISCODE ) {
seg_type res;
res = ClassNameType( token );
if( res != SEGTYPE_UNDEF ) {
dirnode->e.seginfo->iscode = res;
} else {
res = SegmentNameType( name );
dirnode->e.seginfo->iscode = res;
}
}
if( defined && !ignore && !dirnode->e.seginfo->ignore ) {
/* Check if new definition is different from previous one */
oldobj = dirnode->e.seginfo->segrec;
if( ( oldreadonly != dirnode->e.seginfo->readonly )
|| ( oldobj->d.segdef.align != seg->d.segdef.align )
|| ( oldobj->d.segdef.combine != seg->d.segdef.combine )
|| ( oldobj->d.segdef.use_32 != seg->d.segdef.use_32 )
|| ( oldobj->d.segdef.class_name_idx != seg->d.segdef.class_name_idx ) ) {
ObjKillRec( seg );
AsmError( SEGDEF_CHANGED );
return( ERROR );
} else {
// definition is the same as before
ObjKillRec( seg );
if( push_seg( dirnode ) == ERROR ) {
return( ERROR );
}
}
} else if( defined && ignore ) {
/* reset to the new values */
oldobj = dirnode->e.seginfo->segrec;
oldobj->d.segdef.align = seg->d.segdef.align;
oldobj->d.segdef.combine = seg->d.segdef.combine;
oldobj->d.segdef.use_32 = seg->d.segdef.use_32;
oldobj->d.segdef.class_name_idx = seg->d.segdef.class_name_idx;
ObjKillRec( seg );
if( push_seg( dirnode ) == ERROR ) {
return( ERROR );
}
} else if( defined && dirnode->e.seginfo->ignore ) {
/* keep the old values */
dirnode->e.seginfo->readonly = oldreadonly;
dirnode->e.seginfo->iscode = oldiscode;
dirnode->e.seginfo->ignore = ignore;
ObjKillRec( seg );
if( push_seg( dirnode ) == ERROR ) {
return( ERROR );
}
} else {
/* A new definition */
dirnode->e.seginfo->segrec = seg;
dirnode->e.seginfo->start_loc = 0;
dirnode->e.seginfo->current_loc = 0;
if( push_seg( dirnode ) == ERROR ) {
return( ERROR );
}
sym = &dirnode->sym;
GetSymInfo( sym );
sym->offset = 0;
LnameInsert( name );
}
if( CurrSeg != NULL ) {
if( !ModuleInfo.mseg
&& ( CurrSeg->seg->e.seginfo->segrec->d.segdef.use_32 != ModuleInfo.use32 ) ) {
ModuleInfo.mseg = TRUE;
}
if( CurrSeg->seg->e.seginfo->segrec->d.segdef.use_32 ) {
ModuleInfo.use32 = TRUE;
}
}
break;
case T_ENDS:
if( CurrSeg == NULL ) {
AsmError( SEGMENT_NOT_OPENED );
return( ERROR );
}
sym = AsmGetSymbol( name );
if( sym == NULL ) {
AsmErr( SEG_NOT_DEFINED, name );
return( ERROR );
}
if( (struct dir_node *)sym != CurrSeg->seg ) {
AsmError( BLOCK_NESTING_ERROR );
return( ERROR );
}
pop_seg();
break;
default:
return( ERROR );
}
return( SetUse32() );
}
int Include( int i )
/******************/
{
switch( AsmBuffer[i]->token ) {
case T_ID:
case T_STRING:
case T_PATH:
return( InputQueueFile( AsmBuffer[i]->string_ptr ) );
default:
AsmError( EXPECTED_FILE_NAME );
return( ERROR );
}
}
int IncludeLib( int i )
/*********************/
{
char *name;
struct asm_sym *sym;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?