Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Support/Path.cpp
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | StringRef find_first_component(StringRef path, Style style) { | ||||
// * empty (in this case we return an empty string) | // * empty (in this case we return an empty string) | ||||
// * either C: or {//,\\}net. | // * either C: or {//,\\}net. | ||||
// * {/,\} | // * {/,\} | ||||
// * {file,directory}name | // * {file,directory}name | ||||
if (path.empty()) | if (path.empty()) | ||||
return path; | return path; | ||||
if (real_style(style) == Style::windows) { | if (is_style_windows(style)) { | ||||
// C: | // C: | ||||
if (path.size() >= 2 && | if (path.size() >= 2 && | ||||
std::isalpha(static_cast<unsigned char>(path[0])) && path[1] == ':') | std::isalpha(static_cast<unsigned char>(path[0])) && path[1] == ':') | ||||
return path.substr(0, 2); | return path.substr(0, 2); | ||||
} | } | ||||
// //net | // //net | ||||
if ((path.size() > 2) && is_separator(path[0], style) && | if ((path.size() > 2) && is_separator(path[0], style) && | ||||
Show All 15 Lines | namespace { | ||||
// Returns the first character of the filename in str. For paths ending in | // Returns the first character of the filename in str. For paths ending in | ||||
// '/', it returns the position of the '/'. | // '/', it returns the position of the '/'. | ||||
size_t filename_pos(StringRef str, Style style) { | size_t filename_pos(StringRef str, Style style) { | ||||
if (str.size() > 0 && is_separator(str[str.size() - 1], style)) | if (str.size() > 0 && is_separator(str[str.size() - 1], style)) | ||||
return str.size() - 1; | return str.size() - 1; | ||||
size_t pos = str.find_last_of(separators(style), str.size() - 1); | size_t pos = str.find_last_of(separators(style), str.size() - 1); | ||||
if (real_style(style) == Style::windows) { | if (is_style_windows(style)) { | ||||
if (pos == StringRef::npos) | if (pos == StringRef::npos) | ||||
pos = str.find_last_of(':', str.size() - 2); | pos = str.find_last_of(':', str.size() - 2); | ||||
} | } | ||||
if (pos == StringRef::npos || (pos == 1 && is_separator(str[0], style))) | if (pos == StringRef::npos || (pos == 1 && is_separator(str[0], style))) | ||||
return 0; | return 0; | ||||
return pos + 1; | return pos + 1; | ||||
} | } | ||||
// Returns the position of the root directory in str. If there is no root | // Returns the position of the root directory in str. If there is no root | ||||
// directory in str, it returns StringRef::npos. | // directory in str, it returns StringRef::npos. | ||||
size_t root_dir_start(StringRef str, Style style) { | size_t root_dir_start(StringRef str, Style style) { | ||||
// case "c:/" | // case "c:/" | ||||
if (real_style(style) == Style::windows) { | if (is_style_windows(style)) { | ||||
if (str.size() > 2 && str[1] == ':' && is_separator(str[2], style)) | if (str.size() > 2 && str[1] == ':' && is_separator(str[2], style)) | ||||
return 2; | return 2; | ||||
} | } | ||||
// case "//net" | // case "//net" | ||||
if (str.size() > 3 && is_separator(str[0], style) && str[0] == str[1] && | if (str.size() > 3 && is_separator(str[0], style) && str[0] == str[1] && | ||||
!is_separator(str[2], style)) { | !is_separator(str[2], style)) { | ||||
return str.find_first_of(separators(style), 2); | return str.find_first_of(separators(style), 2); | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | const_iterator &const_iterator::operator++() { | ||||
bool was_net = Component.size() > 2 && is_separator(Component[0], S) && | bool was_net = Component.size() > 2 && is_separator(Component[0], S) && | ||||
Component[1] == Component[0] && !is_separator(Component[2], S); | Component[1] == Component[0] && !is_separator(Component[2], S); | ||||
// Handle separators. | // Handle separators. | ||||
if (is_separator(Path[Position], S)) { | if (is_separator(Path[Position], S)) { | ||||
// Root dir. | // Root dir. | ||||
if (was_net || | if (was_net || | ||||
// c:/ | // c:/ | ||||
(real_style(S) == Style::windows && Component.endswith(":"))) { | (is_style_windows(S) && Component.endswith(":"))) { | ||||
Component = Path.substr(Position, 1); | Component = Path.substr(Position, 1); | ||||
return *this; | return *this; | ||||
} | } | ||||
// Skip extra separators. | // Skip extra separators. | ||||
while (Position != Path.size() && is_separator(Path[Position], S)) { | while (Position != Path.size() && is_separator(Path[Position], S)) { | ||||
++Position; | ++Position; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | ptrdiff_t reverse_iterator::operator-(const reverse_iterator &RHS) const { | ||||
return Position - RHS.Position; | return Position - RHS.Position; | ||||
} | } | ||||
StringRef root_path(StringRef path, Style style) { | StringRef root_path(StringRef path, Style style) { | ||||
const_iterator b = begin(path, style), pos = b, e = end(path); | const_iterator b = begin(path, style), pos = b, e = end(path); | ||||
if (b != e) { | if (b != e) { | ||||
bool has_net = | bool has_net = | ||||
b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; | b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; | ||||
bool has_drive = (real_style(style) == Style::windows) && b->endswith(":"); | bool has_drive = is_style_windows(style) && b->endswith(":"); | ||||
if (has_net || has_drive) { | if (has_net || has_drive) { | ||||
if ((++pos != e) && is_separator((*pos)[0], style)) { | if ((++pos != e) && is_separator((*pos)[0], style)) { | ||||
// {C:/,//net/}, so get the first two components. | // {C:/,//net/}, so get the first two components. | ||||
return path.substr(0, b->size() + pos->size()); | return path.substr(0, b->size() + pos->size()); | ||||
} | } | ||||
// just {C:,//net}, return the first component. | // just {C:,//net}, return the first component. | ||||
return *b; | return *b; | ||||
} | } | ||||
// POSIX style root directory. | // POSIX style root directory. | ||||
if (is_separator((*b)[0], style)) { | if (is_separator((*b)[0], style)) { | ||||
return *b; | return *b; | ||||
} | } | ||||
} | } | ||||
return StringRef(); | return StringRef(); | ||||
} | } | ||||
StringRef root_name(StringRef path, Style style) { | StringRef root_name(StringRef path, Style style) { | ||||
const_iterator b = begin(path, style), e = end(path); | const_iterator b = begin(path, style), e = end(path); | ||||
if (b != e) { | if (b != e) { | ||||
bool has_net = | bool has_net = | ||||
b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; | b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; | ||||
bool has_drive = (real_style(style) == Style::windows) && b->endswith(":"); | bool has_drive = is_style_windows(style) && b->endswith(":"); | ||||
if (has_net || has_drive) { | if (has_net || has_drive) { | ||||
// just {C:,//net}, return the first component. | // just {C:,//net}, return the first component. | ||||
return *b; | return *b; | ||||
} | } | ||||
} | } | ||||
// No path or no name. | // No path or no name. | ||||
return StringRef(); | return StringRef(); | ||||
} | } | ||||
StringRef root_directory(StringRef path, Style style) { | StringRef root_directory(StringRef path, Style style) { | ||||
const_iterator b = begin(path, style), pos = b, e = end(path); | const_iterator b = begin(path, style), pos = b, e = end(path); | ||||
if (b != e) { | if (b != e) { | ||||
bool has_net = | bool has_net = | ||||
b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; | b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0]; | ||||
bool has_drive = (real_style(style) == Style::windows) && b->endswith(":"); | bool has_drive = is_style_windows(style) && b->endswith(":"); | ||||
if ((has_net || has_drive) && | if ((has_net || has_drive) && | ||||
// {C:,//net}, skip to the next component. | // {C:,//net}, skip to the next component. | ||||
(++pos != e) && is_separator((*pos)[0], style)) { | (++pos != e) && is_separator((*pos)[0], style)) { | ||||
return *pos; | return *pos; | ||||
} | } | ||||
// POSIX style root directory. | // POSIX style root directory. | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | void replace_extension(SmallVectorImpl<char> &path, const Twine &extension, | ||||
// Append extension. | // Append extension. | ||||
path.append(ext.begin(), ext.end()); | path.append(ext.begin(), ext.end()); | ||||
} | } | ||||
static bool starts_with(StringRef Path, StringRef Prefix, | static bool starts_with(StringRef Path, StringRef Prefix, | ||||
Style style = Style::native) { | Style style = Style::native) { | ||||
// Windows prefix matching : case and separator insensitive | // Windows prefix matching : case and separator insensitive | ||||
if (real_style(style) == Style::windows) { | if (is_style_windows(style)) { | ||||
if (Path.size() < Prefix.size()) | if (Path.size() < Prefix.size()) | ||||
return false; | return false; | ||||
for (size_t I = 0, E = Prefix.size(); I != E; ++I) { | for (size_t I = 0, E = Prefix.size(); I != E; ++I) { | ||||
bool SepPath = is_separator(Path[I], style); | bool SepPath = is_separator(Path[I], style); | ||||
bool SepPrefix = is_separator(Prefix[I], style); | bool SepPrefix = is_separator(Prefix[I], style); | ||||
if (SepPath != SepPrefix) | if (SepPath != SepPrefix) | ||||
return false; | return false; | ||||
if (!SepPath && toLower(Path[I]) != toLower(Prefix[I])) | if (!SepPath && toLower(Path[I]) != toLower(Prefix[I])) | ||||
Show All 34 Lines | void native(const Twine &path, SmallVectorImpl<char> &result, Style style) { | ||||
result.clear(); | result.clear(); | ||||
path.toVector(result); | path.toVector(result); | ||||
native(result, style); | native(result, style); | ||||
} | } | ||||
void native(SmallVectorImpl<char> &Path, Style style) { | void native(SmallVectorImpl<char> &Path, Style style) { | ||||
if (Path.empty()) | if (Path.empty()) | ||||
return; | return; | ||||
if (real_style(style) == Style::windows) { | if (is_style_windows(style)) { | ||||
std::replace(Path.begin(), Path.end(), '/', '\\'); | std::replace(Path.begin(), Path.end(), '/', '\\'); | ||||
if (Path[0] == '~' && (Path.size() == 1 || is_separator(Path[1], style))) { | if (Path[0] == '~' && (Path.size() == 1 || is_separator(Path[1], style))) { | ||||
SmallString<128> PathHome; | SmallString<128> PathHome; | ||||
home_directory(PathHome); | home_directory(PathHome); | ||||
PathHome.append(Path.begin() + 1, Path.end()); | PathHome.append(Path.begin() + 1, Path.end()); | ||||
Path = PathHome; | Path = PathHome; | ||||
} | } | ||||
} else { | } else { | ||||
std::replace(Path.begin(), Path.end(), '\\', '/'); | std::replace(Path.begin(), Path.end(), '\\', '/'); | ||||
} | } | ||||
} | } | ||||
std::string convert_to_slash(StringRef path, Style style) { | std::string convert_to_slash(StringRef path, Style style) { | ||||
if (real_style(style) != Style::windows) | if (is_style_posix(style)) | ||||
return std::string(path); | return std::string(path); | ||||
std::string s = path.str(); | std::string s = path.str(); | ||||
std::replace(s.begin(), s.end(), '\\', '/'); | std::replace(s.begin(), s.end(), '\\', '/'); | ||||
return s; | return s; | ||||
} | } | ||||
StringRef filename(StringRef path, Style style) { return *rbegin(path, style); } | StringRef filename(StringRef path, Style style) { return *rbegin(path, style); } | ||||
Show All 18 Lines | if ((fname.size() == 1 && fname == ".") || | ||||
(fname.size() == 2 && fname == "..")) | (fname.size() == 2 && fname == "..")) | ||||
return StringRef(); | return StringRef(); | ||||
return fname.substr(pos); | return fname.substr(pos); | ||||
} | } | ||||
bool is_separator(char value, Style style) { | bool is_separator(char value, Style style) { | ||||
if (value == '/') | if (value == '/') | ||||
return true; | return true; | ||||
if (real_style(style) == Style::windows) | if (is_style_windows(style)) | ||||
return value == '\\'; | return value == '\\'; | ||||
return false; | return false; | ||||
} | } | ||||
StringRef get_separator(Style style) { | StringRef get_separator(Style style) { | ||||
if (real_style(style) == Style::windows) | if (is_style_windows(style)) | ||||
return "\\"; | return "\\"; | ||||
return "/"; | return "/"; | ||||
} | } | ||||
bool has_root_name(const Twine &path, Style style) { | bool has_root_name(const Twine &path, Style style) { | ||||
SmallString<128> path_storage; | SmallString<128> path_storage; | ||||
StringRef p = path.toStringRef(path_storage); | StringRef p = path.toStringRef(path_storage); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | bool has_extension(const Twine &path, Style style) { | ||||
return !extension(p, style).empty(); | return !extension(p, style).empty(); | ||||
} | } | ||||
bool is_absolute(const Twine &path, Style style) { | bool is_absolute(const Twine &path, Style style) { | ||||
SmallString<128> path_storage; | SmallString<128> path_storage; | ||||
StringRef p = path.toStringRef(path_storage); | StringRef p = path.toStringRef(path_storage); | ||||
bool rootDir = has_root_directory(p, style); | bool rootDir = has_root_directory(p, style); | ||||
bool rootName = | bool rootName = is_style_posix(style) || has_root_name(p, style); | ||||
(real_style(style) != Style::windows) || has_root_name(p, style); | |||||
return rootDir && rootName; | return rootDir && rootName; | ||||
} | } | ||||
bool is_absolute_gnu(const Twine &path, Style style) { | bool is_absolute_gnu(const Twine &path, Style style) { | ||||
SmallString<128> path_storage; | SmallString<128> path_storage; | ||||
StringRef p = path.toStringRef(path_storage); | StringRef p = path.toStringRef(path_storage); | ||||
// Handle '/' which is absolute for both Windows and POSIX systems. | // Handle '/' which is absolute for both Windows and POSIX systems. | ||||
// Handle '\\' on Windows. | // Handle '\\' on Windows. | ||||
if (!p.empty() && is_separator(p.front(), style)) | if (!p.empty() && is_separator(p.front(), style)) | ||||
return true; | return true; | ||||
if (real_style(style) == Style::windows) { | if (is_style_windows(style)) { | ||||
// Handle drive letter pattern (a character followed by ':') on Windows. | // Handle drive letter pattern (a character followed by ':') on Windows. | ||||
if (p.size() >= 2 && (p[0] && p[1] == ':')) | if (p.size() >= 2 && (p[0] && p[1] == ':')) | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
void make_absolute(const Twine ¤t_directory, | void make_absolute(const Twine ¤t_directory, | ||||
SmallVectorImpl<char> &path) { | SmallVectorImpl<char> &path) { | ||||
StringRef p(path.data(), path.size()); | StringRef p(path.data(), path.size()); | ||||
bool rootDirectory = path::has_root_directory(p); | bool rootDirectory = path::has_root_directory(p); | ||||
bool rootName = path::has_root_name(p); | bool rootName = path::has_root_name(p); | ||||
// Already absolute. | // Already absolute. | ||||
if ((rootName || real_style(Style::native) != Style::windows) && | if ((rootName || is_style_posix(Style::native)) && rootDirectory) | ||||
rootDirectory) | |||||
return; | return; | ||||
// All of the following conditions will need the current directory. | // All of the following conditions will need the current directory. | ||||
SmallString<128> current_dir; | SmallString<128> current_dir; | ||||
current_directory.toVector(current_dir); | current_directory.toVector(current_dir); | ||||
// Relative path. Prepend the current directory. | // Relative path. Prepend the current directory. | ||||
if (!rootName && !rootDirectory) { | if (!rootName && !rootDirectory) { | ||||
▲ Show 20 Lines • Show All 416 Lines • Show Last 20 Lines |