Add an option to show / hide filtered frames vs printing a placeholder
This commit is contained in:
parent
d1ce9c8896
commit
eb83ee2a1c
@ -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;
|
||||||
|
|||||||
@ -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,20 +144,24 @@ 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)) {
|
||||||
counter++;
|
if(!options.show_filtered_frames) {
|
||||||
continue;
|
counter++;
|
||||||
}
|
continue;
|
||||||
print_frame_internal(stream, frame, color, frame_number_width, counter);
|
}
|
||||||
if(frame.line.has_value() && !frame.filename.empty() && options.snippets) {
|
print_placeholder_frame(stream, frame_number_width, counter);
|
||||||
auto snippet = detail::get_snippet(
|
} else {
|
||||||
frame.filename,
|
print_frame_internal(stream, frame, color, frame_number_width, counter);
|
||||||
frame.line.value(),
|
if(frame.line.has_value() && !frame.filename.empty() && options.snippets) {
|
||||||
options.context_lines,
|
auto snippet = detail::get_snippet(
|
||||||
color
|
frame.filename,
|
||||||
);
|
frame.line.value(),
|
||||||
if(!snippet.empty()) {
|
options.context_lines,
|
||||||
stream << '\n';
|
color
|
||||||
stream << snippet;
|
);
|
||||||
|
if(!snippet.empty()) {
|
||||||
|
stream << '\n';
|
||||||
|
stream << snippet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(newline_at_end || &frame != &frames.back()) {
|
if(newline_at_end || &frame != &frames.back()) {
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user