Add an option to show / hide filtered frames vs printing a placeholder

This commit is contained in:
Jeremy Rifkin 2025-02-02 16:20:47 -06:00
parent d1ce9c8896
commit eb83ee2a1c
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
3 changed files with 54 additions and 14 deletions

View File

@ -37,6 +37,7 @@ namespace cpptrace {
formatter& set_snippets(bool); formatter& set_snippets(bool);
formatter& set_snippet_context(int); formatter& set_snippet_context(int);
formatter& include_column(bool); formatter& include_column(bool);
formatter& show_filtered_frames(bool);
formatter& set_filter(std::function<bool(const stacktrace_frame&)>); formatter& set_filter(std::function<bool(const stacktrace_frame&)>);
std::string format(const stacktrace_frame&) const; std::string format(const stacktrace_frame&) const;

View File

@ -21,6 +21,7 @@ namespace cpptrace {
bool snippets = false; bool snippets = false;
int context_lines = 2; int context_lines = 2;
bool columns = true; bool columns = true;
bool show_filtered_frames = true;
std::function<bool(const stacktrace_frame&)> filter; std::function<bool(const stacktrace_frame&)> filter;
} options; } options;
@ -43,6 +44,9 @@ namespace cpptrace {
void include_column(bool columns) { void include_column(bool columns) {
options.columns = columns; options.columns = columns;
} }
void show_filtered_frames(bool show) {
options.show_filtered_frames = show;
}
void set_filter(std::function<bool(const stacktrace_frame&)> filter) { void set_filter(std::function<bool(const stacktrace_frame&)> filter) {
options.filter = filter; options.filter = filter;
} }
@ -140,9 +144,12 @@ namespace cpptrace {
const auto frame_number_width = detail::n_digits(static_cast<int>(frames.size()) - 1); const auto frame_number_width = detail::n_digits(static_cast<int>(frames.size()) - 1);
for(const auto& frame : frames) { for(const auto& frame : frames) {
if(options.filter && !options.filter(frame)) { if(options.filter && !options.filter(frame)) {
if(!options.show_filtered_frames) {
counter++; counter++;
continue; continue;
} }
print_placeholder_frame(stream, frame_number_width, counter);
} else {
print_frame_internal(stream, frame, color, frame_number_width, counter); print_frame_internal(stream, frame, color, frame_number_width, counter);
if(frame.line.has_value() && !frame.filename.empty() && options.snippets) { if(frame.line.has_value() && !frame.filename.empty() && options.snippets) {
auto snippet = detail::get_snippet( auto snippet = detail::get_snippet(
@ -156,6 +163,7 @@ namespace cpptrace {
stream << snippet; stream << snippet;
} }
} }
}
if(newline_at_end || &frame != &frames.back()) { if(newline_at_end || &frame != &frames.back()) {
stream << '\n'; stream << '\n';
} }
@ -174,6 +182,11 @@ namespace cpptrace {
stream << line; stream << line;
} }
void print_placeholder_frame(std::ostream& stream, unsigned frame_number_width, std::size_t counter) const {
std::string line = microfmt::format("#{<{}} (filtered)", frame_number_width, counter);
stream << line;
}
void print_frame_internal( void print_frame_internal(
std::ostream& stream, std::ostream& stream,
const stacktrace_frame& frame, const stacktrace_frame& frame,
@ -258,6 +271,10 @@ namespace cpptrace {
pimpl->include_column(columns); pimpl->include_column(columns);
return *this; return *this;
} }
formatter& formatter::show_filtered_frames(bool show) {
pimpl->show_filtered_frames(show);
return *this;
}
formatter& formatter::set_filter(std::function<bool(const stacktrace_frame&)> filter) { formatter& formatter::set_filter(std::function<bool(const stacktrace_frame&)> filter) {
pimpl->set_filter(std::move(filter)); pimpl->set_filter(std::move(filter));
return *this; return *this;

View File

@ -191,6 +191,24 @@ TEST(FormatterTest, Filtering) {
return frame.filename.find("foo.cpp") != std::string::npos; return frame.filename.find("foo.cpp") != std::string::npos;
}); });
auto res = split(formatter.format(make_test_stacktrace()), "\n"); auto res = split(formatter.format(make_test_stacktrace()), "\n");
EXPECT_THAT(
res,
ElementsAre(
"Stack trace (most recent call first):",
"#0 0x0000000000000001 in foo() at foo.cpp:20:30",
"#1 (filtered)",
"#2 0x0000000000000003 in main at foo.cpp:40:25"
)
);
}
TEST(FormatterTest, DontShowFilteredFrames) {
auto formatter = cpptrace::formatter{}
.set_filter([] (const cpptrace::stacktrace_frame& frame) -> bool {
return frame.filename.find("foo.cpp") != std::string::npos;
})
.show_filtered_frames(false);
auto res = split(formatter.format(make_test_stacktrace()), "\n");
EXPECT_THAT( EXPECT_THAT(
res, res,
ElementsAre( ElementsAre(
@ -213,6 +231,7 @@ TEST(FormatterTest, MoveSemantics) {
ElementsAre( ElementsAre(
"Stack trace (most recent call first):", "Stack trace (most recent call first):",
"#0 0x0000000000000001 in foo() at foo.cpp:20:30", "#0 0x0000000000000001 in foo() at foo.cpp:20:30",
"#1 (filtered)",
"#2 0x0000000000000003 in main at foo.cpp:40:25" "#2 0x0000000000000003 in main at foo.cpp:40:25"
) )
); );
@ -224,6 +243,7 @@ TEST(FormatterTest, MoveSemantics) {
ElementsAre( ElementsAre(
"Stack trace (most recent call first):", "Stack trace (most recent call first):",
"#0 0x0000000000000001 in foo() at foo.cpp:20:30", "#0 0x0000000000000001 in foo() at foo.cpp:20:30",
"#1 (filtered)",
"#2 0x0000000000000003 in main at foo.cpp:40:25" "#2 0x0000000000000003 in main at foo.cpp:40:25"
) )
); );
@ -241,6 +261,7 @@ TEST(FormatterTest, CopySemantics) {
ElementsAre( ElementsAre(
"Stack trace (most recent call first):", "Stack trace (most recent call first):",
"#0 0x0000000000000001 in foo() at foo.cpp:20:30", "#0 0x0000000000000001 in foo() at foo.cpp:20:30",
"#1 (filtered)",
"#2 0x0000000000000003 in main at foo.cpp:40:25" "#2 0x0000000000000003 in main at foo.cpp:40:25"
) )
); );
@ -252,6 +273,7 @@ TEST(FormatterTest, CopySemantics) {
ElementsAre( ElementsAre(
"Stack trace (most recent call first):", "Stack trace (most recent call first):",
"#0 0x0000000000000001 in foo() at foo.cpp:20:30", "#0 0x0000000000000001 in foo() at foo.cpp:20:30",
"#1 (filtered)",
"#2 0x0000000000000003 in main at foo.cpp:40:25" "#2 0x0000000000000003 in main at foo.cpp:40:25"
) )
); );