Пример #1
0
BOOL
MRE::FPushFile ( PMREFile * ppmrefile, SZC szFile, HANDLE hFile ) {
	
	_TCHAR	szCanon[ ctchMrePathMax ];
	NI		ni;
	PFI		pfi = NULL;

	precondition ( szFile );

	ni = NiFromName ( SzFullCanonFilename ( szFile, szCanon, countof(szCanon) ) );
	m_pmrefRoot->Push ( ni );
	m_mrelog.LogPush ( ni );
	if ( FFileInfoFromNi ( ni, &pfi ) ) {
		assert ( pfi->fiTime != 0 );
		assert ( pfi->fiSize != 0 );
		pfi->SetBuildId ( BuildId() );
		}
	else {
		// insert a new FILEINFO
		FI		fi(ni, fsmVisited, BuildId());

		// add in the new one after updating the timestamp info
		if ( !FInsertFileInfo ( fi ) ) {
			// review:error
			}
		else {
			FFileInfoFromNi ( ni, &pfi );
			if ( pfi ) {
				if ( hFile != INVALID_HANDLE_VALUE ) {
					::FFileInfo ( hFile, *pfi );
					CheckIgnoreFile ( *pfi, hFile );
					}
				else {
					::FFileInfo ( szCanon, *pfi );
					}
				}
			}
		}

	// have we visited this file recently?
	if ( pfi ) {
		if ( FUpdateFileInfo ( pfi, hFile ) ) {
			// clear out any status bits that may change how we operate with
			//	this file in the future
			pfi->ClearFstatus ( fsmInclByPch );
			}
		}
	if ( !(pfi && pfi->FIsFsmSet ( fsmIgnoreDep )) ) {
		m_mrfibufRoot.FAddFileDep ( ni );
		}
	*ppmrefile = m_pmrefRoot;
	return fTrue;
	}
Пример #2
0
plString plProduct::ProductString()
{
    static plString _cache = plString::Format(
            "%s.%u.%u - " RELEASE_ACCESS "." RELEASE_TYPE,
            CoreName().c_str(), BranchId(), BuildId());
    return _cache;
}
Пример #3
0
BOOL
MRE::FUpdateTargetFile ( SZC szTarget, TrgType trgtype ) {
	// REVIEW:TODO actually do the patch (novel concept)
	_TCHAR	szCanon [ ctchMrePathMax ];
	NI		ni;
	PFI		pfi;
	BOOL	fRet = fFalse;

	ni = NiFromName (
		SzFullCanonFilename ( szTarget, szCanon, countof(szCanon) )
		);

	if ( trgtype == trgtypeObject && FFileInfoFromNi ( ni, &pfi ) ) {
		MREFT	mreft;
		QWORD	cb;

		switch ( m_lcrechandler.LcrhrPatchFile ( pfi->BuildId(), szCanon ) ) {
			case LCRecHandler::lcrhrFail :
			case LCRecHandler::lcrhrNotApplicable : {
				_tutime ( szCanon, NULL);
				break;
				}
			case LCRecHandler::lcrhrSuccess : {
				break;
				}
			default : {
				notReached();
				}
			}
		IncBuildId();
		// update our FILEINFO so that we don't have to deal with those
		//	changes on our next refresh.
		if ( ::FFileInfo ( szCanon, mreft, cb ) ) {
			pfi->fiTime = mreft;
			pfi->fiSize = cb;
			pfi->SetBuildId ( BuildId() );
			}
		fRet = fTrue;
		}
	else {
		fRet = !_tutime ( szCanon, NULL);
		}

	m_mrelog.LogNote (
		"Note: update of '%s', type = %d, was %ssuccessful.\n",
		szCanon,
		int(trgtype),
		fRet ? "" : "un"
		);
	return fRet;
	}
