Some cleanup, and warning fixes and test code issues on clang 7.

This commit is contained in:
Steffen Schuemann 2018-11-03 11:15:18 +01:00
parent 59d496c2bb
commit 9e4eb59e9c
6 changed files with 54 additions and 10 deletions

View File

@ -360,6 +360,10 @@ to the expected behavior.
* Starting with this version, only even patch level versions will be tagged and
odd patch levels mark in-between non-stable wip states.
* Tests can now also be run against MS version of std::filesystem for comparison.
* Added missing `fstream` include.
* Removed non-conforming C99 `timespec`/`timeval` usage.
* Fixed some integer type mismatches that could lead to warnings.
* Fixed `chrono` conversion issues in test and example on clang 7.0.0.
### [v1.0.1](https://github.com/gulrak/filesystem/tree/v1.0.1)

View File

@ -5,6 +5,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
endif()
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)
include_directories(/usr/local/opt/llvm/include)
link_directories(/usr/local/opt/llvm/lib)
endif()
add_executable(std_fs_dir dir.cpp)
set_property(TARGET std_fs_dir PROPERTY CXX_STANDARD 17)
target_link_libraries(std_fs_dir -lc++fs)

View File

@ -14,7 +14,8 @@ template<typename TP>
std::time_t to_time_t(TP tp)
{
// Based on trick from: Nico Josuttis, C++17 - The Complete Guide
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + (tp - TP::clock::now()));
std::chrono::system_clock::duration dt = std::chrono::duration_cast<std::chrono::system_clock::duration>(tp - TP::clock::now());
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + dt);
}
static std::string perm_to_str(fs::perms prms)

View File

@ -89,6 +89,7 @@
#include <cstdlib>
#include <cstring>
#include <functional>
#include <fstream>
#include <clocale>
#include <memory>
#include <stack>
@ -1094,7 +1095,7 @@ static inline unsigned consumeUtf8Fragment(const unsigned state, const uint8_t f
{
uint8_t category = fragment < 128 ? 0 : (utf8_state_info[(fragment >> 3) & 0xf] >> ((fragment & 7) << 2)) & 0xf;
codepoint = (state ? (codepoint << 6) | (fragment & 0x3f) : (0xff >> category) & fragment);
return state == S_RJCT ? S_RJCT : (utf8_state_info[category + 16] >> (state << 2)) & 0xf;
return state == S_RJCT ? static_cast<unsigned>(S_RJCT) : static_cast<unsigned>((utf8_state_info[category + 16] >> (state << 2)) & 0xf);
}
template <class StringType>
@ -1463,7 +1464,7 @@ inline path resolveSymlink(const path& p, std::error_code& ec)
ec = std::error_code(errno, std::system_category());
return path();
}
else if (rc < bufferSize) {
else if (rc < static_cast<int>(bufferSize)) {
return path(std::string(buffer.data(), rc));
}
bufferSize *= 2;
@ -3481,8 +3482,11 @@ inline void last_write_time(const path& p, file_time_type new_time, std::error_c
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300
struct ::stat fs;
if (::stat(p.c_str(), &fs) == 0) {
struct ::timeval tv[2] = {{.tv_sec = fs.st_atimespec.tv_sec, .tv_usec = static_cast<int>(fs.st_atimespec.tv_nsec / 1000)},
{.tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count(), .tv_usec = static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(d).count() % 1000000)}};
struct ::timeval tv[2];
tv[0].tv_sec = fs.st_atimespec.tv_sec;
tv[0].tv_usec = static_cast<int>(fs.st_atimespec.tv_nsec / 1000);
tv[1].tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count();
tv[1].tv_usec = static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(d).count() % 1000000);
if (::utimes(p.c_str(), tv) == 0) {
return;
}
@ -3490,7 +3494,11 @@ inline void last_write_time(const path& p, file_time_type new_time, std::error_c
ec = std::error_code(errno, std::system_category());
return;
#else
struct ::timespec times[2] = {{.tv_nsec = UTIME_OMIT}, {.tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count(), .tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000}};
struct ::timespec times[2];
times[0].tv_sec = 0;
times[0].tv_nsec = UTIME_OMIT;
times[1].tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count();
times[1].tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000;
if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
ec = std::error_code(errno, std::system_category());
}
@ -3498,7 +3506,11 @@ inline void last_write_time(const path& p, file_time_type new_time, std::error_c
#endif
#endif
#else
struct ::timespec times[2] = {{.tv_sec = 0, .tv_nsec = UTIME_OMIT}, {.tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count(), .tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000}};
struct ::timespec times[2];
times[0].tv_sec = 0;
times[0].tv_nsec = UTIME_OMIT;
times[1].tv_sec = std::chrono::duration_cast<std::chrono::seconds>(d).count();
times[1].tv_nsec = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000;
if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) {
ec = std::error_code(errno, std::system_category());
}

View File

@ -7,8 +7,10 @@ if(CMAKE_GENERATOR STREQUAL Xcode)
endif()
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))
include_directories(/usr/local/opt/llvm/include)
link_directories(/usr/local/opt/llvm/lib)
if(APPLE)
include_directories(/usr/local/opt/llvm/include)
link_directories(/usr/local/opt/llvm/lib)
endif()
add_executable(std_filesystem_test filesystem_test.cpp ../filesystem.h catch.hpp)
set_property(TARGET std_filesystem_test PROPERTY CXX_STANDARD 17)
target_compile_definitions(std_filesystem_test PRIVATE USE_STD_FS)

View File

@ -77,6 +77,14 @@ using fstream = ghc::filesystem::fstream;
//#define TEST_LWG_2935_BEHAVIOUR
#define TEST_LWG_2937_BEHAVIOUR
template<typename TP>
std::time_t to_time_t(TP tp)
{
// Based on trick from: Nico Josuttis, C++17 - The Complete Guide
std::chrono::system_clock::duration dt = std::chrono::duration_cast<std::chrono::system_clock::duration>(tp - TP::clock::now());
return std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + dt);
}
namespace Catch {
template <>
struct StringMaker<fs::path>
@ -89,6 +97,18 @@ struct StringMaker<fs::perms>
{
static std::string convert(fs::perms const& value) { return std::to_string(static_cast<unsigned int>(value)); }
};
template <>
struct StringMaker<fs::file_time_type>
{
static std::string convert(fs::file_time_type const& value) {
std::time_t t = to_time_t(value);
std::tm ttm = *std::localtime(&t);
std::ostringstream os;
os << std::put_time(&ttm, "%Y-%m-%d %H:%M:%S");
return os.str();
}
};
} // namespace Catch
enum class TempOpt { none, change_path };
@ -1858,7 +1878,8 @@ TEST_CASE("30.10.15.25 last_write_time", "[filesystem][operations][fs.op.last_wr
CHECK(std::abs(std::chrono::duration_cast<std::chrono::seconds>(fs::last_write_time("foo") - now).count()) < 3);
CHECK_THROWS_AS(fs::last_write_time("bar"), fs::filesystem_error);
CHECK_NOTHROW(ft = fs::last_write_time("bar", ec));
CHECK(ft == fs::file_time_type::min());
bool equal = (ft == fs::file_time_type::min());
CHECK(equal); // Workaround a problem in catch with clang 7 and time_points.
CHECK(ec);
ec.clear();
if (is_symlink_creation_supported()) {