better error handling with if statements

This commit is contained in:
Ken Martin 2002-07-10 11:38:38 -04:00
parent 9f6ebe4eb7
commit 32ad30e883
5 changed files with 58 additions and 40 deletions

View File

@ -28,22 +28,18 @@ bool cmElseCommand::InitialPass(std::vector<std::string> const& args)
return false; 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 is true create a blocker for the else
if (isTrue) cmIfFunctionBlocker *f = new cmIfFunctionBlocker();
{ f->m_IsBlocking = isTrue;
cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); for(std::vector<std::string>::const_iterator j = args.begin();
for(std::vector<std::string>::const_iterator j = args.begin(); j != args.end(); ++j)
j != args.end(); ++j) {
{ f->m_Args.push_back(*j);
f->m_Args.push_back(*j);
}
m_Makefile->AddFunctionBlocker(f);
}
else
{
// remove any function blockers for this define
m_Makefile->RemoveFunctionBlocker("ENDIF",args);
} }
m_Makefile->AddFunctionBlocker(f);
return true; return true;
} }

View File

@ -44,14 +44,21 @@ IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
cmSystemTools::Error(err.c_str()); cmSystemTools::Error(err.c_str());
} }
} }
return true; return m_IsBlocking;
} }
bool cmIfFunctionBlocker:: bool cmIfFunctionBlocker::
ShouldRemove(const char *name, const std::vector<std::string> &args, ShouldRemove(const char *name, const std::vector<std::string> &args,
cmMakefile &mf) 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:: void cmIfFunctionBlocker::
@ -80,17 +87,15 @@ bool cmIfCommand::InitialPass(std::vector<std::string> const& args)
return false; return false;
} }
// if is isn't true create a blocker cmIfFunctionBlocker *f = new cmIfFunctionBlocker();
if (!isTrue) // if is isn't true block the commands
{ f->m_IsBlocking = !isTrue;
cmIfFunctionBlocker *f = new cmIfFunctionBlocker(); for(std::vector<std::string>::const_iterator j = args.begin();
for(std::vector<std::string>::const_iterator j = args.begin(); j != args.end(); ++j)
j != args.end(); ++j) {
{ f->m_Args.push_back(*j);
f->m_Args.push_back(*j);
}
m_Makefile->AddFunctionBlocker(f);
} }
m_Makefile->AddFunctionBlocker(f);
return true; return true;
} }

View File