Пример #4
0
//-----------------------------------------------------------------------------
//	MRE::YnmFileOutOfDate
//
//  Purpose:	tells whether a file is, isn't, or may be out of date
//
//  Input: a SRCTARG containing the following fields:
//		st.szFileSrc,	source file
//		st.szFileTarg,	target (object) file
//		st.szOptions,	compiler options it will be built with this time
//
//	Output:
//		st.dwWeightMaybe,	weighting factor for when we return ynmMaybe
//
//  Returns:
//		ynmNo, ynmYes, or ynmMaybe
//
//	Note:
//		This method depends on having up-to-date information from
//		FRefreshFilesysInfo
//-----------------------------------------------------------------------------
YNM
MRE::YnmFileOutOfDate ( SRCTARG & st ) {

	precondition ( st.szSrc );
	precondition ( st.szTarg );

	YNM		ynmRet = ynmYes;
	_TCHAR	szCanonSrc [ ctchMrePathMax ];
	_TCHAR	szCanonTarg[ ctchMrePathMax ];
	NI		niSrc;
	NI		niTarg;
	NI		niOptions;
	BOOL	fUsingPch = fFalse;

	st.dwWeightMaybe = 0;
	niSrc = NiFromName (
		SzFullCanonFilename ( st.szSrc, szCanonSrc, countof(szCanonSrc) )
		);
	niTarg = NiFromName (
		SzFullCanonFilename ( st.szTarg, szCanonTarg, countof(szCanonTarg) )
		);
	niOptions = st.szOptions ? NiFromName ( st.szOptions ) : niNil;

	// find out if it is using a pch...we can safely skip checking files
	//	that were included in the pch in our dep scan.
	if ( st.szOptions ) {
		SZC	szYu = NULL;
		SZC	szT = st.szOptions;
		
		// find last " -Yu" in the options.  this will skip any in the -D...
		//	portions and won't match any path name in the includes
		//	since the driver canonicalizes by lowercasing them.
		while ( szT = _tcsstr ( szT, _TEXT(" -Yu") ) ) {
			szYu = szT;
			szT++;
			}

		// now, make sure we are not also creating a new pch via a 2-level
		//	pch create (both -Yc and -Yu on the command line)
		szT = st.szOptions;
		SZC	szYc = NULL;

		while ( szT = _tcsstr ( szT, _TEXT(" -Yc") ) ) {
			szYc = szT;
			szT++;
			}

		// check to see if are using and not creating a PCH.
		fUsingPch = ((szYu != NULL) && (szYc == NULL));
		}

	PFI		pfiSrc = NULL;
	if ( FFileInfoFromNi ( niSrc, &pfiSrc ) ) {

		if ( !st.fCpp ) {
			// not a C++ file anymore, so remove any info we have and bail
			m_mpnifi.remove ( niSrc );
			m_mpnifi.remove ( niTarg );
			return ynmYes;
			}

		assert ( pfiSrc->niFile == niSrc );
		assert ( pfiSrc->FHasTarget() );

		// pre-check the source/target pair to see if they are out of date
		//	in any way.  This call will update the outofdate bit if anything
		//	changed (options, missing src/targ file, src/targ file changes).
		CheckSrcTarg ( pfiSrc, niTarg, niOptions );

		// if the file is not already marked as out of date, or out of date
		//	due to rude file changes or class deps, then we have to do some
		//	more work.
		if ( !pfiSrc->FTargOutOfDate() && !FIsFileOutOfDate ( pfiSrc ) ) {
			
			BldId		bldidSrc = pfiSrc->BuildId();
			unsigned	itagni = 0;

			// go thru the loop at least once
			//	1st iteration checks for any existing pending files that would
			//	cause us to classify this as a maybe instead of a no.
			//	2nd iteration will happen if a new changed file we haven't
			//	visited yet is included by this source file.
			for ( unsigned cIterations = 0; cIterations < 2; cIterations++ ) {
				if ( !FLoadMrfi ( pfiSrc->Ni() ) ) {
					break;
					}

				// does the file include any of the "pending
				// parse" files?
				unsigned	itagniMac = m_rgtagniPending.size();
				for ( ; itagni < itagniMac; itagni++ ) {
					TagNi *	ptni = &m_rgtagniPending[ itagni ];

					debug ( SZC sz = SzFromNi ( ptni->Ni() ) );

					if ( ptni->BuildId() > bldidSrc &&
						 FNiDependsOnNiFile ( pfiSrc->Ni(), ptni->Ni() )
						) {
						ynmRet = ynmMaybe;
						st.dwWeightMaybe += 1 + m_mrfibufRoot.MapNiClassdep().count();
						m_mrelog.LogNote (
							"Note: '%s' may be out of date due to changes in '%s'.\n",
							szCanonSrc,
							SzFromNi ( ptni->Ni() )
							);
						}
					else if ( m_mrelog.FLogging() ) {
						m_mrelog.LogNote (
							"Note: '%s' not out of date due to '%s' or "
							"build id's (%d,%d).\n",
							szCanonSrc,
							SzFromNi ( ptni->Ni() ),
							bldidSrc,
							ptni->BuildId()
							);
						}
					}

				// if we didn't find any files that need to be compiled,
				//	we check for any new files that have changed, and check
				//	again, else we are done.
				if ( st.dwWeightMaybe == 0 && !FCheckVisitedDeps ( pfiSrc, fUsingPch ) ) {
					ynmRet = ynmNo;
					break;
					}
				}

			if ( ynmRet == ynmNo ) {
				m_mrelog.LogNote (
					"Note: '%s' is not out of date due to current pending changes.\n",
					szCanonSrc
					);
				}
			}
		}
	else {
		// file didn't exist in our list.  this is our only chance to snarf
		//	the compile options.
		FI	fiSrc(niSrc, fsmHasTarget | fsmOutOfDate, BuildId(), niOptions);
		FI	fiTrg(niTarg, fsmIsTarget | fsmOutOfDate);

		// add the file into the list if it exists.
		if ( ::FFileInfo ( szCanonSrc, fiSrc ) ) {
			::FFileInfo ( szCanonTarg, fiTrg );
			FInsertFileInfo ( fiSrc );
			FInsertFileInfo ( fiTrg );
			FFileInfoFromNi ( niSrc, &pfiSrc );
			}
		}
	if ( pfiSrc && pfiSrc->NiOptions() != niOptions ) {
		assert ( ynmRet == ynmYes );
		if ( m_mrelog.FLogging() && pfiSrc->NiOptions() != niNil ) {
			m_mrelog.LogNote (
				"Note: '%s' must be compiled date due to options changing.\n",
				SzFromNi ( pfiSrc->Ni() )
				);
			}
		pfiSrc->SetNiOptions ( niOptions );
		}
		
	if ( m_mrelog.FLogging() ) {
		m_mrelog.LogNote (
			"Note: '%s' returning %s\n",
			szCanonSrc,
			((ynmRet == ynmNo) ? "ynmNo" : ((ynmRet == ynmYes) ? "ynmYes" : "ynmMaybe"))
			);
		}
	return ynmRet;
	}
