summaryrefslogtreecommitdiffstats
path: root/lib/libcxx/src/experimental/filesystem/path.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2019-02-04 17:04:33 +0000
committerpatrick <patrick@openbsd.org>2019-02-04 17:04:33 +0000
commit71d9f34297ef5b8104aac6236e8dc7c95ff5da15 (patch)
tree92fdcc887ac1b153c5e7da9cb557e6207705d89e /lib/libcxx/src/experimental/filesystem/path.cpp
parentImport libc++ 7.0.1. (diff)
downloadwireguard-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.cpp448
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