Compare commits

..

No commits in common. "master" and "v1.4.0" have entirely different histories.

20 changed files with 3043 additions and 8237 deletions

View File

@ -1,6 +1,6 @@
freebsd_task: freebsd_task:
freebsd_instance: freebsd_instance:
image_family: freebsd-14-0 image_family: freebsd-12-1
install_script: | install_script: |
pkg install -y cmake pkg install -y cmake
pw groupadd testgrp pw groupadd testgrp
@ -11,24 +11,25 @@ freebsd_task:
test_script: | test_script: |
sudo -u testuser .ci/unix-test.sh sudo -u testuser .ci/unix-test.sh
rockylinux8_task: centos7_task:
container: container:
image: docker.io/rockylinux:8 image: centos:7
install_script: | install_script: |
dnf group install -y "Development Tools" yum install -y centos-release-scl
dnf install cmake -y yum install -y devtoolset-9
curl -L https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-Linux-x86_64.tar.gz | tar xzvf - -C /usr/local --strip-components 1
build_script: | build_script: |
.ci/unix-build.sh source /opt/rh/devtoolset-9/enable && PATH=$PATH:/usr/local/bin .ci/unix-build.sh
test_script: | test_script: |
.ci/unix-test.sh PATH=$PATH:/usr/local/bin .ci/unix-test.sh
rockylinux9_task: centos8_task:
container: container:
image: docker.io/rockylinux:9 image: centos:8
install_script: | install_script: |
dnf group install -y "Development Tools" yum group install -y "Development Tools"
dnf install cmake -y curl -L https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-Linux-x86_64.tar.gz | tar xzvf - -C /usr/local --strip-components 1
build_script: | build_script: |
.ci/unix-build.sh PATH=$PATH:/usr/local/bin .ci/unix-build.sh
test_script: | test_script: |
.ci/unix-test.sh PATH=$PATH:/usr/local/bin .ci/unix-test.sh

View File

@ -1,170 +0,0 @@
name: CMake Build Matrix
on: [ push, pull_request ]
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- name: "Ubuntu 22.04 GCC 11"
os: ubuntu-22.04
build_type: Release
packages: ninja-build
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: gcc
cxx: g++
- name: "Ubuntu 22.04 Clang 13.0"
os: ubuntu-22.04
build_type: Release
packages: ninja-build libc++-13-dev libc++abi-13-dev
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: clang-13
cxx: clang++-13
- name: "Ubuntu 22.04 Clang 15.0"
os: ubuntu-22.04
build_type: Release
packages: ninja-build libc++-15-dev libc++abi-15-dev
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: clang-15
cxx: clang++-15
- name: "Ubuntu 22.04 GCC 11 coverage"
os: ubuntu-22.04
build_type: Debug
packages: ninja-build lcov
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: gcc
cxx: g++
- name: "Ubuntu 20.04 GCC 9.3"
os: ubuntu-20.04
build_type: Release
packages: ninja-build
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: gcc
cxx: g++
- name: "Ubuntu 20.04 Clang 10.0"
os: ubuntu-20.04
build_type: Release
packages: ninja-build
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: clang-10
cxx: clang++-10
- name: "Ubuntu 20.04 Clang 11.0"
os: ubuntu-20.04
build_type: Release
packages: ninja-build clang-11 libc++-11-dev libc++abi-11-dev
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: clang-11
cxx: clang++-11
- name: "Ubuntu 20.04 GCC 9.3 coverage"
os: ubuntu-20.04
build_type: Debug
packages: ninja-build lcov
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: gcc
cxx: g++
- name: "Windows MSVC 2019"
os: windows-2019
build_type: Release
packages: ninja
generator: "Visual Studio 16 2019"
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: cl
cxx: cl
- name: "macOS 13 AppleClang"
os: macos-13
build_type: Release
packages: ninja
generator: Ninja
compatibility: "cxx_std_11;cxx_std_17;cxx_std_20"
cc: clang
cxx: clang++
steps:
- uses: actions/checkout@v2
- name: print environment
run: |
echo github.event.action: ${{ github.event.action }}
echo github.event_name: ${{ github.event_name }}
- name: Install dependencies on Ubuntu
if: startsWith(matrix.config.os, 'ubuntu')
shell: bash
run: |
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt update
sudo apt install ${{ matrix.config.packages }}
- name: Install dependencies on windows
if: startsWith(matrix.config.os, 'windows')
run: |
choco install ${{ matrix.config.packages }}
- name: Install dependencies on macOS
if: startsWith(matrix.config.os, 'macos')
run: |
brew install ${{ matrix.config.packages }}
- name: Configure project
shell: bash
run: |
export CC=${{ matrix.config.cc }}
export CXX=${{ matrix.config.cxx }}
ninja --version
cmake --version
mkdir build
mkdir install
if [[ "${{ matrix.config.build_type }}" == "Debug" ]]; then
cmake -G "${{ matrix.config.generator }}" -S . -B build -DCMAKE_BUILD_TYPE=Debug -DGHC_COVERAGE=ON -DGHC_FILESYSTEM_TEST_COMPILE_FEATURES="${{ matrix.config.compatibility }}" -DCMAKE_INSTALL_PREFIX:PATH=install
else
cmake -G "${{ matrix.config.generator }}" -S . -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DGHC_FILESYSTEM_TEST_COMPILE_FEATURES="${{ matrix.config.compatibility }}" -DCMAKE_INSTALL_PREFIX:PATH=install
fi
- name: Build project
shell: bash
run: |
cmake --build build --config ${{ matrix.config.build_type }}
- name: Run tests
run: |
cd build && ctest -C ${{ matrix.config.build_type }}
- name: Collect coverage info
if: startsWith(matrix.config.build_type, 'Debug')
run: |
cd build
lcov --compat-libtool --directory . --capture --output-file coverage_output.info
lcov --remove coverage_output.info '/usr/*' '*/c++/*' '*.h' '*/catch.hpp' -o coverage.info
# sed -i 's|SF:/.*/filesystem/|SF:../|g' coverage.info
- name: Upload coverage info
if: startsWith(matrix.config.build_type, 'Debug')
env:
COVERALLS_DEBUG: true
NODE_COVERALLS_DEBUG: 1
uses: coverallsapp/github-action@master
with:
path-to-lcov: ${{ github.workspace }}/build/coverage.info
github-token: ${{ secrets.GITHUB_TOKEN }}

100
.travis.yml Normal file
View File

@ -0,0 +1,100 @@
language: cpp
dist: xenial # default distribution
os: linux # default os
sudo: false
matrix:
fast_finish: true
include:
- env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["g++-5"], sources: ["ubuntu-toolchain-r-test"] } }
- env: MATRIX_EVAL="CC=gcc-6 && CXX=g++-6 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["g++-6"], sources: ["ubuntu-toolchain-r-test"] } }
- env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["g++-7"], sources: ["ubuntu-toolchain-r-test"] } }
- env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7 && GENERATOR='Unix Makefiles' && CONFIG=Debug && GHC_COVERAGE=1"
addons: { apt: { packages: ["g++-7", "lcov"], sources: ["ubuntu-toolchain-r-test"] } }
- env: MATRIX_EVAL="CC=gcc-8 && CXX=g++-8 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["g++-8"], sources: ["ubuntu-toolchain-r-test"] } }
- env: MATRIX_EVAL="CC=gcc-9 && CXX=g++-9 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["g++-9"], sources: ["ubuntu-toolchain-r-test"] } }
- env: MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["clang-5.0"] } }
- env: MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["clang-6.0"] } }
- env: MATRIX_EVAL="CC=clang-7 && CXX=clang++-7 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["clang-7", "libc++-7-dev", "libc++abi-7-dev"], sources: ["llvm-toolchain-xenial-7"] } }
- env: MATRIX_EVAL="CC=clang-8 && CXX=clang++-8 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["clang-8", "libc++-8-dev", "libc++abi-8-dev"], sources: ["llvm-toolchain-xenial-8"] } }
- env: MATRIX_EVAL="CC=clang-9 && CXX=clang++-9 && GENERATOR='Unix Makefiles' && CONFIG=Release"
addons: { apt: { packages: ["clang-9", "libc++-9-dev", "libc++abi-9-dev"], sources: [{sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main', key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'}] } }
- os: osx
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
osx_image: xcode9.2
- os: osx
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
osx_image: xcode10.1
- os: osx
env: MATRIX_EVAL="CC=clang && CXX=clang++ && GENERATOR=Xcode && CONFIG=Release"
osx_image: xcode11.3
install:
- eval "${MATRIX_EVAL}"
- |
if [ "${GHC_COVERAGE}" = "1" ]; then
gem install coveralls-lcov
fi
- $CC --version
- $CXX --version
- cmake --version
before_script:
- eval "${MATRIX_EVAL}"
- mkdir build
- cd build
- export VERBOSE=1
- |
if [ "${CONFIG}" = "Debug" ]; then
cmake -G"${GENERATOR}" -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} -DCMAKE_BUILD_TYPE=${CONFIG} -DGHC_COVERAGE=ON ..
else
cmake -G"${GENERATOR}" -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} -DCMAKE_BUILD_TYPE=${CONFIG} ..
fi
script:
- export VERBOSE=1
- cmake --build . --config ${CONFIG} --target filesystem_test
- |
if [ "${GHC_COVERAGE}" = "1" ]; then
cmake --build . --config ${CONFIG} --target filesystem_test
test/filesystem_test
else
cmake --build . --config ${CONFIG}
ctest -C ${CONFIG} -E Windows
if [ -f "test/std_filesystem_test" ]; then
test/std_filesystem_test || true
fi
fi
after_success:
- |
if [ "${GHC_COVERAGE}" = "1" ]; then
lcov --compat-libtool --directory . --capture --output-file coverage_output.info
lcov --remove coverage_output.info '/usr/*' '*/c++/*' '*.h' '*/catch.hpp' -o coverage.info
sed -i 's|SF:/.*/filesystem/|SF:../|g' coverage.info
coveralls-lcov coverage.info
fi

View File