Пример #5
0
BOOL
MRE::FCloseCompiland ( PMREFile pmrefile, BOOL fCommit ) {
	assert ( m_pmrefRoot );
	assert ( pmrefile == m_pmrefRoot );

	_TCHAR		szStreamName[ ctchMrePathMax ];
	Stream *	pstream;
	BOOL		fRet = fFalse;

	if ( m_mrelog.FLogging() ) {
		m_mrelog.LogNote ( 
			"Note: '%s' deps will %sbe committed.\n",
			SzFromNi ( m_pmrefRoot->Ni() ),
			fCommit ? "" : "not "
			);
		m_mrelog.LogSep();
		}

	if ( fCommit ) {
		_sntprintf (
			szStreamName,
			countof(szStreamName),
			c_szMreFileFmt,
			m_pmrefRoot->Ni()
			);
		// if we haven't hit all the classes that were noted as mr detectable,
		// we need to rude out those classes.
		Array<NI> &	rgni = m_pmrefRoot->RgNiClassesChanged();
		unsigned	iniMax = rgni.size();
		for ( unsigned ini = 0; ini < iniMax; ini++ ) {
			if ( rgni[ ini ] != niNil ) {
				// a class we didn't see a different type id for...
				PCI	pci;
				if ( FClassInfoFromNi ( rgni[ ini ], &pci ) ) {
					// we have to promote all nested types to rude.
					NoteRudeNestedClasses ( pci->Ti() );
					}
				}
			}

		if ( m_ppdb->OpenStream ( szStreamName, &pstream ) ) {
			// if we need to merge the class dependency data, we need
			// to read in the old stream first...
			if ( !m_pmrefRoot->FAllCodeCompiled() ) {
				MRFIBuf	mrfibufT;
				mrfibufT.SetPmre ( this );
				if ( mrfibufT.FInitFromStream ( pstream ) ) {
					assert ( mrfibufT.Pmrfi()->niFile == m_pmrefRoot->Ni() );

					m_mrfibufRoot.FmergeClassDeps ( mrfibufT );
					}
				}
			if ( m_mrfibufRoot.FReplaceStream ( pstream ) ) {
				fRet = fTrue;
				}
			else {
				pstream->Delete();
				}
			pstream->Release();
			}
		if ( fRet ) {
			// if everything is ok for the gen'ed dependencies, we
			// need to update the build # in the file info stream
			PFI	pfi = NULL;
			verify ( m_mpnifi.map ( m_pmrefRoot->Ni(), &pfi ) );
			if ( pfi ) {
				pfi->SetBuildId ( BuildId() );
				verify ( m_mpnifi.map ( pfi->NiRelated(), &pfi ) );
				if ( pfi ) {
					pfi->SetBuildId ( BuildId() );
					}
				}
			}
		}
	else {
		fRet = fTrue;
		}
	delete m_pmrefRoot;
	m_pmrefRoot = NULL;
	return fRet;
	}