@ -40,6 +40,7 @@ public:
virtual void ScopeEnded(cmMakefile &mf); virtual void ScopeEnded(cmMakefile &mf);
std::vector<std::string> m_Args; std::vector<std::string> m_Args;
bool m_IsBlocking;
}; };
/** \class cmIfCommand /** \class cmIfCommand

View File

@ -126,12 +126,12 @@ cmMakefile::~cmMakefile()
delete d->second; delete d->second;
} }
} }
std::set<cmFunctionBlocker *>::const_iterator pos; std::list<cmFunctionBlocker *>::const_iterator pos;
for (pos = m_FunctionBlockers.begin(); for (pos = m_FunctionBlockers.begin();
pos != m_FunctionBlockers.end(); pos = m_FunctionBlockers.begin()) pos != m_FunctionBlockers.end(); pos = m_FunctionBlockers.begin())
{ {
cmFunctionBlocker* b = *pos; cmFunctionBlocker* b = *pos;
m_FunctionBlockers.erase(*pos); m_FunctionBlockers.remove(*pos);
delete b; delete b;
} }
delete m_MakefileGenerator; delete m_MakefileGenerator;
@ -263,15 +263,26 @@ void cmMakefile::ExecuteCommand(std::string &name,
// is "filename" and not "external". // is "filename" and not "external".
bool cmMakefile::ReadListFile(const char* filename, const char* 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<cmFunctionBlocker *> originalBlockers;
// keep track of the current file being read
if (filename) if (filename)
{ {
if(m_cmCurrentListFile != filename) if(m_cmCurrentListFile != filename)
{ {
m_cmCurrentListFile = filename; m_cmCurrentListFile = filename;
} }
// loop over current function blockers and record them
std::list<cmFunctionBlocker *>::const_iterator pos;
for (pos = m_FunctionBlockers.begin();
pos != m_FunctionBlockers.end(); ++pos)
{
originalBlockers.insert(*pos);
}
} }
// if this is not a remote makefile // if this is not a remote makefile
// (if it were, this would be called from the "filename" call, // (if it were, this would be called from the "filename" call,
// rather than the "external" call) // rather than the "external" call)
@ -343,11 +354,16 @@ bool cmMakefile::ReadListFile(const char* filename, const char* external)
if (filename) if (filename)
{ {
// loop over all function blockers to see if any block this command // loop over all function blockers to see if any block this command
std::set<cmFunctionBlocker *>::const_iterator pos; std::list<cmFunctionBlocker *>::const_iterator pos;
for (pos = m_FunctionBlockers.begin(); for (pos = m_FunctionBlockers.begin();
pos != m_FunctionBlockers.end(); ++pos) 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 // loop over all function blockers to see if any block this command
std::set<cmFunctionBlocker *>::const_iterator pos; std::list<cmFunctionBlocker *>::const_iterator pos;
std::vector<std::string> expandedArguments = args; std::vector<std::string> expandedArguments = args;
for(std::vector<std::string>::iterator i = expandedArguments.begin(); for(std::vector<std::string>::iterator i = expandedArguments.begin();
i != expandedArguments.end(); ++i) i != expandedArguments.end(); ++i)
@ -1249,14 +1265,14 @@ void cmMakefile::RemoveFunctionBlocker(const char *name,
const std::vector<std::string> &args) const std::vector<std::string> &args)
{ {
// loop over all function blockers to see if any block this command // loop over all function blockers to see if any block this command
std::set<cmFunctionBlocker *>::const_iterator pos; std::list<cmFunctionBlocker *>::reverse_iterator pos;
for (pos = m_FunctionBlockers.begin(); for (pos = m_FunctionBlockers.rbegin();
pos != m_FunctionBlockers.end(); ++pos) pos != m_FunctionBlockers.rend(); ++pos)
{ {
if ((*pos)->ShouldRemove(name, args, *this)) if ((*pos)->ShouldRemove(name, args, *this))
{ {
cmFunctionBlocker* b = *pos; cmFunctionBlocker* b = *pos;
m_FunctionBlockers.erase(*pos); m_FunctionBlockers.remove(*pos);
delete b; delete b;
return; return;
} }

View File

@ -79,9 +79,9 @@ public:
* Add a function blocker to this makefile * Add a function blocker to this makefile
*/ */
void AddFunctionBlocker(cmFunctionBlocker *fb) void AddFunctionBlocker(cmFunctionBlocker *fb)
{ m_FunctionBlockers.insert(fb);} { m_FunctionBlockers.push_back(fb);}
void RemoveFunctionBlocker(cmFunctionBlocker *fb) void RemoveFunctionBlocker(cmFunctionBlocker *fb)
{ m_FunctionBlockers.erase(fb);} { m_FunctionBlockers.remove(fb);}
void RemoveFunctionBlocker(const char *name, const std::vector<std::string> &args); void RemoveFunctionBlocker(const char *name, const std::vector<std::string> &args);
/** /**
@ -571,7 +571,7 @@ private:
void PrintStringVector(const char* s, const std::vector<std::string>& v) const; void PrintStringVector(const char* s, const std::vector<std::string>& v) const;
void AddDefaultCommands(); void AddDefaultCommands();
void AddDefaultDefinitions(); void AddDefaultDefinitions();
std::set<cmFunctionBlocker *> m_FunctionBlockers; std::list<cmFunctionBlocker *> m_FunctionBlockers;
typedef std::map<cmStdString, cmData*> DataMap; typedef std::map<cmStdString, cmData*> DataMap;
DataMap m_DataMap; DataMap m_DataMap;