mparse.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,157 行 · 第 1/3 页
C
1,157 行
while( walk != NULL ) {
if( !walk->target->special ) {
PrtMsg( DBG | WRN | LOC | ASSUMING_SYMBOLIC, walk->target->node.name );
break;
}
walk = walk->next;
}
}
STATIC void parseTargDep( TOKEN_T t, TLIST **btlist )
/****************************************************
* parse a line of form {target}+ (scolon||dcolon) {depend}*
* or {target}+
* where: target ::= TOK_FILENAME || TOK_SUFSUF || TOK_DOTNAME(with cmds)
* depend ::= TOK_FILENAME || DOT_PREC/SYMB/...
*
* stack targets into btlist
*/
{
TATTR attr; /* hold attributes here */
DEPEND *dep; /* a DEPEND that describes dependents from file */
BOOLEAN nodep; /* true if no dependents from file */
/* get the target list, and the last token processed */
t = buildTargs( btlist, t );
if( *btlist == NULL ) { /* only in error conditions */
return;
}
nodep = t == EOL || t == STRM_END; /* check if there wasn't a colon */
/* set the scolon attribute for each of these targets */
setSColon( *btlist, (int)(t == TOK_SCOLON || nodep) );
if( !nodep ) {
dep = buildDepend( &attr );
} else {
/* we've reached EOL already, so we'll just assume this */
if( Glob.debug ) {
parseTargWarning( *btlist );
}
dep = NewDepend();
TargInitAttr( &attr );
attr.symb = TRUE;
}
/* now we attach this depend to each target */
linkDepend( *btlist, dep, attr );
setFirstTarget( *btlist );
}
STATIC void parseExtensions( void )
/**********************************
* parse lines of form .EXTENSIONS:
* or .EXTENSIONS: {ext}+
*/
{
TOKEN_T t;
BOOLEAN any;
for( ;; ) {
t = LexToken( LEX_PARSER );
if( t == EOL || t == STRM_END || t == TOK_SCOLON ) {
break;
}
PrtMsg( ERR | LOC | EXPECTING_M, M_SCOLON );
LexMaybeFree( t );
}
if( t == EOL || t == STRM_END ) {
ClearSuffixes();
return;
}
any = FALSE;
for( ;; ) {
t = LexToken( LEX_PARSER );
if( t == EOL || t == STRM_END ) {
break;
}
if( t == TOK_SUF ) {
if( !SufExists( CurAttr.ptr ) ) {
AddSuffix( CurAttr.ptr ); /* we lose CurAttr.ptr */
/*
* if microsoft option is set we put it in anyway don't
* care whether or not it exists
*/
} else if( Glob.microsoft | Glob.unix ) {
FreeSafe( CurAttr.ptr );
} else {
PrtMsg( ERR | LOC | REDEF_OF_SUFFIX, CurAttr.ptr );
FreeSafe( CurAttr.ptr );
}
any = TRUE;
} else {
ignoring( t, TRUE );
}
}
if( !any ) {
ClearSuffixes();
}
}
STATIC void parseDotName( TOKEN_T t, TLIST **btlist )
/****************************************************
* parse any of the dotnames
*/
{
if( IsDotWithCmds( CurAttr.num ) ) {
parseTargDep( TOK_DOTNAME, btlist );
return;
}
if( CurAttr.num == DOT_EXTENSIONS || CurAttr.num == DOT_SUFFIXES ) {
parseExtensions();
return;
}
for( ;; ) {
switch( CurAttr.num ) {
case DOT_BLOCK: Glob.block = TRUE; break;
case DOT_CONTINUE: Glob.cont = TRUE; break;
case DOT_ERASE: Glob.erase = TRUE; break;
case DOT_FUZZY: Glob.fuzzy = TRUE; break;
case DOT_IGNORE: Glob.ignore = TRUE; break;
case DOT_HOLD: Glob.hold = TRUE; break;
case DOT_NOCHECK: Glob.nocheck = TRUE; break;
case DOT_OPTIMIZE: Glob.optimize = TRUE; break;
case DOT_SILENT: Glob.silent = TRUE; break;
case DOT_RCS_MAKE: Glob.rcs_make = TRUE; break;
default:
ignoring( TOK_DOTNAME, TRUE );
break;
}
for( ;; ) {
t = LexToken( LEX_PARSER );
if( t == EOL || t == STRM_END ) {
return;
}
if( t != TOK_DOTNAME ) {
ignoring( t, TRUE );
}
}
}
}
/* links the clist to the sufsuf target */
STATIC void linkClistSufsuf( const TARGET *curtarg, const CLIST *clist,
const char *cur_target_path, const char *cur_depend_path )
/*********************************************************************/
{
DEPEND *walk;
SLIST *slist;
assert( curtarg != NULL && curtarg->depend != NULL );
walk = curtarg->depend;
while( walk->next != NULL ) {
walk = walk->next;
}
/*
* if both the dep_path and the target path is null
* then we are doing the trivial case of just replacing the
* current clist if not we have to create an SLIST that contains
* both the new targ_path and new dep_path
*/
if( cur_depend_path == NULL && cur_target_path == NULL ) {
if( walk->clist != NULL ) {
FreeSafe( walk->clist );
}
walk->clist = DupCList( clist );
} else {
if( walk->slist == NULL ) {
walk->slist = NewSList ();
walk->slist->targ_path = StrDupSafe( cur_target_path );
walk->slist->dep_path = StrDupSafe( cur_depend_path );
walk->slist->clist = DupCList ( clist );
walk->slist->next = NULL;
} else {
slist = NewSList ();
slist->targ_path = StrDupSafe( cur_target_path );
slist->dep_path = StrDupSafe( cur_depend_path );
slist->clist = DupCList ( clist );
slist->next = walk->slist;
walk->slist = slist;
}
}
}
STATIC void linkCList( TLIST *btlist, CLIST *bclist, const char *cur_target_path,
const char *cur_depend_path)
/********************************************************************************
* attach bclist to each target in btlist
*/
{
CLIST *clisthead;
CLIST *clistcur;
TLIST const *tlist;
DEPEND * const *walk;
CLIST **walkClist;
TARGET const *curtarg;
assert( btlist != NULL );
/*
* Remember that cmds were stacked in reverse order. Now we simply
* do a pull, and pop onto another stack to reverse them.
*/
clisthead = NULL;
while( bclist != NULL ) {
clistcur = bclist;
bclist = bclist->next;
clistcur->next = clisthead;
clisthead = clistcur;
}
/*
* Attach cmds to the targets. Assumes that for each of the targets,
* the last depend in the list target->depend is the owner of this clist.
*/
tlist = btlist;
while( tlist != NULL ) {
curtarg = tlist->target;
tlist = tlist->next; /* advance to next in tlist */
assert( curtarg->depend != NULL ); /* linkDepend() assures this */
walk = &curtarg->depend;
if( curtarg->scolon ) {
/* check if it's an scolon, and attempt more than one clist */
if( clisthead != NULL && (*walk)->clist != NULL ) {
if( Glob.microsoft | Glob.unix ) {
PrtMsg( WRN | LOC | MORE_THAN_ONE_CLIST, curtarg->node.name );
} else {
PrtMsg( ERR | LOC | MORE_THAN_ONE_CLIST, curtarg->node.name );
}
} else if( clisthead != NULL ) {
/* this is the first clist for this scolon */
(*walk)->clist = clisthead;
clisthead = DupCList( clisthead );
}
} else if( curtarg->sufsuf ) {
/* special processing is needed for sufsuf */
linkClistSufsuf( curtarg, clisthead, cur_target_path,
cur_depend_path );
} else {
/* we walk the dependents to find the last one */
while( (*walk)->next != NULL ) {
walk = &(*walk)->next;
}
if( curtarg->before_after ) {
walkClist = &(*walk)->clist;
/* if the clist being appended is null then clear the list */
/* just like .SUFFIXES */
if( clisthead != NULL ) {
// for .AFTER and .BEFORE we need to add to the end of the
// clist the new clists
while( (*walkClist) != NULL ) {
walkClist = &(*walkClist)->next;
}
*walkClist = clisthead;
} else {
FreeCList( *walkClist );
*walkClist = NULL;
}
} else {
(*walk)->clist = clisthead;
}
clisthead = DupCList( clisthead );
}
}
FreeCList( clisthead ); /* we always make an extra copy */
FreeTList( btlist ); /* free the tlist we were passed */
}
STATIC void parseSuf( void )
/***************************
* parse {TOK_SUF}+ : TOK_PATH
* or {TOK_SUF}+ :
* or {TOK_SUF}+
*/
{
TOKEN_T t;
char *path;
NODE *head;
NODE *cur;
head = NULL;
t = TOK_SUF;
for( ;; ) {
if( t == EOL || t == STRM_END || t == TOK_SCOLON ) {
break;
}
if( t == TOK_SUF ) {
if( !SufExists( CurAttr.ptr ) ) {
PrtMsg( ERR | LOC | SUFFIX_DOESNT_EXIST, CurAttr.ptr );
FreeSafe( CurAttr.ptr );
} else {
cur = MallocSafe( sizeof( *cur ) );
cur->name = CurAttr.ptr;
cur->next = head;
head = cur;
}
} else {
ignoring( t, TRUE );
}
t = LexToken( LEX_PARSER );
}
/* note that we use mode LEX_PATH here NOT LEX_PARSER! */
if( t == STRM_END || t == EOL ) {
path = NULL;
} else {
t = LexToken( LEX_PATH );
assert( t == TOK_PATH || t == STRM_END || t == EOL );
if( t == STRM_END || t == EOL ) {
path = NULL;
} else {
path = CurAttr.ptr;
t = LexToken( LEX_PATH ); /* prefetch next token */
}
}
for( ;; ) {
if( t == STRM_END || t == EOL ) {
break;
}
ignoring( t, TRUE );
t = LexToken( LEX_PATH );
}
while( head != NULL ) {
cur = head;
head = head->next;
SetSufPath( cur->name, path );
FreeSafe( cur->name );
FreeSafe( cur );
}
if( path != NULL ) {
FreeSafe( path ); /* from CurAttr.ptr */
}
}
STATIC char *getFileName( const char *intext, size_t *offset )
/*************************************************************
* get the filename from the given text
* if there is no file name then get the text body
* offset - how long after the << is the file name
* this only gets the explicit fileName
* for the fileNames that need to be generated
* we do it later but still we create an FLIST for
* the temp file anyway
*/
{
VECSTR tempStr;
char *ret;
BOOLEAN doubleQuote; //are there double quotes
assert( intext != NULL && offset != NULL );
*offset = 0;
doubleQuote = FALSE;
if( intext[*offset] == DOUBLEQUOTE ) {
doubleQuote = TRUE;
*offset = 1;
}
for( ;; ) {
if( intext[*offset] == NULLCHAR ) {
break;
} else if( (isws( intext[*offset] ) ||
intext[*offset]== LESSTHAN ||
intext[*offset]== GREATERTHAN) &&
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?