STATIC bool 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 bool targExists( TARGET *targ ) /************************************/ { char buffer[_MAX_PATH]; getStats( targ ); /* get date stamp */ if( targ->existing ) { return( true ); } if( targ->attr.symbolic ) { return( false ); } if( TrySufPath( buffer, targ->node.name, NULL, false ) == RET_SUCCESS ) { RenameTarget( targ, buffer ); targ->executed = true; /* force get date */ getStats( targ ); assert( targ->existing ); return( true ); } return( false ); }
STATIC BOOLEAN targExists( TARGET *targ ) /***************************************/ { char buffer[_MAX_PATH]; getStats( targ ); /* get date stamp */ if( targ->existing ) { return( TRUE ); } if( targ->attr.symb ) { return( FALSE ); } if( TrySufPath( buffer, targ->node.name, NULL, FALSE ) == RET_SUCCESS ) { RenameTarget( targ, buffer ); targ->executed = TRUE; /* force get date */ getStats( targ ); assert( targ->existing ); return( TRUE ); } return( FALSE ); }
RET_T InsFile( const char *name, BOOLEAN envsearch ) /********************************************************** * Open file named name, and push it into stream. If can't find name, it * tries an implicit suffix search (possibly using the env variable PATH) */ { SENT *tmp; int fh; char path[_MAX_PATH]; assert( name != NULL ); if( TrySufPath( path, name, NULL, envsearch ) == RET_SUCCESS ) { PrtMsg( DBG | INF | LOC | ENTERING_FILE, path ); fh = sopen3( path, O_RDONLY | O_BINARY, SH_DENYWR ); if( fh == -1 ) { return( RET_ERROR ); } tmp = getSENT( SENT_FILE ); tmp->free = TRUE; tmp->data.file.name = StrDupSafe( path ); pushFH( tmp, fh ); if( !Glob.overide ) { UnGetCH( EOL ); InsString( path, FALSE ); InsString( "$+$(__MAKEFILES__)$- ", FALSE ); DefMacro( "__MAKEFILES__" ); } return( RET_SUCCESS ); } return( RET_ERROR ); }
STATIC RET_T imply( TARGET *targ, const char *drive, const char *dir, const char *fname, const char *ext, bool 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 = NULL; RET_T ret; bool newtarg; UINT32 startcount; char *buf; SLIST *curslist; SLIST *slist; // Slist chosen for sufsuf SLIST *slistDef; // Slist that has dependent path = "" SLIST *slistEmptyTargDepPath; bool 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 ); slist = NULL; slistDef = NULL; slistEmptyTargDepPath = NULL; ret = RET_ERROR; UseDefaultSList = true; /* find path in SLIST */ slistCount = 0; for( curslist = cur->slist; curslist != NULL && ret != RET_SUCCESS; curslist = curslist->next ) { _makepath( buf, drive, dir, NULL, NULL ); FixName( buf ); /* * note the path of the current target must match the * path as specified in the slist */ if( stricmp( 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 ) { slist = 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 == NULLCHAR && *curslist->dep_path == NULLCHAR ) { slistEmptyTargDepPath = curslist; } if( slistCount > 0 && slistEmptyTargDepPath != NULL ) { UseDefaultSList = false; } ++slistCount; } if( UseDefaultSList && slist == NULL && !Glob.compat_nmake ) { _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.compat_nmake ) { slistDef = slistEmptyTargDepPath; } break; case RET_SUCCESS: slist = slistEmptyTargDepPath; break; } } if( ret == RET_ERROR && slistDef == NULL ) { /* * No Default Slist found so must continue and find * another slist */ FreeSafe( buf ); continue; } 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 ) { slist = slistDef; /* file doesn't exist, assume in directory */ /* pointed to by the slistDef */ _makepath( buf, NULL, slist->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, slist->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; } 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, slist->cretarg, must ); 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 carryOut( TARGET *targ, CLIST *clist, time_t max_time ) /******************************************************************/ { CLIST *err; int i; struct utimbuf times; char msg[max( MAX_RESOURCE_SIZE, _MAX_PATH )]; assert( targ != NULL && clist != NULL ); ++cListCount; if( ExecCList( clist ) == RET_SUCCESS ) { if( Glob.rcs_make && !Glob.noexec && !Glob.touch ) { if( max_time != OLDEST_DATE ) { targ->date = max_time; targ->backdated = true; if( TrySufPath( msg, targ->node.name, NULL, false ) == RET_SUCCESS ) { if( USE_AUTO_DEP( targ ) ) { // target has auto dependency info // result: max_time may be incorrect! CacheRelease(); checkForAutoDeps( targ, msg, &max_time ); } times.actime = max_time; times.modtime = max_time; utime( msg, × ); CacheRelease(); } } } targ->cmds_done = true; return( RET_SUCCESS ); } /* * ok - here is something I don't like. In this portion of code here, * carryOut is ignoring the target passed to it, and digging the targets * out of the stack. Be careful of changes. */ PrtMsg( ERR | NEOL | LAST_CMD_MAKING_RET_BAD ); for( i = exStackP - 1; i >= 0; --i ) { PrtMsg( ERR | NEOL | PRNTSTR, exStack[i].targ->node.name ); if( i > 0 ) { PrtMsg( ERR | NEOL | PRNTSTR, ";" ); } } MsgGetTail( LAST_CMD_MAKING_RET_BAD, msg ); PrtMsg( ERR | PRNTSTR, msg ); err = DotCList( DOT_ERROR ); if( err != NULL ) { ++cListCount; if( ExecCList( err ) != RET_SUCCESS ) { PrtMsg( FTL | S_COMMAND_RET_BAD, DotNames[DOT_ERROR] ); ExitFatal(); } } else if( !(targ->attr.precious || targ->attr.symbolic) ) { if( !Glob.hold && targExists( targ ) ) { if( Glob.erase || GetYes( SHOULD_FILE_BE_DELETED ) ) { if( unlink( targ->node.name ) != 0 ) { PrtMsg( FTL | SYSERR_DELETING_ITEM, targ->node.name ); ExitFatal(); } } } } if( Glob.cont ) { return( RET_WARN ); } return( RET_ERROR ); }