diff --git a/cppformat/format.cc b/cppformat/format.cc index 4fc7220b..0857965e 100644 --- a/cppformat/format.cc +++ b/cppformat/format.cc @@ -207,10 +207,15 @@ void format_error_code(fmt::Writer &out, int error_code, out.clear(); static const char SEP[] = ": "; static const char ERROR_STR[] = "error "; - fmt::internal::IntTraits::MainType ec_value = error_code; // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; - error_code_size += fmt::internal::count_digits(ec_value); + typedef fmt::internal::IntTraits::MainType MainType; + MainType abs_value = static_cast(error_code); + if (internal::is_negative(error_code)) { + abs_value = 0 - abs_value; + ++error_code_size; + } + error_code_size += fmt::internal::count_digits(abs_value); if (message.size() <= fmt::internal::INLINE_BUFFER_SIZE - error_code_size) out << message << SEP; out << ERROR_STR << error_code; diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index 187dcbdf..9f9cc5dd 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -101,13 +101,21 @@ TEST(FormatTest, FormatErrorCode) { fmt::format_error_code(w, 42, prefix); EXPECT_EQ(msg, w.str()); } - { + int codes[] = {42, -1}; + for (std::size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) { + // Test maximum buffer size. + msg = fmt::format("error {}", codes[i]); fmt::MemoryWriter w; std::string prefix( fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size(), 'x'); - fmt::format_error_code(w, 42, prefix); + fmt::format_error_code(w, codes[i], prefix); EXPECT_EQ(prefix + sep + msg, w.str()); std::size_t size = fmt::internal::INLINE_BUFFER_SIZE; EXPECT_EQ(size, w.size()); + w.clear(); + // Test with a message that doesn't fit into the buffer. + prefix += 'x'; + fmt::format_error_code(w, codes[i], prefix); + EXPECT_EQ(msg, w.str()); } }