diff --git a/Source/cmElseCommand.cxx b/Source/cmElseCommand.cxx index dd396901f..2e309dd35 100644 --- a/Source/cmElseCommand.cxx +++ b/Source/cmElseCommand.cxx @@ -28,22 +28,18 @@ bool cmElseCommand::InitialPass(std::vector const& args) return false; } + // first remove any function blockers for the IF + m_Makefile->RemoveFunctionBlocker("ELSE",args); + // if is true create a blocker for the else - if (isTrue) - { - cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); - for(std::vector::const_iterator j = args.begin(); - j != args.end(); ++j) - { - f->m_Args.push_back(*j); - } - m_Makefile->AddFunctionBlocker(f); - } - else - { - // remove any function blockers for this define - m_Makefile->RemoveFunctionBlocker("ENDIF",args); + cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); + f->m_IsBlocking = isTrue; + for(std::vector::const_iterator j = args.begin(); + j != args.end(); ++j) + { + f->m_Args.push_back(*j); } + m_Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 5d207d4bf..4ad0b42a8 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -44,14 +44,21 @@ IsFunctionBlocked(const char *name, const std::vector &args, cmSystemTools::Error(err.c_str()); } } - return true; + return m_IsBlocking; } bool cmIfFunctionBlocker:: ShouldRemove(const char *name, const std::vector &args, cmMakefile &mf) { - return !this->IsFunctionBlocked(name,args,mf); + if (!strcmp(name,"ELSE") || !strcmp(name,"ENDIF")) + { + if (args == m_Args) + { + return true; + } + } + return false; } void cmIfFunctionBlocker:: @@ -80,17 +87,15 @@ bool cmIfCommand::InitialPass(std::vector const& args) return false; } - // if is isn't true create a blocker - if (!isTrue) - { - cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); - for(std::vector::const_iterator j = args.begin(); - j != args.end(); ++j) - { - f->m_Args.push_back(*j); - } - m_Makefile->AddFunctionBlocker(f); + cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); + // if is isn't true block the commands + f->m_IsBlocking = !isTrue; + for(std::vector::const_iterator j = args.begin(); + j != args.end(); ++j) + { + f->m_Args.push_back(*j); } + m_Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index b9a4fbb41..b5647c893 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -40,6 +40,7 @@ public: virtual void ScopeEnded(cmMakefile &mf); std::vector m_Args; + bool m_IsBlocking; }; /** \class cmIfCommand diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index e4ed43745..90e78d2bf 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -126,12 +126,12 @@ cmMakefile::~cmMakefile() delete d->second; } } - std::set::const_iterator pos; + std::list::const_iterator pos; for (pos = m_FunctionBlockers.begin(); pos != m_FunctionBlockers.end(); pos = m_FunctionBlockers.begin()) { cmFunctionBlocker* b = *pos; - m_FunctionBlockers.erase(*pos); + m_FunctionBlockers.remove(*pos); delete b; } delete m_MakefileGenerator; @@ -263,15 +263,26 @@ void cmMakefile::ExecuteCommand(std::string &name, // is "filename" and not "external". bool cmMakefile::ReadListFile(const char* filename, const char* external) { - // keep track of the current file being read + // used to watch for blockers going out of scope + // e.g. mismatched IF statement + std::set originalBlockers; + + // keep track of the current file being read if (filename) { if(m_cmCurrentListFile != filename) { m_cmCurrentListFile = filename; } + // loop over current function blockers and record them + std::list::const_iterator pos; + for (pos = m_FunctionBlockers.begin(); + pos != m_FunctionBlockers.end(); ++pos) + { + originalBlockers.insert(*pos); + } } - + // if this is not a remote makefile // (if it were, this would be called from the "filename" call, // rather than the "external" call) @@ -343,11 +354,16 @@ bool cmMakefile::ReadListFile(const char* filename, const char* external) if (filename) { // loop over all function blockers to see if any block this command - std::set::const_iterator pos; + std::list::const_iterator pos; for (pos = m_FunctionBlockers.begin(); pos != m_FunctionBlockers.end(); ++pos) { - (*pos)->ScopeEnded(*this); + // if this blocker was not in the original then send a + // scope ended message + if (originalBlockers.find(*pos) == originalBlockers.end()) + { + (*pos)->ScopeEnded(*this); + } } } @@ -1216,7 +1232,7 @@ bool cmMakefile::IsFunctionBlocked(const char *name, } // loop over all function blockers to see if any block this command - std::set::const_iterator pos; + std::list::const_iterator pos; std::vector expandedArguments = args; for(std::vector::iterator i = expandedArguments.begin(); i != expandedArguments.end(); ++i) @@ -1249,14 +1265,14 @@ void cmMakefile::RemoveFunctionBlocker(const char *name, const std::vector &args) { // loop over all function blockers to see if any block this command - std::set::const_iterator pos; - for (pos = m_FunctionBlockers.begin(); - pos != m_FunctionBlockers.end(); ++pos) + std::list::reverse_iterator pos; + for (pos = m_FunctionBlockers.rbegin(); + pos != m_FunctionBlockers.rend(); ++pos) { if ((*pos)->ShouldRemove(name, args, *this)) { cmFunctionBlocker* b = *pos; - m_FunctionBlockers.erase(*pos); + m_FunctionBlockers.remove(*pos); delete b; return; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index c1985f0f5..915950d17 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -79,9 +79,9 @@ public: * Add a function blocker to this makefile */ void AddFunctionBlocker(cmFunctionBlocker *fb) - { m_FunctionBlockers.insert(fb);} + { m_FunctionBlockers.push_back(fb);} void RemoveFunctionBlocker(cmFunctionBlocker *fb) - { m_FunctionBlockers.erase(fb);} + { m_FunctionBlockers.remove(fb);} void RemoveFunctionBlocker(const char *name, const std::vector &args); /** @@ -571,7 +571,7 @@ private: void PrintStringVector(const char* s, const std::vector& v) const; void AddDefaultCommands(); void AddDefaultDefinitions(); - std::set m_FunctionBlockers; + std::list m_FunctionBlockers; typedef std::map DataMap; DataMap m_DataMap;