mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Support/PathV2: Implement reverse iteration and parent_path.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120496 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
63c133b67d
commit
a42cf73c77
@ -81,16 +81,21 @@ public:
|
||||
typedef value_type *pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
reference operator*() const;
|
||||
pointer operator->() const;
|
||||
reference operator*() const { return Component; }
|
||||
pointer operator->() const { return &Component; }
|
||||
const_iterator &operator++(); // preincrement
|
||||
const_iterator &operator++(int); // postincrement
|
||||
const_iterator &operator--(); // predecrement
|
||||
const_iterator &operator--(int); // postdecrement
|
||||
bool operator==(const const_iterator &RHS) const;
|
||||
bool operator!=(const const_iterator &RHS) const;
|
||||
|
||||
/// @brief Difference in bytes between this and RHS.
|
||||
ptrdiff_t operator-(const const_iterator &RHS) const;
|
||||
};
|
||||
|
||||
typedef std::reverse_iterator<const_iterator> reverse_iterator;
|
||||
|
||||
/// @brief Get begin iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized with the first component of \a path.
|
||||
@ -101,6 +106,20 @@ const_iterator begin(const StringRef &path);
|
||||
/// @returns Iterator initialized to the end of \a path.
|
||||
const_iterator end(const StringRef &path);
|
||||
|
||||
/// @brief Get reverse begin iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized with the first reverse component of \a path.
|
||||
inline reverse_iterator rbegin(const StringRef &path) {
|
||||
return reverse_iterator(end(path));
|
||||
}
|
||||
|
||||
/// @brief Get reverse end iterator over \a path.
|
||||
/// @param path Input path.
|
||||
/// @returns Iterator initialized to the reverse end of \a path.
|
||||
inline reverse_iterator rend(const StringRef &path) {
|
||||
return reverse_iterator(begin(path));
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Lexical Modifiers
|
||||
/// @{
|
||||
|
@ -82,6 +82,78 @@ namespace {
|
||||
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
size_t filename_pos(const StringRef &str) {
|
||||
if (str.size() == 2 &&
|
||||
is_separator(str[0]) &&
|
||||
is_separator(str[1]))
|
||||
return 0;
|
||||
|
||||
if (str.size() > 0 && is_separator(str[str.size() - 1]))
|
||||
return str.size() - 1;
|
||||
|
||||
size_t pos = str.find_last_of(separators, str.size() - 1);
|
||||
|
||||
#ifdef LLVM_ON_WIN32
|
||||
if (pos == StringRef::npos)
|
||||
pos = str.find_last_of(':', str.size() - 2);
|
||||
#endif
|
||||
|
||||
if (pos == StringRef::npos ||
|
||||
(pos == 1 && is_separator(str[0])))
|
||||
return 0;
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
size_t root_dir_start(const StringRef &str) {
|
||||
// case "c:/"
|
||||
#ifdef LLVM_ON_WIN32
|
||||
if (str.size() > 2 &&
|
||||
str[1] == ':' &&
|
||||
is_separator(str[2]))
|
||||
return 2;
|
||||
#endif
|
||||
|
||||
// case "//"
|
||||
if (str.size() == 2 &&
|
||||
is_separator(str[0]) &&
|
||||
str[0] == str[1])
|
||||
return StringRef::npos;
|
||||
|
||||
// case "//net"
|
||||
if (str.size() > 3 &&
|
||||
is_separator(str[0]) &&
|
||||
str[0] == str[1] &&
|
||||
!is_separator(str[2])) {
|
||||
return str.find_first_of(separators, 2);
|
||||
}
|
||||
|
||||
// case "/"
|
||||
if (str.size() > 0 && is_separator(str[0]))
|
||||
return 0;
|
||||
|
||||
return StringRef::npos;
|
||||
}
|
||||
|
||||
size_t parent_path_end(const StringRef &path) {
|
||||
size_t end_pos = filename_pos(path);
|
||||
|
||||
bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
|
||||
|
||||
// Skip separators except for root dir.
|
||||
size_t root_dir_pos = root_dir_start(StringRef(path.begin(), end_pos));
|
||||
|
||||
while(end_pos > 0 &&
|
||||
(end_pos - 1) != root_dir_pos &&
|
||||
is_separator(path[end_pos - 1]))
|
||||
--end_pos;
|
||||
|
||||
if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
|
||||
return StringRef::npos;
|
||||
|
||||
return end_pos;
|
||||
}
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
@ -103,14 +175,6 @@ const_iterator end(const StringRef &path) {
|
||||
return i;
|
||||
}
|
||||
|
||||
const_iterator::reference const_iterator::operator*() const {
|
||||
return Component;
|
||||
}
|
||||
|
||||
const_iterator::pointer const_iterator::operator->() const {
|
||||
return &Component;
|
||||
}
|
||||
|
||||
const_iterator &const_iterator::operator++() {
|
||||
assert(Position < Path.size() && "Tried to increment past end!");
|
||||
|
||||
@ -166,6 +230,36 @@ const_iterator &const_iterator::operator++() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator &const_iterator::operator--() {
|
||||
// If we're at the end and the previous char was a '/', return '.'.
|
||||
if (Position == Path.size() &&
|
||||
Path.size() > 1 &&
|
||||
is_separator(Path[Position - 1])
|
||||
#ifdef LLVM_ON_WIN32
|
||||
&& Path[Position - 2] != ':'
|
||||
#endif
|
||||
) {
|
||||
--Position;
|
||||
Component = ".";
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Skip separators unless it's the root directory.
|
||||
size_t root_dir_pos = root_dir_start(Path);
|
||||
size_t end_pos = Position;
|
||||
|
||||
while(end_pos > 0 &&
|
||||
(end_pos - 1) != root_dir_pos &&
|
||||
is_separator(Path[end_pos - 1]))
|
||||
--end_pos;
|
||||
|
||||
// Find next separator.
|
||||
size_t start_pos = filename_pos(StringRef(Path.begin(), end_pos));
|
||||
Component = StringRef(Path.begin() + start_pos, end_pos - start_pos);
|
||||
Position = start_pos;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool const_iterator::operator==(const const_iterator &RHS) const {
|
||||
return Path.begin() == RHS.Path.begin() &&
|
||||
Position == RHS.Position;
|
||||
@ -175,6 +269,10 @@ bool const_iterator::operator!=(const const_iterator &RHS) const {
|
||||
return !(*this == RHS);
|
||||
}
|
||||
|
||||
ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
|
||||
return Position - RHS.Position;
|
||||
}
|
||||
|
||||
error_code root_path(const StringRef &path, StringRef &result) {
|
||||
const_iterator b = begin(path),
|
||||
pos = b,
|
||||
@ -396,6 +494,15 @@ error_code make_absolute(SmallVectorImpl<char> &path) {
|
||||
"occurred above!");
|
||||
}
|
||||
|
||||
error_code parent_path(const StringRef &path, StringRef &result) {
|
||||
size_t end_pos = parent_path_end(path);
|
||||
if (end_pos == StringRef::npos)
|
||||
result = StringRef();
|
||||
else
|
||||
result = StringRef(path.data(), end_pos);
|
||||
return make_error_code(errc::success);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,15 @@ TEST(Support, Path) {
|
||||
}
|
||||
outs() << "]\n";
|
||||
|
||||
outs() << " Reverse Iteration: [";
|
||||
for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
|
||||
ce = sys::path::rend(*i);
|
||||
ci != ce;
|
||||
++ci) {
|
||||
outs() << *ci << ',';
|
||||
}
|
||||
outs() << "]\n";
|
||||
|
||||
StringRef res;
|
||||
SmallString<16> temp_store;
|
||||
if (error_code ec = sys::path::root_path(*i, res))
|
||||
@ -82,6 +91,9 @@ TEST(Support, Path) {
|
||||
if (error_code ec = sys::path::root_directory(*i, res))
|
||||
ASSERT_FALSE(ec.message().c_str());
|
||||
outs() << " root_directory: " << res << '\n';
|
||||
if (error_code ec = sys::path::parent_path(*i, res))
|
||||
ASSERT_FALSE(ec.message().c_str());
|
||||
outs() << " parent_path: " << res << '\n';
|
||||
|
||||
temp_store = *i;
|
||||
if (error_code ec = sys::path::make_absolute(temp_store))
|
||||
|
Loading…
x
Reference in New Issue
Block a user