| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmConfigure.h" // IWYU pragma: keep | |
| #include "cmCMakePath.h" | |
| #include <string> | |
| #include "cmStringAlgorithms.h" | |
| #if defined(_WIN32) | |
| # include <cstdlib> | |
| #endif | |
| #include <cm/filesystem> | |
| #include <cm/string_view> | |
| #if defined(_WIN32) | |
| # include <cmext/string_view> | |
| #endif | |
| cmCMakePath& cmCMakePath::ReplaceWideExtension(cm::string_view extension) | |
| { | |
| auto file = this->Path.filename().string(); | |
| if (!file.empty() && file != "." && file != "..") { | |
| auto pos = file.find('.', file[0] == '.' ? 1 : 0); | |
| if (pos != std::string::npos) { | |
| file.erase(pos); | |
| } | |
| } | |
| if (!extension.empty()) { | |
| if (extension[0] != '.') { | |
| file += '.'; | |
| } | |
| file = cmStrCat(std::move(file), extension); | |
| } | |
| this->Path.replace_filename(file); | |
| return *this; | |
| } | |
| cmCMakePath cmCMakePath::GetWideExtension() const | |
| { | |
| auto file = this->Path.filename().string(); | |
| if (file.empty() || file == "." || file == "..") { | |
| return cmCMakePath{}; | |
| } | |
| auto pos = file.find('.', file[0] == '.' ? 1 : 0); | |
| if (pos != std::string::npos) { | |
| return cm::string_view(file.data() + pos, file.length() - pos); | |
| } | |
| return cmCMakePath{}; | |
| } | |
| cmCMakePath cmCMakePath::GetNarrowStem() const | |
| { | |
| auto stem = this->Path.stem().string(); | |
| if (stem.empty() || stem == "." || stem == "..") { | |
| return stem; | |
| } | |
| auto pos = stem.find('.', stem[0] == '.' ? 1 : 0); | |
| if (pos != std::string::npos) { | |
| return stem.substr(0, pos); | |
| } | |
| return stem; | |
| } | |
| cmCMakePath cmCMakePath::Absolute(cm::filesystem::path const& base) const | |
| { | |
| if (this->Path.is_relative()) { | |
| auto path = base; | |
| path /= this->Path; | |
| // filesystem::path::operator/= use preferred_separator ('\' on Windows) | |
| // so converts back to '/' | |
| return path.generic_string(); | |
| } | |
| return *this; | |
| } | |
| bool cmCMakePath::IsPrefix(cmCMakePath const& path) const | |
| { | |
| // An empty path is not a prefix of any path, including another empty path. | |
| if (this->Path.empty()) { | |
| return false; | |
| } | |
| auto prefix_it = this->Path.begin(); | |
| auto prefix_end = this->Path.end(); | |
| auto path_it = path.Path.begin(); | |
| auto path_end = path.Path.end(); | |
| while (prefix_it != prefix_end && path_it != path_end && | |
| *prefix_it == *path_it) { | |
| ++prefix_it; | |
| ++path_it; | |
| } | |
| return (prefix_it == prefix_end) || | |
| (prefix_it->empty() && path_it != path_end); | |
| } | |
| std::string cmCMakePath::FormatPath(std::string path, format fmt) | |
| { | |
| #if defined(_WIN32) | |
| if (fmt == auto_format || fmt == native_format) { | |
| auto prefix = path.substr(0, 4); | |
| for (auto& c : prefix) { | |
| if (c == '\\') { | |
| c = '/'; | |
| } | |
| } | |
| // remove Windows long filename marker | |
| if (prefix == "//?/"_s) { | |
| path.erase(0, 4); | |
| } | |
| if (cmHasPrefix(path, "UNC/"_s) || cmHasPrefix(path, "UNC\\"_s)) { | |
| path.erase(0, 2); | |
| path[0] = '/'; | |
| } | |
| } | |
| #else | |
| static_cast<void>(fmt); | |
| #endif | |
| return path; | |
| } | |
| void cmCMakePath::GetNativePath(std::string& path) const | |
| { | |
| cm::filesystem::path tmp(this->Path); | |
| tmp.make_preferred(); | |
| path = tmp.string(); | |
| } | |
| void cmCMakePath::GetNativePath(std::wstring& path) const | |
| { | |
| cm::filesystem::path tmp(this->Path); | |
| tmp.make_preferred(); | |
| path = tmp.wstring(); | |
| #if defined(_WIN32) | |
| // Windows long filename | |
| static std::wstring UNC(L"\\\\?\\UNC"); | |
| static std::wstring PREFIX(L"\\\\?\\"); | |
| if (this->IsAbsolute() && path.length() > _MAX_PATH - 12) { | |
| if (this->HasRootName() && path[0] == L'\\') { | |
| path = UNC + path.substr(1); | |
| } else { | |
| path = PREFIX + path; | |
| } | |
| } | |
| #endif | |
| } |