1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/* 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>
#if defined(_WIN32)
# include <cstdlib>
#endif
#include <cm/filesystem>
#include <cm/string_view>
#if defined(_WIN32)
# include <cmext/string_view>
# include "cmStringAlgorithms.h"
#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.append(std::string(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
{
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
}
|