Commit cee35f7d authored by gabime's avatar gabime

Added truncate flag (issue #1297)

parent 1f5f1762
......@@ -39,47 +39,50 @@ public:
: padinfo_(padinfo)
, dest_(dest)
{
if (padinfo_.width_ <= wrapped_size)
remaining_pad_ = static_cast<long>(padinfo.width_) - static_cast<long>(wrapped_size);
if (remaining_pad_ <= 0)
{
total_pad_ = 0;
return;
}
total_pad_ = padinfo.width_ - wrapped_size;
if (padinfo_.side_ == padding_info::left)
{
pad_it(total_pad_);
total_pad_ = 0;
pad_it(remaining_pad_);
remaining_pad_ = 0;
}
else if (padinfo_.side_ == padding_info::center)
{
auto half_pad = total_pad_ / 2;
auto reminder = total_pad_ & 1;
auto half_pad = remaining_pad_ / 2;
auto reminder = remaining_pad_ & 1;
pad_it(half_pad);
total_pad_ = half_pad + reminder; // for the right side
remaining_pad_ = half_pad + reminder; // for the right side
}
}
~scoped_padder()
{
if (total_pad_)
if (remaining_pad_ >= 0)
{
pad_it(remaining_pad_);
}
else if (padinfo_.truncate_)
{
pad_it(total_pad_);
long new_size = static_cast<long>(dest_.size()) + remaining_pad_;
dest_.resize(static_cast<size_t>(new_size));
}
}
private:
void pad_it(size_t count)
void pad_it(long count)
{
// count = std::min(count, spaces_.size());
assert(count <= spaces_.size());
// assert(count <= spaces_.size());
fmt_helper::append_string_view(string_view_t(spaces_.data(), count), dest_);
}
const padding_info &padinfo_;
memory_buf_t &dest_;
size_t total_pad_;
long remaining_pad_;
string_view_t spaces_{" ", 64};
};
......@@ -1209,7 +1212,7 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i
}
}
// Extract given pad spec (e.g. %8X)
// Extract given pad spec (e.g. %8X, %=8X, %-8!X, %8!X, %=8!X, %-8!X, %+8!X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end)
......@@ -1240,7 +1243,7 @@ SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::stri
if (it == end || !std::isdigit(static_cast<unsigned char>(*it)))
{
return padding_info{0, side};
return padding_info{}; // no padding if no digit found here
}
auto width = static_cast<size_t>(*it) - '0';
......@@ -1249,7 +1252,20 @@ SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::stri
auto digit = static_cast<size_t>(*it) - '0';
width = width * 10 + digit;
}
return details::padding_info{std::min<size_t>(width, max_width), side};
// search for the optional truncate marker '!'
bool truncate;
if (it != end && *it == '!')
{
truncate = true;
++it;
}
else
{
truncate = false;
}
return details::padding_info{std::min<size_t>(width, max_width), side, truncate};
}
SPDLOG_INLINE void pattern_formatter::compile_pattern_(const std::string &pattern)
......
......@@ -29,17 +29,21 @@ struct padding_info
};
padding_info() = default;
padding_info(size_t width, padding_info::pad_side side)
padding_info(size_t width, padding_info::pad_side side, bool truncate)
: width_(width)
, side_(side)
, truncate_(truncate)
, enabled_(true)
{}
bool enabled() const
{
return width_ != 0;
return enabled_;
}
const size_t width_ = 0;
const pad_side side_ = left;
bool truncate_ = false;
bool enabled_ = false;
};
class flag_formatter
......
#include "includes.h"
#include "test_sink.h"
using spdlog::memory_buf_t;
......@@ -138,58 +139,111 @@ TEST_CASE("color range test6", "[pattern_formatter]")
TEST_CASE("level_left_padded", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%8l] %v", spdlog::pattern_time_type::local, "\n") == "[ info] Some message\n");
REQUIRE(log_to_str("Some message", "[%8!l] %v", spdlog::pattern_time_type::local, "\n") == "[ info] Some message\n");
}
TEST_CASE("level_right_padded", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%-8l] %v", spdlog::pattern_time_type::local, "\n") == "[info ] Some message\n");
REQUIRE(log_to_str("Some message", "[%-8!l] %v", spdlog::pattern_time_type::local, "\n") == "[info ] Some message\n");
}
TEST_CASE("level_center_padded", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%=8l] %v", spdlog::pattern_time_type::local, "\n") == "[ info ] Some message\n");
REQUIRE(log_to_str("Some message", "[%=8!l] %v", spdlog::pattern_time_type::local, "\n") == "[ info ] Some message\n");
}
TEST_CASE("short level_left_padded", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%3L] %v", spdlog::pattern_time_type::local, "\n") == "[ I] Some message\n");
REQUIRE(log_to_str("Some message", "[%3!L] %v", spdlog::pattern_time_type::local, "\n") == "[ I] Some message\n");
}
TEST_CASE("short level_right_padded", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%-3L] %v", spdlog::pattern_time_type::local, "\n") == "[I ] Some message\n");
REQUIRE(log_to_str("Some message", "[%-3!L] %v", spdlog::pattern_time_type::local, "\n") == "[I ] Some message\n");
}
TEST_CASE("short level_center_padded", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%=3L] %v", spdlog::pattern_time_type::local, "\n") == "[ I ] Some message\n");
REQUIRE(log_to_str("Some message", "[%=3!L] %v", spdlog::pattern_time_type::local, "\n") == "[ I ] Some message\n");
}
TEST_CASE("left_padded_short", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
REQUIRE(log_to_str("Some message", "[%3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n");
}
TEST_CASE("right_padded_short", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%-3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
REQUIRE(log_to_str("Some message", "[%-3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n");
}
TEST_CASE("center_padded_short", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%=3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n");
REQUIRE(log_to_str("Some message", "[%=3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n");
}
TEST_CASE("left_padded_huge", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%-300n] %v", spdlog::pattern_time_type::local, "\n") ==
"[pattern_tester ] Some message\n");
REQUIRE(log_to_str("Some message", "[%-300!n] %v", spdlog::pattern_time_type::local, "\n") ==
"[pattern_tester ] Some message\n");
}
TEST_CASE("left_padded_max", "[pattern_formatter]")
{
REQUIRE(log_to_str("Some message", "[%-64n] %v", spdlog::pattern_time_type::local, "\n") ==
"[pattern_tester ] Some message\n");
REQUIRE(log_to_str("Some message", "[%-64!n] %v", spdlog::pattern_time_type::local, "\n") ==
"[pattern_tester ] Some message\n");
}
// Test padding + truncate flag
TEST_CASE("paddinng_truncate", "[pattern_formatter]")
{
REQUIRE(log_to_str("123456", "%6!v", spdlog::pattern_time_type::local, "\n") == "123456\n");
REQUIRE(log_to_str("123456", "%5!v", spdlog::pattern_time_type::local, "\n") == "12345\n");
REQUIRE(log_to_str("123456", "%7!v", spdlog::pattern_time_type::local, "\n") == " 123456\n");
REQUIRE(log_to_str("123456", "%-6!v", spdlog::pattern_time_type::local, "\n") == "123456\n");
REQUIRE(log_to_str("123456", "%-5!v", spdlog::pattern_time_type::local, "\n") == "12345\n");
REQUIRE(log_to_str("123456", "%-7!v", spdlog::pattern_time_type::local, "\n") == "123456 \n");
REQUIRE(log_to_str("123456", "%=6!v", spdlog::pattern_time_type::local, "\n") == "123456\n");
REQUIRE(log_to_str("123456", "%=5!v", spdlog::pattern_time_type::local, "\n") == "12345\n");
REQUIRE(log_to_str("123456", "%=7!v", spdlog::pattern_time_type::local, "\n") == "123456 \n");
REQUIRE(log_to_str("123456", "%0!v", spdlog::pattern_time_type::local, "\n") == "\n");
}
TEST_CASE("paddinng_truncate_funcname", "[pattern_formatter]")
{
spdlog::sinks::test_sink_st test_sink;
const char* pattern = "%v [%5!!]";
auto formatter = std::unique_ptr<spdlog::formatter>(new spdlog::pattern_formatter(pattern));
test_sink.set_formatter(std::move(formatter));
spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"};
test_sink.log(msg1);
spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "function"}, "test_logger", spdlog::level::info, "message"};
test_sink.log(msg2);
auto lines = test_sink.lines();
REQUIRE(lines[0] == "message [ func]");
REQUIRE(lines[1] == "message [funct]");
}
TEST_CASE("clone-default-formatter", "[pattern_formatter]")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment