direct.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,214 行 · 第 1/5 页
C
2,214 行
}
static void dir_add( dir_node *new, int tab )
/*******************************************/
{
/* note: this is only for those above which do NOT return right away */
/* put the new entry into the queue for its type of symbol */
if( Tables[tab].head == NULL ) {
Tables[tab].head = Tables[tab].tail = new;
new->next = new->prev = NULL;
} else {
new->prev = Tables[tab].tail;
Tables[tab].tail->next = new;
Tables[tab].tail = new;
new->next = NULL;
}
}
static void dir_init( dir_node *dir, int tab )
/********************************************/
/* Change node and insert it into the table specified by tab */
{
struct asm_sym *sym;
sym = &dir->sym;
dir->line_num = LineNumber;
dir->next = dir->prev = NULL;
switch( tab ) {
case TAB_SEG:
sym->state = SYM_SEG;
dir->e.seginfo = AsmAlloc( sizeof( seg_info ) );
dir->e.seginfo->lname_idx = 0;
dir->e.seginfo->group = NULL;
dir->e.seginfo->segrec = NULL;
break;
case TAB_GRP:
sym->state = SYM_GRP;
dir->e.grpinfo = AsmAlloc( sizeof( grp_info ) );
dir->e.grpinfo->idx = ++grpdefidx;
dir->e.grpinfo->seglist = NULL;
dir->e.grpinfo->numseg = 0;
dir->e.grpinfo->lname_idx = 0;
break;
case TAB_EXT:
sym->state = SYM_EXTERNAL;
dir->e.extinfo = AsmAlloc( sizeof( ext_info ) );
dir->e.extinfo->idx = ++extdefidx;
dir->e.extinfo->use32 = Use32;
dir->e.extinfo->comm = 0;
break;
case TAB_COMM:
sym->state = SYM_EXTERNAL;
dir->e.comminfo = AsmAlloc( sizeof( comm_info ) );
dir->e.comminfo->idx = ++extdefidx;
dir->e.comminfo->use32 = Use32;
dir->e.comminfo->comm = 1;
tab = TAB_EXT;
break;
case TAB_CONST:
sym->state = SYM_CONST;
sym->segment = NULL;
sym->offset = 0;
dir->e.constinfo = AsmAlloc( sizeof( const_info ) );
dir->e.constinfo->data = NULL;
dir->e.constinfo->count = 0;
return;
case TAB_PROC:
sym->state = SYM_PROC;
dir->e.procinfo = AsmAlloc( sizeof( proc_info ) );
dir->e.procinfo->regslist = NULL;
dir->e.procinfo->paralist = NULL;
dir->e.procinfo->locallist = NULL;
break;
case TAB_MACRO:
sym->state = SYM_MACRO;
dir->e.macroinfo = AsmAlloc( sizeof( macro_info ) );
dir->e.macroinfo->parmlist = NULL;
dir->e.macroinfo->data = NULL;
dir->e.macroinfo->srcfile = NULL;
break;
case TAB_CLASS_LNAME:
case TAB_LNAME:
sym->state = ( tab == TAB_LNAME ) ? SYM_LNAME : SYM_CLASS_LNAME;
dir->e.lnameinfo = AsmAlloc( sizeof( lname_info ) );
dir->e.lnameinfo->idx = ++LnamesIdx;
// fixme
return;
case TAB_PUB:
sym->public = TRUE;
return;
case TAB_GLOBAL:
return;
case TAB_STRUCT:
sym->state = SYM_STRUCT;
dir->e.structinfo = AsmAlloc( sizeof( struct_info ) );
dir->e.structinfo->size = 0;
dir->e.structinfo->alignment = 0;
dir->e.structinfo->head = NULL;
dir->e.structinfo->tail = NULL;
return;
case TAB_LIB:
break;
default:
// unknown table
/**/myassert( 0 );
break;
}
dir_add( dir, tab );
return;
}
static void RemoveFromTable( dir_node *dir )
/******************************************/
{
int tab;
if( dir->prev != dir->next ) {
dir->next->prev = dir->prev;
dir->prev->next = dir->next;
} else {
if( dir->prev != NULL ) {
dir->next->prev = NULL;
dir->prev->next = NULL;
}
switch( dir->sym.state ) {
case SYM_EXTERNAL:
tab = TAB_EXT;
break;
case SYM_SEG:
tab = TAB_SEG;
break;
case SYM_GRP:
tab = TAB_GRP;
break;
case SYM_PROC:
tab = TAB_PROC;
break;
case SYM_MACRO:
tab = TAB_MACRO;
break;
default:
return;
}
Tables[tab].head = Tables[tab].tail = dir->prev;
}
}
void dir_change( dir_node *dir, int tab )
/***************************************/
/* Change node type and insert it into the table specified by tab */
{
FreeInfo( dir );
RemoveFromTable( dir);
dir_init( dir, tab );
}
dir_node *dir_insert( const char *name, int tab )
/***********************************************/
/* Insert a node into the table specified by tab */
{
dir_node *new;
/**/myassert( name != NULL );
/* don't put class lnames into the symbol table - separate name space */
new = (dir_node *)AllocDSym( name, ( tab != TAB_CLASS_LNAME ) );
if( new != NULL )
dir_init( new, tab );
return( new );
}
void FreeInfo( dir_node *dir )
/****************************/
{
int i;
switch( dir->sym.state ) {
case SYM_GRP:
{
seg_list *segcurr;
seg_list *segnext;
segcurr = dir->e.grpinfo->seglist;
if( segcurr != NULL ) {
for( ;; ) {
segnext = segcurr->next;
AsmFree( segcurr );
if( segnext == NULL )
break;
segcurr = segnext;
}
}
AsmFree( dir->e.grpinfo );
}
break;
case SYM_SEG:
if( dir->e.seginfo->segrec != NULL )
ObjKillRec( dir->e.seginfo->segrec );
AsmFree( dir->e.seginfo );
break;
case SYM_EXTERNAL:
AsmFree( dir->e.extinfo );
break;
case SYM_LNAME:
case SYM_CLASS_LNAME:
AsmFree( dir->e.lnameinfo );
break;
case SYM_CONST:
#ifdef DEBUG_OUT
if( ( dir->e.constinfo->count > 0 )
&& ( dir->e.constinfo->data[0].token != T_NUM ) ) {
DebugMsg( ( "freeing const(String): %s = ", dir->sym.name ) );
} else {
DebugMsg( ( "freeing const(Number): %s = ", dir->sym.name ) );
}
#endif
for( i=0; i < dir->e.constinfo->count; i++ ) {
#ifdef DEBUG_OUT
if( dir->e.constinfo->data[i].token == T_NUM ) {
DebugMsg(( "%d ", dir->e.constinfo->data[i].value ));
} else {
DebugMsg(( "%s ", dir->e.constinfo->data[i].string_ptr ));
}
#endif
AsmFree( dir->e.constinfo->data[i].string_ptr );
}
DebugMsg(( "\n" ));
AsmFree( dir->e.constinfo->data );
AsmFree( dir->e.constinfo );
break;
case SYM_PROC:
{
label_list *labelcurr;
label_list *labelnext;
regs_list *regcurr;
regs_list *regnext;
labelcurr = dir->e.procinfo->paralist;
if( labelcurr != NULL ) {
for( ;; ) {
labelnext = labelcurr->next;
AsmFree( labelcurr->label );
AsmFree( labelcurr->replace );
AsmFree( labelcurr );
if( labelnext == NULL )
break;
labelcurr = labelnext;
}
}
labelcurr = dir->e.procinfo->locallist;
if( labelcurr != NULL ) {
for( ;; ) {
labelnext = labelcurr->next;
AsmFree( labelcurr->label );
AsmFree( labelcurr->replace );
AsmFree( labelcurr );
if( labelnext == NULL )
break;
labelcurr = labelnext;
}
}
regcurr = dir->e.procinfo->regslist;
if( regcurr != NULL ) {
for( ;; ) {
regnext = regcurr->next;
AsmFree( regcurr->reg );
AsmFree( regcurr );
if( regnext == NULL )
break;
regcurr = regnext;
}
}
AsmFree( dir->e.procinfo );
}
break;
case SYM_MACRO:
{
parm_list *labelcurr;
parm_list *labelnext;
asmlines *datacurr;
asmlines *datanext;
/* free the parm list */
labelcurr = dir->e.macroinfo->parmlist;
if( labelcurr != NULL ) {
for( ;; ) {
labelnext = labelcurr->next;
AsmFree( labelcurr->label );
if( labelcurr->replace != NULL ) {
AsmFree( labelcurr->replace );
}
if( labelcurr->def != NULL ) {
AsmFree( labelcurr->def );
}
AsmFree( labelcurr );
if( labelnext == NULL )
break;
labelcurr = labelnext;
}
}
/* free the lines list */
datacurr = dir->e.macroinfo->data;
if( datacurr != NULL ) {
for( ;; ) {
datanext = datacurr->next;
AsmFree( datacurr->line );
AsmFree( datacurr );
if( datanext == NULL )
break;
datacurr = datanext;
}
}
AsmFree( dir->e.macroinfo );
}
break;
case SYM_STRUCT:
{
field_list *ptr;
field_list *next;
for( ptr = dir->e.structinfo->head; ptr != NULL; ptr = next ) {
AsmFree( ptr->initializer );
AsmFree( ptr->value );
next = ptr->next;
AsmFree( ptr );
}
AsmFree( dir->e.structinfo );
}
break;
default:
break;
}
}
direct_idx GetLnameIdx( char *name )
/**********************************/
{
struct asm_sym *sym;
dir_node *dir;
sym = AsmGetSymbol( name );
if( sym == NULL )
return( LNAME_NULL );
dir = (dir_node *)sym;
if( sym->state == SYM_UNDEFINED ) {
return( LNAME_NULL );
} else if( sym->state == SYM_GRP ) {
return( dir->e.grpinfo->lname_idx );
} else if( sym->state == SYM_SEG ) {
return( dir->e.seginfo->lname_idx );
} else { /* it is an lname record */
return( dir->e.lnameinfo->idx );
}
}
static direct_idx InsertClassLname( char *name )
/**********************************************/
{
dir_node *dir;
if( strlen( name ) > MAX_LNAME ) {
AsmError( LNAME_TOO_LONG );
return( LNAME_NULL );
}
dir = dir_insert( name, TAB_CLASS_LNAME );
/* put it into the lname table */
AddLnameData( dir );
return( LnamesIdx );
}
direct_idx LnameInsert( char *name )
/**********************************/
{
struct asm_sym *sym;
dir_node *dir;
sym = AsmGetSymbol( name );
if( sym != NULL ) {
dir = (dir_node *)sym;
/* The name is already in the table*/
if( sym->state == SYM_GRP ) {
if( dir->e.grpinfo->lname_idx == 0 ) {
dir->e.grpinfo->lname_idx = ++LnamesIdx;
}
} else if( sym->state == SYM_SEG ) {
if( dir->e.seginfo->lname_idx == 0 ) {
dir->e.seginfo->lname_idx = ++LnamesIdx;
}
} else {
return( ERROR );
}
} else {
if( strlen( name ) > MAX_LNAME ) {
AsmError( LNAME_TOO_LONG );
return( ERROR );
}
dir = dir_insert( name, TAB_LNAME );
}
/* put it into the lname table */
AddLnameData( dir );
return( LnamesIdx );
}
void wipe_space( char *token )
/****************************/
/* wipe out the spaces at the beginning of a token */
{
char *start;
if( token == NULL )
return;
if( strlen( token ) == 0 )
return;
for( start = token;; start++ ){
if( *start != ' ' && *start != '\t' ) {
break;
}
}
if( start == token )
return;
memmove( token, start, strlen( start ) + 1 );
}
static uint checkword( char **token )
/***********************************/
/* wipes out prceding and tailing spaces, and make sure token contains only
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?