Browse Source

better error handling with if statements

Ken Martin 23 years ago
parent
commit
32ad30e883
5 changed files with 58 additions and 40 deletions
  1. 10 14
      Source/cmElseCommand.cxx
  2. 17 12
      Source/cmIfCommand.cxx
  3. 1 0
      Source/cmIfCommand.h
  4. 27 11
      Source/cmMakefile.cxx
  5. 3 3
      Source/cmMakefile.h

+ 10 - 14
Source/cmElseCommand.cxx

@@ -28,22 +28,18 @@ bool cmElseCommand::InitialPass(std::vector<std::string> 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<std::string>::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<std::string>::const_iterator j = args.begin();
+      j != args.end(); ++j)
+    {   
+    f->m_Args.push_back(*j);
     }
+  m_Makefile->AddFunctionBlocker(f);
   
   return true;
 }

+ 17 - 12
Source/cmIfCommand.cxx

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

+ 1 - 0
Source/cmIfCommand.h

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

+ 27 - 11
Source/cmMakefile.cxx

@@ -126,12 +126,12 @@ cmMakefile::~cmMakefile()
       delete d->second;
       }
     }
-  std::set<cmFunctionBlocker *>::const_iterator pos;
+  std::list<cmFunctionBlocker *>::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<cmFunctionBlocker *> 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<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 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<cmFunctionBlocker *>::const_iterator pos;
+    std::list<cmFunctionBlocker *>::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<cmFunctionBlocker *>::const_iterator pos;
+  std::list<cmFunctionBlocker *>::const_iterator pos;
   std::vector<std::string> expandedArguments = args;
   for(std::vector<std::string>::iterator i = expandedArguments.begin();
       i != expandedArguments.end(); ++i)
@@ -1249,14 +1265,14 @@ void cmMakefile::RemoveFunctionBlocker(const char *name,
 				       const std::vector<std::string> &args)
 {
   // loop over all function blockers to see if any block this command
-  std::set<cmFunctionBlocker *>::const_iterator pos;
-  for (pos = m_FunctionBlockers.begin(); 
-       pos != m_FunctionBlockers.end(); ++pos)
+  std::list<cmFunctionBlocker *>::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;
       }

+ 3 - 3
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<std::string> &args);
   
   /**
@@ -571,7 +571,7 @@ private:
   void PrintStringVector(const char* s, const std::vector<std::string>& v) const;
   void AddDefaultCommands();
   void AddDefaultDefinitions();
-  std::set<cmFunctionBlocker *> m_FunctionBlockers;
+  std::list<cmFunctionBlocker *> m_FunctionBlockers;
   
   typedef std::map<cmStdString, cmData*> DataMap;
   DataMap m_DataMap;