mupdate.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,176 行 · 第 1/3 页
C
1,176 行
TARGET *targ;
ret = RET_SUCCESS;
while( tlist != NULL ) {
targ = tlist->target;
tlist = tlist->next;
if( targ->mentioned == FALSE ) {
PrtMsg( WRN | TARGET_NOT_MENTIONED, targ->node.name );
targ->mentioned = TRUE;
} /* warning suggested by John */
if( Update( targ ) != RET_SUCCESS ) {
ret = RET_ERROR;
}
}
return( ret );
}
STATIC void implyDebugInfo( TARGET *targ, UINT32 startcount )
/***********************************************************/
{
enum MsgClass msg;
if( Glob.debug ) {
if( targExists( targ ) ) {
if( startcount != cListCount ) {
msg = M_HAD_TO_BE_UPDATED;
} else {
msg = M_IS_CLEAR_WITH;
}
} else {
msg = M_COULD_NOT_BE_IMPLIED;
}
PrtMsg( DBG | INF | IMP_ENV_M, targ->node.name, msg );
}
}
STATIC BOOLEAN autoDepCompare( time_t targ_time, time_t auto_time )
/*****************************************************************/
{
if( dateCmp( targ_time, auto_time ) < 0 ) {
return( TRUE );
}
return( FALSE );
}
STATIC BOOLEAN checkForAutoDeps( TARGET *targ, char *name, time_t *max_time )
/***************************************************************************/
{
return( AutoDepCheck( name, targ->date, autoDepCompare, max_time ) );
}
STATIC BOOLEAN autoOutOfDate( TARGET *targ, time_t *max_time )
/************************************************************/
{
char buffer[_MAX_PATH];
if( TrySufPath( buffer, targ->node.name, NULL, FALSE ) != RET_SUCCESS ) {
return( FALSE );
}
return( checkForAutoDeps( targ, buffer, max_time ) );
}
STATIC RET_T isOutOfDate( TARGET *targ, TARGET *deptarg, BOOLEAN *outofdate )
/****************************************************************************
* Checks if the current target is out of date
*/
{
getDate( targ );
if( targ->existing && targ->attr.existsonly ) {
return( RET_SUCCESS );
}
getDate( deptarg );
if( targ->existing && deptarg->existing && deptarg->attr.existsonly ) {
return( RET_SUCCESS );
}
if( dateCmp( targ->date, deptarg->date ) < 0 ) {
*outofdate = TRUE;
if( Glob.show_offenders ) {
PrtMsg( INF | WILL_BE_BUILT_BECAUSE_OF,
targ->node.name, deptarg->node.name);
}
}
if( deptarg->error ) {
/* one of the targets had an error while being updated
* abort now
*/
return( RET_ERROR );
}
if( (!deptarg->attr.recheck && deptarg->cmds_done) || deptarg->backdated ) {
*outofdate = TRUE;
}
return( RET_SUCCESS );
}
STATIC RET_T implyMaybePerform( TARGET *targ, TARGET *imptarg,
TARGET *cretarg, BOOLEAN must, SLIST *slistCmd )
/*************************************************************
* perform cmds if targ is older than imptarg || must
*
* targ is the target to be updated
* imptarg is the dependent for target (ie: "targ : imptarg" )
* cretarg is the implicit rule to use
* must must we do it?
*/
{
RET_T ret;
DEPEND *newdep;
TLIST *newtlist;
time_t max_time;
max_time = OLDEST_DATE;
if( imptarg->error ) {
/* there was an error making imptarg before, so just abort */
return( RET_ERROR );
}
if( cretarg->attr.always ) {
must = TRUE;
}
if( isOutOfDate( targ, imptarg, &must ) == RET_ERROR ) {
return( RET_ERROR );
}
if( !must && USE_AUTO_DEP( cretarg ) ) {
if( autoOutOfDate( targ, &max_time ) ) {
must = TRUE;
}
}
if( must ) {
assert( cretarg->depend != NULL );
/* construct a depend for perform */
newdep = DupDepend( cretarg->depend );
newtlist = NewTList();
newtlist->target = imptarg;
newdep->targs = newtlist;
newdep->slistCmd = slistCmd;
/* handle implied attributes (.symb/.prec/.multi) */
TargOrAttr( targ, cretarg->attr );
ret = perform( targ, newdep, max_time );
FreeDepend( newdep ); /* don't need depend any more */
if( ret != RET_SUCCESS ) {
return( RET_ERROR );
}
if( Glob.noexec || Glob.query ) { /* 29-oct-90 */
targ->executed = TRUE;
targ->touched = TRUE;
}
}
return( RET_SUCCESS );
}
STATIC RET_T imply( TARGET *targ, const char *drive, const char *dir,
const char *fname, const char *ext, BOOLEAN must )
/********************************************************************
* targ is the target to be implied
* drive is the drive of the target
* dir is the path of the target
* fname is the portion of targ's name without the extension
* ext is the extension of targ's name
* must must we make this target?
*
* RET_SUCCESS - performed cmds,
* RET_WARN unable to imply,
* RET_ERROR - perform failed
*/
{
SUFFIX *srcsuf;
CREATOR *cur;
SUFFIX *cursuf;
TARGET *imptarg;
RET_T ret;
BOOLEAN newtarg;
UINT32 startcount;
char *buf;
SLIST *curslist;
SLIST *slistCmd; // Slist chosen for sufsuf
SLIST *slistDef; // Slist that has dependent path = ""
SLIST *slistEmptyTargDepPath;
BOOLEAN UseDefaultSList;
int slistCount;
srcsuf = FindSuffix( ext );
if( srcsuf == NULL || srcsuf->creator == NULL ) {
PrtMsg( DBG | INF | IMP_ENV_M, targ->node.name, M_HAS_NO_IMPLICIT );
return( RET_WARN );
}
PrtMsg( DBG | INF | IMP_ENV_M, targ->node.name, M_CHECKING_IMPLICIT );
startcount = cListCount;
for( cur = srcsuf->creator; cur != NULL; cur = cur->next ) {
cursuf = cur->suffix;
/* allocate a buffer */
buf = MallocSafe( _MAX_PATH );
slistCmd = NULL;
slistDef = NULL;
slistEmptyTargDepPath = NULL;
assert( cur->cretarg != NULL );
assert( cur->cretarg->depend != NULL );
curslist = cur->cretarg->depend->slist;
ret = RET_ERROR;
UseDefaultSList = TRUE;
slistCount = 0;
/* find path in SLIST */
while( curslist != NULL && ret != RET_SUCCESS ) {
_makepath( buf, drive, dir, NULL, NULL );
/*
* note the path of the current target must match the
* path as specified in the slist
*/
if( strcmpi( buf, curslist->targ_path ) == 0 ) {
/* build filename for implied target */
_makepath( buf, NULL, curslist->dep_path,
fname, cursuf->node.name );
/* try to find this file on path or in targets */
ret = TrySufPath( buf, buf, &imptarg, FALSE );
if( ret == RET_SUCCESS ) {
slistCmd = curslist;
/* later on we need to check if implied target does not */
/* exist we need to create it on the first directory we */
/* see on the SLIST since */
/* the first on the list is the one that was defined */
/* last in the makefile */
} else if( slistDef == NULL ) {
slistDef = curslist;
}
}
if( curslist->targ_path[0] == NULLCHAR &&
curslist->dep_path[0] == NULLCHAR ) {
slistEmptyTargDepPath = curslist;
}
if( slistCount > 0 && slistEmptyTargDepPath != NULL ) {
UseDefaultSList = FALSE;
}
curslist = curslist->next ;
++slistCount;
}
if( UseDefaultSList && slistCmd == NULL && !Glob.microsoft ) {
_makepath( buf, NULL, NULL, fname, cursuf->node.name );
/* try to find this file on path or in targets */
ret = TrySufPath( buf, buf, &imptarg, FALSE );
switch( ret ) {
case RET_WARN:
break;
case RET_ERROR:
if( !Glob.microsoft ) {
slistDef = slistEmptyTargDepPath;
}
break;
case RET_SUCCESS:
slistCmd = slistEmptyTargDepPath;
break;
}
}
if( (ret == RET_SUCCESS && imptarg == NULL) || ret == RET_ERROR ) {
/* Either file doesn't exist, or it exists and we don't already
* have a target for it. Either way, we create a new target.
*/
if( ret == RET_ERROR ) {
/*
* No Default Slist found so must continue and find
* another slist
*/
if( slistDef == NULL ) {
FreeSafe( buf );
continue;
} else {
slistCmd = slistDef;
}
/* file doesn't exist, assume in directory */
/* pointed to by the slistDef */
_makepath( buf, NULL, slistCmd->dep_path,
fname, cursuf->node.name );
}
newtarg = TRUE;
imptarg = NewTarget( buf );
FreeSafe( buf ); /* don't need any more */
getStats( imptarg );
imptarg->busy = TRUE; /* protect against recursion */
if( imply( imptarg, NULL, slistCmd->dep_path,
fname, cursuf->node.name, FALSE ) ==
RET_ERROR ) {
imptarg->error = TRUE;
}
if( startcount != cListCount && (Glob.noexec || Glob.query) ) {
imptarg->touched = TRUE;
imptarg->executed = TRUE; /* 29-oct-90 */
}
imptarg->updated = TRUE;
imptarg->busy = FALSE;
} else {
/* We already know about imptarg, so just update it */
assert( imptarg != NULL );
FreeSafe( buf ); /* don't need any more */
newtarg = FALSE; /* this isn't a new target */
Update( imptarg );
}
/* We've tried our best to make the imptarg, check if it exists
* after our efforts.
*/
if( targExists( imptarg ) ) {
/* it exists - now we perform the implicit cmd list, and return */
ret = implyMaybePerform( targ, imptarg, cur->cretarg, must,
slistCmd );
if( newtarg && !Glob.noexec ) {
/* destroy the implied target, because the info in the target
* structure is nicely stored on disk (unless Glob.noexec)
*/
KillTarget( imptarg->node.name );
}
implyDebugInfo( targ, startcount );
return( ret );
} else if( newtarg ) {
/* we created an unsuccessful target - so destroy it */
KillTarget( imptarg->node.name );
}
/* We couldn't imply with this suffix... try next one */
}
implyDebugInfo( targ, startcount );
return( RET_WARN );
}
STATIC RET_T tryImply( TARGET *targ, BOOLEAN must )
/*************************************************/
{
PGROUP *pg;
RET_T ret;
if( Glob.block ) {
return( RET_WARN );
}
pg = SplitPath( targ->node.name );
ret = imply( targ, pg->drive,pg->dir,pg->fname, pg->ext, must );
DropPGroup( pg );
return( ret );
}
STATIC void ExpandWildCards( TARGET *targ, DEPEND *depend )
/**********************************************************
* Expand the wild cards now
* also deMacroSpecial macros
*/
{
TLIST *tlist;
TLIST *currentEnd;
TLIST *outTList;
TLIST *temp;
char *NodeName;
assert( depend != NULL );
tlist = depend->targs;
currentEnd = outTList = NULL;
while( tlist != NULL ) {
temp = NULL;
// In Microsoft it is possible to have macros in the dependency.
if( Glob.microsoft ) {
exPush( targ, NULL, NULL );
NodeName = DeMacroSpecial( tlist->target->node.name );
exPop();
WildTList( &temp, NodeName, TRUE, TRUE );
FreeSafe( NodeName );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?