Просмотр исходного кода

cmFileCommand: Port to cmArgumentParser

Regina Pfeifer 6 лет назад
Родитель
Сommit
4336a29edd
1 измененных файлов с 74 добавлено и 81 удалено
  1. 74 81
      Source/cmFileCommand.cxx

+ 74 - 81
Source/cmFileCommand.cxx

@@ -3,6 +3,7 @@
 #include "cmFileCommand.h"
 
 #include "cm_kwiml.h"
+#include "cm_static_string_view.hxx"
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
@@ -19,7 +20,7 @@
 #include <vector>
 
 #include "cmAlgorithms.h"
-#include "cmCommandArgumentsHelper.h"
+#include "cmArgumentParser.h"
 #include "cmCryptoHash.h"
 #include "cmFileCopier.h"
 #include "cmFileInstaller.h"
@@ -268,36 +269,34 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
     return false;
   }
 
-  cmCommandArgumentsHelper argHelper;
-  cmCommandArgumentGroup group;
+  std::string const& fileNameArg = args[1];
+  std::string const& variable = args[2];
 
-  cmCAString readArg(&argHelper, "READ");
-  cmCAString fileNameArg(&argHelper, nullptr);
-  cmCAString resultArg(&argHelper, nullptr);
+  struct Arguments
+  {
+    std::string Offset;
+    std::string Limit;
+    bool Hex = false;
+  };
+
+  static auto const parser = cmArgumentParser<Arguments>{}
+                               .Bind("OFFSET"_s, &Arguments::Offset)
+                               .Bind("LIMIT"_s, &Arguments::Limit)
+                               .Bind("HEX"_s, &Arguments::Hex);
 
-  cmCAString offsetArg(&argHelper, "OFFSET", &group);
-  cmCAString limitArg(&argHelper, "LIMIT", &group);
-  cmCAEnabler hexOutputArg(&argHelper, "HEX", &group);
-  readArg.Follows(nullptr);
-  fileNameArg.Follows(&readArg);
-  resultArg.Follows(&fileNameArg);
-  group.Follows(&resultArg);
-  argHelper.Parse(&args, nullptr);
+  Arguments const arguments = parser.Parse(cmMakeRange(args).advance(3));
 
-  std::string fileName = fileNameArg.GetString();
+  std::string fileName = fileNameArg;
   if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
     fileName = this->Makefile->GetCurrentSourceDirectory();
-    fileName += "/" + fileNameArg.GetString();
+    fileName += "/" + fileNameArg;
   }
 
-  std::string variable = resultArg.GetString();
-
 // Open the specified file.
 #if defined(_WIN32) || defined(__CYGWIN__)
-  cmsys::ifstream file(
-    fileName.c_str(),
-    std::ios::in |
-      (hexOutputArg.IsEnabled() ? std::ios::binary : std::ios::in));
+  cmsys::ifstream file(fileName.c_str(),
+                       arguments.Hex ? (std::ios::binary | std::ios::in)
+                                     : std::ios::in);
 #else
   cmsys::ifstream file(fileName.c_str());
 #endif
@@ -313,21 +312,21 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
 
   // is there a limit?
   long sizeLimit = -1;
