cmFindPackageCommand: Fix searching a root path as a prefix

A root path like `/` or `c:/` needs to end in a slash.  Revise our
prefix search logic to maintain a trailing slash instead of removing one
just to add it again.
This commit is contained in:
Brad King
2024-12-19 09:18:10 -05:00
parent 1beb742d1b
commit 1c6cecdce9
2 changed files with 21 additions and 38 deletions

View File

@@ -130,7 +130,7 @@ public:
return {};
}
this->NeedReset = true;
return cmStrCat(parent, '/', this->DirName);
return cmStrCat(parent, this->DirName, '/');
}
void Reset() { this->NeedReset = false; }
@@ -152,7 +152,7 @@ public:
std::string GetNextCandidate(const std::string& parent)
{
if (this->Current != this->Names.get().cend()) {
return cmStrCat(parent, '/', *this->Current++);
return cmStrCat(parent, *this->Current++, '/');
}
return {};
}
@@ -189,7 +189,7 @@ public:
continue;
}
if (cmsysString_strcasecmp(fname, this->DirName.data()) == 0) {
auto candidate = cmStrCat(parent, '/', fname);
auto candidate = cmStrCat(parent, fname, '/');
if (cmSystemTools::FileIsDirectory(candidate)) {
return candidate;
}
@@ -271,7 +271,7 @@ public:
}
if (this->Current != this->Matches.cend()) {
auto candidate = cmStrCat(parent, '/', *this->Current++);
auto candidate = cmStrCat(parent, *this->Current++, '/');
return candidate;
}
@@ -386,8 +386,8 @@ bool TryGeneratedPaths(CallbackFn&& filesCollector,
cmFindPackageCommand::PackageDescriptionType type,
const std::string& fullPath)
{
assert(!fullPath.empty() && fullPath.back() != '/');
return std::forward<CallbackFn&&>(filesCollector)(fullPath + '/', type);
assert(!fullPath.empty() && fullPath.back() == '/');
return std::forward<CallbackFn&&>(filesCollector)(fullPath, type);
}
template <typename CallbackFn, typename Generator, typename... Rest>
@@ -2744,17 +2744,17 @@ void cmFindPackageCommand::StoreVersionFound()
}
}
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
assert(!prefix.empty() && prefix.back() == '/');
// Skip this if the prefix does not exist.
if (!cmSystemTools::FileIsDirectory(prefix_in)) {
if (!cmSystemTools::FileIsDirectory(prefix)) {
return false;
}
// Skip this if it's in ignored paths.
std::string prefixWithoutSlash = prefix_in;
std::string prefixWithoutSlash = prefix;
if (prefixWithoutSlash != "/" && prefixWithoutSlash.back() == '/') {
prefixWithoutSlash.erase(prefixWithoutSlash.length() - 1);
}
@@ -2763,10 +2763,6 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
return false;
}
// Strip the trailing slash because the path generator is about to
// add one.
std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
auto searchFn = [this](const std::string& fullPath,
PackageDescriptionType type) -> bool {
return this->SearchDirectory(fullPath, type);
@@ -2811,7 +2807,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
}
// PREFIX/ (useful on windows or in build trees)
if (this->SearchDirectory(prefix_in, pdt::CMake)) {
if (this->SearchDirectory(prefix, pdt::CMake)) {
return true;
}
@@ -2916,13 +2912,9 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
commonGen, secondPkgDirGen, iCMakeGen);
}
bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
// Strip the trailing slash because the path generator is about to
// add one.
std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
assert(!prefix.empty() && prefix.back() == '/');
auto searchFn = [this](const std::string& fullPath,
PackageDescriptionType type) -> bool {
@@ -2971,13 +2963,9 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
rGen, iCMakeGen);
}
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
// Strip the trailing slash because the path generator is about to
// add one.
std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
assert(!prefix.empty() && prefix.back() == '/');
auto searchFn = [this](const std::string& fullPath,
PackageDescriptionType type) -> bool {
@@ -3004,20 +2992,15 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s });
}
bool cmFindPackageCommand::SearchEnvironmentPrefix(
std::string const& prefix_in)
bool cmFindPackageCommand::SearchEnvironmentPrefix(std::string const& prefix)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
assert(!prefix.empty() && prefix.back() == '/');
// Skip this if the prefix does not exist.
if (!cmSystemTools::FileIsDirectory(prefix_in)) {
if (!cmSystemTools::FileIsDirectory(prefix)) {
return false;
}
// Strip the trailing slash because the path generator is about to
// add one.
std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
auto searchFn = [this](const std::string& fullPath,
PackageDescriptionType type) -> bool {
return this->SearchDirectory(fullPath, type);

View File

@@ -173,9 +173,9 @@ private:
bool CheckVersionFile(std::string const& version_file,
std::string& result_version);
bool SearchPrefix(std::string const& prefix);
bool SearchFrameworkPrefix(std::string const& prefix_in);
bool SearchAppBundlePrefix(std::string const& prefix_in);
bool SearchEnvironmentPrefix(std::string const& prefix_in);
bool SearchFrameworkPrefix(std::string const& prefix);
bool SearchAppBundlePrefix(std::string const& prefix);
bool SearchEnvironmentPrefix(std::string const& prefix);
struct OriginalDef
{