diff --git a/libcxx/src/filesystem/filesystem_clock.cpp b/libcxx/src/filesystem/filesystem_clock.cpp --- a/libcxx/src/filesystem/filesystem_clock.cpp +++ b/libcxx/src/filesystem/filesystem_clock.cpp @@ -11,7 +11,9 @@ #include #include -#include "time_utils.h" +#if defined(_LIBCPP_WIN32API) +# include "time_utils.h" +#endif #if defined(_LIBCPP_WIN32API) # define WIN32_LEAN_AND_MEAN diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_normal.pass.cpp @@ -16,13 +16,13 @@ // path lexically_normal() const; #include "filesystem_include.h" -#include #include #include "../../path_helper.h" #include "count_new.h" #include "test_macros.h" - +#include "assert_macros.h" +#include "concat_macros.h" int main(int, char**) { // clang-format off @@ -127,22 +127,15 @@ {"foo/..", "."} }; // clang-format on - int ID = 0; - bool Failed = false; for (auto& TC : TestCases) { - ++ID; fs::path p(TC.input); const fs::path output = p.lexically_normal(); fs::path expect(TC.expect); expect.make_preferred(); - if (!PathEq(output, expect)) { - Failed = true; - std::fprintf(stderr, "TEST CASE #%d FAILED:\n" - " Input: '%s'\n" - " Expected: '%s'\n" - " Output: '%s'\n", - ID, TC.input.c_str(), expect.string().c_str(), output.string().c_str()); - } + + TEST_REQUIRE( + PathEq(output, expect), + TEST_WRITE_CONCATENATED("Input: ", TC.input, "\nExpected: ", expect.string(), "\nOutput: ", output.string())); } - return Failed; + return 0; } diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.gen/lexically_relative_and_proximate.pass.cpp @@ -17,10 +17,11 @@ // path lexically_proximate(const path& p) const; #include "filesystem_include.h" -#include #include #include "../../path_helper.h" +#include "assert_macros.h" +#include "concat_macros.h" #include "count_new.h" #include "test_macros.h" @@ -58,35 +59,40 @@ {"a/b", "c/d", "../../a/b"} }; // clang-format on - int ID = 0; - bool Failed = false; for (auto& TC : TestCases) { - ++ID; const fs::path p(TC.input); const fs::path output = p.lexically_relative(TC.base); fs::path expect(TC.expect); expect.make_preferred(); - auto ReportErr = [&](const char* Testing, fs::path const& Output, - fs::path const& Expected) { - Failed = true; - std::fprintf(stderr, "TEST CASE #%d FAILED:\n" - " Testing: %s\n" - " Input: '%s'\n" - " Base: '%s'\n" - " Expected: '%s'\n" - " Output: '%s'\n", - ID, Testing, TC.input.c_str(), TC.base.c_str(), - Expected.string().c_str(), Output.string().c_str()); - }; - if (!PathEq(output, expect)) - ReportErr("path::lexically_relative", output, expect); + + // clang-format off + TEST_REQUIRE( + PathEq(output, expect), + TEST_WRITE_CONCATENATED( + "path::lexically_relative test case failed", + "\nInput: ", TC.input, + "\nBase: ", TC.base, + "\nExpected: ", expect, + "\nOutput: ", output)); + // clang-format on + const fs::path proximate_output = p.lexically_proximate(TC.base); // [path.gen] lexically_proximate // Returns: If the value of lexically_relative(base) is not an empty path, // return it. Otherwise return *this. const fs::path proximate_expect = expect.empty() ? p : expect; - if (!PathEq(proximate_output, proximate_expect)) - ReportErr("path::lexically_proximate", proximate_output, proximate_expect); + + // clang-format off + TEST_REQUIRE( + PathEq(proximate_output, proximate_expect), + TEST_WRITE_CONCATENATED( + "path::lexically_proximate test case failed", + "\nInput: ", TC.input, + "\nBase: ", TC.base, + "\nExpected: ", proximate_expect, + "\nOutput: ", proximate_output)); + // clang-format on } - return Failed; + + return 0; } diff --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.directory_options.pass.cpp @@ -15,7 +15,6 @@ #include "filesystem_include.h" #include #include -#include #include "test_macros.h" #include "check_bitmask_types.h" diff --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perm_options.pass.cpp @@ -15,7 +15,6 @@ #include "filesystem_include.h" #include #include -#include #include "test_macros.h" #include "check_bitmask_types.h" diff --git a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.enum/enum.perms.pass.cpp @@ -15,7 +15,6 @@ #include "filesystem_include.h" #include #include -#include #include "test_macros.h" #include "check_bitmask_types.h" diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp @@ -18,8 +18,9 @@ #include "filesystem_include.h" #include -#include +#include "assert_macros.h" +#include "concat_macros.h" #include "test_macros.h" #include "count_new.h" #include "filesystem_test_helper.h" @@ -34,27 +35,27 @@ return count; } - -static void signature_test() -{ - using fs::path; - const path p; ((void)p); - std::error_code ec; ((void)ec); - ASSERT_NOT_NOEXCEPT(proximate(p)); - ASSERT_NOT_NOEXCEPT(proximate(p, p)); - ASSERT_NOT_NOEXCEPT(proximate(p, ec)); - ASSERT_NOT_NOEXCEPT(proximate(p, p, ec)); +static void signature_test() { + using fs::path; + const path p; + ((void)p); + std::error_code ec; + ((void)ec); + ASSERT_NOT_NOEXCEPT(proximate(p)); + ASSERT_NOT_NOEXCEPT(proximate(p, p)); + ASSERT_NOT_NOEXCEPT(proximate(p, ec)); + ASSERT_NOT_NOEXCEPT(proximate(p, p, ec)); } static void basic_test() { using fs::path; - const path cwd = fs::current_path(); + const path cwd = fs::current_path(); const path parent_cwd = cwd.parent_path(); - const path curdir = cwd.filename(); + const path curdir = cwd.filename(); assert(!cwd.native().empty()); int cwd_depth = count_path_elems(cwd); path dot_dot_to_root; - for (int i=0; i < cwd_depth; ++i) + for (int i = 0; i < cwd_depth; ++i) dot_dot_to_root /= ".."; path relative_cwd = cwd.native().substr(cwd.root_path().native().size()); // clang-format off @@ -131,41 +132,36 @@ {"a/b", "c/d", "../../a/b"} }; // clang-format on - int ID = 0; for (auto& TC : TestCases) { - ++ID; - std::error_code ec = GetTestEC(); - fs::path p = TC.input; + std::error_code ec = GetTestEC(); + fs::path p = TC.input; const fs::path output = fs::proximate(p, TC.base, ec); - fs::path expect = TC.expect; + fs::path expect = TC.expect; expect.make_preferred(); - if (ec) { - assert(!ec); - std::fprintf(stderr, "TEST CASE #%d FAILED:\n" - " Input: '%s'\n" - " Base: '%s'\n" - " Expected: '%s'\n", - ID, TC.input.string().c_str(), TC.base.string().c_str(), - expect.string().c_str()); - } else if (!PathEq(output, expect)) { - assert(PathEq(output, expect)); + TEST_REQUIRE(!ec, + TEST_WRITE_CONCATENATED( + "Input: ", TC.input.string(), "\nBase: ", TC.base.string(), "\nExpected: ", expect.string())); - const path canon_input = fs::weakly_canonical(TC.input); - const path canon_base = fs::weakly_canonical(TC.base); - const path lexically_p = canon_input.lexically_proximate(canon_base); - std::fprintf(stderr, "TEST CASE #%d FAILED:\n" - " Input: '%s'\n" - " Base: '%s'\n" - " Expected: '%s'\n" - " Output: '%s'\n" - " Lex Prox: '%s'\n" - " Canon Input: '%s'\n" - " Canon Base: '%s'\n", - ID, TC.input.string().c_str(), TC.base.string().c_str(), - expect.string().c_str(), output.string().c_str(), - lexically_p.string().c_str(), canon_input.string().c_str(), - canon_base.string().c_str()); - } + const path canon_input = fs::weakly_canonical(TC.input); + const path canon_base = fs::weakly_canonical(TC.base); + const path lexically_p = canon_input.lexically_proximate(canon_base); + TEST_REQUIRE( + PathEq(output, expect), + TEST_WRITE_CONCATENATED( + "Input: ", + TC.input.string(), + "\nBase: ", + TC.base.string(), + "\nExpected: ", + expect.string(), + "\nOutput: ", + output.string(), + "\nLex Prox: ", + lexically_p.string(), + "\nCanon Input: ", + canon_input.string(), + "\nCanon Base: ", + canon_base.string())); } } diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp @@ -16,9 +16,10 @@ // path weakly_canonical(const path& p, error_code& ec); #include "filesystem_include.h" -#include #include +#include "assert_macros.h" +#include "concat_macros.h" #include "test_macros.h" #include "test_iterators.h" #include "count_new.h" @@ -26,7 +27,6 @@ #include "../../class.path/path_helper.h" int main(int, char**) { - static_test_env static_env; fs::path root = fs::current_path().root_path(); @@ -68,23 +68,15 @@ {static_env.Dir / "DNE/../foo", static_env.Dir / "foo"} }; // clang-format on - int ID = 0; - bool Failed = false; for (auto& TC : TestCases) { - ++ID; - fs::path p = TC.input; + fs::path p = TC.input; fs::path expect = TC.expect; expect.make_preferred(); const fs::path output = fs::weakly_canonical(p); - if (!PathEq(output, expect)) { - Failed = true; - std::fprintf(stderr, "TEST CASE #%d FAILED:\n" - " Input: '%s'\n" - " Expected: '%s'\n" - " Output: '%s'\n", - ID, TC.input.string().c_str(), expect.string().c_str(), - output.string().c_str()); - } + + TEST_REQUIRE(PathEq(output, expect), + TEST_WRITE_CONCATENATED( + "Input: ", TC.input.string(), "\nExpected: ", expect.string(), "\nOutput: ", output.string())); } - return Failed; + return 0; } diff --git a/libcxx/test/support/concat_macros.h b/libcxx/test/support/concat_macros.h --- a/libcxx/test/support/concat_macros.h +++ b/libcxx/test/support/concat_macros.h @@ -49,6 +49,11 @@ // Writes its arguments to stderr, using the test_concat_message helper. # define TEST_WRITE_CONCATENATED(...) [&] { ::test_eprintf("%s", ::test_concat_message(__VA_ARGS__).c_str()); } +#else + +// Fallback definition before C++20 that allows using the macro but doesn't provide a very good message. +# define TEST_WRITE_CONCATENATED(...) [&] { ::test_eprintf("%s", TEST_STRINGIZE(__VA_ARGS__)); } + #endif // TEST_STD_VER > 17 #endif // TEST_SUPPORT_CONCAT_MACROS_H diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -23,8 +23,8 @@ #include #endif -#define TEST_STRINGIZE_IMPL(x) #x -#define TEST_STRINGIZE(x) TEST_STRINGIZE_IMPL(x) +#define TEST_STRINGIZE_IMPL(...) #__VA_ARGS__ +#define TEST_STRINGIZE(...) TEST_STRINGIZE_IMPL(__VA_ARGS__) #define TEST_CONCAT1(X, Y) X##Y #define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y)