-  if (!limitArg.GetString().empty()) {
-    sizeLimit = atoi(limitArg.GetCString());
+  if (!arguments.Limit.empty()) {
+    sizeLimit = atoi(arguments.Limit.c_str());
   }
 
   // is there an offset?
   long offset = 0;
-  if (!offsetArg.GetString().empty()) {
-    offset = atoi(offsetArg.GetCString());
+  if (!arguments.Offset.empty()) {
+    offset = atoi(arguments.Offset.c_str());
   }
 
   file.seekg(offset, std::ios::beg); // explicit ios::beg for IBM VisualAge 6
 
   std::string output;
 
-  if (hexOutputArg.IsEnabled()) {
+  if (arguments.Hex) {
     // Convert part of the file into hex code
     char c;
     while ((sizeLimit != 0) && (file.get(c))) {
@@ -1272,55 +1271,54 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
     return false;
   }
 
-  cmCommandArgumentsHelper argHelper;
-  cmCommandArgumentGroup group;
-
-  cmCAString readArg(&argHelper, "READ_ELF");
-  cmCAString fileNameArg(&argHelper, nullptr);
+  std::string const& fileNameArg = args[1];
 
-  cmCAString rpathArg(&argHelper, "RPATH", &group);
-  cmCAString runpathArg(&argHelper, "RUNPATH", &group);
-  cmCAString errorArg(&argHelper, "CAPTURE_ERROR", &group);
+  struct Arguments
+  {
+    std::string RPath;
+    std::string RunPath;
+    std::string Error;
+  };
 
-  readArg.Follows(nullptr);
-  fileNameArg.Follows(&readArg);
-  group.Follows(&fileNameArg);
-  argHelper.Parse(&args, nullptr);
+  static auto const parser = cmArgumentParser<Arguments>{}
+                               .Bind("RPATH"_s, &Arguments::RPath)
+                               .Bind("RUNPATH"_s, &Arguments::RunPath)
+                               .Bind("CAPTURE_ERROR"_s, &Arguments::Error);
+  Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2));
 
-  if (!cmSystemTools::FileExists(fileNameArg.GetString(), true)) {
+  if (!cmSystemTools::FileExists(fileNameArg, true)) {
     std::ostringstream e;
-    e << "READ_ELF given FILE \"" << fileNameArg.GetString()
-      << "\" that does not exist.";
+    e << "READ_ELF given FILE \"" << fileNameArg << "\" that does not exist.";
     this->SetError(e.str());
     return false;
   }
 
 #if defined(CMAKE_USE_ELF_PARSER)
-  cmELF elf(fileNameArg.GetCString());
+  cmELF elf(fileNameArg.c_str());
 
-  if (!rpathArg.GetString().empty()) {
+  if (!arguments.RPath.empty()) {
     if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
       std::string rpath(se_rpath->Value);
       std::replace(rpath.begin(), rpath.end(), ':', ';');
-      this->Makefile->AddDefinition(rpathArg.GetString(), rpath.c_str());
+      this->Makefile->AddDefinition(arguments.RPath, rpath.c_str());
     }
   }
-  if (!runpathArg.GetString().empty()) {
+  if (!arguments.RunPath.empty()) {
     if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
       std::string runpath(se_runpath->Value);
       std::replace(runpath.begin(), runpath.end(), ':', ';');
-      this->Makefile->AddDefinition(runpathArg.GetString(), runpath.c_str());
+      this->Makefile->AddDefinition(arguments.RunPath, runpath.c_str());
     }
   }
 
   return true;
 #else
   std::string error = "ELF parser not available on this platform.";
-  if (errorArg.GetString().empty()) {
+  if (arguments.Error.empty()) {
     this->SetError(error);
     return false;
   }
-  this->Makefile->AddDefinition(errorArg.GetString(), error.c_str());
+  this->Makefile->AddDefinition(arguments.Error, error.c_str());
   return true;
 #endif
 }
@@ -2597,44 +2595,39 @@ bool cmFileCommand::HandleCreateLinkCommand(
     return false;
   }
 
-  cmCommandArgumentsHelper argHelper;
-  cmCommandArgumentGroup group;
-
-  cmCAString linkArg(&argHelper, "CREATE_LINK");
-  cmCAString fileArg(&argHelper, nullptr);
-  cmCAString newFileArg(&argHelper, nullptr);
+  std::string const& fileName = args[1];
+  std::string const& newFileName = args[2];
 
-  cmCAString resultArg(&argHelper, "RESULT", &group);
-  cmCAEnabler copyOnErrorArg(&argHelper, "COPY_ON_ERROR", &group);
-  cmCAEnabler symbolicArg(&argHelper, "SYMBOLIC", &group);
+  struct Arguments
+  {
+    std::string Result;
+    bool CopyOnError = false;
+    bool Symbolic = false;
+  };
 
-  linkArg.Follows(nullptr);
-  fileArg.Follows(&linkArg);
-  newFileArg.Follows(&fileArg);
-  group.Follows(&newFileArg);
+  static auto const parser =
+    cmArgumentParser<Arguments>{}
+      .Bind("RESULT"_s, &Arguments::Result)
+      .Bind("COPY_ON_ERROR"_s, &Arguments::CopyOnError)
+      .Bind("SYMBOLIC"_s, &Arguments::Symbolic);
 
   std::vector<std::string> unconsumedArgs;
-  argHelper.Parse(&args, &unconsumedArgs);
+  Arguments const arguments =
+    parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
 
   if (!unconsumedArgs.empty()) {
     this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
     return false;
   }
 
-  std::string fileName = fileArg.GetString();
-  std::string newFileName = newFileArg.GetString();
-
-  // Output variable for storing the result.
-  const std::string& resultVar = resultArg.GetString();
-
   // The system error message generated in the operation.
   std::string result;
 
   // Check if the paths are distinct.
   if (fileName == newFileName) {
     result = "CREATE_LINK cannot use same file and newfile";
-    if (!resultVar.empty()) {
-      this->Makefile->AddDefinition(resultVar, result.c_str());
+    if (!arguments.Result.empty()) {
+      this->Makefile->AddDefinition(arguments.Result, result.c_str());
       return true;
     }
     this->SetError(result);
@@ -2642,10 +2635,10 @@ bool cmFileCommand::HandleCreateLinkCommand(
   }
 
   // Hard link requires original file to exist.
-  if (!symbolicArg.IsEnabled() && !cmSystemTools::FileExists(fileName)) {
+  if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) {
     result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
-    if (!resultVar.empty()) {
-      this->Makefile->AddDefinition(resultVar, result.c_str());
+    if (!arguments.Result.empty()) {
+      this->Makefile->AddDefinition(arguments.Result, result.c_str());
       return true;
     }
     this->SetError(result);
@@ -2661,8 +2654,8 @@ bool cmFileCommand::HandleCreateLinkCommand(
       << "' because existing path cannot be removed: "
       << cmSystemTools::GetLastSystemError() << "\n";
 
-    if (!resultVar.empty()) {
-      this->Makefile->AddDefinition(resultVar, e.str().c_str());
+    if (!arguments.Result.empty()) {
+      this->Makefile->AddDefinition(arguments.Result, e.str().c_str());
       return true;
     }
     this->SetError(e.str());
@@ -2673,14 +2666,14 @@ bool cmFileCommand::HandleCreateLinkCommand(
   bool completed = false;
 
   // Check if the command requires a symbolic link.
-  if (symbolicArg.IsEnabled()) {
+  if (arguments.Symbolic) {
     completed = cmSystemTools::CreateSymlink(fileName, newFileName, &result);
   } else {
     completed = cmSystemTools::CreateLink(fileName, newFileName, &result);
   }
 
   // Check if copy-on-error is enabled in the arguments.
-  if (!completed && copyOnErrorArg.IsEnabled()) {
+  if (!completed && arguments.CopyOnError) {
     completed = cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
     if (!completed) {
       result = "Copy failed: " + cmSystemTools::GetLastSystemError();
@@ -2690,14 +2683,14 @@ bool cmFileCommand::HandleCreateLinkCommand(
   // Check if the operation was successful.
   if (completed) {
     result = "0";
-  } else if (resultVar.empty()) {
+  } else if (arguments.Result.empty()) {
     // The operation failed and the result is not reported in a variable.
     this->SetError(result);
     return false;
   }
 
-  if (!resultVar.empty()) {
-    this->Makefile->AddDefinition(resultVar, result.c_str());
+  if (!arguments.Result.empty()) {
+    this->Makefile->AddDefinition(arguments.Result, result.c_str());
   }
 
   return true;