[Cmake-commits] [cmake-commits] king committed cmMakefile.cxx 1.493 1.494 cmMakefile.h 1.243 1.244
cmake-commits at cmake.org
cmake-commits at cmake.org
Wed Jan 21 09:48:02 EST 2009
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv8272/Source
Modified Files:
cmMakefile.cxx cmMakefile.h
Log Message:
ENH: Refactor logical block enforcement
This uses a stack of 'barriers' to efficiently divide function blockers
into groups corresponding to each input file. It simplifies detection
of missing block close commands and factors it out of ReadListFile.
Index: cmMakefile.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefile.h,v
retrieving revision 1.243
retrieving revision 1.244
diff -C 2 -d -r1.243 -r1.244
*** cmMakefile.h 20 Jan 2009 19:36:18 -0000 1.243
--- cmMakefile.h 21 Jan 2009 14:48:00 -0000 1.244
***************
*** 99,102 ****
--- 99,115 ----
RemoveFunctionBlocker(const cmListFileFunction& lff);
+ /** Push/pop a lexical (function blocker) barrier automatically. */
+ class LexicalPushPop
+ {
+ public:
+ LexicalPushPop(cmMakefile* mf);
+ ~LexicalPushPop();
+ void Quiet() { this->ReportError = false; }
+ private:
+ cmMakefile* Makefile;
+ bool ReportError;
+ };
+ friend class LexicalPushPop;
+
/**
* Try running cmake and building a file. This is used for dynalically
***************
*** 877,881 ****
void AddDefaultDefinitions();
! std::list<cmFunctionBlocker *> FunctionBlockers;
typedef std::map<cmStdString, cmData*> DataMapType;
--- 890,898 ----
void AddDefaultDefinitions();
! typedef std::vector<cmFunctionBlocker*> FunctionBlockersType;
! FunctionBlockersType FunctionBlockers;
! std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
! void PushFunctionBlockerBarrier();
! void PopFunctionBlockerBarrier(bool reportError = true);
typedef std::map<cmStdString, cmData*> DataMapType;
Index: cmMakefile.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefile.cxx,v
retrieving revision 1.493
retrieving revision 1.494
diff -C 2 -d -r1.493 -r1.494
*** cmMakefile.cxx 20 Jan 2009 19:36:18 -0000 1.493
--- cmMakefile.cxx 21 Jan 2009 14:48:00 -0000 1.494
***************
*** 207,211 ****
}
}
! std::list<cmFunctionBlocker *>::iterator pos;
for (pos = this->FunctionBlockers.begin();
pos != this->FunctionBlockers.end(); ++pos)
--- 207,211 ----
}
}
! std::vector<cmFunctionBlocker*>::iterator pos;
for (pos = this->FunctionBlockers.begin();
pos != this->FunctionBlockers.end(); ++pos)
***************
*** 454,461 ****
this->AddDefinition("CMAKE_PARENT_LIST_FILE", filename_in);
- // used to watch for blockers going out of scope
- // e.g. mismatched IF statement
- std::set<cmFunctionBlocker *> originalBlockers;
-
const char* external = 0;
std::string external_abs;
--- 454,457 ----
***************
*** 488,499 ****
}
- // loop over current function blockers and record them
- for (std::list<cmFunctionBlocker *>::iterator pos
- = this->FunctionBlockers.begin();
- pos != this->FunctionBlockers.end(); ++pos)
- {
- originalBlockers.insert(*pos);
- }
-
// Now read the input file
const char *filenametoread= filename;
--- 484,487 ----
***************
*** 542,545 ****
--- 530,537 ----
// add this list file to the list of dependencies
this->ListFiles.push_back( filenametoread);
+
+ // Enforce balanced blocks (if/endif, function/endfunction, etc.).
+ {
+ LexicalPushPop lexScope(this);
bool endScopeNicely = true;
***************
*** 553,561 ****
cmExecutionStatus status;
this->ExecuteCommand(cacheFile.Functions[i],status);
! if (status.GetReturnInvoked() ||
! cmSystemTools::GetFatalErrorOccured() )
{
! // Exit early from processing this file.
endScopeNicely = false;
break;
}
--- 545,558 ----
cmExecutionStatus status;
this->ExecuteCommand(cacheFile.Functions[i],status);
! if(cmSystemTools::GetFatalErrorOccured())
{
! // Exit early due to error.
endScopeNicely = false;
+ lexScope.Quiet();
+ break;
+ }
+ if(status.GetReturnInvoked())
+ {
+ // Exit early due to return command.
break;
}
***************
*** 572,592 ****
this->PopPolicy(false);
}
!
! // send scope ended to and function blockers
! if (endScopeNicely)
! {
! // loop over all function blockers to see if any block this command
! for (std::list<cmFunctionBlocker *>::iterator pos
! = this->FunctionBlockers.begin();
! pos != this->FunctionBlockers.end(); ++pos)
! {
! // if this blocker was not in the original then send a
! // scope ended message
! if (originalBlockers.find(*pos) == originalBlockers.end())
! {
! (*pos)->ScopeEnded(*this);
! }
! }
! }
// If this is the directory-level CMakeLists.txt file then perform
--- 569,573 ----
this->PopPolicy(false);
}
! }
// If this is the directory-level CMakeLists.txt file then perform
***************
*** 2354,2358 ****
// loop over all function blockers to see if any block this command
// evaluate in reverse, this is critical for balanced IF statements etc
! std::list<cmFunctionBlocker *>::reverse_iterator pos;
for (pos = this->FunctionBlockers.rbegin();
pos != this->FunctionBlockers.rend(); ++pos)
--- 2335,2339 ----
// loop over all function blockers to see if any block this command
// evaluate in reverse, this is critical for balanced IF statements etc
! std::vector<cmFunctionBlocker*>::reverse_iterator pos;
for (pos = this->FunctionBlockers.rbegin();
pos != this->FunctionBlockers.rend(); ++pos)
***************
*** 2367,2370 ****
--- 2348,2377 ----
}
+ //----------------------------------------------------------------------------
+ void cmMakefile::PushFunctionBlockerBarrier()
+ {
+ this->FunctionBlockerBarriers.push_back(this->FunctionBlockers.size());
+ }
+
+ //----------------------------------------------------------------------------
+ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
+ {
+ // Remove any extra entries pushed on the barrier.
+ FunctionBlockersType::size_type barrier =
+ this->FunctionBlockerBarriers.back();
+ while(this->FunctionBlockers.size() > barrier)
+ {
+ cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back());
+ this->FunctionBlockers.pop_back();
+ if(reportError)
+ {
+ fb->ScopeEnded(*this);
+ }
+ }
+
+ // Remove the barrier.
+ this->FunctionBlockerBarriers.pop_back();
+ }
+
bool cmMakefile::ExpandArguments(
std::vector<cmListFileArgument> const& inArgs,
***************
*** 2399,2411 ****
cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
{
! // loop over all function blockers to see if any block this command
! std::list<cmFunctionBlocker *>::reverse_iterator pos;
! for (pos = this->FunctionBlockers.rbegin();
! pos != this->FunctionBlockers.rend(); ++pos)
{
if ((*pos)->ShouldRemove(lff, *this))
{
cmFunctionBlocker* b = *pos;
! this->FunctionBlockers.remove(b);
return cmsys::auto_ptr<cmFunctionBlocker>(b);
}
--- 2406,2427 ----
cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
{
! // Find the function blocker stack barrier for the current scope.
! // We only remove a blocker whose index is not less than the barrier.
! FunctionBlockersType::size_type barrier = 0;
! if(!this->FunctionBlockerBarriers.empty())
{
+ barrier = this->FunctionBlockerBarriers.back();
+ }
+
+ // Search for the function blocker whose scope this command ends.
+ for(FunctionBlockersType::size_type
+ i = this->FunctionBlockers.size(); i > barrier; --i)
+ {
+ std::vector<cmFunctionBlocker*>::iterator pos =
+ this->FunctionBlockers.begin() + (i - 1);
if ((*pos)->ShouldRemove(lff, *this))
{
cmFunctionBlocker* b = *pos;
! this->FunctionBlockers.erase(pos);
return cmsys::auto_ptr<cmFunctionBlocker>(b);
}
***************
*** 2415,2418 ****
--- 2431,2447 ----
}
+ //----------------------------------------------------------------------------
+ cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
+ Makefile(mf), ReportError(true)
+ {
+ this->Makefile->PushFunctionBlockerBarrier();
+ }
+
+ //----------------------------------------------------------------------------
+ cmMakefile::LexicalPushPop::~LexicalPushPop()
+ {
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+ }
+
void cmMakefile::SetHomeDirectory(const char* dir)
{
More information about the Cmake-commits
mailing list