Пример #6
0
BOOL
MRE::FOpenCompiland ( PMREFile * ppmrefile, SZC szFileSrc, SZC szFileTarg ) {
	BOOL	fRet = fFalse;
	_TCHAR	szCanonSrc [ ctchMrePathMax ];
	_TCHAR	szCanonTarg[ ctchMrePathMax ];

	*ppmrefile = NULL;

	// update the build count in the fileinfo stream
	IncBuildId();

	if ( m_mrfibufRoot.FInitEmpty() ) {
		NI	niSrc, niTarg;

		niSrc = NiFromName (
			SzFullCanonFilename ( szFileSrc, szCanonSrc, countof(szCanonSrc) )
			);
		niTarg = NiFromName (
			SzFullCanonFilename ( szFileTarg, szCanonTarg, countof(szCanonTarg) )
			);
		m_mrelog.LogCompiland ( niSrc, niTarg );
		if ( niSrc != niNil && niTarg != niNil ) {
			m_mrfibufRoot.SetNiFile ( niSrc, niTarg );


			// insert/update the fileinfo's if necessary.
			PFI	pfiSrc = NULL;
			if ( FFileInfoFromNi ( niSrc, &pfiSrc ) ) {
				assert ( pfiSrc->FHasTarget() );
				pfiSrc->SetFstatus ( fsmOutOfDate );
				m_mrelog.LogCompilandOptions ( pfiSrc->NiOptions() );
				}
			else {
				FI	fiSrc(niSrc, fsmHasTarget | fsmOutOfDate, BuildId());
				verify ( ::FFileInfo ( szCanonSrc, fiSrc ) );
				FInsertFileInfo ( fiSrc );
				}
			
			PFI	pfiTarg = NULL;
			if ( !FFileInfoFromNi ( niTarg, &pfiTarg ) ) {
				FI	fiTarg(niTarg, fsmIsTarget);
				::FFileInfo ( szCanonTarg, fiTarg );
				FInsertFileInfo ( fiTarg );
				}
			// update xref data, must get the pointers now, after all inserts
			if ( FFileInfoFromNi ( niSrc, &pfiSrc ) ) {
				pfiSrc->SetNiRelated ( niTarg );
				}
			if ( FFileInfoFromNi ( niTarg, &pfiTarg ) ) {
				pfiTarg->SetNiRelated ( niSrc );
				}

			if ( pfiSrc &&
				 pfiTarg &&
				 (m_pmrefRoot = new MREF(this, niSrc))
				) {
				// ready to go!
				*ppmrefile = m_pmrefRoot;
				fRet = fTrue;
				}
			}
		}

	return fRet;
	}