@ -1,55 +1,41 @@
cmake_minimum_required(VERSION 3.7.2) cmake_minimum_required(VERSION 3.7.2)
project( project(ghcfilesystem)
ghcfilesystem,
VERSION 1.5.15
)
if (POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
if(POLICY CMP0110) if(POLICY CMP0110)
cmake_policy(SET CMP0110 NEW) cmake_policy(PUSH)
cmake_policy(SET CMP0110 OLD)
endif() endif()
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) include(CMakeDependentOption)
option(GHC_FILESYSTEM_BUILD_TESTING "Enable tests" ON)
option(GHC_FILESYSTEM_BUILD_EXAMPLES "Build examples" ON) cmake_dependent_option(GHC_FILESYSTEM_BUILD_TESTING
option(GHC_FILESYSTEM_WITH_INSTALL "With install target" ON) "Enable tests" ON
else() "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
option(GHC_FILESYSTEM_BUILD_EXAMPLES "Build examples" OFF) cmake_dependent_option(GHC_FILESYSTEM_BUILD_EXAMPLES
option(GHC_FILESYSTEM_BUILD_TESTING "Enable tests" OFF) "Build examples" ON
option(GHC_FILESYSTEM_WITH_INSTALL "With install target" OFF) "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
endif() cmake_dependent_option(GHC_FILESYSTEM_WITH_INSTALL
option(GHC_FILESYSTEM_BUILD_STD_TESTING "Enable STD tests" ${GHC_FILESYSTEM_BUILD_TESTING}) "With install target" ON
if(NOT DEFINED GHC_FILESYSTEM_TEST_COMPILE_FEATURES) "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
set(GHC_FILESYSTEM_TEST_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES})
endif()
if(NOT DEFINED CMAKE_CXX_STANDARD) if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CYGWIN) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
endif() endif()
if(CMAKE_CXX_STANDARD LESS 11) if(CMAKE_CXX_STANDARD LESS 11)
message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, ghc::filesystem only works with C++11 and above.") message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, ghc::filesystem only works with C++11 and above.")
endif() endif()
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
message(STATUS "System name: ${CMAKE_SYSTEM_NAME}")
message(STATUS "Compiler ID: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMAKE_CXX_COMPILE_FEATURES: ${CMAKE_CXX_COMPILE_FEATURES}")
endif()
add_library(ghc_filesystem INTERFACE) add_library(ghc_filesystem INTERFACE)
add_library(ghcFilesystem::ghc_filesystem ALIAS ghc_filesystem)
target_include_directories(ghc_filesystem INTERFACE target_include_directories(ghc_filesystem INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>) $<INSTALL_INTERFACE:include>)
target_compile_options(ghc_filesystem INTERFACE "$<$<C_COMPILER_ID:MSVC>:/utf-8>") target_compile_options(ghc_filesystem INTERFACE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>") target_compile_options(ghc_filesystem INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
if(GHC_FILESYSTEM_BUILD_TESTING OR GHC_FILESYSTEM_BUILD_EXAMPLES) get_directory_property(hasParent PARENT_DIRECTORY)
if(NOT hasParent)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
include(GhcHelper) include(GhcHelper)
@ -67,24 +53,12 @@ endif()
if(GHC_FILESYSTEM_WITH_INSTALL) if(GHC_FILESYSTEM_WITH_INSTALL)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
include(GNUInstallDirs) include(GNUInstallDirs)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(TARGETS ghc_filesystem EXPORT ghc_filesystem-targets) install(TARGETS ghc_filesystem EXPORT ghcFilesystemConfig)
install(EXPORT ghc_filesystem-targets NAMESPACE ghcFilesystem:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem") install(EXPORT ghcFilesystemConfig NAMESPACE ghcFilesystem:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ghcFilesystem)
export(EXPORT ghc_filesystem-targets NAMESPACE ghcFilesystem:: FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/ghc_filesystem-targets.cmake") endif()
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/config.cmake.in" if(POLICY CMP0110)
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake" cmake_policy(POP)
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem"
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMinorVersion
)
install(
FILES
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config.cmake"
"${PROJECT_BINARY_DIR}/cmake/ghc_filesystem-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ghc_filesystem"
)
endif() endif()

714
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
macro(AddExecutableWithStdFS targetName) macro(AddExecutableWithStdFS targetName)
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0))
if(APPLE) if(APPLE)
include_directories(/usr/local/opt/llvm/include) include_directories(/usr/local/opt/llvm/include)
link_directories(/usr/local/opt/llvm/lib) link_directories(/usr/local/opt/llvm/lib)
@ -11,7 +12,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION V
target_link_libraries(${targetName} -lc++fs) target_link_libraries(${targetName} -lc++fs)
else() else()
target_compile_options(${targetName} PRIVATE "-stdlib=libc++") target_compile_options(${targetName} PRIVATE "-stdlib=libc++")
target_link_libraries(${targetName} -stdlib=libc++ -lc++fs $<$<PLATFORM_ID:Linux>:rt>) target_link_libraries(${targetName} -stdlib=libc++ -lc++fs)
endif() endif()
else() else()
if(NOT APPLE) if(NOT APPLE)
@ -19,12 +20,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND (CMAKE_CXX_COMPILER_VERSION V
target_link_libraries(${targetName} -stdlib=libc++) target_link_libraries(${targetName} -stdlib=libc++)
endif() endif()
endif() endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
target_link_libraries(filesystem_test xnet)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
target_link_libraries(filesystem_test network)
endif()
target_compile_definitions(${targetName} PRIVATE USE_STD_FS) target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
endif() endif()
@ -34,13 +29,6 @@ if (CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0 O
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
target_link_libraries(${targetName} -lstdc++fs) target_link_libraries(${targetName} -lstdc++fs)
endif() endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
target_link_libraries(${targetName} xnet)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
target_link_libraries(${targetName} network)
endif()
target_compile_options(${targetName} PRIVATE $<$<BOOL:${CYGWIN}>:-Wa,-mbig-obj>)
target_compile_definitions(${targetName} PRIVATE USE_STD_FS) target_compile_definitions(${targetName} PRIVATE USE_STD_FS)
endif() endif()
@ -58,19 +46,11 @@ macro(AddTestExecutableWithStdCpp cppStd)
add_executable(filesystem_test_cpp${cppStd} ${ARGN}) add_executable(filesystem_test_cpp${cppStd} ${ARGN})
set_property(TARGET filesystem_test_cpp${cppStd} PROPERTY CXX_STANDARD ${cppStd}) set_property(TARGET filesystem_test_cpp${cppStd} PROPERTY CXX_STANDARD ${cppStd})
target_link_libraries(filesystem_test_cpp${cppStd} ghc_filesystem) target_link_libraries(filesystem_test_cpp${cppStd} ghc_filesystem)
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
target_link_libraries(filesystem_test_cpp${cppStd} xnet)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
target_link_libraries(filesystem_test_cpp${cppStd} network)
endif()
target_compile_options(filesystem_test_cpp${cppStd} PRIVATE target_compile_options(filesystem_test_cpp${cppStd} PRIVATE
$<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0> $<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-error=deprecated-declarations> $<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-error=deprecated-declarations>
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror -Wno-error=deprecated-declarations> $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror -Wno-error=deprecated-declarations>
$<$<CXX_COMPILER_ID:MSVC>:/WX /wd4996> $<$<CXX_COMPILER_ID:MSVC>:/WX /wd"4996">)
$<$<BOOL:${CYGWIN}>:-Wa,-mbig-obj>
$<$<BOOL:${GHC_COVERAGE}>:--coverage>)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(filesystem_test_cpp${cppStd} PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(filesystem_test_cpp${cppStd} PRIVATE _CRT_SECURE_NO_WARNINGS)
endif() endif()

View File

@ -1,6 +1,5 @@
@PACKAGE_INIT@ @PACKAGE_INIT@
# import targets set_and_check(ghcfilesystem_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@")
include("${CMAKE_CURRENT_LIST_DIR}/ghc_filesystem-targets.cmake")
check_required_components(ghcfilesystem) check_required_components(ghcfilesystem)

View File

@ -10,8 +10,3 @@ add_executable(fs_du du.cpp)
target_link_libraries(fs_du ghc_filesystem) target_link_libraries(fs_du ghc_filesystem)
AddExecutableWithStdFS(std_fs_du du.cpp) AddExecutableWithStdFS(std_fs_du du.cpp)
if(EXISTS "${PROJECT_SOURCE_DIR}/examples/benchmark.cpp")
add_executable(fs_benchmark benchmark.cpp)
set_property(TARGET fs_benchmark PROPERTY CXX_STANDARD 17)
target_link_libraries(fs_benchmark ghc_filesystem)
endif()

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
// SOFTWARE. // SOFTWARE.
// //
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
// fs_fwd.hpp - The forwarding header for the header/implementation separated usage of // fs_fwd.hpp - The forwarding header for the header/implementation seperated usage of
// ghc::filesystem. // ghc::filesystem.
// This file can be include at any place, where ghc::filesystem api is needed while // This file can be include at any place, where ghc::filesystem api is needed while
// not bleeding implementation details (e.g. system includes) into the global namespace, // not bleeding implementation details (e.g. system includes) into the global namespace,
@ -34,5 +34,5 @@
#ifndef GHC_FILESYSTEM_FWD_H #ifndef GHC_FILESYSTEM_FWD_H
#define GHC_FILESYSTEM_FWD_H #define GHC_FILESYSTEM_FWD_H
#define GHC_FILESYSTEM_FWD #define GHC_FILESYSTEM_FWD
#include "filesystem.hpp" #include <ghc/filesystem.hpp>
#endif // GHC_FILESYSTEM_FWD_H #endif // GHC_FILESYSTEM_FWD_H

View File

@ -25,11 +25,11 @@
// SOFTWARE. // SOFTWARE.
// //
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
// fs_impl.hpp - The implementation header for the header/implementation separated usage of // fs_impl.hpp - The implementation header for the header/implementation seperated usage of
// ghc::filesystem. // ghc::filesystem.
// This file can be used to hide the implementation of ghc::filesystem into a single cpp. // This file can be used to hide the implementation of ghc::filesystem into a single cpp.
// The cpp has to include this before including fs_fwd.hpp directly or via a different // The cpp has to include this before including fs_fwd.hpp directly or via a different
// header to work. // header to work.
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
#define GHC_FILESYSTEM_IMPLEMENTATION #define GHC_FILESYSTEM_IMPLEMENTATION
#include "filesystem.hpp" #include <ghc/filesystem.hpp>

View File

@ -30,48 +30,27 @@
// namespace fs. // namespace fs.
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
#ifndef GHC_FILESYSTEM_STD_H #ifndef GHC_FILESYSTEM_STD_H
#define GHC_FILESYSTEM_STD_H #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include) #define GHC_USE_STD_FS
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus #include <filesystem>
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/ namespace fs {
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html using namespace std::filesystem;
#define GHC_USE_STD_FS using ifstream = std::ifstream;
using ofstream = std::ofstream;
// Old Apple OSs don't support std::filesystem, though the header is available at compile using fstream = std::fstream;
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0, }
// and watchOS 6.0.
#ifdef __APPLE__
#include <Availability.h>
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
#undef GHC_USE_STD_FS
#endif
#endif
#endif
#endif #endif
#ifdef GHC_USE_STD_FS
#include <filesystem>
namespace fs {
using namespace std::filesystem;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
#else
#include "filesystem.hpp"
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
#endif #endif
#ifndef GHC_USE_STD_FS
#define GHC_WIN_WSTRING_STRING_TYPE
#include <ghc/filesystem.hpp>
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
#endif
#endif // GHC_FILESYSTEM_STD_H #endif // GHC_FILESYSTEM_STD_H

View File

@ -25,7 +25,7 @@
// SOFTWARE. // SOFTWARE.
// //
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
// fs_std_fwd.hpp - The forwarding header for the header/implementation separated usage of // fs_std_fwd.hpp - The forwarding header for the header/implementation seperated usage of
// ghc::filesystem that uses std::filesystem if it detects it. // ghc::filesystem that uses std::filesystem if it detects it.
// This file can be include at any place, where fs::filesystem api is needed while // This file can be include at any place, where fs::filesystem api is needed while
// not bleeding implementation details (e.g. system includes) into the global namespace, // not bleeding implementation details (e.g. system includes) into the global namespace,
@ -33,47 +33,28 @@
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
#ifndef GHC_FILESYSTEM_STD_FWD_H #ifndef GHC_FILESYSTEM_STD_FWD_H
#define GHC_FILESYSTEM_STD_FWD_H #define GHC_FILESYSTEM_STD_FWD_H
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include) #if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus #define GHC_USE_STD_FS
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/ #include <filesystem>
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html namespace fs {
#define GHC_USE_STD_FS using namespace std::filesystem;
using ifstream = std::ifstream;
// Old Apple OSs don't support std::filesystem, though the header is available at compile using ofstream = std::ofstream;
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0, using fstream = std::fstream;
// and watchOS 6.0. }
#ifdef __APPLE__
#include <Availability.h>
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
#undef GHC_USE_STD_FS
#endif
#endif
#endif
#endif #endif
#ifdef GHC_USE_STD_FS
#include <filesystem>
namespace fs {
using namespace std::filesystem;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
#else
#include "fs_fwd.hpp"
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
#endif #endif
#ifndef GHC_USE_STD_FS
#define GHC_WIN_WSTRING_STRING_TYPE
#define GHC_FILESYSTEM_FWD
#include <ghc/filesystem.hpp>
namespace fs {
using namespace ghc::filesystem;
using ifstream = ghc::filesystem::ifstream;
using ofstream = ghc::filesystem::ofstream;
using fstream = ghc::filesystem::fstream;
}
#endif
#endif // GHC_FILESYSTEM_STD_FWD_H #endif // GHC_FILESYSTEM_STD_FWD_H

View File

@ -25,36 +25,19 @@
// SOFTWARE. // SOFTWARE.
// //
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
// fs_std_impl.hpp - The implementation header for the header/implementation separated usage of // fs_std_impl.hpp - The implementation header for the header/implementation seperated usage of
// ghc::filesystem that does nothing if std::filesystem is detected. // ghc::filesystem that does nothing if std::filesystem is detected.
// This file can be used to hide the implementation of ghc::filesystem into a single cpp. // This file can be used to hide the implementation of ghc::filesystem into a single cpp.
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different // The cpp has to include this before including fs_std_fwd.hpp directly or via a different
// header to work. // header to work.
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
#if defined(_MSVC_LANG) && _MSVC_LANG >= 201703L || __cplusplus >= 201703L && defined(__has_include) #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
// ^ Supports MSVC prior to 15.7 without setting /Zc:__cplusplus to fix __cplusplus #if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
// _MSVC_LANG works regardless. But without the switch, the compiler always reported 199711L: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/ #define GHC_USE_STD_FS
#if __has_include(<filesystem>) // Two stage __has_include needed for MSVC 2015 and per https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005finclude.html #endif
#define GHC_USE_STD_FS
// Old Apple OSs don't support std::filesystem, though the header is available at compile
// time. In particular, std::filesystem is unavailable before macOS 10.15, iOS/tvOS 13.0,
// and watchOS 6.0.
#ifdef __APPLE__
#include <Availability.h>
// Note: This intentionally uses std::filesystem on any new Apple OS, like visionOS
// released after std::filesystem, where std::filesystem is always available.
// (All other __<platform>_VERSION_MIN_REQUIREDs will be undefined and thus 0.)
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 \
|| defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED < 130000 \
|| defined(__WATCH_OS_VERSION_MAX_ALLOWED) && __WATCH_OS_VERSION_MAX_ALLOWED < 60000
#undef GHC_USE_STD_FS
#endif
#endif
#endif
#endif #endif
#ifndef GHC_USE_STD_FS #ifndef GHC_USE_STD_FS
#include "fs_impl.hpp" #define GHC_WIN_WSTRING_STRING_TYPE
#define GHC_FILESYSTEM_IMPLEMENTATION
#include <ghc/filesystem.hpp>
#endif #endif

View File

@ -3,20 +3,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
set(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS ON) set(PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS ON)
include(ParseAndAddCatchTests) include(ParseAndAddCatchTests)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND UNIX AND NOT APPLE AND NOT BSD)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "-lc++abi")
endif()
function(SetTestCompileOptions target_name)
target_compile_options(${target_name} PRIVATE
$<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror -Wno-deprecated-declarations>
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror -Wno-deprecated-declarations>
$<$<CXX_COMPILER_ID:MSVC>:/WX /wd4996>
$<$<BOOL:${CYGWIN}>:-Wa,-mbig-obj>)
endfunction()
if(GHC_COVERAGE) if(GHC_COVERAGE)
message("Generating test runner for coverage run...") message("Generating test runner for coverage run...")
set(CMAKE_EXE_LINKER_FLAGS "${CMCMAKE_EXE_LINKER_FLAGS} --coverage") set(CMAKE_EXE_LINKER_FLAGS "${CMCMAKE_EXE_LINKER_FLAGS} --coverage")
@ -27,54 +13,41 @@ if(GHC_COVERAGE)
target_compile_options(filesystem_test PUBLIC --coverage) target_compile_options(filesystem_test PUBLIC --coverage)
endif() endif()
target_link_libraries(filesystem_test PUBLIC ghc_filesystem --coverage) target_link_libraries(filesystem_test PUBLIC ghc_filesystem --coverage)
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
target_link_libraries(filesystem_test PUBLIC xnet)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
target_link_libraries(filesystem_test PUBLIC network)
endif()
if("cxx_std_17" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp)
endif()
if("cxx_std_20" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES)
AddTestExecutableWithStdCpp(20 filesystem_test.cpp catch.hpp)
endif()
else() else()
message("Generating test runner for normal test...") message("Generating test runner for normal test...")
add_executable(filesystem_test filesystem_test.cpp catch.hpp) add_executable(filesystem_test filesystem_test.cpp catch.hpp)
target_link_libraries(filesystem_test ghc_filesystem) target_link_libraries(filesystem_test ghc_filesystem)
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)") target_compile_options(filesystem_test PRIVATE
target_link_libraries(filesystem_test xnet) $<$<BOOL:${EMSCRIPTEN}>:-s DISABLE_EXCEPTION_CATCHING=0>
endif() $<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Werror>
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku") $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wpedantic -Wno-psabi -Werror>
target_link_libraries(filesystem_test network) $<$<CXX_COMPILER_ID:MSVC>:/WX>)
endif()
SetTestCompileOptions(filesystem_test)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(filesystem_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX) target_compile_definitions(filesystem_test PRIVATE _CRT_SECURE_NO_WARNINGS)
endif() endif()
if(EMSCRIPTEN) if(EMSCRIPTEN)
set_target_properties(filesystem_test PROPERTIES LINK_FLAGS "-g4 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1") set_target_properties(filesystem_test PROPERTIES LINK_FLAGS "-g4 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1")
endif() endif()
ParseAndAddCatchTests(filesystem_test) ParseAndAddCatchTests(filesystem_test)
if(GHC_FILESYSTEM_BUILD_STD_TESTING) AddExecutableWithStdFS(std_filesystem_test filesystem_test.cpp catch.hpp)
AddExecutableWithStdFS(std_filesystem_test filesystem_test.cpp catch.hpp)
endif()
if(WIN32) if(WIN32)
add_executable(filesystem_test_char filesystem_test.cpp catch.hpp) add_executable(filesystem_test_wchar filesystem_test.cpp catch.hpp)
target_link_libraries(filesystem_test_char ghc_filesystem) target_link_libraries(filesystem_test_wchar ghc_filesystem)
SetTestCompileOptions(filesystem_test_char) target_compile_options(filesystem_test_wchar PRIVATE
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Werror>
$<$<CXX_COMPILER_ID:GNU>:-Wall -Werror>
$<$<CXX_COMPILER_ID:MSVC>:/WX>)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(filesystem_test_char PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) target_compile_definitions(filesystem_test_wchar PRIVATE _CRT_SECURE_NO_WARNINGS GHC_WIN_WSTRING_STRING_TYPE)
else() else()
target_compile_definitions(filesystem_test_char PRIVATE GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) target_compile_definitions(filesystem_test_wchar PRIVATE GHC_WIN_WSTRING_STRING_TYPE)
endif() endif()
ParseAndAddCatchTests(filesystem_test_char) ParseAndAddCatchTests(filesystem_test_wchar)
endif() endif()
if("cxx_std_17" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES) if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp) AddTestExecutableWithStdCpp(17 filesystem_test.cpp catch.hpp)
endif() endif()
if("cxx_std_20" IN_LIST GHC_FILESYSTEM_TEST_COMPILE_FEATURES) if("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
AddTestExecutableWithStdCpp(20 filesystem_test.cpp catch.hpp) AddTestExecutableWithStdCpp(20 filesystem_test.cpp catch.hpp)
endif() endif()
endif() endif()
@ -85,15 +58,8 @@ add_test(multifile_test multifile_test)
add_executable(fwd_impl_test fwd_test.cpp impl_test.cpp) add_executable(fwd_impl_test fwd_test.cpp impl_test.cpp)
target_link_libraries(fwd_impl_test ghc_filesystem) target_link_libraries(fwd_impl_test ghc_filesystem)
if(${CMAKE_SYSTEM_NAME} MATCHES "(SunOS|Solaris)")
target_link_libraries(fwd_impl_test xnet)
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Haiku")
target_link_libraries(fwd_impl_test network)
endif()
SetTestCompileOptions(fwd_impl_test)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN NOMINMAX) target_compile_definitions(fwd_impl_test PRIVATE _CRT_SECURE_NO_WARNINGS)
endif() endif()
add_test(fwd_impl_test fwd_impl_test) add_test(fwd_impl_test fwd_impl_test)
@ -102,4 +68,3 @@ if(NOT MSVC)
target_compile_options(exception PRIVATE -fno-exceptions) target_compile_options(exception PRIVATE -fno-exceptions)
endif() endif()
target_include_directories(exception PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include) target_include_directories(exception PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../include)
SetTestCompileOptions(exception)

