Work on shared/static library mode

Took 1 hour 56 minutes
This commit is contained in:
Steffen Schuemann 2021-10-26 07:57:43 +02:00
parent a07ddedeae
commit 270d6876dc
8 changed files with 757 additions and 697 deletions

View File

@ -21,5 +21,5 @@ BraceWrapping:
SplitEmptyNamespace: true
BreakConstructorInitializers: BeforeComma
ConstructorInitializerAllOnOneLineOrOnePerLine: false
IndentPPDirectives: None
IndentPPDirectives: AfterHash
...

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.7.2)
project(ghcfilesystem)
project(ghc_filesystem)
if (POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
@ -17,6 +17,8 @@ else()
option(GHC_FILESYSTEM_BUILD_TESTING "Enable tests" OFF)
option(GHC_FILESYSTEM_WITH_INSTALL "With install target" ON)
endif()
option(GHC_FILESYSTEM_BUILD_STATIC "Enable building static library" OFF)
option(GHC_FILESYSTEM_BUILD_SHARED "Enable building shared library" OFF)
option(GHC_FILESYSTEM_BUILD_STD_TESTING "Enable STD tests" ${GHC_FILESYSTEM_BUILD_TESTING})
if(NOT DEFINED GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
set(GHC_FILESYSTEM_TEST_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES})
@ -41,6 +43,28 @@ target_include_directories(ghc_filesystem INTERFACE
target_compile_options(ghc_filesystem INTERFACE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
if(GHC_FILESYSTEM_BUILD_STATIC)
add_library(ghc_filesystem_static STATIC src/filesystem.cpp)
target_include_directories(ghc_filesystem_static PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_definitions(ghc_filesystem_static PRIVATE GHC_FILESYSTEM_IMPLEMENTATION)
target_compile_definitions(ghc_filesystem_static INTERFACE GHC_FILESYSTEM_FWD)
target_compile_options(ghc_filesystem_static PUBLIC "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
target_compile_options(ghc_filesystem_static PUBLIC "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
endif()
if(GHC_FILESYSTEM_BUILD_SHARED)
add_library(ghc_filesystem_shared SHARED src/filesystem.cpp)
target_include_directories(ghc_filesystem_shared PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_compile_definitions(ghc_filesystem_shared PRIVATE GHC_FILESYSTEM_IMPLEMENTATION GHC_FILESYSTEM_SHARED)
target_compile_definitions(ghc_filesystem_shared INTERFACE GHC_FILESYSTEM_FWD GHC_FILESYSTEM_SHARED)
target_compile_options(ghc_filesystem_shared PUBLIC "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
target_compile_options(ghc_filesystem_shared PUBLIC "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
endif()
if(GHC_FILESYSTEM_BUILD_TESTING OR GHC_FILESYSTEM_BUILD_EXAMPLES)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")

View File

@ -104,7 +104,7 @@ for more information._
Unit tests are currently run with:
* macOS 10.12: Xcode 9.2 (clang-900.0.39.2), GCC 9.2, Clang 9.0, macOS 10.13: Xcode 10.1, macOS 10.14: Xcode 11.2, macOS 10.15: Xcode 11.6, Xcode 12.4
* macOS 10.12: Xcode 9.2 (clang-900.0.39.2), GCC 9.2, Clang 9.0, macOS 10.13: Xcode 10.1, macOS 10.14: Xcode 11.2, macOS 10.15: Xcode 11.6, Xcode 12.4, macOS 11.6: Xcode 13.0
* Windows: Visual Studio 2017, Visual Studio 2015, Visual Studio 2019, MinGW GCC 6.3 (Win32), GCC 7.2 (Win64), Cygwin GCC 10.2 (no CI yet)
* Linux (Ubuntu): GCC (5.5, 6.5, 7.4, 8.3, 9.2), Clang (5.0, 6.0, 7.1, 8.0, 9.0)
* Linux (Alpine ARM/ARM64): GCC 9.2.0

View File

@ -3,4 +3,4 @@
# import targets
include("${CMAKE_CURRENT_LIST_DIR}/ghc_filesystem-targets.cmake")
check_required_components(ghcfilesystem)
check_required_components(ghc_filesystem)

File diff suppressed because it is too large Load Diff

28
src/filesystem.cpp Normal file
View File

@ -0,0 +1,28 @@
//---------------------------------------------------------------------------------------
//
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
//
//---------------------------------------------------------------------------------------
//
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//---------------------------------------------------------------------------------------
#include <ghc/filesystem.hpp>

View File

@ -78,6 +78,18 @@ if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
endif()
add_test(fwd_impl_test fwd_impl_test)
if(GHC_FILESYSTEM_BUILD_STATIC)
add_executable(filesystem_test_static filesystem_test.cpp catch.hpp)
target_link_libraries(filesystem_test_static ghc_filesystem_static)
ParseAndAddCatchTests(filesystem_test_static)
endif()
if(GHC_FILESYSTEM_BUILD_SHARED)
add_executable(filesystem_test_shared filesystem_test.cpp catch.hpp)
target_link_libraries(filesystem_test_shared ghc_filesystem_shared)
ParseAndAddCatchTests(filesystem_test_shared)
endif()
add_executable(exception exception.cpp)
if(NOT MSVC)
target_compile_options(exception PRIVATE -fno-exceptions)

View File

@ -35,32 +35,32 @@
#include <thread>
#if (defined(WIN32) || defined(_WIN32)) && !defined(__GNUC__)
#define NOMINMAX 1
# define NOMINMAX 1
#endif
#ifdef USE_STD_FS
#include <filesystem>
# include <filesystem>
namespace fs {
using namespace std::filesystem;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
} // namespace fs
#ifdef __GNUC__
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#ifdef _MSC_VER
#define IS_WCHAR_PATH
#endif
#ifdef WIN32
#define GHC_OS_WINDOWS
#endif
# ifdef __GNUC__
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
# endif
# ifdef _MSC_VER
# define IS_WCHAR_PATH
# endif
# ifdef WIN32
# define GHC_OS_WINDOWS
# endif
#else
#ifdef GHC_FILESYSTEM_FWD_TEST
#include <ghc/fs_fwd.hpp>
#else
#include <ghc/filesystem.hpp>
#endif
# ifdef GHC_FILESYSTEM_FWD_TEST
# include <ghc/fs_fwd.hpp>
# else
# include <ghc/filesystem.hpp>
# endif
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
@ -70,17 +70,17 @@ using fstream = ghc::filesystem::fstream;
#endif
#if defined(WIN32) || defined(_WIN32)
#include <windows.h>
# include <windows.h>
#else
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
# include <sys/socket.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/un.h>
# include <unistd.h>
#endif
#ifndef GHC_FILESYSTEM_FWD_TEST
#define CATCH_CONFIG_MAIN
# define CATCH_CONFIG_MAIN
#endif
#include "catch.hpp"
@ -131,9 +131,7 @@ struct StringMaker<fs::perms>
template <>
struct StringMaker<fs::file_status>
{
static std::string convert(fs::file_status const& value) {
return std::string("[") + std::to_string(static_cast<unsigned int>(value.type())) + "," + std::to_string(static_cast<unsigned int>(value.permissions())) + "]";
}
static std::string convert(fs::file_status const& value) { return std::string("[") + std::to_string(static_cast<unsigned int>(value.type())) + "," + std::to_string(static_cast<unsigned int>(value.permissions())) + "]"; }
};
#ifdef __cpp_lib_char8_t
@ -232,18 +230,18 @@ static bool is_symlink_creation_supported()
bool result = true;
HKEY key;
REGSAM flags = KEY_READ;
#ifdef _WIN64
# ifdef _WIN64
flags |= KEY_WOW64_64KEY;
#elif defined(KEY_WOW64_64KEY)
# elif defined(KEY_WOW64_64KEY)
if (isWow64Proc()) {
flags |= KEY_WOW64_64KEY;
}
else {
flags |= KEY_WOW64_32KEY;
}
#else
# else
result = false;
#endif
# endif
if (result) {
auto err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", 0, flags, &key);
if (err == ERROR_SUCCESS) {
@ -296,8 +294,9 @@ public:
}
value_type* allocate(std::size_t n) { return static_cast<value_type*>(::operator new(n * sizeof(value_type))); }
void deallocate(value_type* p, std::size_t) noexcept { ::operator delete(p); }
template<class U>
struct rebind {
template <class U>
struct rebind
{
typedef TestAllocator<U> other;
};
};
@ -337,29 +336,29 @@ TEST_CASE("fs::detail::fromUtf8", "[filesystem][fs.detail.utf8]")
CHECK(fs::detail::toUtf8(std::wstring(L"foobar")).length() == 6);
CHECK(fs::detail::toUtf8(std::wstring(L"foobar")) == "foobar");
CHECK(fs::detail::toUtf8(std::wstring(L"föobar")).length() == 7);
//CHECK(fs::detail::toUtf8(std::wstring(L"föobar")) == u8"föobar");
// CHECK(fs::detail::toUtf8(std::wstring(L"föobar")) == u8"föobar");
#ifdef GHC_RAISE_UNICODE_ERRORS
# ifdef GHC_RAISE_UNICODE_ERRORS
CHECK_THROWS_AS(fs::detail::fromUtf8<std::u16string>(std::string("\xed\xa0\x80")), fs::filesystem_error);
CHECK_THROWS_AS(fs::detail::fromUtf8<std::u16string>(std::string("\xc3")), fs::filesystem_error);
#else
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")));
#endif
# else
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")));
# endif
}
TEST_CASE("fs::detail::toUtf8", "[filesystem][fs.detail.utf8]")
{
std::string t;
CHECK(std::string("\xc3\xa4/\xe2\x82\xac\xf0\x9d\x84\x9e") == fs::detail::toUtf8(std::u16string(u"\u00E4/\u20AC\U0001D11E")));
#ifdef GHC_RAISE_UNICODE_ERRORS
# ifdef GHC_RAISE_UNICODE_ERRORS
CHECK_THROWS_AS(fs::detail::toUtf8(std::u16string(1, 0xd800)), fs::filesystem_error);
CHECK_THROWS_AS(fs::detail::appendUTF8(t, 0x200000), fs::filesystem_error);
#else
# else
CHECK(std::string("\xEF\xBF\xBD") == fs::detail::toUtf8(std::u16string(1, 0xd800)));
fs::detail::appendUTF8(t, 0x200000);
CHECK(std::string("\xEF\xBF\xBD") == t);
#endif
# endif
}
#endif
@ -586,21 +585,21 @@ TEST_CASE("fs.path.modifiers - path modifiers", "[filesystem][path][fs.path.modi
TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][path][fs.path.native.obs]")
{
#ifdef GHC_OS_WINDOWS
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
# if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").native() == fs::path::string_type(L"\u00E4\\\u20AC"));
// CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").string() == std::string("ä\\€")); // MSVCs returns local DBCS encoding
#else
# else
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").native() == fs::path::string_type("\xc3\xa4\\\xe2\x82\xac"));
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").string() == std::string("\xc3\xa4\\\xe2\x82\xac"));
CHECK(!::strcmp(fs::u8path("\xc3\xa4\\\xe2\x82\xac").c_str(), "\xc3\xa4\\\xe2\x82\xac"));
CHECK((std::string)fs::u8path("\xc3\xa4\\\xe2\x82\xac") == std::string("\xc3\xa4\\\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").wstring() == std::wstring(L"\u00E4\\\u20AC"));
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
# if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u8string() == std::u8string(u8"\u00E4\\\u20AC"));
#else
# else
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u8string() == std::string("\xc3\xa4\\\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u16string() == std::u16string(u"\u00E4\\\u20AC"));
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").u32string() == std::u32string(U"\U000000E4\\\U000020AC"));
#else
@ -609,11 +608,11 @@ TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][pat
CHECK((std::string)fs::u8path("\xc3\xa4/\xe2\x82\xac") == std::string("\xc3\xa4/\xe2\x82\xac"));
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").string() == std::string("\xc3\xa4/\xe2\x82\xac"));
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").wstring() == std::wstring(L"ä/€"));
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
# if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").u8string() == std::u8string(u8"\xc3\xa4/\xe2\x82\xac"));
#else
# else
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").u8string() == std::string("\xc3\xa4/\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").u16string() == std::u16string(u"\u00E4/\u20AC"));
INFO("This check might fail on GCC8 (with \"Illegal byte sequence\") due to not detecting the valid unicode codepoint U+1D11E.");
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac\xf0\x9d\x84\x9e").u16string() == std::u16string(u"\u00E4/\u20AC\U0001D11E"));
@ -624,33 +623,33 @@ TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][pat
TEST_CASE("fs.path.generic.obs - path generic format observers", "[filesystem][path][fs.path.generic.obs]")
{
#ifdef GHC_OS_WINDOWS
#ifndef IS_WCHAR_PATH
# ifndef IS_WCHAR_PATH
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_string() == std::string("\xc3\xa4/\xe2\x82\xac"));
#endif
#ifndef USE_STD_FS
# endif
# ifndef USE_STD_FS
auto t = fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_string<char, std::char_traits<char>, TestAllocator<char>>();
CHECK(t.c_str() == std::string("\xc3\xa4/\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_wstring() == std::wstring(L"\U000000E4/\U000020AC"));
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
# if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_u8string() == std::u8string(u8"\u00E4/\u20AC"));
#else
# else
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_u8string() == std::string("\xc3\xa4/\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_u16string() == std::u16string(u"\u00E4/\u20AC"));
CHECK(fs::u8path("\xc3\xa4\\\xe2\x82\xac").generic_u32string() == std::u32string(U"\U000000E4/\U000020AC"));
#else
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_string() == std::string("\xc3\xa4/\xe2\x82\xac"));
#ifndef USE_STD_FS
# ifndef USE_STD_FS
auto t = fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_string<char, std::char_traits<char>, TestAllocator<char>>();
CHECK(t.c_str() == std::string("\xc3\xa4/\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_wstring() == std::wstring(L"ä/€"));
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
# if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_u8string() == std::u8string(u8"\xc3\xa4/\xe2\x82\xac"));
#else
# else
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_u8string() == std::string("\xc3\xa4/\xe2\x82\xac"));
#endif
# endif
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_u16string() == std::u16string(u"\u00E4/\u20AC"));
CHECK(fs::u8path("\xc3\xa4/\xe2\x82\xac").generic_u32string() == std::u32string(U"\U000000E4/\U000020AC"));
#endif
@ -1403,7 +1402,7 @@ TEST_CASE("fs.class.directory_iterator - class directory_iterator", "[filesystem
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())) {
for (auto de : fs::directory_iterator(t.path())) {
++cnt;
}
CHECK(cnt == 1);
@ -1521,12 +1520,12 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
generateFile("e");
auto iter = fs::recursive_directory_iterator(".");
std::multimap<std::string, int> result;
while(iter != fs::recursive_directory_iterator()) {
while (iter != fs::recursive_directory_iterator()) {
result.insert(std::make_pair(iter->path().generic_string(), iter.depth()));
++iter;
}
std::stringstream os;
for(auto p : result) {
for (auto p : result) {
os << "[" << p.first << "," << p.second << "],";
}
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/b,1],[./d1/c,1],[./d1/d2,1],[./d1/d2/d,2],[./e,0],");
@ -1541,11 +1540,11 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
generateFile("d1/d2/d");
generateFile("e");
std::multiset<std::string> result;
for(auto de : fs::recursive_directory_iterator(".")) {
for (auto de : fs::recursive_directory_iterator(".")) {
result.insert(de.path().generic_string());
}
std::stringstream os;
for(auto p : result) {
for (auto p : result) {
os << p << ",";
}
CHECK(os.str() == "./a,./d1,./d1/b,./d1/c,./d1/d2,./d1/d2/d,./e,");
@ -1559,15 +1558,15 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
generateFile("e");
auto iter = fs::recursive_directory_iterator(".");
std::multimap<std::string, int> result;
while(iter != fs::recursive_directory_iterator()) {
while (iter != fs::recursive_directory_iterator()) {
result.insert(std::make_pair(iter->path().generic_string(), iter.depth()));
if(iter->path() == "./d1/d2") {
if (iter->path() == "./d1/d2") {
iter.disable_recursion_pending();
}
++iter;
}
std::stringstream os;
for(auto p : result) {
for (auto p : result) {
os << "[" << p.first << "," << p.second << "],";
}
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/d2,1],[./e,0],");
@ -1581,9 +1580,9 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
generateFile("e");
auto iter = fs::recursive_directory_iterator(".");
std::multimap<std::string, int> result;
while(iter != fs::recursive_directory_iterator()) {
while (iter != fs::recursive_directory_iterator()) {
result.insert(std::make_pair(iter->path().generic_string(), iter.depth()));
if(iter->path() == "./d1/d2") {
if (iter->path() == "./d1/d2") {
iter.pop();
}
else {
@ -1591,7 +1590,7 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
}
}
std::stringstream os;
for(auto p : result) {
for (auto p : result) {
os << "[" << p.first << "," << p.second << "],";
}
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/d2,1],[./e,0],");
@ -1605,24 +1604,24 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
fs::create_directory_symlink("../d1", "d2/ds1");
fs::create_directory_symlink("d3", "d2/ds2");
std::multiset<std::string> result;
REQUIRE_NOTHROW([&](){
REQUIRE_NOTHROW([&]() {
for (const auto& de : fs::recursive_directory_iterator("d2", fs::directory_options::follow_directory_symlink)) {
result.insert(de.path().generic_string());
}
}());
std::stringstream os;
for(const auto& p : result) {
for (const auto& p : result) {
os << p << ",";
}
CHECK(os.str() == "d2/b,d2/ds1,d2/ds1/a,d2/ds2,");
os.str("");
result.clear();
REQUIRE_NOTHROW([&](){
REQUIRE_NOTHROW([&]() {
for (const auto& de : fs::recursive_directory_iterator("d2")) {
result.insert(de.path().generic_string());
}
}());
for(const auto& p : result) {
for (const auto& p : result) {
os << p << ",";
}
CHECK(os.str() == "d2/b,d2/ds1,d2/ds2,");
@ -2089,20 +2088,20 @@ TEST_CASE("fs.op.hard_link_count - hard_link_count", "[filesystem][operations][f
#ifndef GHC_OS_WEB
TemporaryDirectory t(TempOpt::change_path);
std::error_code ec;
#ifdef GHC_OS_WINDOWS
# ifdef GHC_OS_WINDOWS
// windows doesn't implement "."/".." as hardlinks, so it
// starts with 1 and subdirectories don't change the count
CHECK(fs::hard_link_count(t.path()) == 1);
fs::create_directory("dir");
CHECK(fs::hard_link_count(t.path()) == 1);
#else
# else
// unix/bsd/linux typically implements "."/".." as hardlinks
// so an empty dir has 2 (from parent and the ".") and
// adding a subdirectory adds one due to its ".."
CHECK(fs::hard_link_count(t.path()) == getHardlinkCount(t.path()));
fs::create_directory("dir");
CHECK(fs::hard_link_count(t.path()) == getHardlinkCount(t.path()));
#endif
# endif
generateFile("foo");
CHECK(fs::hard_link_count(t.path() / "foo") == 1);
ec = std::error_code(42, std::system_category());
@ -2770,7 +2769,7 @@ TEST_CASE("fs.op.weakly_canonical - weakly_canonical", "[filesystem][operations]
{
INFO("This might fail on std::implementations that return fs::current_path() for fs::canonical(\"\")");
CHECK(fs::weakly_canonical("") == ".");
if(fs::weakly_canonical("") == ".") {
if (fs::weakly_canonical("") == ".") {
CHECK(fs::weakly_canonical("foo/bar") == "foo/bar");
CHECK(fs::weakly_canonical("foo/./bar") == "foo/bar");
CHECK(fs::weakly_canonical("foo/../bar") == "bar");
@ -2807,14 +2806,14 @@ TEST_CASE("std::string_view support", "[filesystem][fs.string_view]")
{
#if defined(GHC_HAS_STD_STRING_VIEW) || defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
#if defined(GHC_HAS_STD_STRING_VIEW)
# if defined(GHC_HAS_STD_STRING_VIEW)
using namespace std::literals;
using string_view = std::string_view;
using wstring_view = std::wstring_view;
#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
# elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
using string_view = std::experimental::string_view;
using wstring_view = std::experimental::wstring_view;
#endif
# endif
{
std::string p("foo/bar");
@ -2895,13 +2894,13 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
};
std::vector<TestInfo> variants = {
{R"(C:\Windows\notepad.exe)", R"(C:\Windows\notepad.exe)", "C:", "C:\\", "C:,/,Windows,notepad.exe"},
#ifdef USE_STD_FS
# ifdef USE_STD_FS
{R"(\\?\C:\Windows\notepad.exe)", R"(\\?\C:\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,C:,Windows,notepad.exe"},
{R"(\??\C:\Windows\notepad.exe)", R"(\??\C:\Windows\notepad.exe)", "\\??", "\\??\\", "/??,/,C:,Windows,notepad.exe"},
#else
# else
{R"(\\?\C:\Windows\notepad.exe)", R"(\\?\C:\Windows\notepad.exe)", "C:", "C:\\", "//?/,C:,/,Windows,notepad.exe"},
{R"(\??\C:\Windows\notepad.exe)", R"(\??\C:\Windows\notepad.exe)", "C:", "C:\\", "/?\?/,C:,/,Windows,notepad.exe"},
#endif
# endif
{R"(\\.\C:\Windows\notepad.exe)", R"(\\.\C:\Windows\notepad.exe)", "\\\\.", "\\\\.\\", "//.,/,C:,Windows,notepad.exe"},
{R"(\\?\HarddiskVolume1\Windows\notepad.exe)", R"(\\?\HarddiskVolume1\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,HarddiskVolume1,Windows,notepad.exe"},
{R"(\\?\Harddisk0Partition1\Windows\notepad.exe)", R"(\\?\Harddisk0Partition1\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,Harddisk0Partition1,Windows,notepad.exe"},