Parcourir la source

ENH: Refactor CTest command argument handling

The previous approach to handling of arguments to ctest_* commands
worked only for keyword/value arguments with a single value.  This
refactors the approach to allow some commands to define alternative
argument forms.
Brad King il y a 17 ans
Parent
commit
ae2c4143d2
2 fichiers modifiés avec 64 ajouts et 50 suppressions
  1. 51 48
      Source/CTest/cmCTestHandlerCommand.cxx
  2. 13 2
      Source/CTest/cmCTestHandlerCommand.h

+ 51 - 48
Source/CTest/cmCTestHandlerCommand.cxx

@@ -38,10 +38,29 @@ cmCTestHandlerCommand::cmCTestHandlerCommand()
 bool cmCTestHandlerCommand
 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
 {
-  if ( !this->ProcessArguments(args, (unsigned int)this->Last, 
-                               &*this->Arguments.begin(),this->Values) )
+  // Allocate space for argument values.
+  this->Values.clear();
+  this->Values.resize(this->Last, 0);
+
+  // Process input arguments.
+  this->ArgumentDoing = ArgumentDoingNone;
+  for(unsigned int i=0; i < args.size(); ++i)
     {
-    return false;
+    // Check this argument.
+    if(!this->CheckArgumentKeyword(args[i]) &&
+       !this->CheckArgumentValue(args[i]))
+      {
+      cmOStringStream e;
+      e << "called with unknown argument \"" << args[i] << "\".";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+
+    // Quit if an argument is invalid.
+    if(this->ArgumentDoing == ArgumentDoingError)
+      {
+      return false;
+      }
     }
 
   cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
@@ -121,57 +140,41 @@ bool cmCTestHandlerCommand
   return true;
 }
 
-bool cmCTestHandlerCommand::ProcessArguments(
-  std::vector<std::string> const& args, int last, const char** strings,
-  std::vector<const char*>& values)
+//----------------------------------------------------------------------------
+bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
 {
-  int state = 0;
-  int cc;
-  values.resize(last);
-  for ( cc = 0; cc < last; ++ cc )
+  // Check for a keyword in our argument/value table.
+  for(unsigned int k=0; k < this->Arguments.size(); ++k)
     {
-    values[cc] = 0;
+    if(this->Arguments[k] && arg == this->Arguments[k])
+      {
+      this->ArgumentDoing = ArgumentDoingKeyword;
+      this->ArgumentIndex = k;
+      return true;
+      }
     }
+  return false;
+}
 
-  for(size_t i=0; i < args.size(); ++i)
+//----------------------------------------------------------------------------
+bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
+{
+  if(this->ArgumentDoing == ArgumentDoingKeyword)
     {
-    if ( state > 0 && state < last )
+    this->ArgumentDoing = ArgumentDoingNone;
+    unsigned int k = this->ArgumentIndex;
+    if(this->Values[k])
       {
-      values[state] = args[i].c_str();
-      cmCTestLog(this->CTest, DEBUG, "Set " << strings[state] << " to "
-        << args[i].c_str() << std::endl);
-      state = 0;
-      }
-    else
-      {
-      bool found = false;
-      for ( cc = 0; cc < last; ++ cc )
-        {
-        if ( strings[cc] && args[i] == strings[cc] )
-          {
-          state = cc;
-          if ( values[state] )
-            {
-            cmOStringStream ostr;
-            ostr << "called with incorrect number of arguments. "
-              << strings[state] << " specified twice.";
-            this->SetError(ostr.str().c_str());
-            return false;
-            }
-          found = true;
-          break;
-          }
-        }
-      if ( !found )
-        {
-        cmOStringStream str;
-        str
-          << "called with incorrect number of arguments. Extra argument is: "
-          << args[i].c_str() << ".";
-        this->SetError(str.str().c_str());
-        return false;
-        }
+      cmOStringStream e;
+      e << "Called with more than one value for " << this->Arguments[k];
+      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      this->ArgumentDoing = ArgumentDoingError;
+      return true;
       }
+    this->Values[k] = arg.c_str();
+    cmCTestLog(this->CTest, DEBUG, "Set " << this->Arguments[k]
+               << " to " << arg << "\n");
+    return true;
     }
-  return true;
+  return false;
 }

+ 13 - 2
Source/CTest/cmCTestHandlerCommand.h

@@ -52,8 +52,19 @@ public:
 
 protected:
   virtual cmCTestGenericHandler* InitializeHandler() = 0;
-  bool ProcessArguments(std::vector<std::string> const& args,
-    int last, const char** strings, std::vector<const char*>& values);
+
+  // Command argument handling.
+  virtual bool CheckArgumentKeyword(std::string const& arg);
+  virtual bool CheckArgumentValue(std::string const& arg);
+  enum
+  {
+    ArgumentDoingNone,
+    ArgumentDoingError,
+    ArgumentDoingKeyword,
+    ArgumentDoingLast1
+  };
+  int ArgumentDoing;
+  unsigned int ArgumentIndex;
 
   std::string ReturnVariable;
   std::vector<const char*> Arguments;