cmSourceFile: Refactor FindFullPath method

Refactors the cmSourceFile::FindFullPath method to
use lambdas.
This commit is contained in:
Sebastian Holtermann 2019-02-01 12:50:28 +01:00
parent 6d407ae439
commit cd8a930d61
4 changed files with 73 additions and 62 deletions

View File

@ -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] = "";
}
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() }
};
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, "")) {
// 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 += "/";
// 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;
}
}
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;
}
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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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.
*/