Add basic option for shortening paths in the formatter
This commit is contained in:
parent
000168b93c
commit
ce97e0004d
@ -34,6 +34,13 @@ namespace cpptrace {
|
|||||||
none,
|
none,
|
||||||
};
|
};
|
||||||
formatter& addresses(address_mode);
|
formatter& addresses(address_mode);
|
||||||
|
enum class path_mode {
|
||||||
|
// full path is used
|
||||||
|
full,
|
||||||
|
// only the file name is used
|
||||||
|
basename,
|
||||||
|
};
|
||||||
|
formatter& paths(path_mode);
|
||||||
formatter& snippets(bool);
|
formatter& snippets(bool);
|
||||||
formatter& snippet_context(int);
|
formatter& snippet_context(int);
|
||||||
formatter& columns(bool);
|
formatter& columns(bool);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ namespace cpptrace {
|
|||||||
std::string header = "Stack trace (most recent call first):";
|
std::string header = "Stack trace (most recent call first):";
|
||||||
color_mode color = color_mode::automatic;
|
color_mode color = color_mode::automatic;
|
||||||
address_mode addresses = address_mode::raw;
|
address_mode addresses = address_mode::raw;
|
||||||
|
path_mode paths = path_mode::full;
|
||||||
bool snippets = false;
|
bool snippets = false;
|
||||||
int context_lines = 2;
|
int context_lines = 2;
|
||||||
bool columns = true;
|
bool columns = true;
|
||||||
@ -35,6 +36,9 @@ namespace cpptrace {
|
|||||||
void addresses(formatter::address_mode mode) {
|
void addresses(formatter::address_mode mode) {
|
||||||
options.addresses = mode;
|
options.addresses = mode;
|
||||||
}
|
}
|
||||||
|
void paths(path_mode mode) {
|
||||||
|
options.paths = mode;
|
||||||
|
}
|
||||||
void snippets(bool snippets) {
|
void snippets(bool snippets) {
|
||||||
options.snippets = snippets;
|
options.snippets = snippets;
|
||||||
}
|
}
|
||||||
@ -213,7 +217,13 @@ namespace cpptrace {
|
|||||||
microfmt::print(stream, " in {}{}{}", yellow, frame.symbol, reset);
|
microfmt::print(stream, " in {}{}{}", yellow, frame.symbol, reset);
|
||||||
}
|
}
|
||||||
if(!frame.filename.empty()) {
|
if(!frame.filename.empty()) {
|
||||||
microfmt::print(stream, " at {}{}{}", green, frame.filename, reset);
|
microfmt::print(
|
||||||
|
stream,
|
||||||
|
" at {}{}{}",
|
||||||
|
green,
|
||||||
|
options.paths == path_mode::full ? frame.filename : detail::basename(frame.filename, true),
|
||||||
|
reset
|
||||||
|
);
|
||||||
if(frame.line.has_value()) {
|
if(frame.line.has_value()) {
|
||||||
microfmt::print(stream, ":{}{}{}", blue, frame.line.value(), reset);
|
microfmt::print(stream, ":{}{}{}", blue, frame.line.value(), reset);
|
||||||
if(frame.column.has_value() && options.columns) {
|
if(frame.column.has_value() && options.columns) {
|
||||||
@ -258,6 +268,10 @@ namespace cpptrace {
|
|||||||
pimpl->addresses(mode);
|
pimpl->addresses(mode);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
formatter& formatter::paths(path_mode mode) {
|
||||||
|
pimpl->paths(mode);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
formatter& formatter::snippets(bool snippets) {
|
formatter& formatter::snippets(bool snippets) {
|
||||||
pimpl->snippets(snippets);
|
pimpl->snippets(snippets);
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@ -162,9 +162,9 @@ namespace detail {
|
|||||||
// shamelessly stolen from stackoverflow
|
// shamelessly stolen from stackoverflow
|
||||||
bool directory_exists(const std::string& path);
|
bool directory_exists(const std::string& path);
|
||||||
|
|
||||||
inline std::string basename(const std::string& path) {
|
inline std::string basename(const std::string& path, bool maybe_windows = false) {
|
||||||
// Assumes no trailing /'s
|
// Assumes no trailing /'s
|
||||||
auto pos = path.rfind('/');
|
auto pos = path.find_last_of(maybe_windows ? "/\\" : "/");
|
||||||
if(pos == std::string::npos) {
|
if(pos == std::string::npos) {
|
||||||
return path;
|
return path;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -96,6 +96,27 @@ TEST(FormatterTest, ObjectAddresses) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatterTest, PathShortening) {
|
||||||
|
cpptrace::stacktrace trace;
|
||||||
|
trace.frames.push_back({0x1, 0x1001, {20}, {30}, "/home/foo/foo.cpp", "foo()", false});
|
||||||
|
trace.frames.push_back({0x2, 0x1002, {30}, {40}, "/bar.cpp", "bar()", false});
|
||||||
|
trace.frames.push_back({0x3, 0x1003, {40}, {25}, "baz/foo.cpp", "main", false});
|
||||||
|
trace.frames.push_back({0x3, 0x1003, {50}, {25}, "C:\\foo\\bar\\baz.cpp", "main", false});
|
||||||
|
auto formatter = cpptrace::formatter{}
|
||||||
|
.paths(cpptrace::formatter::path_mode::basename);
|
||||||
|
auto res = split(formatter.format(trace), "\n");
|
||||||
|
EXPECT_THAT(
|
||||||
|
res,
|
||||||
|
ElementsAre(
|
||||||
|
"Stack trace (most recent call first):",
|
||||||
|
"#0 0x0000000000000001 in foo() at foo.cpp:20:30",
|
||||||
|
"#1 0x0000000000000002 in bar() at bar.cpp:30:40",
|
||||||
|
"#2 0x0000000000000003 in main at foo.cpp:40:25",
|
||||||
|
"#3 0x0000000000000003 in main at baz.cpp:50:25"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CPPTRACE_NO_TEST_SNIPPETS
|
#ifndef CPPTRACE_NO_TEST_SNIPPETS
|
||||||
TEST(FormatterTest, Snippets) {
|
TEST(FormatterTest, Snippets) {
|
||||||
cpptrace::stacktrace trace;
|
cpptrace::stacktrace trace;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user