diff --git a/include/fmt/printf.h b/include/fmt/printf.h index dece20e6..8ed1748f 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -236,12 +236,6 @@ class printf_arg_formatter : public arg_formatter { context_type& context_; - void write_null_pointer(bool is_string = false) { - auto s = this->specs; - s.set_type(presentation_type::none); - write_bytes(this->out, is_string ? "(null)" : "(nil)", s); - } - template void write(T value) { detail::write(this->out, value, this->specs, this->locale); } @@ -292,27 +286,20 @@ class printf_arg_formatter : public arg_formatter { } void operator()(const char* value) { - if (value) - write(value); - else - write_null_pointer(this->specs.type() != presentation_type::pointer); + if (!value && this->specs.type() != presentation_type::pointer) + value = "(null)"; + write(value); } void operator()(const wchar_t* value) { - if (value) - write(value); - else - write_null_pointer(this->specs.type() != presentation_type::pointer); + if (!value && this->specs.type() != presentation_type::pointer) + value = L"(null)"; + write(value); } void operator()(basic_string_view value) { write(value); } - void operator()(const void* value) { - if (value) - write(value); - else - write_null_pointer(); - } + void operator()(const void* value) { write(value); } void operator()(typename basic_format_arg::handle handle) { auto parse_ctx = parse_context({}); @@ -500,9 +487,6 @@ void vprintf(buffer& buf, basic_string_view format, auto sv = basic_string_view( str, to_unsigned(nul != str_end ? nul - str : specs.precision)); arg = sv; - } else if (specs.precision < 6) { - // Like glibc, print "(null)" only if it fits in the precision. - arg = basic_string_view(); } } if (specs.fill_unit() == '0') { diff --git a/test/printf-test.cc b/test/printf-test.cc index 414cd974..341253b0 100644 --- a/test/printf-test.cc +++ b/test/printf-test.cc @@ -544,10 +544,11 @@ TEST(printf_test, string) { const char* null_str = nullptr; EXPECT_PRINTF("(null)", "%s", null_str); EXPECT_PRINTF(" (null)", "%10s", null_str); - // Like glibc, a precision too small for "(null)" gives an empty string. + // A precision truncates "(null)" as it would any other string. EXPECT_PRINTF("", "%.0s", null_str); - EXPECT_PRINTF("", "%.3s", null_str); + EXPECT_PRINTF("(nu", "%.3s", null_str); EXPECT_PRINTF("(null)", "%.6s", null_str); + EXPECT_PRINTF(" (nu", "%10.3s", null_str); } TEST(printf_test, pointer) { @@ -555,12 +556,12 @@ TEST(printf_test, pointer) { void* p = &n; EXPECT_PRINTF(fmt::format("{}", p), "%p", p); p = nullptr; - EXPECT_PRINTF("(nil)", "%p", p); - EXPECT_PRINTF(" (nil)", "%10p", p); + EXPECT_PRINTF("0x0", "%p", p); + EXPECT_PRINTF(" 0x0", "%10p", p); const char* s = "test"; EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); const char* null_str = nullptr; - EXPECT_PRINTF("(nil)", "%p", null_str); + EXPECT_PRINTF("0x0", "%p", null_str); } enum test_enum { answer = 42 };