File diff suppressed because it is too large Load Diff

View File

@ -76,7 +76,6 @@ using fstream = ghc::filesystem::fstream;
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h>
#endif #endif
#ifndef GHC_FILESYSTEM_FWD_TEST #ifndef GHC_FILESYSTEM_FWD_TEST
@ -99,7 +98,7 @@ using fstream = ghc::filesystem::fstream;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <typename TP> template <typename TP>
static std::time_t to_time_t(TP tp) std::time_t to_time_t(TP tp)
{ {
using namespace std::chrono; using namespace std::chrono;
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now()); auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
@ -107,7 +106,7 @@ static std::time_t to_time_t(TP tp)
} }
template <typename TP> template <typename TP>
static TP from_time_t(std::time_t t) TP from_time_t(std::time_t t)
{ {
using namespace std::chrono; using namespace std::chrono;
auto sctp = system_clock::from_time_t(t); auto sctp = system_clock::from_time_t(t);
@ -128,14 +127,6 @@ struct StringMaker<fs::perms>
static std::string convert(fs::perms const& value) { return std::to_string(static_cast<unsigned int>(value)); } static std::string convert(fs::perms const& value) { return std::to_string(static_cast<unsigned int>(value)); }
}; };
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())) + "]";
}
};
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
template <> template <>
struct StringMaker<char8_t> struct StringMaker<char8_t>
@ -214,8 +205,7 @@ static void generateFile(const fs::path& pathname, int withSize = -1)
} }
#ifdef GHC_OS_WINDOWS #ifdef GHC_OS_WINDOWS
#if !defined(_WIN64) && defined(KEY_WOW64_64KEY) inline bool isWow64Proc()
static bool isWow64Proc()
{ {
typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL); typedef BOOL(WINAPI * IsWow64Process_t)(HANDLE, PBOOL);
BOOL bIsWow64 = FALSE; BOOL bIsWow64 = FALSE;
@ -227,7 +217,6 @@ static bool isWow64Proc()
} }
return bIsWow64 == TRUE; return bIsWow64 == TRUE;
} }
#endif
static bool is_symlink_creation_supported() static bool is_symlink_creation_supported()
{ {
@ -305,13 +294,13 @@ public:
}; };
template <class T, class U> template <class T, class U>
static bool operator==(TestAllocator<T> const&, TestAllocator<U> const&) noexcept bool operator==(TestAllocator<T> const&, TestAllocator<U> const&) noexcept
{ {
return true; return true;
} }
template <class T, class U> template <class T, class U>
static bool operator!=(TestAllocator<T> const& x, TestAllocator<U> const& y) noexcept bool operator!=(TestAllocator<T> const& x, TestAllocator<U> const& y) noexcept
{ {
return !(x == y); return !(x == y);
} }
@ -365,7 +354,7 @@ TEST_CASE("fs::detail::toUtf8", "[filesystem][fs.detail.utf8]")
} }
#endif #endif
TEST_CASE("fs.path.generic - path::preferred_separator", "[filesystem][path][fs.path.generic]") TEST_CASE("30.10.8.1 path::preferred_separator", "[filesystem][path][fs.path.generic]")
{ {
#ifdef GHC_OS_WINDOWS #ifdef GHC_OS_WINDOWS
CHECK(fs::path::preferred_separator == '\\'); CHECK(fs::path::preferred_separator == '\\');
@ -375,7 +364,7 @@ TEST_CASE("fs.path.generic - path::preferred_separator", "[filesystem][path][fs.
} }
#ifndef GHC_OS_WINDOWS #ifndef GHC_OS_WINDOWS
TEST_CASE("fs.path.generic - path(\"//host\").has_root_name()", "[filesystem][path][fs.path.generic]") TEST_CASE("30.10.8.1 path(\"//host\").has_root_name()", "[filesystem][path][fs.path.generic]")
{ {
if (!has_host_root_name_support()) { if (!has_host_root_name_support()) {
WARN("This implementation doesn't support path(\"//host\").has_root_name() == true [C++17 30.12.8.1 par. 4] on this platform, tests based on this are skipped. (Should be okay.)"); WARN("This implementation doesn't support path(\"//host\").has_root_name() == true [C++17 30.12.8.1 par. 4] on this platform, tests based on this are skipped. (Should be okay.)");
@ -383,26 +372,15 @@ TEST_CASE("fs.path.generic - path(\"//host\").has_root_name()", "[filesystem][pa
} }
#endif #endif
TEST_CASE("fs.path.construct - path constructors and destructor", "[filesystem][path][fs.path.construct]") TEST_CASE("30.10.8.4.1 path constructors and destructor", "[filesystem][path][fs.path.construct]")
{ {
CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string()); CHECK("/usr/local/bin" == fs::path("/usr/local/bin").generic_string());
std::string str = "/usr/local/bin"; std::string str = "/usr/local/bin";
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
std::u8string u8str = u8"/usr/local/bin";
#endif
std::u16string u16str = u"/usr/local/bin"; std::u16string u16str = u"/usr/local/bin";
std::u32string u32str = U"/usr/local/bin"; std::u32string u32str = U"/usr/local/bin";
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(u8str == fs::path(u8str).generic_u8string());
#endif
CHECK(u16str == fs::path(u16str).generic_u16string());
CHECK(u32str == fs::path(u32str).generic_u32string());
CHECK(str == fs::path(str, fs::path::format::generic_format)); CHECK(str == fs::path(str, fs::path::format::generic_format));
CHECK(str == fs::path(str.begin(), str.end())); CHECK(str == fs::path(str.begin(), str.end()));
CHECK(fs::path(std::wstring(3, 67)) == "CCC"); CHECK(fs::path(std::wstring(3, 67)) == "CCC");
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(str == fs::path(u8str.begin(), u8str.end()));
#endif
CHECK(str == fs::path(u16str.begin(), u16str.end())); CHECK(str == fs::path(u16str.begin(), u16str.end()));
CHECK(str == fs::path(u32str.begin(), u32str.end())); CHECK(str == fs::path(u32str.begin(), u32str.end()));
#ifdef GHC_FILESYSTEM_VERSION #ifdef GHC_FILESYSTEM_VERSION
@ -419,7 +397,7 @@ TEST_CASE("fs.path.construct - path constructors and destructor", "[filesystem][
CHECK("//host/foo/bar" == fs::path("//host/foo/bar")); CHECK("//host/foo/bar" == fs::path("//host/foo/bar"));
} }
#if !defined(GHC_OS_WINDOWS) && !(defined(__GLIBCXX__) && !(defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 8))) && !defined(USE_STD_FS) #if !defined(GHC_OS_WINDOWS) && !(defined(GCC_VERSION) && GCC_VERSION < 80100) && !defined(USE_STD_FS)
std::locale loc; std::locale loc;
bool testUTF8Locale = false; bool testUTF8Locale = false;
try { try {
@ -446,7 +424,7 @@ TEST_CASE("fs.path.construct - path constructors and destructor", "[filesystem][
#endif #endif
} }
TEST_CASE("fs.path.assign - path assignments", "[filesystem][path][fs.path.assign]") TEST_CASE("30.10.8.4.2 path assignments", "[filesystem][path][fs.path.assign]")
{ {
fs::path p1{"/foo/bar"}; fs::path p1{"/foo/bar"};
fs::path p2{"/usr/local"}; fs::path p2{"/usr/local"};
@ -455,10 +433,6 @@ TEST_CASE("fs.path.assign - path assignments", "[filesystem][path][fs.path.assig
REQUIRE(p1 == p3); REQUIRE(p1 == p3);
p3 = fs::path{"/usr/local"}; p3 = fs::path{"/usr/local"};
REQUIRE(p2 == p3); REQUIRE(p2 == p3);
p3 = fs::path{L"/usr/local"};
REQUIRE(p2 == p3);
p3.assign(L"/usr/local");
REQUIRE(p2 == p3);
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T) #if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
p3 = fs::path::string_type{L"/foo/bar"}; p3 = fs::path::string_type{L"/foo/bar"};
REQUIRE(p1 == p3); REQUIRE(p1 == p3);
@ -481,7 +455,7 @@ TEST_CASE("fs.path.assign - path assignments", "[filesystem][path][fs.path.assig
REQUIRE(p2 == p3); REQUIRE(p2 == p3);
} }
TEST_CASE("fs.path.append - path appends", "[filesystem][path][fs.path.append]") TEST_CASE("30.10.8.4.3 path appends", "[filesystem][path][fs.path.append]")
{ {
#ifdef GHC_OS_WINDOWS #ifdef GHC_OS_WINDOWS
CHECK(fs::path("foo") / "c:/bar" == "c:/bar"); CHECK(fs::path("foo") / "c:/bar" == "c:/bar");
@ -507,7 +481,7 @@ TEST_CASE("fs.path.append - path appends", "[filesystem][path][fs.path.append]")
// TODO: append(first, last) // TODO: append(first, last)
} }
TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.concat]") TEST_CASE("30.10.8.4.4 path concatenation", "[filesystem][path][fs.path.concat]")
{ {
CHECK((fs::path("foo") += fs::path("bar")) == "foobar"); CHECK((fs::path("foo") += fs::path("bar")) == "foobar");
CHECK((fs::path("foo") += fs::path("/bar")) == "foo/bar"); CHECK((fs::path("foo") += fs::path("/bar")) == "foo/bar");
@ -517,13 +491,9 @@ TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.con
CHECK((fs::path("foo") += "bar") == "foobar"); CHECK((fs::path("foo") += "bar") == "foobar");
CHECK((fs::path("foo") += "/bar") == "foo/bar"); CHECK((fs::path("foo") += "/bar") == "foo/bar");
CHECK((fs::path("foo") += L"bar") == "foobar");
CHECK((fs::path("foo") += L"/bar") == "foo/bar");
CHECK((fs::path("foo") += 'b') == "foob"); CHECK((fs::path("foo") += 'b') == "foob");
CHECK((fs::path("foo") += '/') == "foo/"); CHECK((fs::path("foo") += '/') == "foo/");
CHECK((fs::path("foo") += L'b') == "foob");
CHECK((fs::path("foo") += L'/') == "foo/");
CHECK((fs::path("foo") += std::string("bar")) == "foobar"); CHECK((fs::path("foo") += std::string("bar")) == "foobar");
CHECK((fs::path("foo") += std::string("/bar")) == "foo/bar"); CHECK((fs::path("foo") += std::string("/bar")) == "foo/bar");
@ -536,8 +506,6 @@ TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.con
CHECK(fs::path("foo").concat("bar") == "foobar"); CHECK(fs::path("foo").concat("bar") == "foobar");
CHECK(fs::path("foo").concat("/bar") == "foo/bar"); CHECK(fs::path("foo").concat("/bar") == "foo/bar");
CHECK(fs::path("foo").concat(L"bar") == "foobar");
CHECK(fs::path("foo").concat(L"/bar") == "foo/bar");
std::string bar = "bar"; std::string bar = "bar";
CHECK(fs::path("foo").concat(bar.begin(), bar.end()) == "foobar"); CHECK(fs::path("foo").concat(bar.begin(), bar.end()) == "foobar");
#ifndef USE_STD_FS #ifndef USE_STD_FS
@ -546,7 +514,7 @@ TEST_CASE("fs.path.concat - path concatenation", "[filesystem][path][fs.path.con
// TODO: contat(first, last) // TODO: contat(first, last)
} }
TEST_CASE("fs.path.modifiers - path modifiers", "[filesystem][path][fs.path.modifiers]") TEST_CASE("30.10.8.4.5 path modifiers", "[filesystem][path][fs.path.modifiers]")
{ {
fs::path p = fs::path("/foo/bar"); fs::path p = fs::path("/foo/bar");
p.clear(); p.clear();
@ -585,7 +553,7 @@ TEST_CASE("fs.path.modifiers - path modifiers", "[filesystem][path][fs.path.modi
CHECK(p2 == "foo"); CHECK(p2 == "foo");
} }
TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][path][fs.path.native.obs]") TEST_CASE("30.10.8.4.6 path native format observers", "[filesystem][path][fs.path.native.obs]")
{ {
#ifdef GHC_OS_WINDOWS #ifdef GHC_OS_WINDOWS
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T) #if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
@ -623,7 +591,7 @@ TEST_CASE("fs.path.native.obs - path native format observers", "[filesystem][pat
#endif #endif
} }
TEST_CASE("fs.path.generic.obs - path generic format observers", "[filesystem][path][fs.path.generic.obs]") TEST_CASE("30.10.8.4.7 path generic format observers", "[filesystem][path][fs.path.generic.obs]")
{ {
#ifdef GHC_OS_WINDOWS #ifdef GHC_OS_WINDOWS
#ifndef IS_WCHAR_PATH #ifndef IS_WCHAR_PATH
@ -658,7 +626,7 @@ TEST_CASE("fs.path.generic.obs - path generic format observers", "[filesystem][p
#endif #endif
} }
TEST_CASE("fs.path.compare - path compare", "[filesystem][path][fs.path.compare]") TEST_CASE("30.10.8.4.8 path compare", "[filesystem][path][fs.path.compare]")
{ {
CHECK(fs::path("/foo/b").compare("/foo/a") > 0); CHECK(fs::path("/foo/b").compare("/foo/a") > 0);
CHECK(fs::path("/foo/b").compare("/foo/b") == 0); CHECK(fs::path("/foo/b").compare("/foo/b") == 0);
@ -684,7 +652,7 @@ TEST_CASE("fs.path.compare - path compare", "[filesystem][path][fs.path.compare]
#endif // LWG_2936_BEHAVIOUR #endif // LWG_2936_BEHAVIOUR
} }
TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.decompose]") TEST_CASE("30.10.8.4.9 path decomposition", "[filesystem][path][fs.path.decompose]")
{ {
// root_name() // root_name()
CHECK(fs::path("").root_name() == ""); CHECK(fs::path("").root_name() == "");
@ -792,9 +760,6 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
CHECK(fs::path("C:/foo").filename() == "foo"); CHECK(fs::path("C:/foo").filename() == "foo");
CHECK(fs::path("C:\\foo").filename() == "foo"); CHECK(fs::path("C:\\foo").filename() == "foo");
CHECK(fs::path("C:foo").filename() == "foo"); CHECK(fs::path("C:foo").filename() == "foo");
CHECK(fs::path("t:est.txt").filename() == "est.txt");
#else
CHECK(fs::path("t:est.txt").filename() == "t:est.txt");
#endif #endif
// stem() // stem()
@ -812,13 +777,6 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
CHECK(fs::path("/foo/.profile").stem() == ".profile"); CHECK(fs::path("/foo/.profile").stem() == ".profile");
CHECK(fs::path(".bar").stem() == ".bar"); CHECK(fs::path(".bar").stem() == ".bar");
CHECK(fs::path("..bar").stem() == "."); CHECK(fs::path("..bar").stem() == ".");
#ifdef GHC_OS_WINDOWS
CHECK(fs::path("t:est.txt").stem() == "est");
#else
CHECK(fs::path("t:est.txt").stem() == "t:est");
#endif
CHECK(fs::path("/foo/.").stem() == ".");
CHECK(fs::path("/foo/..").stem() == "..");
// extension() // extension()
CHECK(fs::path("/foo/bar.txt").extension() == ".txt"); CHECK(fs::path("/foo/bar.txt").extension() == ".txt");
@ -826,9 +784,6 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
CHECK(fs::path("/foo/.profile").extension() == ""); CHECK(fs::path("/foo/.profile").extension() == "");
CHECK(fs::path(".bar").extension() == ""); CHECK(fs::path(".bar").extension() == "");
CHECK(fs::path("..bar").extension() == ".bar"); CHECK(fs::path("..bar").extension() == ".bar");
CHECK(fs::path("t:est.txt").extension() == ".txt");
CHECK(fs::path("/foo/.").extension() == "");
CHECK(fs::path("/foo/..").extension() == "");
if (has_host_root_name_support()) { if (has_host_root_name_support()) {
// //host-based root-names // //host-based root-names
@ -847,7 +802,7 @@ TEST_CASE("fs.path.decompose - path decomposition", "[filesystem][path][fs.path.
} }
} }
TEST_CASE("fs.path.query - path query", "[fielsystem][path][fs.path.query]") TEST_CASE("30.10.8.4.10 path query", "[fielsystem][path][fs.path.query]")
{ {
// empty // empty
CHECK(fs::path("").empty()); CHECK(fs::path("").empty());
@ -945,7 +900,7 @@ TEST_CASE("fs.path.query - path query", "[fielsystem][path][fs.path.query]")
} }
} }
TEST_CASE("fs.path.gen - path generation", "[filesystem][path][fs.path.gen]") TEST_CASE("30.10.8.4.11 path generation", "[filesystem][path][fs.path.gen]")
{ {
// lexically_normal() // lexically_normal()
CHECK(fs::path("foo/./bar/..").lexically_normal() == "foo/"); CHECK(fs::path("foo/./bar/..").lexically_normal() == "foo/");
@ -965,10 +920,6 @@ TEST_CASE("fs.path.gen - path generation", "[filesystem][path][fs.path.gen]")
// lexically_relative() // lexically_relative()
CHECK(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d"); CHECK(fs::path("/a/d").lexically_relative("/a/b/c") == "../../d");
CHECK(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c"); CHECK(fs::path("/a/b/c").lexically_relative("/a/d") == "../b/c");
CHECK(fs::path("/a/b/c").lexically_relative("/a/b/c/d/..") == ".");
CHECK(fs::path("/a/b/c/").lexically_relative("/a/b/c/d/..") == ".");
CHECK(fs::path("").lexically_relative("/a/..") == "");
CHECK(fs::path("").lexically_relative("a/..") == ".");
CHECK(fs::path("a/b/c").lexically_relative("a") == "b/c"); CHECK(fs::path("a/b/c").lexically_relative("a") == "b/c");
CHECK(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../.."); CHECK(fs::path("a/b/c").lexically_relative("a/b/c/x/y") == "../..");
CHECK(fs::path("a/b/c").lexically_relative("a/b/c") == "."); CHECK(fs::path("a/b/c").lexically_relative("a/b/c") == ".");
@ -1036,7 +987,7 @@ static std::string reverseIterateResult(const fs::path& path)
return result.str(); return result.str();
} }
TEST_CASE("fs.path.itr - path iterators", "[filesystem][path][fs.path.itr]") TEST_CASE("30.10.8.5 path iterators", "[filesystem][path][fs.path.itr]")
{ {
CHECK(iterateResult(fs::path()).empty()); CHECK(iterateResult(fs::path()).empty());
CHECK("." == iterateResult(fs::path("."))); CHECK("." == iterateResult(fs::path(".")));
@ -1119,7 +1070,7 @@ TEST_CASE("fs.path.itr - path iterators", "[filesystem][path][fs.path.itr]")
} }
} }
TEST_CASE("fs.path.nonmember - path non-member functions", "[filesystem][path][fs.path.nonmember]") TEST_CASE("30.10.8.6 path non-member functions", "[filesystem][path][fs.path.nonmember]")
{ {
fs::path p1("foo/bar"); fs::path p1("foo/bar");
fs::path p2("some/other"); fs::path p2("some/other");
@ -1141,7 +1092,7 @@ TEST_CASE("fs.path.nonmember - path non-member functions", "[filesystem][path][f
CHECK(p1 / p2 == "some/other/foo/bar"); CHECK(p1 / p2 == "some/other/foo/bar");
} }
TEST_CASE("fs.path.io - path inserter and extractor", "[filesystem][path][fs.path.io]") TEST_CASE("30.10.8.6.1 path inserter and extractor", "[filesystem][path][fs.path.io]")
{ {
{ {
std::ostringstream os; std::ostringstream os;
@ -1191,7 +1142,7 @@ TEST_CASE("fs.path.io - path inserter and extractor", "[filesystem][path][fs.pat
} }
} }
TEST_CASE("fs.path.factory - path factory functions", "[filesystem][path][fs.path.factory]") TEST_CASE("30.10.8.6.2 path factory functions", "[filesystem][path][fs.path.factory]")
{ {
CHECK(fs::u8path("foo/bar") == fs::path("foo/bar")); CHECK(fs::u8path("foo/bar") == fs::path("foo/bar"));
CHECK(fs::u8path("foo/bar") == fs::path("foo/bar")); CHECK(fs::u8path("foo/bar") == fs::path("foo/bar"));
@ -1199,7 +1150,7 @@ TEST_CASE("fs.path.factory - path factory functions", "[filesystem][path][fs.pat
CHECK(fs::u8path(str.begin(), str.end()) == str); CHECK(fs::u8path(str.begin(), str.end()) == str);
} }
TEST_CASE("fs.class.filesystem_error - class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]") TEST_CASE("30.10.9 class filesystem_error", "[filesystem][filesystem_error][fs.class.filesystem_error]")
{ {
std::error_code ec(1, std::system_category()); std::error_code ec(1, std::system_category());
fs::filesystem_error fse("None", std::error_code()); fs::filesystem_error fse("None", std::error_code());
@ -1218,12 +1169,12 @@ TEST_CASE("fs.class.filesystem_error - class filesystem_error", "[filesystem][fi
CHECK(fse.path2() == "some/other"); CHECK(fse.path2() == "some/other");
} }
static constexpr fs::perms constExprOwnerAll() constexpr fs::perms constExprOwnerAll()
{ {
return fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec; return fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec;
} }
TEST_CASE("fs.enum - enum class perms", "[filesystem][enum][fs.enum]") TEST_CASE("30.10.10.4 enum class perms", "[filesystem][enum][fs.enum]")
{ {
static_assert(constExprOwnerAll() == fs::perms::owner_all, "constexpr didn't result in owner_all"); static_assert(constExprOwnerAll() == fs::perms::owner_all, "constexpr didn't result in owner_all");
CHECK((fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec) == fs::perms::owner_all); CHECK((fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec) == fs::perms::owner_all);
@ -1233,7 +1184,7 @@ TEST_CASE("fs.enum - enum class perms", "[filesystem][enum][fs.enum]")
CHECK((fs::perms::all | fs::perms::set_uid | fs::perms::set_gid | fs::perms::sticky_bit) == fs::perms::mask); CHECK((fs::perms::all | fs::perms::set_uid | fs::perms::set_gid | fs::perms::sticky_bit) == fs::perms::mask);
} }
TEST_CASE("fs.class.file_status - class file_status", "[filesystem][file_status][fs.class.file_status]") TEST_CASE("30.10.11 class file_status", "[filesystem][file_status][fs.class.file_status]")
{ {
{ {
fs::file_status fs; fs::file_status fs;
@ -1268,20 +1219,9 @@ TEST_CASE("fs.class.file_status - class file_status", "[filesystem][file_status]
CHECK(fs.type() == fs::file_type::regular); CHECK(fs.type() == fs::file_type::regular);
CHECK(fs.permissions() == fs::perms::unknown); CHECK(fs.permissions() == fs::perms::unknown);
} }
#if !defined(USE_STD_FS) || defined(GHC_FILESYSTEM_RUNNING_CPP20)
{
fs::file_status fs1{fs::file_type::regular, fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec};
fs::file_status fs2{fs::file_type::regular, fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec};
fs::file_status fs3{fs::file_type::directory, fs::perms::owner_read | fs::perms::owner_write | fs::perms::owner_exec};
fs::file_status fs4{fs::file_type::regular, fs::perms::owner_read | fs::perms::owner_write};
CHECK(fs1 == fs2);
CHECK_FALSE(fs1 == fs3);
CHECK_FALSE(fs1 == fs4);
}
#endif
} }
TEST_CASE("fs.dir.entry - class directory_entry", "[filesystem][directory_entry][fs.dir.entry]") TEST_CASE("30.10.12 class directory_entry", "[filesystem][directory_entry][fs.dir.entry]")
{ {
TemporaryDirectory t; TemporaryDirectory t;
std::error_code ec; std::error_code ec;
@ -1396,19 +1336,9 @@ TEST_CASE("fs.dir.entry - class directory_entry", "[filesystem][directory_entry]
CHECK(!(d2 != d2)); CHECK(!(d2 != d2));
CHECK(d1 == d1); CHECK(d1 == d1);
CHECK(!(d1 == d2)); CHECK(!(d1 == d2));
if(is_symlink_creation_supported()) {
fs::create_symlink(t.path() / "nonexistent", t.path() / "broken");
for (auto d3 : fs::directory_iterator(t.path())) {
CHECK_NOTHROW(d3.symlink_status());
CHECK_NOTHROW(d3.status());
CHECK_NOTHROW(d3.refresh());
}
fs::directory_entry entry(t.path() / "broken");
CHECK_NOTHROW(entry.refresh());
}
} }
TEST_CASE("fs.class.directory_iterator - class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]") TEST_CASE("30.10.13 class directory_iterator", "[filesystem][directory_iterator][fs.class.directory_iterator]")
{ {
{ {
TemporaryDirectory t; TemporaryDirectory t;
@ -1469,7 +1399,7 @@ TEST_CASE("fs.class.directory_iterator - class directory_iterator", "[filesystem
} }
} }
TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]") TEST_CASE("30.10.14 class recursive_directory_iterator", "[filesystem][recursive_directory_iterator][fs.class.rec.dir.itr]")
{ {
{ {
auto iter = fs::recursive_directory_iterator("."); auto iter = fs::recursive_directory_iterator(".");
@ -1625,40 +1555,9 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
} }
CHECK(os.str() == "[./a,0],[./d1,0],[./d1/d2,1],[./e,0],"); CHECK(os.str() == "[./a,0],[./d1,0],[./d1/d2,1],[./e,0],");
} }
if (is_symlink_creation_supported()) {
TemporaryDirectory t(TempOpt::change_path);
fs::create_directory("d1");
generateFile("d1/a");
fs::create_directory("d2");
generateFile("d2/b");
fs::create_directory_symlink("../d1", "d2/ds1");
fs::create_directory_symlink("d3", "d2/ds2");
std::multiset<std::string> result;
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) {
os << p << ",";
}
CHECK(os.str() == "d2/b,d2/ds1,d2/ds1/a,d2/ds2,");
os.str("");
result.clear();
REQUIRE_NOTHROW([&](){
for (const auto& de : fs::recursive_directory_iterator("d2")) {
result.insert(de.path().generic_string());
}
}());
for(const auto& p : result) {
os << p << ",";
}
CHECK(os.str() == "d2/b,d2/ds1,d2/ds2,");
}
} }
TEST_CASE("fs.op.absolute - absolute", "[filesystem][operations][fs.op.absolute]") TEST_CASE("30.10.15.1 absolute", "[filesystem][operations][fs.op.absolute]")
{ {
CHECK(fs::absolute("") == fs::current_path() / ""); CHECK(fs::absolute("") == fs::current_path() / "");
CHECK(fs::absolute(fs::current_path()) == fs::current_path()); CHECK(fs::absolute(fs::current_path()) == fs::current_path());
@ -1672,7 +1571,7 @@ TEST_CASE("fs.op.absolute - absolute", "[filesystem][operations][fs.op.absolute]
CHECK(!ec); CHECK(!ec);
} }
TEST_CASE("fs.op.canonical - canonical", "[filesystem][operations][fs.op.canonical]") TEST_CASE("30.10.15.2 canonical", "[filesystem][operations][fs.op.canonical]")
{ {
CHECK_THROWS_AS(fs::canonical(""), fs::filesystem_error); CHECK_THROWS_AS(fs::canonical(""), fs::filesystem_error);
{ {
@ -1715,7 +1614,7 @@ TEST_CASE("fs.op.canonical - canonical", "[filesystem][operations][fs.op.canonic
} }
} }
TEST_CASE("fs.op.copy - copy", "[filesystem][operations][fs.op.copy]") TEST_CASE("30.10.15.3 copy", "[filesystem][operations][fs.op.copy]")
{ {
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
@ -1784,7 +1683,7 @@ TEST_CASE("fs.op.copy - copy", "[filesystem][operations][fs.op.copy]")
#endif #endif
} }
TEST_CASE("fs.op.copy_file - copy_file", "[filesystem][operations][fs.op.copy_file]") TEST_CASE("30.10.15.4 copy_file", "[filesystem][operations][fs.op.copy_file]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -1807,22 +1706,9 @@ TEST_CASE("fs.op.copy_file - copy_file", "[filesystem][operations][fs.op.copy_fi
CHECK_NOTHROW(fs::copy_file("foobar", "foobar2", ec)); CHECK_NOTHROW(fs::copy_file("foobar", "foobar2", ec));
CHECK(ec); CHECK(ec);
CHECK(!fs::exists("foobar")); CHECK(!fs::exists("foobar"));
fs::path file1("temp1.txt");
fs::path file2("temp2.txt");
generateFile(file1, 200);
generateFile(file2, 200);
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
CHECK_NOTHROW(fs::permissions(file1, allWrite, fs::perm_options::remove));
CHECK((fs::status(file1).permissions() & fs::perms::owner_write) != fs::perms::owner_write);
CHECK_NOTHROW(fs::permissions(file2, allWrite, fs::perm_options::add));
CHECK((fs::status(file2).permissions() & fs::perms::owner_write) == fs::perms::owner_write);
fs::copy_file(file1, file2, fs::copy_options::overwrite_existing);
CHECK((fs::status(file2).permissions() & fs::perms::owner_write) != fs::perms::owner_write);
CHECK_NOTHROW(fs::permissions(file1, allWrite, fs::perm_options::add));
CHECK_NOTHROW(fs::permissions(file2, allWrite, fs::perm_options::add));
} }
TEST_CASE("fs.op.copy_symlink - copy_symlink", "[filesystem][operations][fs.op.copy_symlink]") TEST_CASE("30.10.15.5 copy_symlink", "[filesystem][operations][fs.op.copy_symlink]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -1847,7 +1733,7 @@ TEST_CASE("fs.op.copy_symlink - copy_symlink", "[filesystem][operations][fs.op.c
CHECK(ec); CHECK(ec);
} }
TEST_CASE("fs.op.create_directories - create_directories", "[filesystem][operations][fs.op.create_directories]") TEST_CASE("30.10.15.6 create_directories", "[filesystem][operations][fs.op.create_directories]")
{ {
TemporaryDirectory t; TemporaryDirectory t;
fs::path p = t.path() / "testdir"; fs::path p = t.path() / "testdir";
@ -1894,7 +1780,7 @@ TEST_CASE("fs.op.create_directories - create_directories", "[filesystem][operati
#endif #endif
} }
TEST_CASE("fs.op.create_directory - create_directory", "[filesystem][operations][fs.op.create_directory]") TEST_CASE("30.10.15.7 create_directory", "[filesystem][operations][fs.op.create_directory]")
{ {
TemporaryDirectory t; TemporaryDirectory t;
fs::path p = t.path() / "testdir"; fs::path p = t.path() / "testdir";
@ -1941,7 +1827,7 @@ TEST_CASE("fs.op.create_directory - create_directory", "[filesystem][operations]
#endif #endif
} }
TEST_CASE("fs.op.create_directory_symlink - create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]") TEST_CASE("30.10.15.8 create_directory_symlink", "[filesystem][operations][fs.op.create_directory_symlink]")
{ {
if (is_symlink_creation_supported()) { if (is_symlink_creation_supported()) {
TemporaryDirectory t; TemporaryDirectory t;
@ -1960,7 +1846,7 @@ TEST_CASE("fs.op.create_directory_symlink - create_directory_symlink", "[filesys
} }
} }
TEST_CASE("fs.op.create_hard_link - create_hard_link", "[filesystem][operations][fs.op.create_hard_link]") TEST_CASE("30.10.15.9 create_hard_link", "[filesystem][operations][fs.op.create_hard_link]")
{ {
#ifndef GHC_OS_WEB #ifndef GHC_OS_WEB
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
@ -1979,7 +1865,7 @@ TEST_CASE("fs.op.create_hard_link - create_hard_link", "[filesystem][operations]
#endif #endif
} }
TEST_CASE("fs.op.create_symlink - create_symlink", "[filesystem][operations][fs.op.create_symlink]") TEST_CASE("30.10.15.10 create_symlink", "[filesystem][operations][fs.op.create_symlink]")
{ {
if (is_symlink_creation_supported()) { if (is_symlink_creation_supported()) {
TemporaryDirectory t; TemporaryDirectory t;
@ -1998,7 +1884,7 @@ TEST_CASE("fs.op.create_symlink - create_symlink", "[filesystem][operations][fs.
} }
} }
TEST_CASE("fs.op.current_path - current_path", "[filesystem][operations][fs.op.current_path]") TEST_CASE("30.10.15.11 current_path", "[filesystem][operations][fs.op.current_path]")
{ {
TemporaryDirectory t; TemporaryDirectory t;
std::error_code ec; std::error_code ec;
@ -2013,7 +1899,7 @@ TEST_CASE("fs.op.current_path - current_path", "[filesystem][operations][fs.op.c
CHECK(ec); CHECK(ec);
} }
TEST_CASE("fs.op.equivalent - equivalent", "[filesystem][operations][fs.op.equivalent]") TEST_CASE("30.10.15.12 equivalent", "[filesystem][operations][fs.op.equivalent]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
generateFile("foo", 1234); generateFile("foo", 1234);
@ -2067,7 +1953,7 @@ TEST_CASE("fs.op.equivalent - equivalent", "[filesystem][operations][fs.op.equiv
#endif #endif
} }
TEST_CASE("fs.op.exists - exists", "[filesystem][operations][fs.op.exists]") TEST_CASE("30.10.15.13 exists", "[filesystem][operations][fs.op.exists]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2077,9 +1963,6 @@ TEST_CASE("fs.op.exists - exists", "[filesystem][operations][fs.op.exists]")
CHECK(!ec); CHECK(!ec);
ec = std::error_code(42, std::system_category()); ec = std::error_code(42, std::system_category());
CHECK(!fs::exists("foo", ec)); CHECK(!fs::exists("foo", ec));
#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API)
CHECK(!fs::exists(u8"foo"));
#endif
CHECK(!ec); CHECK(!ec);
ec.clear(); ec.clear();
CHECK(fs::exists(t.path())); CHECK(fs::exists(t.path()));
@ -2095,7 +1978,7 @@ TEST_CASE("fs.op.exists - exists", "[filesystem][operations][fs.op.exists]")
#endif #endif
} }
TEST_CASE("fs.op.file_size - file_size", "[filesystem][operations][fs.op.file_size]") TEST_CASE("30.10.15.14 file_size", "[filesystem][operations][fs.op.file_size]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2117,16 +2000,7 @@ TEST_CASE("fs.op.file_size - file_size", "[filesystem][operations][fs.op.file_si
ec.clear(); ec.clear();
} }
#ifndef GHC_OS_WINDOWS TEST_CASE("30.10.15.15 hard_link_count", "[filesystem][operations][fs.op.hard_link_count]")
static uintmax_t getHardlinkCount(const fs::path& p)
{
struct stat st = {};
auto rc = ::lstat(p.c_str(), &st);
return rc == 0 ? st.st_nlink : ~0u;
}
#endif
TEST_CASE("fs.op.hard_link_count - hard_link_count", "[filesystem][operations][fs.op.hard_link_count]")
{ {
#ifndef GHC_OS_WEB #ifndef GHC_OS_WEB
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
@ -2141,9 +2015,9 @@ TEST_CASE("fs.op.hard_link_count - hard_link_count", "[filesystem][operations][f
// unix/bsd/linux typically implements "."/".." as hardlinks // unix/bsd/linux typically implements "."/".." as hardlinks
// so an empty dir has 2 (from parent and the ".") and // so an empty dir has 2 (from parent and the ".") and
// adding a subdirectory adds one due to its ".." // adding a subdirectory adds one due to its ".."
CHECK(fs::hard_link_count(t.path()) == getHardlinkCount(t.path())); CHECK(fs::hard_link_count(t.path()) == 2);
fs::create_directory("dir"); fs::create_directory("dir");
CHECK(fs::hard_link_count(t.path()) == getHardlinkCount(t.path())); CHECK(fs::hard_link_count(t.path()) == 3);
#endif #endif
generateFile("foo"); generateFile("foo");
CHECK(fs::hard_link_count(t.path() / "foo") == 1); CHECK(fs::hard_link_count(t.path() / "foo") == 1);
@ -2205,7 +2079,6 @@ public:
fs::path character_path() const fs::path character_path() const
{ {
#ifndef GHC_OS_SOLARIS
std::error_code ec; std::error_code ec;
if (fs::exists("/dev/null", ec)) { if (fs::exists("/dev/null", ec)) {
return "/dev/null"; return "/dev/null";
@ -2213,7 +2086,6 @@ public:
else if (fs::exists("NUL", ec)) { else if (fs::exists("NUL", ec)) {
return "NUL"; return "NUL";
} }
#endif
return fs::path(); return fs::path();
} }
fs::path temp_path() const { return _t.path(); } fs::path temp_path() const { return _t.path(); }
@ -2224,7 +2096,7 @@ private:
bool _hasSocket; bool _hasSocket;
}; };
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_block_file - is_block_file", "[filesystem][operations][fs.op.is_block_file]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.16 is_block_file", "[filesystem][operations][fs.op.is_block_file]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_block_file("directory")); CHECK(!fs::is_block_file("directory"));
@ -2253,7 +2125,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_block_file - is_block_file", "[fi
CHECK(!fs::is_block_file(fs::file_status(fs::file_type::unknown))); CHECK(!fs::is_block_file(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_character_file - is_character_file", "[filesystem][operations][fs.op.is_character_file]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.17 is_character_file", "[filesystem][operations][fs.op.is_character_file]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_character_file("directory")); CHECK(!fs::is_character_file("directory"));
@ -2282,7 +2154,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_character_file - is_character_fil
CHECK(!fs::is_character_file(fs::file_status(fs::file_type::unknown))); CHECK(!fs::is_character_file(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_directory - is_directory", "[filesystem][operations][fs.op.is_directory]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.18 is_directory", "[filesystem][operations][fs.op.is_directory]")
{ {
std::error_code ec; std::error_code ec;
CHECK(fs::is_directory("directory")); CHECK(fs::is_directory("directory"));
@ -2311,7 +2183,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_directory - is_directory", "[file
CHECK(!fs::is_directory(fs::file_status(fs::file_type::unknown))); CHECK(!fs::is_directory(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE("fs.op.is_empty - is_empty", "[filesystem][operations][fs.op.is_empty]") TEST_CASE("30.10.15.19 is_empty", "[filesystem][operations][fs.op.is_empty]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2333,7 +2205,7 @@ TEST_CASE("fs.op.is_empty - is_empty", "[filesystem][operations][fs.op.is_empty]
CHECK(ec); CHECK(ec);
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_fifo - is_fifo", "[filesystem][operations][fs.op.is_fifo]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.20 is_fifo", "[filesystem][operations][fs.op.is_fifo]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_fifo("directory")); CHECK(!fs::is_fifo("directory"));
@ -2362,7 +2234,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_fifo - is_fifo", "[filesystem][op
CHECK(!fs::is_fifo(fs::file_status(fs::file_type::unknown))); CHECK(!fs::is_fifo(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_other - is_other", "[filesystem][operations][fs.op.is_other]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.21 is_other", "[filesystem][operations][fs.op.is_other]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_other("directory")); CHECK(!fs::is_other("directory"));
@ -2391,7 +2263,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_other - is_other", "[filesystem][
CHECK(fs::is_other(fs::file_status(fs::file_type::unknown))); CHECK(fs::is_other(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_regular_file - is_regular_file", "[filesystem][operations][fs.op.is_regular_file]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.22 is_regular_file", "[filesystem][operations][fs.op.is_regular_file]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_regular_file("directory")); CHECK(!fs::is_regular_file("directory"));
@ -2420,7 +2292,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_regular_file - is_regular_file",
CHECK(!fs::is_regular_file(fs::file_status(fs::file_type::unknown))); CHECK(!fs::is_regular_file(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_socket - is_socket", "[filesystem][operations][fs.op.is_socket]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.23 is_socket", "[filesystem][operations][fs.op.is_socket]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_socket("directory")); CHECK(!fs::is_socket("directory"));
@ -2449,7 +2321,7 @@ TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_socket - is_socket", "[filesystem
CHECK(!fs::is_socket(fs::file_status(fs::file_type::unknown))); CHECK(!fs::is_socket(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE_METHOD(FileTypeMixFixture, "fs.op.is_symlink - is_symlink", "[filesystem][operations][fs.op.is_symlink]") TEST_CASE_METHOD(FileTypeMixFixture, "30.10.15.24 is_symlink", "[filesystem][operations][fs.op.is_symlink]")
{ {
std::error_code ec; std::error_code ec;
CHECK(!fs::is_symlink("directory")); CHECK(!fs::is_symlink("directory"));
@ -2492,7 +2364,7 @@ static fs::file_time_type timeFromString(const std::string& str)
} }
#endif #endif
TEST_CASE("fs.op.last_write_time - last_write_time", "[filesystem][operations][fs.op.last_write_time]") TEST_CASE("30.10.15.25 last_write_time", "[filesystem][operations][fs.op.last_write_time]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2527,7 +2399,7 @@ TEST_CASE("fs.op.last_write_time - last_write_time", "[filesystem][operations][f
#endif #endif
} }
TEST_CASE("fs.op.permissions - permissions", "[filesystem][operations][fs.op.permissions]") TEST_CASE("30.10.15.26 permissions", "[filesystem][operations][fs.op.permissions]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2535,13 +2407,8 @@ TEST_CASE("fs.op.permissions - permissions", "[filesystem][operations][fs.op.per
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write; auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
CHECK_NOTHROW(fs::permissions("foo", allWrite, fs::perm_options::remove)); CHECK_NOTHROW(fs::permissions("foo", allWrite, fs::perm_options::remove));
CHECK((fs::status("foo").permissions() & fs::perms::owner_write) != fs::perms::owner_write); CHECK((fs::status("foo").permissions() & fs::perms::owner_write) != fs::perms::owner_write);
#if !defined(GHC_OS_WINDOWS) CHECK_THROWS_AS(fs::resize_file("foo", 1024), fs::filesystem_error);
if (geteuid() != 0) CHECK(fs::file_size("foo") == 512);
#endif
{
CHECK_THROWS_AS(fs::resize_file("foo", 1024), fs::filesystem_error);
CHECK(fs::file_size("foo") == 512);
}
CHECK_NOTHROW(fs::permissions("foo", fs::perms::owner_write, fs::perm_options::add)); CHECK_NOTHROW(fs::permissions("foo", fs::perms::owner_write, fs::perm_options::add));
CHECK((fs::status("foo").permissions() & fs::perms::owner_write) == fs::perms::owner_write); CHECK((fs::status("foo").permissions() & fs::perms::owner_write) == fs::perms::owner_write);
CHECK_NOTHROW(fs::resize_file("foo", 2048)); CHECK_NOTHROW(fs::resize_file("foo", 2048));
@ -2552,7 +2419,7 @@ TEST_CASE("fs.op.permissions - permissions", "[filesystem][operations][fs.op.per
CHECK_THROWS_AS(fs::permissions("bar", fs::perms::owner_write, static_cast<fs::perm_options>(0)), fs::filesystem_error); CHECK_THROWS_AS(fs::permissions("bar", fs::perms::owner_write, static_cast<fs::perm_options>(0)), fs::filesystem_error);
} }
TEST_CASE("fs.op.proximate - proximate", "[filesystem][operations][fs.op.proximate]") TEST_CASE("30.10.15.27 proximate", "[filesystem][operations][fs.op.proximate]")
{ {
std::error_code ec; std::error_code ec;
CHECK(fs::proximate("/a/d", "/a/b/c") == "../../d"); CHECK(fs::proximate("/a/d", "/a/b/c") == "../../d");
@ -2582,7 +2449,7 @@ TEST_CASE("fs.op.proximate - proximate", "[filesystem][operations][fs.op.proxima
#endif #endif
} }
TEST_CASE("fs.op.read_symlink - read_symlink", "[filesystem][operations][fs.op.read_symlink]") TEST_CASE("30.10.15.28 read_symlink", "[filesystem][operations][fs.op.read_symlink]")
{ {
if (is_symlink_creation_supported()) { if (is_symlink_creation_supported()) {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
@ -2598,7 +2465,7 @@ TEST_CASE("fs.op.read_symlink - read_symlink", "[filesystem][operations][fs.op.r
} }
} }
TEST_CASE("fs.op.relative - relative", "[filesystem][operations][fs.op.relative]") TEST_CASE("30.10.15.29 relative", "[filesystem][operations][fs.op.relative]")
{ {
CHECK(fs::relative("/a/d", "/a/b/c") == "../../d"); CHECK(fs::relative("/a/d", "/a/b/c") == "../../d");
CHECK(fs::relative("/a/b/c", "/a/d") == "../b/c"); CHECK(fs::relative("/a/b/c", "/a/d") == "../b/c");
@ -2611,7 +2478,7 @@ TEST_CASE("fs.op.relative - relative", "[filesystem][operations][fs.op.relative]
CHECK(!ec); CHECK(!ec);
} }
TEST_CASE("fs.op.remove - remove", "[filesystem][operations][fs.op.remove]") TEST_CASE("30.10.15.30 remove", "[filesystem][operations][fs.op.remove]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2635,7 +2502,7 @@ TEST_CASE("fs.op.remove - remove", "[filesystem][operations][fs.op.remove]")
CHECK(!ec); CHECK(!ec);
} }
TEST_CASE("fs.op.remove_all - remove_all", "[filesystem][operations][fs.op.remove_all]") TEST_CASE("30.10.15.31 remove_all", "[filesystem][operations][fs.op.remove_all]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2651,15 +2518,11 @@ TEST_CASE("fs.op.remove_all - remove_all", "[filesystem][operations][fs.op.remov
CHECK_NOTHROW(fs::remove_all("dir1/non-existing", ec)); CHECK_NOTHROW(fs::remove_all("dir1/non-existing", ec));
CHECK(!ec); CHECK(!ec);
CHECK(fs::remove_all("dir1/non-existing", ec) == 0); CHECK(fs::remove_all("dir1/non-existing", ec) == 0);
if (is_symlink_creation_supported()) {
fs::create_directory_symlink("dir1", "dir1link");
CHECK(fs::remove_all("dir1link") == 1);
}
CHECK(fs::remove_all("dir1") == 5); CHECK(fs::remove_all("dir1") == 5);
CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator()); CHECK(fs::directory_iterator(t.path()) == fs::directory_iterator());
} }
TEST_CASE("fs.op.rename - rename", "[filesystem][operations][fs.op.rename]") TEST_CASE("30.10.15.32 rename", "[filesystem][operations][fs.op.rename]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2683,7 +2546,7 @@ TEST_CASE("fs.op.rename - rename", "[filesystem][operations][fs.op.rename]")
CHECK(!fs::exists("barfoo")); CHECK(!fs::exists("barfoo"));
} }
TEST_CASE("fs.op.resize_file - resize_file", "[filesystem][operations][fs.op.resize_file]") TEST_CASE("30.10.15.33 resize_file", "[filesystem][operations][fs.op.resize_file]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2701,7 +2564,7 @@ TEST_CASE("fs.op.resize_file - resize_file", "[filesystem][operations][fs.op.res
CHECK(!fs::exists("bar")); CHECK(!fs::exists("bar"));
} }
TEST_CASE("fs.op.space - space", "[filesystem][operations][fs.op.space]") TEST_CASE("30.10.15.34 space", "[filesystem][operations][fs.op.space]")
{ {
{ {
fs::space_info si; fs::space_info si;
@ -2733,7 +2596,7 @@ TEST_CASE("fs.op.space - space", "[filesystem][operations][fs.op.space]")
#endif #endif
} }
TEST_CASE("fs.op.status - status", "[filesystem][operations][fs.op.status]") TEST_CASE("30.10.15.35 status", "[filesystem][operations][fs.op.status]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2761,7 +2624,7 @@ TEST_CASE("fs.op.status - status", "[filesystem][operations][fs.op.status]")
} }
} }
TEST_CASE("fs.op.status_known - status_known", "[filesystem][operations][fs.op.status_known]") TEST_CASE("30.10.15.36 status_known", "[filesystem][operations][fs.op.status_known]")
{ {
CHECK(!fs::status_known(fs::file_status())); CHECK(!fs::status_known(fs::file_status()));
CHECK(fs::status_known(fs::file_status(fs::file_type::not_found))); CHECK(fs::status_known(fs::file_status(fs::file_type::not_found)));
@ -2774,7 +2637,7 @@ TEST_CASE("fs.op.status_known - status_known", "[filesystem][operations][fs.op.s
CHECK(fs::status_known(fs::file_status(fs::file_type::unknown))); CHECK(fs::status_known(fs::file_status(fs::file_type::unknown)));
} }
TEST_CASE("fs.op.symlink_status - symlink_status", "[filesystem][operations][fs.op.symlink_status]") TEST_CASE("30.10.15.37 symlink_status", "[filesystem][operations][fs.op.symlink_status]")
{ {
TemporaryDirectory t(TempOpt::change_path); TemporaryDirectory t(TempOpt::change_path);
std::error_code ec; std::error_code ec;
@ -2801,7 +2664,7 @@ TEST_CASE("fs.op.symlink_status - symlink_status", "[filesystem][operations][fs.
} }
} }
TEST_CASE("fs.op.temp_dir_path - temporary_directory_path", "[filesystem][operations][fs.op.temp_dir_path]") TEST_CASE("30.10.15.38 temporary_directory_path", "[filesystem][operations][fs.op.temp_dir_path]")
{ {
std::error_code ec; std::error_code ec;
CHECK_NOTHROW(fs::exists(fs::temp_directory_path())); CHECK_NOTHROW(fs::exists(fs::temp_directory_path()));
@ -2810,7 +2673,7 @@ TEST_CASE("fs.op.temp_dir_path - temporary_directory_path", "[filesystem][operat
CHECK(!ec); CHECK(!ec);
} }
TEST_CASE("fs.op.weakly_canonical - weakly_canonical", "[filesystem][operations][fs.op.weakly_canonical]") TEST_CASE("30.10.15.39 weakly_canonical", "[filesystem][operations][fs.op.weakly_canonical]")
{ {
INFO("This might fail on std::implementations that return fs::current_path() for fs::canonical(\"\")"); INFO("This might fail on std::implementations that return fs::current_path() for fs::canonical(\"\")");
CHECK(fs::weakly_canonical("") == "."); CHECK(fs::weakly_canonical("") == ".");
@ -2849,40 +2712,33 @@ TEST_CASE("fs.op.weakly_canonical - weakly_canonical", "[filesystem][operations]
TEST_CASE("std::string_view support", "[filesystem][fs.string_view]") 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 __cpp_lib_string_view
#if defined(GHC_HAS_STD_STRING_VIEW)
using namespace std::literals; using namespace std::literals;
using string_view = std::string_view;
using wstring_view = std::wstring_view;
#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW)
using string_view = std::experimental::string_view;
using wstring_view = std::experimental::wstring_view;
#endif
{ {
std::string p("foo/bar"); std::string p("foo/bar");
string_view sv(p); std::string_view sv(p);
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar"); CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
fs::path p2("fo"); fs::path p2("fo");
p2 += string_view("o"); p2 += std::string_view("o");
CHECK(p2 == "foo"); CHECK(p2 == "foo");
CHECK(p2.compare(string_view("foo")) == 0); CHECK(p2.compare(std::string_view("foo")) == 0);
} }
{ {
auto p = fs::path{"XYZ"}; auto p = fs::path{"XYZ"};
p /= string_view("Appendix"); p /= std::string_view("Appendix");
CHECK(p == "XYZ/Appendix"); CHECK(p == "XYZ/Appendix");
} }
#if defined(IS_WCHAR_PATH) || defined(GHC_USE_WCHAR_T)
{ {
std::wstring p(L"foo/bar"); std::wstring p(L"foo/bar");
wstring_view sv(p); std::wstring_view sv(p);
CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar"); CHECK(fs::path(sv, fs::path::format::generic_format).generic_string() == "foo/bar");
fs::path p2(L"fo"); fs::path p2(L"fo");
p2 += wstring_view(L"o"); p2 += std::wstring_view(L"o");
CHECK(p2 == "foo"); CHECK(p2 == "foo");
CHECK(p2.compare(wstring_view(L"foo")) == 0); CHECK(p2.compare(std::wstring_view(L"foo")) == 0);
} }
#endif
#else #else
WARN("std::string_view specific tests are empty without std::string_view."); WARN("std::string_view specific tests are empty without std::string_view.");
@ -2902,15 +2758,13 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long
CHECK_NOTHROW(fs::create_directory(dir)); CHECK_NOTHROW(fs::create_directory(dir));
CHECK(fs::exists(dir)); CHECK(fs::exists(dir));
generateFile(dir / "f0"); generateFile(dir / "f0");
REQUIRE(fs::exists(dir / "f0")); CHECK(fs::exists(dir / "f0"));
auto native = dir.u8string();
if (native.substr(0, 4) == u8"\\\\?\\") {
break;
}
} }
CHECK(c > 'Z'); CHECK(c <= 'Z');
fs::remove_all(fs::current_path() / std::string(16, 'A'));
CHECK(!fs::exists(fs::current_path() / std::string(16, 'A')));
CHECK_NOTHROW(fs::create_directories(dir));
CHECK(fs::exists(dir));
generateFile(dir / "f0");
CHECK(fs::exists(dir / "f0"));
#else #else
WARN("Windows specific tests are empty on non-Windows systems."); WARN("Windows specific tests are empty on non-Windows systems.");
#endif #endif
@ -2943,8 +2797,8 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
{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"},
{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"},
{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"(\\.\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"(\\?\HarddiskVolume1\Windows\notepad.exe)", R"(\\?\HarddiskVolume1\Windows\notepad.exe)", "\\\\?", "\\\\?\\", "//?,/,HarddiskVolume1,Windows,notepad.exe"},
@ -2961,7 +2815,6 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
INFO("Used path: " + ti._path); INFO("Used path: " + ti._path);
auto p = fs::path(ti._path); auto p = fs::path(ti._path);
CHECK(p.string() == ti._string); CHECK(p.string() == ti._string);
CHECK(p.is_absolute());
CHECK(p.root_name().string() == ti._rootName); CHECK(p.root_name().string() == ti._rootName);
CHECK(p.root_path().string() == ti._rootPath); CHECK(p.root_path().string() == ti._rootPath);
CHECK(iterateResult(p) == ti._iterateResult); CHECK(iterateResult(p) == ti._iterateResult);
@ -2970,31 +2823,3 @@ TEST_CASE("Windows: path namespace handling", "[filesystem][path][fs.path.win.na
WARN("Windows specific tests are empty on non-Windows systems."); WARN("Windows specific tests are empty on non-Windows systems.");
#endif #endif
} }
TEST_CASE("Windows: Mapped folders handling ", "[filesystem][fs.win][fs.win.mapped]")
{
#ifdef GHC_OS_WINDOWS
// this test expects a mapped volume on C:\\fs-test as is the case on the development test system
// does nothing on other systems
if (fs::exists("C:\\fs-test")) {
CHECK(fs::canonical("C:\\fs-test\\Test.txt").string() == "C:\\fs-test\\Test.txt");
}
#else
WARN("Windows specific tests are empty on non-Windows systems.");
#endif
}
TEST_CASE("Windows: Deletion of Read-only Files", "[filesystem][fs.win][fs.win.remove]")
{
#ifdef GHC_OS_WINDOWS
TemporaryDirectory t(TempOpt::change_path);
std::error_code ec;
generateFile("foo", 512);
auto allWrite = fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write;
CHECK_NOTHROW(fs::permissions("foo", allWrite, fs::perm_options::remove));
CHECK_NOTHROW(fs::remove("foo"));
CHECK(!fs::exists("foo"));
#else
WARN("Windows specific tests are empty on non-Windows systems.");
#endif
}

View File

@ -3,6 +3,7 @@
// where exactly one cpp includes fs_impl.hpp and all others use // where exactly one cpp includes fs_impl.hpp and all others use
// fs_fwd.hpp (to test this with maximum functionality, the unit tests // fs_fwd.hpp (to test this with maximum functionality, the unit tests
// are included here, signaling they should only include the fs_fwd.hpp) // are included here, signaling they should only include the fs_fwd.hpp)
#define NOMINMAX
#include <ghc/fs_impl.hpp> #include <ghc/fs_impl.hpp>
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include "catch.hpp" #include "catch.hpp"

View File

@ -27,7 +27,7 @@
#include <ghc/filesystem.hpp> #include <ghc/filesystem.hpp>
namespace fs = ghc::filesystem; namespace fs = ghc::filesystem;
// This test and the one in multi2.cpp doesn't actually test relevant functionality, // This test and the one in multi2.cpp doesn't actualy test relevant functionality,
// it is just used to check that it is possible to include filesystem.h in multiple // it is just used to check that it is possible to include filesystem.h in multiple
// source files. // source files.
TEST_CASE("Multifile-test 1", "[multi]") TEST_CASE("Multifile-test 1", "[multi]")