소스 검색

ENH: allow loose loop constructs

Ken Martin 19 년 전
부모
커밋
29a03db7ce
5개의 변경된 파일74개의 추가작업 그리고 63개의 파일을 삭제
  1. 19 8
      Source/cmForEachCommand.cxx
  2. 3 1
      Source/cmForEachCommand.h
  3. 13 32
      Source/cmIfCommand.cxx
  4. 36 21
      Source/cmWhileCommand.cxx
  5. 3 1
      Source/cmWhileCommand.h

+ 19 - 8
Source/cmForEachCommand.cxx

@@ -25,14 +25,18 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
     {
     return false;
     }
-  
-  // at end of for each execute recorded commands
-  if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
+
+  if (cmSystemTools::LowerCase(lff.Name) == "foreach")
     {
-    std::vector<std::string> expandedArguments;
-    mf.ExpandArguments(lff.Arguments, expandedArguments);
-    if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
+    // record the number of nested foreach commands
+    this->Depth++;
+    }
+  else if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
+    {
+    // if this is the endofreach for this statement
+    if (!this->Depth) 
       {
+      // at end of for each execute recorded commands
       // store the old value
       std::string oldDef;
       if (mf.GetDefinition(this->Args[0].c_str()))
@@ -60,8 +64,13 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
       mf.RemoveFunctionBlocker(lff);
       return true;
       }
+    else
+      {
+      // close out a nested foreach
+      this->Depth--;
+      }
     }
-
+  
   // record the command
   this->Functions.push_back(lff);
   
@@ -76,7 +85,9 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
     {
     std::vector<std::string> expandedArguments;
     mf.ExpandArguments(lff.Arguments, expandedArguments);
-    if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
+    if ((!expandedArguments.empty() && 
+         (expandedArguments[0] == this->Args[0]))
+        || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
       {
       return true;
       }

+ 3 - 1
Source/cmForEachCommand.h

@@ -29,7 +29,7 @@
 class cmForEachFunctionBlocker : public cmFunctionBlocker
 {
 public:
-  cmForEachFunctionBlocker() {this->Executing = false;}
+  cmForEachFunctionBlocker() {this->Executing = false; Depth = 0;}
   virtual ~cmForEachFunctionBlocker() {}
   virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
                                  cmMakefile &mf);
@@ -39,6 +39,8 @@ public:
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
   bool Executing;
+private:
+  int Depth;
 };
 
 /** \class cmForEachCommand

+ 13 - 32
Source/cmIfCommand.cxx

@@ -34,53 +34,34 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
   if (cmSystemTools::LowerCase(lff.Name) == "else" || 
       cmSystemTools::LowerCase(lff.Name) == "endif")
     {
-    if (args == this->Args)
-      {
-      // if it was an else statement then we should change state
-      // and block this Else Command
-      if (cmSystemTools::LowerCase(lff.Name) == "else")
+    // if it was an else statement then we should change state
+    // and block this Else Command
+    if (cmSystemTools::LowerCase(lff.Name) == "else")
         {
         this->IsBlocking = !this->IsBlocking;
         return true;
         }
-      // otherwise it must be an ENDIF statement, in that case remove the
-      // function blocker
-      mf.RemoveFunctionBlocker(lff);
-      return true;
-      }
-    else if(args.empty())
-      {
-      std::string err = "Empty arguments for ";
-      err += name;
-      err += ".  Did you mean ";
-      err += name;
-      err += "( ";
-      for(std::vector<cmListFileArgument>::const_iterator a = 
-            this->Args.begin();
-          a != this->Args.end();++a)
-        {
-        err += (a->Quoted?"\"":"");
-        err += a->Value;
-        err += (a->Quoted?"\"":"");
-        err += " ";
-        }
-      err += ")?";
-      cmSystemTools::Error(err.c_str());
-      }
-    }
+     // otherwise it must be an ENDIF statement, in that case remove the
+     // function blocker
+     mf.RemoveFunctionBlocker(lff);
+     return true;
+   }
+   
   return this->IsBlocking;
 }
 
 bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
-                                       cmMakefile&)
+                                       cmMakefile& mf)
 {
   if (cmSystemTools::LowerCase(lff.Name) == "endif")
     {
-    if (lff.Arguments == this->Args)
+    if (mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS") 
+        || lff.Arguments == this->Args)
       {
       return true;
       }
     }
+
   return false;
 }
 

+ 36 - 21
Source/cmWhileCommand.cxx

@@ -28,30 +28,44 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
     }
   
   // at end of for each execute recorded commands
-  if (cmSystemTools::LowerCase(lff.Name) == "endwhile")
+  if (cmSystemTools::LowerCase(lff.Name) == "while")
     {
-    char* errorString = 0;
+    // record the number of while commands past this one
+    this->Depth++;
+    }
+  else if (cmSystemTools::LowerCase(lff.Name) == "endwhile")
+    {
+    // if this is the endwhile for this while loop then execute
+    if (!this->Depth) 
+      {
+      char* errorString = 0;
     
-    std::vector<std::string> expandedArguments;
-    mf.ExpandArguments(this->Args, expandedArguments);
-    bool isTrue = 
-      cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
-
-    this->Executing = true;
-    while (isTrue)
-      {      
-      // Invoke all the functions that were collected in the block.
-      for(unsigned int c = 0; c < this->Functions.size(); ++c)
-        {
-        mf.ExecuteCommand(this->Functions[c]);
-        }
-      expandedArguments.clear();
+      std::vector<std::string> expandedArguments;
       mf.ExpandArguments(this->Args, expandedArguments);
-      isTrue = 
+      bool isTrue = 
         cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
+
+      this->Executing = true;
+      while (isTrue)
+        {      
+        // Invoke all the functions that were collected in the block.
+        for(unsigned int c = 0; c < this->Functions.size(); ++c)
+          {
+          mf.ExecuteCommand(this->Functions[c]);
+          }
+        expandedArguments.clear();
+        mf.ExpandArguments(this->Args, expandedArguments);
+        isTrue = 
+          cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
+        }
+      mf.RemoveFunctionBlocker(lff);
+      return true;
+      }
+    else
+      {
+      // decrement for each nested while that ends
+      this->Depth--;
       }
-    mf.RemoveFunctionBlocker(lff);
-    return true;
     }
 
   // record the command
@@ -62,11 +76,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
 }
 
 bool cmWhileFunctionBlocker::
-ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
+ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
 {
   if(cmSystemTools::LowerCase(lff.Name) == "endwhile")
     {
-    if (lff.Arguments == this->Args)
+    if (lff.Arguments == this->Args
+        || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
       {
       return true;
       }

+ 3 - 1
Source/cmWhileCommand.h

@@ -29,7 +29,7 @@
 class cmWhileFunctionBlocker : public cmFunctionBlocker
 {
 public:
-  cmWhileFunctionBlocker() {Executing = false;}
+  cmWhileFunctionBlocker() {Executing = false; Depth=0;}
   virtual ~cmWhileFunctionBlocker() {}
   virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
                                  cmMakefile &mf);
@@ -39,6 +39,8 @@ public:
   std::vector<cmListFileArgument> Args;
   std::vector<cmListFileFunction> Functions;
   bool Executing;
+private:
+  int Depth;
 };
 
 /** \class cmWhileCommand