Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2019-10-14 13:10:11 +0300
committerNiall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com>2019-10-14 13:10:11 +0300
commit34e40a322e66e754369f4fe84a976c7669d5bc9f (patch)
tree3805a4fb535466e9d8d5d4d2572b7803d31235de
parent2cca7cc4bc914d4cb92306faabb9d6db765b8464 (diff)
Path view refactor passes all unit tests and asan.
-rw-r--r--CMakeLists.txt5
-rw-r--r--include/llfio/revision.hpp6
-rw-r--r--include/llfio/v2.0/detail/impl/path_view.ipp43
-rw-r--r--include/llfio/v2.0/path_view.hpp120
-rw-r--r--test/tests/directory_handle_enumerate/runner.cpp8
-rw-r--r--test/tests/path_view.cpp6
6 files changed, 136 insertions, 52 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f09ae18..112bd8a2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -177,10 +177,10 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
# Do make libc++ a requirement for the _dl edition
target_compile_definitions(${PROJECT_NAME}_dl PUBLIC _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_FILESYSTEM=1)
target_compile_options(${PROJECT_NAME}_dl PUBLIC -stdlib=libc++)
- target_link_libraries(${PROJECT_NAME}_dl PUBLIC -stdlib=libc++ -lc++abi -lc++experimental)
+ target_link_libraries(${PROJECT_NAME}_dl PUBLIC -stdlib=libc++ -lc++abi)
foreach(special ${SPECIAL_BUILDS})
target_compile_options(${PROJECT_NAME}_dl-${special} PUBLIC -stdlib=libc++)
- target_link_libraries(${PROJECT_NAME}_dl-${special} PUBLIC -stdlib=libc++ -lc++abi -lc++experimental)
+ target_link_libraries(${PROJECT_NAME}_dl-${special} PUBLIC -stdlib=libc++ -lc++abi)
endforeach()
endif()
endif()
@@ -242,7 +242,6 @@ if(NOT PROJECT_IS_DEPENDENCY)
if(USING_LIBCXX_ON_LINUX)
if(NOT test_target MATCHES _sl)
apply_cxx_coroutines_to(PRIVATE ${test_target})
- target_link_libraries(${test_target} PRIVATE -lc++experimental)
endif()
else()
apply_cxx_coroutines_to(PRIVATE ${test_target})
diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp
index ae369fea..565f9c05 100644
--- a/include/llfio/revision.hpp
+++ b/include/llfio/revision.hpp
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
-#define LLFIO_PREVIOUS_COMMIT_REF 7a854e59e7bb402399a590be35c2292b6f081268
-#define LLFIO_PREVIOUS_COMMIT_DATE "2019-10-12 15:17:03 +00:00"
-#define LLFIO_PREVIOUS_COMMIT_UNIQUE 7a854e59
+#define LLFIO_PREVIOUS_COMMIT_REF 2cca7cc4bc914d4cb92306faabb9d6db765b8464
+#define LLFIO_PREVIOUS_COMMIT_DATE "2019-10-14 08:51:16 +00:00"
+#define LLFIO_PREVIOUS_COMMIT_UNIQUE 2cca7cc4
diff --git a/include/llfio/v2.0/detail/impl/path_view.ipp b/include/llfio/v2.0/detail/impl/path_view.ipp
index 3e948a57..f2171651 100644
--- a/include/llfio/v2.0/detail/impl/path_view.ipp
+++ b/include/llfio/v2.0/detail/impl/path_view.ipp
@@ -287,30 +287,31 @@ namespace detail
state.str.Length = state.str.MaximumLength = (USHORT) src_buffer_length;
// Try using the internal buffer
NTSTATUS ntstat = AreFileApisANSI() ? RtlAnsiStringToUnicodeString(&state.buffer, &state.str, false) : RtlOemStringToUnicodeString(&state.buffer, &state.str, false);
+ if(ntstat >= 0)
+ {
+ // Successful
+ toallocate = 0;
+ state.buffer.Buffer[(state.buffer.Length / sizeof(wchar_t))] = 0;
+ state.buffer.Buffer = nullptr;
+ return dest_buffer + (state.buffer.Length / sizeof(wchar_t));
+ }
+ if(ntstat != STATUS_BUFFER_OVERFLOW)
+ {
+ LLFIO_LOG_FATAL(ntstat, ntkernel_error(ntstat).message().c_str());
+ abort();
+ }
+ // Dynamically allocate
+ ntstat = AreFileApisANSI() ? RtlAnsiStringToUnicodeString(&state.buffer, &state.str, true) : RtlOemStringToUnicodeString(&state.buffer, &state.str, true);
if(ntstat < 0)
{
- if(ntstat != STATUS_BUFFER_OVERFLOW)
- {
- LLFIO_LOG_FATAL(ntstat, ntkernel_error(ntstat).message().c_str());
- abort();
- }
- // Dynamically allocate
- ntstat = AreFileApisANSI() ? RtlAnsiStringToUnicodeString(&state.buffer, &state.str, true) : RtlOemStringToUnicodeString(&state.buffer, &state.str, true);
- if(ntstat < 0)
- {
- LLFIO_LOG_FATAL(ntstat, ntkernel_error(ntstat).message().c_str());
- abort();
- }
- // The thread local state will cache this for later
- state.buffer.MaximumLength = state.buffer.Length + sizeof(wchar_t);
- // Retry me with this dynamic allocation
- toallocate = state.buffer.MaximumLength / sizeof(wchar_t);
- return dest_buffer;
+ LLFIO_LOG_FATAL(ntstat, ntkernel_error(ntstat).message().c_str());
+ abort();
}
- // Successful
- toallocate = 0;
- state.buffer.Buffer[(state.buffer.Length / sizeof(wchar_t))] = 0;
- return state.buffer.Buffer + (state.buffer.Length / sizeof(wchar_t));
+ // The thread local state will cache this for later
+ state.buffer.MaximumLength = state.buffer.Length + sizeof(wchar_t);
+ // Retry me with this dynamic allocation
+ toallocate = state.buffer.MaximumLength / sizeof(wchar_t);
+ return dest_buffer;
#elif defined(_LIBCPP_VERSION)
(void) toallocate;
(void) dest_buffer;
diff --git a/include/llfio/v2.0/path_view.hpp b/include/llfio/v2.0/path_view.hpp
index f1b345e7..52791503 100644
--- a/include/llfio/v2.0/path_view.hpp
+++ b/include/llfio/v2.0/path_view.hpp
@@ -302,6 +302,15 @@ private:
basic_string_view<char>((const char *) _bytestr, _length).rfind(preferred_separator, endidx)));
#endif
}
+ LLFIO_PATH_VIEW_GCC_CONSTEXPR path_view_component _filename() const noexcept
+ {
+ auto sep_idx = _find_last_sep();
+ if(_npos == sep_idx)
+ {
+ return *this;
+ }
+ return _invoke([sep_idx, this](const auto &v) { return path_view_component(v.data() + sep_idx + 1, v.size() - sep_idx - 1, _zero_terminated); });
+ }
public:
path_view_component(const path_view_component &) = default;
@@ -344,23 +353,23 @@ public:
//! Returns a view of the filename without any file extension
constexpr path_view_component stem() const noexcept
{
- auto sep_idx = _find_last_sep();
- return _invoke([sep_idx, this](const auto &v) {
+ auto self = _filename();
+ return self._invoke([self](const auto &v) {
auto dot_idx = v.rfind('.');
- if(_npos == dot_idx || (_npos != sep_idx && dot_idx < sep_idx) || dot_idx == sep_idx + 1 || (dot_idx == sep_idx + 2 && v[dot_idx - 1] == '.'))
+ if(_npos == dot_idx || dot_idx == 0 || (dot_idx == 1 && v[dot_idx - 1] == '.'))
{
- return path_view_component(v.data() + sep_idx + 1, v.size() - sep_idx - 1, false);
+ return self;
}
- return path_view_component(v.data() + sep_idx + 1, dot_idx - sep_idx - 1, _zero_terminated);
+ return path_view_component(v.data(), dot_idx, false);
});
}
//! Returns a view of the file extension part of this view
constexpr path_view_component extension() const noexcept
{
- auto sep_idx = _find_last_sep();
- return _invoke([sep_idx, this](const auto &v) {
+ auto self = _filename();
+ return self._invoke([this](const auto &v) {
auto dot_idx = v.rfind('.');
- if(_npos == dot_idx || (_npos != sep_idx && dot_idx < sep_idx) || dot_idx == sep_idx + 1 || (dot_idx == sep_idx + 2 && v[dot_idx - 1] == '.'))
+ if(_npos == dot_idx || dot_idx == 0 || (dot_idx == 1 && v[dot_idx - 1] == '.'))
{
return path_view_component();
}
@@ -552,6 +561,13 @@ public:
*/
template <class U> c_str(path_view_component view, bool no_zero_terminate, U &&allocate)
{
+ if(0 == view._length)
+ {
+ _buffer[0] = 0;
+ buffer = _buffer;
+ length = 0;
+ return;
+ }
if(std::is_same<T, byte>::value || view._passthrough)
{
length = view._length;
@@ -725,6 +741,12 @@ inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator==(path_view_component x, path
{
return false;
}
+ if(0 == x._length && 0 == y._length)
+ {
+ return true;
+ }
+ assert(x._bytestr != nullptr);
+ assert(y._bytestr != nullptr);
return 0 == memcmp(x._bytestr, y._bytestr, x._length);
}
inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(path_view_component x, path_view_component y) noexcept
@@ -753,8 +775,42 @@ inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(path_view_component x, path
{
return true;
}
+ if(0 == x._length && 0 == y._length)
+ {
+ return false;
+ }
+ assert(x._bytestr != nullptr);
+ assert(y._bytestr != nullptr);
return 0 != memcmp(x._bytestr, y._bytestr, x._length);
}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator==(path_view_component /*unused*/, const CharT * /*unused*/) noexcept {
+ static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator== with path_view_component and a string literal, use .compare<>()");
+ return false;
+}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator==(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
+{
+ static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator== with path_view_component and a string literal, use .compare<>()");
+ return false;
+}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(path_view_component /*unused*/, const CharT * /*unused*/) noexcept
+{
+ static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator!= with path_view_component and a string literal, use .compare<>()");
+ return false;
+}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view_component::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(const CharT * /*unused*/, path_view_component /*unused*/) noexcept
+{
+ static_assert(!path_view_component::is_source_acceptable<CharT>, "Do not use operator!= with path_view_component and a string literal, use .compare<>()");
+ return false;
+}
+
namespace detail
{
struct string_view_printer
@@ -1112,7 +1168,7 @@ public:
auto sep_idx = _state._find_last_sep();
if(_npos == sep_idx)
{
- return *this;
+ return path_view();
}
return _state._invoke([sep_idx](auto v) { return path_view(v.data(), sep_idx, false); });
}
@@ -1226,15 +1282,7 @@ public:
return _state._invoke([sep_idx](const auto &v) { return path_view(v.data(), sep_idx, false); });
}
//! Returns a view of the filename part of this view.
- LLFIO_PATH_VIEW_GCC_CONSTEXPR path_view filename() const noexcept
- {
- auto sep_idx = _state._find_last_sep();
- if(_npos == sep_idx)
- {
- return _state;
- }
- return _state._invoke([sep_idx, this](const auto &v) { return path_view_component(v.data() + sep_idx + 1, v.size() - sep_idx - 1, _state._zero_terminated); });
- }
+ LLFIO_PATH_VIEW_GCC_CONSTEXPR path_view filename() const noexcept { return _state._filename(); }
//! Returns a view of the filename without any file extension
constexpr path_view_component stem() const noexcept { return _state.stem(); }
//! Returns a view of the file extension part of this view
@@ -1310,6 +1358,34 @@ inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(path_view x, path_view y) n
{
return x._state != y._state;
}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator==(path_view /*unused*/, const CharT * /*unused*/) noexcept
+{
+ static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator== with path_view and a string literal, use .compare<>()");
+ return false;
+}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator==(const CharT * /*unused*/, path_view /*unused*/) noexcept
+{
+ static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator== with path_view and a string literal, use .compare<>()");
+ return false;
+}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(path_view /*unused*/, const CharT * /*unused*/) noexcept
+{
+ static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator!= with path_view and a string literal, use .compare<>()");
+ return false;
+}
+LLFIO_TEMPLATE(class CharT)
+LLFIO_TREQUIRES(LLFIO_TPRED(path_view::is_source_acceptable<CharT>))
+inline LLFIO_PATH_VIEW_GCC_CONSTEXPR bool operator!=(const CharT * /*unused*/, path_view /*unused*/) noexcept
+{
+ static_assert(!path_view::is_source_acceptable<CharT>, "Do not use operator!= with path_view and a string literal, use .compare<>()");
+ return false;
+}
inline std::ostream &operator<<(std::ostream &s, const path_view &v)
{
return s << v._state;
@@ -1372,6 +1448,10 @@ namespace detail
{
_parent->_state._invoke([this](const auto &v) { _end = v.size(); });
}
+ if(_end > _begin)
+ {
+ ++_begin;
+ }
}
constexpr void _dec() noexcept
{
@@ -1381,6 +1461,10 @@ namespace detail
{
_begin = 0;
}
+ if(_begin < _end)
+ {
+ --_end;
+ }
}
constexpr path_view_iterator(const path_view *p, bool end)
diff --git a/test/tests/directory_handle_enumerate/runner.cpp b/test/tests/directory_handle_enumerate/runner.cpp
index f762f6ed..ec1d25f9 100644
--- a/test/tests/directory_handle_enumerate/runner.cpp
+++ b/test/tests/directory_handle_enumerate/runner.cpp
@@ -100,19 +100,19 @@ template <class U> inline void directory_handle_enumerate_(U &&f)
bool havedir = !glob.empty();
for (directory_entry &i : info)
{
- if (i.leafname == "012345678901234567890123456789012345678901234567890123456789012z.deleted")
+ if (0 == i.leafname.compare<>("012345678901234567890123456789012345678901234567890123456789012z.deleted"))
{
havedeleted1 = true;
}
- if (i.leafname == "0123456789012345678901234567890123456789012345678901234567890123.deleted")
+ if (0 == i.leafname.compare<>("0123456789012345678901234567890123456789012345678901234567890123.deleted"))
{
havedeleted2 = true;
}
- if (i.leafname == "foo.txt")
+ if (0 == i.leafname.compare<>("foo.txt"))
{
havefoo = true;
}
- if (i.leafname == "dir")
+ if (0 == i.leafname.compare<>("dir"))
{
havedir = true;
}
diff --git a/test/tests/path_view.cpp b/test/tests/path_view.cpp
index b9b821b6..aa92b0c8 100644
--- a/test/tests/path_view.cpp
+++ b/test/tests/path_view.cpp
@@ -57,7 +57,7 @@ static inline void TestPathView()
constexpr llfio::path_view a, b("hello");
BOOST_CHECK(a.empty());
BOOST_CHECK(!b.empty());
- BOOST_CHECK(b == "hello");
+ BOOST_CHECK(0 == b.compare<>("hello"));
// Globs
BOOST_CHECK(llfio::path_view("niall*").contains_glob());
// Splitting
@@ -65,8 +65,8 @@ static inline void TestPathView()
llfio::path_view e(p); // NOLINT
llfio::path_view f(e.filename());
e = e.remove_filename();
- BOOST_CHECK(e == "/mnt/c/Users/ned/Documents/boostish/afio/programs/build_posix/testdir");
- BOOST_CHECK(f == "0");
+ BOOST_CHECK(0 == e.compare<>("/mnt/c/Users/ned/Documents/boostish/afio/programs/build_posix/testdir"));
+ BOOST_CHECK(0 == f.compare<>("0"));
#ifndef _WIN32
// cstr
llfio::path_view::c_str<> g(e);