diff options
author | 2019-02-04 17:04:33 +0000 | |
---|---|---|
committer | 2019-02-04 17:04:33 +0000 | |
commit | 71d9f34297ef5b8104aac6236e8dc7c95ff5da15 (patch) | |
tree | 92fdcc887ac1b153c5e7da9cb557e6207705d89e /lib/libcxx/src/experimental/filesystem/path.cpp | |
parent | Import libc++ 7.0.1. (diff) | |
download | wireguard-openbsd-71d9f34297ef5b8104aac6236e8dc7c95ff5da15.tar.xz wireguard-openbsd-71d9f34297ef5b8104aac6236e8dc7c95ff5da15.zip |
Merge libc++, libc++abi and libunwind version 7.0.1.
Tested by visa on octeon
Tested by kettenis on arm64, armv7 and sparc64
"go for it" deraadt and sthen
Diffstat (limited to 'lib/libcxx/src/experimental/filesystem/path.cpp')
-rw-r--r-- | lib/libcxx/src/experimental/filesystem/path.cpp | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/lib/libcxx/src/experimental/filesystem/path.cpp b/lib/libcxx/src/experimental/filesystem/path.cpp deleted file mode 100644 index dd4026cfe13..00000000000 --- a/lib/libcxx/src/experimental/filesystem/path.cpp +++ /dev/null @@ -1,448 +0,0 @@ -//===--------------------- filesystem/path.cpp ----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#include "experimental/filesystem" -#include "string_view" -#include "utility" - -namespace { namespace parser -{ -using namespace std; -using namespace std::experimental::filesystem; - -using string_view_t = path::__string_view; -using string_view_pair = pair<string_view_t, string_view_t>; -using PosPtr = path::value_type const*; - -struct PathParser { - enum ParserState : unsigned char { - // Zero is a special sentinel value used by default constructed iterators. - PS_BeforeBegin = 1, - PS_InRootName, - PS_InRootDir, - PS_InFilenames, - PS_InTrailingSep, - PS_AtEnd - }; - - const string_view_t Path; - string_view_t RawEntry; - ParserState State; - -private: - PathParser(string_view_t P, ParserState State) noexcept - : Path(P), State(State) {} - -public: - PathParser(string_view_t P, string_view_t E, unsigned char S) - : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) { - // S cannot be '0' or PS_BeforeBegin. - } - - static PathParser CreateBegin(string_view_t P) noexcept { - PathParser PP(P, PS_BeforeBegin); - PP.increment(); - return PP; - } - - static PathParser CreateEnd(string_view_t P) noexcept { - PathParser PP(P, PS_AtEnd); - return PP; - } - - PosPtr peek() const noexcept { - auto TkEnd = getNextTokenStartPos(); - auto End = getAfterBack(); - return TkEnd == End ? nullptr : TkEnd; - } - - void increment() noexcept { - const PosPtr End = getAfterBack(); - const PosPtr Start = getNextTokenStartPos(); - if (Start == End) - return makeState(PS_AtEnd); - - switch (State) { - case PS_BeforeBegin: { - PosPtr TkEnd = consumeSeparator(Start, End); - // If we consumed exactly two separators we have a root name. - if (TkEnd && TkEnd == Start + 2) { - // FIXME Do we need to consume a name or is '//' a root name on its own? - // what about '//.', '//..', '//...'? - auto NameEnd = consumeName(TkEnd, End); - if (NameEnd) - TkEnd = NameEnd; - return makeState(PS_InRootName, Start, TkEnd); - } - else if (TkEnd) - return makeState(PS_InRootDir, Start, TkEnd); - else - return makeState(PS_InFilenames, Start, consumeName(Start, End)); - } - - case PS_InRootName: - return makeState(PS_InRootDir, Start, consumeSeparator(Start, End)); - case PS_InRootDir: - return makeState(PS_InFilenames, Start, consumeName(Start, End)); - - case PS_InFilenames: { - PosPtr SepEnd = consumeSeparator(Start, End); - if (SepEnd != End) { - PosPtr TkEnd = consumeName(SepEnd, End); - if (TkEnd) - return makeState(PS_InFilenames, SepEnd, TkEnd); - } - return makeState(PS_InTrailingSep, Start, SepEnd); - } - - case PS_InTrailingSep: - return makeState(PS_AtEnd); - - case PS_AtEnd: - _LIBCPP_UNREACHABLE(); - } - } - - void decrement() noexcept { - const PosPtr REnd = getBeforeFront(); - const PosPtr RStart = getCurrentTokenStartPos() - 1; - - switch (State) { - case PS_AtEnd: { - // Try to consume a trailing separator or root directory first. - if (PosPtr SepEnd = consumeSeparator(RStart, REnd)) { - if (SepEnd == REnd) - return makeState((RStart == REnd + 2) ? PS_InRootName : PS_InRootDir, - Path.data(), RStart + 1); - // Check if we're seeing the root directory separator - auto PP = CreateBegin(Path); - bool InRootDir = PP.State == PS_InRootName && - &PP.RawEntry.back() == SepEnd; - return makeState(InRootDir ? PS_InRootDir : PS_InTrailingSep, - SepEnd + 1, RStart + 1); - } else { - PosPtr TkStart = consumeName(RStart, REnd); - if (TkStart == REnd + 2 && consumeSeparator(TkStart, REnd) == REnd) - return makeState(PS_InRootName, Path.data(), RStart + 1); - else - return makeState(PS_InFilenames, TkStart + 1, RStart + 1); - } - } - case PS_InTrailingSep: - return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1, RStart + 1); - case PS_InFilenames: { - PosPtr SepEnd = consumeSeparator(RStart, REnd); - if (SepEnd == REnd) - return makeState((RStart == REnd + 2) ? PS_InRootName : PS_InRootDir, - Path.data(), RStart + 1); - PosPtr TkEnd = consumeName(SepEnd, REnd); - if (TkEnd == REnd + 2 && consumeSeparator(TkEnd, REnd) == REnd) - return makeState(PS_InRootDir, SepEnd + 1, RStart + 1); - return makeState(PS_InFilenames, TkEnd + 1, SepEnd + 1); - } - case PS_InRootDir: - return makeState(PS_InRootName, Path.data(), RStart + 1); - case PS_InRootName: - case PS_BeforeBegin: - _LIBCPP_UNREACHABLE(); - } - } - - /// \brief Return a view with the "preferred representation" of the current - /// element. For example trailing separators are represented as a '.' - string_view_t operator*() const noexcept { - switch (State) { - case PS_BeforeBegin: - case PS_AtEnd: - return ""; - case PS_InRootDir: - return "/"; - case PS_InTrailingSep: - return "."; - case PS_InRootName: - case PS_InFilenames: - return RawEntry; - } - _LIBCPP_UNREACHABLE(); - } - - explicit operator bool() const noexcept { - return State != PS_BeforeBegin && State != PS_AtEnd; - } - - PathParser& operator++() noexcept { - increment(); - return *this; - } - - PathParser& operator--() noexcept { - decrement(); - return *this; - } - -private: - void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept { - State = NewState; - RawEntry = string_view_t(Start, End - Start); - } - void makeState(ParserState NewState) noexcept { - State = NewState; - RawEntry = {}; - } - - PosPtr getAfterBack() const noexcept { - return Path.data() + Path.size(); - } - - PosPtr getBeforeFront() const noexcept { - return Path.data() - 1; - } - - /// \brief Return a pointer to the first character after the currently - /// lexed element. - PosPtr getNextTokenStartPos() const noexcept { - switch (State) { - case PS_BeforeBegin: - return Path.data(); - case PS_InRootName: - case PS_InRootDir: - case PS_InFilenames: - return &RawEntry.back() + 1; - case PS_InTrailingSep: - case PS_AtEnd: - return getAfterBack(); - } - _LIBCPP_UNREACHABLE(); - } - - /// \brief Return a pointer to the first character in the currently lexed - /// element. - PosPtr getCurrentTokenStartPos() const noexcept { - switch (State) { - case PS_BeforeBegin: - case PS_InRootName: - return &Path.front(); - case PS_InRootDir: - case PS_InFilenames: - case PS_InTrailingSep: - return &RawEntry.front(); - case PS_AtEnd: - return &Path.back() + 1; - } - _LIBCPP_UNREACHABLE(); - } - - PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept { - if (P == End || *P != '/') - return nullptr; - const int Inc = P < End ? 1 : -1; - P += Inc; - while (P != End && *P == '/') - P += Inc; - return P; - } - - PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { - if (P == End || *P == '/') - return nullptr; - const int Inc = P < End ? 1 : -1; - P += Inc; - while (P != End && *P != '/') - P += Inc; - return P; - } -}; - -string_view_pair separate_filename(string_view_t const & s) { - if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""}; - auto pos = s.find_last_of('.'); - if (pos == string_view_t::npos) - return string_view_pair{s, string_view_t{}}; - return string_view_pair{s.substr(0, pos), s.substr(pos)}; -} - -string_view_t createView(PosPtr S, PosPtr E) noexcept { - return {S, static_cast<size_t>(E - S) + 1}; -} - -}} // namespace parser - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM - -using parser::string_view_t; -using parser::string_view_pair; -using parser::PathParser; -using parser::createView; - -/////////////////////////////////////////////////////////////////////////////// -// path definitions -/////////////////////////////////////////////////////////////////////////////// - -constexpr path::value_type path::preferred_separator; - -path & path::replace_extension(path const & replacement) -{ - path p = extension(); - if (not p.empty()) { - __pn_.erase(__pn_.size() - p.native().size()); - } - if (!replacement.empty()) { - if (replacement.native()[0] != '.') { - __pn_ += "."; - } - __pn_.append(replacement.__pn_); - } - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// path.decompose - -string_view_t path::__root_name() const -{ - auto PP = PathParser::CreateBegin(__pn_); - if (PP.State == PathParser::PS_InRootName) - return *PP; - return {}; -} - -string_view_t path::__root_directory() const -{ - auto PP = PathParser::CreateBegin(__pn_); - if (PP.State == PathParser::PS_InRootName) - ++PP; - if (PP.State == PathParser::PS_InRootDir) - return *PP; - return {}; -} - -string_view_t path::__root_path_raw() const -{ - auto PP = PathParser::CreateBegin(__pn_); - if (PP.State == PathParser::PS_InRootName) { - auto NextCh = PP.peek(); - if (NextCh && *NextCh == '/') { - ++PP; - return createView(__pn_.data(), &PP.RawEntry.back()); - } - return PP.RawEntry; - } - if (PP.State == PathParser::PS_InRootDir) - return *PP; - return {}; -} - -string_view_t path::__relative_path() const -{ - auto PP = PathParser::CreateBegin(__pn_); - while (PP.State <= PathParser::PS_InRootDir) - ++PP; - if (PP.State == PathParser::PS_AtEnd) - return {}; - return createView(PP.RawEntry.data(), &__pn_.back()); -} - -string_view_t path::__parent_path() const -{ - if (empty()) - return {}; - auto PP = PathParser::CreateEnd(__pn_); - --PP; - if (PP.RawEntry.data() == __pn_.data()) - return {}; - --PP; - return createView(__pn_.data(), &PP.RawEntry.back()); -} - -string_view_t path::__filename() const -{ - if (empty()) return {}; - return *(--PathParser::CreateEnd(__pn_)); -} - -string_view_t path::__stem() const -{ - return parser::separate_filename(__filename()).first; -} - -string_view_t path::__extension() const -{ - return parser::separate_filename(__filename()).second; -} - -//////////////////////////////////////////////////////////////////////////// -// path.comparisons -int path::__compare(string_view_t __s) const { - auto PP = PathParser::CreateBegin(__pn_); - auto PP2 = PathParser::CreateBegin(__s); - while (PP && PP2) { - int res = (*PP).compare(*PP2); - if (res != 0) return res; - ++PP; ++PP2; - } - if (PP.State == PP2.State && PP.State == PathParser::PS_AtEnd) - return 0; - if (PP.State == PathParser::PS_AtEnd) - return -1; - return 1; -} - -//////////////////////////////////////////////////////////////////////////// -// path.nonmembers -size_t hash_value(const path& __p) noexcept { - auto PP = PathParser::CreateBegin(__p.native()); - size_t hash_value = 0; - std::hash<string_view_t> hasher; - while (PP) { - hash_value = __hash_combine(hash_value, hasher(*PP)); - ++PP; - } - return hash_value; -} - -//////////////////////////////////////////////////////////////////////////// -// path.itr -path::iterator path::begin() const -{ - auto PP = PathParser::CreateBegin(__pn_); - iterator it; - it.__path_ptr_ = this; - it.__state_ = PP.State; - it.__entry_ = PP.RawEntry; - it.__stashed_elem_.__assign_view(*PP); - return it; -} - -path::iterator path::end() const -{ - iterator it{}; - it.__state_ = PathParser::PS_AtEnd; - it.__path_ptr_ = this; - return it; -} - -path::iterator& path::iterator::__increment() { - static_assert(__at_end == PathParser::PS_AtEnd, ""); - PathParser PP(__path_ptr_->native(), __entry_, __state_); - ++PP; - __state_ = PP.State; - __entry_ = PP.RawEntry; - __stashed_elem_.__assign_view(*PP); - return *this; -} - -path::iterator& path::iterator::__decrement() { - PathParser PP(__path_ptr_->native(), __entry_, __state_); - --PP; - __state_ = PP.State; - __entry_ = PP.RawEntry; - __stashed_elem_.__assign_view(*PP); - return *this; -} - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM |