Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit 9cc8cbf
Author: Steffen Schuemann <[email protected]>
Date:   Mon May 27 09:36:09 2019 +0200

    Workaround for bug in clangs libc++ std::filesystem::path::format.

commit 72285d0
Author: Steffen Schuemann <[email protected]>
Date:   Mon May 27 09:17:49 2019 +0200

    Test coverage.

commit f3ab2af
Author: Steffen Schuemann <[email protected]>
Date:   Sun May 26 12:35:39 2019 +0200

    Fixed std builds, removed non-standard conforming swap in directory_iterator/recursive_directory_iterator.

commit 3ae76b2
Author: gulrak <[email protected]>
Date:   Sun May 26 11:08:52 2019 +0200

    Additional tests.

commit af4bbe1
Author: gulrak <[email protected]>
Date:   Fri May 24 21:52:15 2019 +0200

    Added more tests.
  • Loading branch information
gulrak committed May 30, 2019
1 parent 8552dc6 commit 235a594
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 23 deletions.
28 changes: 9 additions & 19 deletions include/ghc/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,6 @@ class GHC_FS_API_CLASS directory_iterator
}
bool operator==(const directory_iterator& rhs) const;
bool operator!=(const directory_iterator& rhs) const;
void swap(directory_iterator& rhs);

private:
friend class recursive_directory_iterator;
Expand Down Expand Up @@ -740,7 +739,6 @@ class GHC_FS_API_CLASS recursive_directory_iterator
}
bool operator==(const recursive_directory_iterator& rhs) const;
bool operator!=(const recursive_directory_iterator& rhs) const;
void swap(recursive_directory_iterator& rhs);

private:
struct recursive_directory_iterator_impl
Expand Down Expand Up @@ -2515,17 +2513,19 @@ GHC_INLINE path::iterator::iterator(const path::string_type::const_iterator& fir
}
else
#endif
{
if (_first != _last && *_first == '/') {
if (_last - _first >= 2 && *(_first + 1) == '/' && !(_last - _first >= 3 && *(_first + 2) == '/')) {
_root = increment(_first);
if (_last - _first >= 2 && *(_first + 1) == '/' && !(_last - _first >= 3 && *(_first + 2) == '/')) {
_root = increment(_first);
}
else {
_root = _first;
}
}
else {
_root = _first;
_root = _last;
}
}
else {
_root = _last;
}
}

GHC_INLINE path::string_type::const_iterator path::iterator::increment(const path::string_type::const_iterator& pos) const
Expand Down Expand Up @@ -2631,7 +2631,7 @@ GHC_INLINE path::iterator& path::iterator::operator--()

GHC_INLINE path::iterator path::iterator::operator--(int)
{
path::iterator i{*this};
auto i = *this;
--(*this);
return i;
}
Expand Down Expand Up @@ -4778,11 +4778,6 @@ GHC_INLINE bool directory_iterator::operator!=(const directory_iterator& rhs) co
return _impl->_current != rhs._impl->_current;
}

GHC_INLINE void directory_iterator::swap(directory_iterator& rhs)
{
std::swap(_impl, rhs._impl);
}

// 30.10.13.2 directory_iterator non-member functions

GHC_INLINE directory_iterator begin(directory_iterator iter) noexcept
Expand Down Expand Up @@ -4948,11 +4943,6 @@ GHC_INLINE bool recursive_directory_iterator::operator!=(const recursive_directo
return _impl->_dir_iter_stack.top() != rhs._impl->_dir_iter_stack.top();
}

GHC_INLINE void recursive_directory_iterator::swap(recursive_directory_iterator& rhs)
{
std::swap(_impl, rhs._impl);
}

// 30.10.14.2 directory_iterator non-member functions
GHC_INLINE recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept
{
Expand Down
133 changes: 129 additions & 4 deletions test/filesystem_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <random>
#include <sstream>
#include <thread>
Expand Down Expand Up @@ -308,7 +309,7 @@ TEST_CASE("Temporary Directory", "[fs.test.tempdir]")
}

#ifdef GHC_FILESYSTEM_VERSION
TEST_CASE("fs::detail::fromUf88", "[filesystem][fs.detail.utf8]")
TEST_CASE("fs::detail::fromUtf8", "[filesystem][fs.detail.utf8]")
{
CHECK(fs::detail::fromUtf8<std::wstring>("foobar").length() == 6);
CHECK(fs::detail::fromUtf8<std::wstring>("foobar") == L"foobar");
Expand All @@ -321,6 +322,7 @@ TEST_CASE("fs::detail::fromUf88", "[filesystem][fs.detail.utf8]")
CHECK(fs::detail::toUtf8(std::wstring(L"föobar")) == u8"föobar");

CHECK(std::u16string(2,0xfffd) == fs::detail::fromUtf8<std::u16string>(std::string("\xed\xa0\x80")));
CHECK(std::u16string(1,0xfffd) == fs::detail::fromUtf8<std::u16string>(std::string("\xc3")));
}

TEST_CASE("fs::detail::toUtf8", "[filesystem][fs.detail.utf8]")
Expand Down Expand Up @@ -348,10 +350,15 @@ TEST_CASE("30.10.8.4.1 path constructors and destructor", "[filesystem][path][fs
std::string str = "/usr/local/bin";
std::u16string u16str = u"/usr/local/bin";
std::u32string u32str = U"/usr/local/bin";
CHECK(str == fs::path(str, fs::path::format::generic_format));
CHECK(str == fs::path(str.begin(), str.end()));
CHECK(fs::path(std::wstring(3, 67)) == "CCC");
CHECK(str == fs::path(u16str.begin(), u16str.end()));
CHECK(str == fs::path(u32str.begin(), u32str.end()));
#ifdef GHC_FILESYSTEM_VERSION
CHECK(fs::path("///foo/bar") == "/foo/bar");
CHECK(fs::path("//foo//bar") == "//foo/bar");
#endif
#ifdef GHC_OS_WINDOWS
CHECK("\\usr\\local\\bin" == fs::path("/usr/local/bin"));
CHECK("C:\\usr\\local\\bin" == fs::path("C:\\usr\\local\\bin"));
Expand Down Expand Up @@ -963,13 +970,19 @@ TEST_CASE("30.10.8.5 path iterators", "[filesystem][path][fs.path.itr]")
p2 /= pe;
}
CHECK(p1 == p2);
CHECK("bar" == *(--fs::path("/foo/bar").end()));
auto p = fs::path("/foo/bar");
auto pi = p.end();
pi--;
CHECK("bar" == *pi);
}

if (has_host_root_name_support()) {
CHECK("foo" == *(--fs::path("//host/foo").end()));
/*auto pi = fs::path("//host/foo").end();
auto p = fs::path("//host/foo");
auto pi = p.end();
pi--;
CHECK("foo" == *pi);*/
CHECK("foo" == *pi);
CHECK("//host" == iterateResult(fs::path("//host")));
CHECK("//host,/,foo" == iterateResult(fs::path("//host/foo")));
CHECK("//host" == reverseIterateResult(fs::path("//host")));
Expand Down Expand Up @@ -1068,7 +1081,8 @@ TEST_CASE("30.10.8.6.2 path factory functions", "[filesystem][path][fs.path.fact
TEST_CASE("30.10.9 class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]")
{
std::error_code ec(1, std::system_category());
auto fse = fs::filesystem_error("Some error", ec);
fs::filesystem_error fse("None", std::error_code());
fse = fs::filesystem_error("Some error", ec);
CHECK(fse.code().value() == 1);
CHECK(!std::string(fse.what()).empty());
CHECK(fse.path1().empty());
Expand Down Expand Up @@ -1132,8 +1146,10 @@ TEST_CASE("30.10.11 class file_status", "[filesystem][file_status][fs.class.file
TEST_CASE("30.10.12 class directory_entry", "[filesystem][directory_entry][fs.dir.entry]")
{
TemporaryDirectory t;
std::error_code ec;
auto de = fs::directory_entry(t.path());
CHECK(de.path() == t.path());
CHECK((fs::path)de == t.path());
CHECK(de.exists());
CHECK(!de.is_block_file());
CHECK(!de.is_character_file());
Expand All @@ -1143,21 +1159,98 @@ TEST_CASE("30.10.12 class directory_entry", "[filesystem][directory_entry][fs.di
CHECK(!de.is_regular_file());
CHECK(!de.is_socket());
CHECK(!de.is_symlink());
CHECK(de.status().type() == fs::file_type::directory);
ec.clear();
CHECK(de.status(ec).type() == fs::file_type::directory);
CHECK(!ec);
CHECK_NOTHROW(de.refresh());
fs::directory_entry none;
CHECK_THROWS_AS(none.refresh(), fs::filesystem_error);
CHECK_THROWS_AS(de.assign(""), fs::filesystem_error);
ec.clear();
CHECK_NOTHROW(de.assign("", ec));
CHECK(ec);
generateFile(t.path() / "foo", 1234);
auto now = fs::file_time_type::clock::now();
CHECK_NOTHROW(de.assign(t.path() / "foo"));
CHECK_NOTHROW(de.assign(t.path() / "foo", ec));
CHECK(!ec);
de = fs::directory_entry(t.path() / "foo");
CHECK(de.path() == t.path() / "foo");
CHECK(de.exists());
CHECK(de.exists(ec));
CHECK(!ec);
CHECK(!de.is_block_file());
CHECK(!de.is_block_file(ec));
CHECK(!ec);
CHECK(!de.is_character_file());
CHECK(!de.is_character_file(ec));
CHECK(!ec);
CHECK(!de.is_directory());
CHECK(!de.is_directory(ec));
CHECK(!ec);
CHECK(!de.is_fifo());
CHECK(!de.is_fifo(ec));
CHECK(!ec);
CHECK(!de.is_other());
CHECK(!de.is_other(ec));
CHECK(!ec);
CHECK(de.is_regular_file());
CHECK(de.is_regular_file(ec));
CHECK(!ec);
CHECK(!de.is_socket());
CHECK(!de.is_socket(ec));
CHECK(!ec);
CHECK(!de.is_symlink());
CHECK(!de.is_symlink(ec));
CHECK(!ec);
CHECK(de.file_size() == 1234);
CHECK(de.file_size(ec) == 1234);
CHECK(std::abs(std::chrono::duration_cast<std::chrono::seconds>(de.last_write_time() - now).count()) < 3);
ec.clear();
CHECK(std::abs(std::chrono::duration_cast<std::chrono::seconds>(de.last_write_time(ec) - now).count()) < 3);
CHECK(!ec);
CHECK(de.hard_link_count() == 1);
CHECK(de.hard_link_count(ec) == 1);
CHECK(!ec);
CHECK_THROWS_AS(de.replace_filename("bar"), fs::filesystem_error);
CHECK_NOTHROW(de.replace_filename("foo"));
ec.clear();
CHECK_NOTHROW(de.replace_filename("bar", ec));
CHECK(ec);
auto de2none = fs::directory_entry();
ec.clear();
CHECK(de2none.hard_link_count(ec) == static_cast<uintmax_t>(-1));
CHECK_THROWS_AS(de2none.hard_link_count(), fs::filesystem_error);
CHECK(ec);
ec.clear();
CHECK_NOTHROW(de2none.last_write_time(ec));
CHECK_THROWS_AS(de2none.last_write_time(), fs::filesystem_error);
CHECK(ec);
ec.clear();
CHECK_THROWS_AS(de2none.file_size(), fs::filesystem_error);
CHECK(de2none.file_size(ec) == static_cast<uintmax_t>(-1));
CHECK(ec);
ec.clear();
CHECK(de2none.status().type() == fs::file_type::not_found);
CHECK(de2none.status(ec).type() == fs::file_type::not_found);
CHECK(ec);
generateFile(t.path() / "a");
generateFile(t.path() / "b");
auto d1 = fs::directory_entry(t.path() / "a");
auto d2 = fs::directory_entry(t.path() / "b");
CHECK(d1 < d2);
CHECK(!(d2 < d1));
CHECK(d1 <= d2);
CHECK(!(d2 <= d1));
CHECK(d2 > d1);
CHECK(!(d1 > d2));
CHECK(d2 >= d1);
CHECK(!(d1 >= d2));
CHECK(d1 != d2);
CHECK(!(d2 != d2));
CHECK(d1 == d1);
CHECK(!(d1 == d2));
}

TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]")
Expand All @@ -1183,6 +1276,11 @@ TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator]
CHECK(iter->file_size() == 1234);
CHECK(++iter == fs::directory_iterator());
CHECK_THROWS_AS(fs::directory_iterator(t.path() / "non-existing"), fs::filesystem_error);
int cnt = 0;
for(auto de : fs::directory_iterator(t.path())) {
++cnt;
}
CHECK(cnt == 1);
}
if (is_symlink_creation_supported()) {
TemporaryDirectory t;
Expand Down Expand Up @@ -1218,6 +1316,11 @@ TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator]

TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]")
{
{
auto iter = fs::recursive_directory_iterator(".");
iter.pop();
CHECK(iter == fs::recursive_directory_iterator());
}
{
TemporaryDirectory t;
CHECK(fs::recursive_directory_iterator(t.path()) == fs::recursive_directory_iterator());
Expand Down Expand Up @@ -1302,6 +1405,25 @@ TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive
}
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/b,1],[./d1/c,1],[./d1/d2,1],[./d1/d2/d,2],[./e,0],");
}
{
TemporaryDirectory t(TempOpt::change_path);
generateFile("a");
fs::create_directory("d1");
fs::create_directory("d1/d2");
generateFile("d1/b");
generateFile("d1/c");
generateFile("d1/d2/d");
generateFile("e");
std::multiset<std::string> result;
for(auto de : fs::recursive_directory_iterator(".")) {
result.insert(de.path().generic_string());
}
std::stringstream os;
for(auto p : result) {
os << p << ",";
}
CHECK(os.str() == "./a,./d1,./d1/b,./d1/c,./d1/d2,./d1/d2/d,./e,");
}
{
TemporaryDirectory t(TempOpt::change_path);
generateFile("a");
Expand Down Expand Up @@ -2243,6 +2365,9 @@ TEST_CASE("30.10.15.29 relative", "[filesystem][operations][fs.op.relative]")
CHECK(fs::relative("a/b/c", "a/b/c/x/y") == "../..");
CHECK(fs::relative("a/b/c", "a/b/c") == ".");
CHECK(fs::relative("a/b", "c/d") == "../../a/b");
std::error_code ec;
CHECK(fs::relative(fs::current_path() / "foo", ec) == "foo");
CHECK(!ec);
}

TEST_CASE("30.10.15.30 remove", "[filesystem][operations][fs.op.remove]")
Expand Down

0 comments on commit 235a594

Please sign in to comment.