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

cmSourceFile: Refactor FindFullPath method

Refactors the cmSourceFile::FindFullPath method to
use lambdas.
Sebastian Holtermann 7 лет назад
Родитель
Сommit
cd8a930d61
4 измененных файлов с 74 добавлено и 63 удалено
  1. 59 62
      Source/cmSourceFile.cxx
  2. 0 1
      Source/cmSourceFile.h
  3. 10 0
      Source/cmSourceFileLocation.cxx
  4. 5 0
      Source/cmSourceFileLocation.h

+ 59 - 62
Source/cmSourceFile.cxx

@@ -2,7 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSourceFile.h"
 
-#include <sstream>
+#include <array>
+#include <utility>
 
 #include "cmCustomCommand.h"
 #include "cmGlobalGenerator.h"
@@ -117,87 +118,83 @@ bool cmSourceFile::FindFullPath(std::string* error)
     return false;
   }
 
-  // If the file is generated compute the location without checking on
-  // disk.
+  // If the file is generated compute the location without checking on disk.
   if (this->GetIsGenerated()) {
     // The file is either already a full path or is relative to the
     // build directory for the target.
     this->Location.DirectoryUseBinary();
-    this->FullPath = this->Location.GetDirectory();
-    this->FullPath += "/";
-    this->FullPath += this->Location.GetName();
+    this->FullPath = this->Location.GetFullPath();
     return true;
   }
 
   // The file is not generated.  It must exist on disk.
-  cmMakefile const* mf = this->Location.GetMakefile();
-  const char* tryDirs[3] = { nullptr, nullptr, nullptr };
-  if (this->Location.DirectoryIsAmbiguous()) {
-    tryDirs[0] = mf->GetCurrentSourceDirectory().c_str();
-    tryDirs[1] = mf->GetCurrentBinaryDirectory().c_str();
-  } else {
-    tryDirs[0] = "";
-  }
-
-  cmake const* const cmakeInst = mf->GetCMakeInstance();
-  std::vector<std::string> const& srcExts = cmakeInst->GetSourceExtensions();
-  std::vector<std::string> const& hdrExts = cmakeInst->GetHeaderExtensions();
-  for (const char* const* di = tryDirs; *di; ++di) {
-    std::string tryPath = this->Location.GetDirectory();
-    if (!tryPath.empty()) {
-      tryPath += "/";
-    }
-    tryPath += this->Location.GetName();
-    tryPath = cmSystemTools::CollapseFullPath(tryPath, *di);
-    if (this->TryFullPath(tryPath, "")) {
+  cmMakefile const* makefile = this->Location.GetMakefile();
+  // Location path
+  std::string const lPath = this->Location.GetFullPath();
+  // List of extension lists
+  std::array<std::vector<std::string> const*, 2> const extsLists = {
+    { &makefile->GetCMakeInstance()->GetSourceExtensions(),
+      &makefile->GetCMakeInstance()->GetHeaderExtensions() }
+  };
+
+  // Tries to find the file in a given directory
+  auto findInDir = [this, &extsLists, &lPath](std::string const& dir) -> bool {
+    // Compute full path
+    std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
+    // Try full path
+    if (cmSystemTools::FileExists(fullPath)) {
+      this->FullPath = fullPath;
       return true;
     }
-    for (std::string const& ext : srcExts) {
-      if (this->TryFullPath(tryPath, ext)) {
-        return true;
+    // Try full path with extension
+    for (auto exts : extsLists) {
+      for (std::string const& ext : *exts) {
+        if (!ext.empty()) {
+          std::string extPath = fullPath;
+          extPath += '.';
+          extPath += ext;
+          if (cmSystemTools::FileExists(extPath)) {
+            this->FullPath = extPath;
+            return true;
+          }
+        }
       }
     }
-    for (std::string const& ext : hdrExts) {
-      if (this->TryFullPath(tryPath, ext)) {
-        return true;
-      }
+    // File not found
+    return false;
+  };
+
+  // Try to find the file in various directories
+  if (this->Location.DirectoryIsAmbiguous()) {
+    if (findInDir(makefile->GetCurrentSourceDirectory()) ||
+        findInDir(makefile->GetCurrentBinaryDirectory())) {
+      return true;
+    }
+  } else {
+    if (findInDir({})) {
+      return true;
     }
   }
 
-  std::ostringstream e;
-  std::string missing = this->Location.GetDirectory();
-  if (!missing.empty()) {
-    missing += "/";
-  }
-  missing += this->Location.GetName();
-  e << "Cannot find source file:\n  " << missing << "\nTried extensions";
-  for (std::string const& srcExt : srcExts) {
-    e << " ." << srcExt;
-  }
-  for (std::string const& ext : hdrExts) {
-    e << " ." << ext;
+  // Compose error
+  std::string err;
+  err += "Cannot find source file:\n  ";
+  err += lPath;
+  err += "\nTried extensions";
+  for (auto exts : extsLists) {
+    for (std::string const& ext : *exts) {
+      err += " .";
+      err += ext;
+    }
   }
-  if (error) {
-    *error = e.str();
+  if (error != nullptr) {
+    *error = std::move(err);
   } else {
-    this->Location.GetMakefile()->IssueMessage(MessageType::FATAL_ERROR,
-                                               e.str());
+    makefile->IssueMessage(MessageType::FATAL_ERROR, err);
   }
   this->FindFullPathFailed = true;
-  return false;
-}
 
-bool cmSourceFile::TryFullPath(const std::string& path, const std::string& ext)
-{
-  std::string tryPath = path;
-  if (!ext.empty()) {
-    tryPath += ".";
-    tryPath += ext;
-  }
-  if (cmSystemTools::FileExists(tryPath)) {
-    this->FullPath = tryPath;
-    return true;
-  }
+  // File not found
   return false;
 }
 

+ 0 - 1
Source/cmSourceFile.h

@@ -120,7 +120,6 @@ private:
   bool IsGenerated = false;
 
   bool FindFullPath(std::string* error);
-  bool TryFullPath(const std::string& path, const std::string& ext);
   void CheckExtension();
   void CheckLanguage(std::string const& ext);
 

+ 10 - 0
Source/cmSourceFileLocation.cxx

@@ -42,6 +42,16 @@ cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
   }
 }
 
+std::string cmSourceFileLocation::GetFullPath() const
+{
+  std::string path = this->GetDirectory();
+  if (!path.empty()) {
+    path += '/';
+  }
+  path += this->GetName();
+  return path;
+}
+
 void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
 {
   if (this->AmbiguousDirectory && !loc.AmbiguousDirectory) {

+ 5 - 0
Source/cmSourceFileLocation.h

@@ -79,6 +79,11 @@ public:
    */
   const std::string& GetName() const { return this->Name; }
 
+  /**
+   * Get the full file path composed of GetDirectory() and GetName().
+   */
+  std::string GetFullPath() const;
+
   /**
    * Get the cmMakefile instance for which the source file was created.
    */