diff --git a/include/fmt/std.h b/include/fmt/std.h index 882e9a86a45e..24bf2c53b6d3 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -77,6 +77,11 @@ inline void write_escaped_path( template struct formatter : formatter> { + template FMT_CONSTEXPR auto parse(ParseContext& ctx) { + auto out = formatter>::parse(ctx); + this->set_debug_format(false); + return out; + } template auto format(const std::filesystem::path& p, FormatContext& ctx) const -> typename FormatContext::iterator { diff --git a/test/std-test.cc b/test/std-test.cc index 39aac5a2fc65..d12dbf5d2cdd 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -21,6 +21,8 @@ TEST(std_test, path) { EXPECT_EQ(fmt::format("{:8}", std::filesystem::path("foo")), "\"foo\" "); EXPECT_EQ(fmt::format("{}", std::filesystem::path("foo\"bar.txt")), "\"foo\\\"bar.txt\""); + EXPECT_EQ(fmt::format("{:?}", std::filesystem::path("foo\"bar.txt")), + "\"foo\\\"bar.txt\""); # ifdef _WIN32 // File.txt in Russian. @@ -46,6 +48,21 @@ TEST(ranges_std_test, format_vector_path) { #endif } +TEST(ranges_std_test, format_quote_path) { + // Test that path is not escaped twice in the debug mode. +#ifdef __cpp_lib_filesystem + auto vec = + std::vector{"path1/file1.txt", "path2/file2.txt"}; + EXPECT_EQ(fmt::format("{}", vec), + "[\"path1/file1.txt\", \"path2/file2.txt\"]"); +# ifdef __cpp_lib_optional + auto o = std::optional("path/file.txt"); + EXPECT_EQ(fmt::format("{}", o), "optional(\"path/file.txt\")"); + EXPECT_EQ(fmt::format("{:?}", o), "optional(\"path/file.txt\")"); +# endif +#endif +} + TEST(std_test, thread_id) { EXPECT_FALSE(fmt::format("{}", std::this_thread::get_id()).empty()); }