Skip to content

Commit be59265

Browse files
committed
Add carrots to snippet printing in case colors aren't used, also use column information. Resolves #273.
1 parent 4e17e27 commit be59265

File tree

8 files changed

+80
-14
lines changed

8 files changed

+80
-14
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,14 @@ namespace cpptrace {
342342
bool color = false
343343
);
344344
345+
std::string get_snippet(
346+
const std::string& path,
347+
std::size_t line,
348+
nullable<std::uint32_t> column,
349+
std::size_t context_size,
350+
bool color = false
351+
);
352+
345353
bool isatty(int fd);
346354
347355
extern const int stdin_fileno;

include/cpptrace/utils.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ CPPTRACE_BEGIN_NAMESPACE
2727
bool color = false
2828
);
2929

30+
CPPTRACE_EXPORT std::string get_snippet(
31+
const std::string& path,
32+
std::size_t line,
33+
nullable<std::uint32_t> column,
34+
std::size_t context_size,
35+
bool color = false
36+
);
37+
3038
CPPTRACE_EXPORT bool isatty(int fd);
3139

3240
CPPTRACE_EXPORT extern const int stdin_fileno;

src/formatting.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ CPPTRACE_BEGIN_NAMESPACE
263263
auto snippet = detail::get_snippet(
264264
frame.filename,
265265
frame.line.value(),
266+
frame.column,
266267
options.context_lines,
267268
color
268269
);

src/snippets/snippet.cpp

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,13 @@ namespace detail {
104104
constexpr std::size_t margin_width = 8;
105105

106106
// 1-indexed line
107-
std::string get_snippet(const std::string& path, std::size_t target_line, std::size_t context_size, bool color) {
107+
std::string get_snippet(
108+
const std::string& path,
109+
std::size_t target_line,
110+
nullable<std::uint32_t> column,
111+
std::size_t context_size,
112+
bool color
113+
) {
108114
const auto& manager = get_manager(path);
109115
if(!manager.ok()) {
110116
return "";
@@ -126,15 +132,35 @@ namespace detail {
126132
// make the snippet
127133
std::string snippet;
128134
for(auto line = begin; line <= end; line++) {
129-
if(color && line == target_line) {
130-
snippet += YELLOW;
131-
}
132135
auto line_str = std::to_string(line);
133-
snippet += microfmt::format("{>{}}: ", margin_width, line_str);
134-
if(color && line == target_line) {
135-
snippet += RESET;
136+
if(line == target_line) {
137+
if(color) {
138+
snippet += YELLOW;
139+
}
140+
auto line_width = line_str.size() + 3;
141+
snippet += microfmt::format(
142+
"{>{}} > {}: ",
143+
line_width > margin_width ? 0 : margin_width - line_width,
144+
"",
145+
line_str
146+
);
147+
if(color) {
148+
snippet += RESET;
149+
}
150+
} else {
151+
snippet += microfmt::format("{>{}}: ", margin_width, line_str);
136152
}
137153
snippet += lines[line - original_begin];
154+
if(line == target_line && column.has_value()) {
155+
snippet += microfmt::format("\n{>{}}", margin_width + 2 + column.value() - 1, "");
156+
if(color) {
157+
snippet += YELLOW;
158+
}
159+
snippet += "^";
160+
if(color) {
161+
snippet += RESET;
162+
}
163+
}
138164
if(line != end) {
139165
snippet += '\n';
140166
}

src/snippets/snippet.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@
44
#include <cstddef>
55
#include <string>
66

7-
#include <cpptrace/forward.hpp>
7+
#include <cpptrace/basic.hpp>
88

99
CPPTRACE_BEGIN_NAMESPACE
1010
namespace detail {
1111
// 1-indexed line
12-
std::string get_snippet(const std::string& path, std::size_t line, std::size_t context_size, bool color);
12+
std::string get_snippet(
13+
const std::string& path,
14+
std::size_t line,
15+
nullable<std::uint32_t> column,
16+
std::size_t context_size,
17+
bool color
18+
);
1319
}
1420
CPPTRACE_END_NAMESPACE
1521

src/utils.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ CPPTRACE_BEGIN_NAMESPACE
2020
}
2121

2222
std::string get_snippet(const std::string& path, std::size_t line, std::size_t context_size, bool color) {
23-
return detail::get_snippet(path, line, context_size, color);
23+
return detail::get_snippet(path, line, nullable<std::uint32_t>::null(), context_size, color);
24+
}
25+
26+
std::string get_snippet(
27+
const std::string& path,
28+
std::size_t line,
29+
nullable<std::uint32_t> column,
30+
std::size_t context_size,
31+
bool color
32+
) {
33+
return detail::get_snippet(path, line, column, context_size, color);
2434
}
2535

2636
bool isatty(int fd) {

test/link_test.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ int main() {
6868

6969
cpptrace::demangle("test");
7070
cpptrace::get_snippet(__FILE__, 1, 1);
71+
cpptrace::get_snippet(__FILE__, 1, 1, false);
72+
cpptrace::get_snippet(__FILE__, 1, 1, 1);
73+
cpptrace::get_snippet(__FILE__, 1, 1, 1, false);
7174
cpptrace::isatty(cpptrace::stderr_fileno);
7275

7376
cpptrace::register_terminate_handler();

test/unit/lib/formatting.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,10 @@ TEST(FormatterTest, Snippets) {
286286
cpptrace::microfmt::format(" {}: cpptrace::stacktrace trace;", line - 2),
287287
cpptrace::microfmt::format(" {}: unsigned line = __LINE__ + 1;", line - 1),
288288
cpptrace::microfmt::format(
289-
" {}: trace.frames.push_back({0x1, 0x1001, {line}, {{20}}, __FILE__, \"foo()\", false});",
289+
" > {}: trace.frames.push_back({0x1, 0x1001, {line}, {{20}}, __FILE__, \"foo()\", false});",
290290
line
291291
),
292+
cpptrace::microfmt::format(" ^"),
292293
cpptrace::microfmt::format(
293294
" {}: trace.frames.push_back({0x2, 0x1002, {line + 1}, {{20}}, __FILE__, \"foo()\", false});",
294295
line + 1
@@ -302,9 +303,10 @@ TEST(FormatterTest, Snippets) {
302303
line
303304
),
304305
cpptrace::microfmt::format(
305-
" {}: trace.frames.push_back({0x2, 0x1002, {line + 1}, {{20}}, __FILE__, \"foo()\", false});",
306+
" > {}: trace.frames.push_back({0x2, 0x1002, {line + 1}, {{20}}, __FILE__, \"foo()\", false});",
306307
line + 1
307308
),
309+
cpptrace::microfmt::format(" ^"),
308310
cpptrace::microfmt::format(" {}: auto formatter = cpptrace::formatter{{}}", line + 2),
309311
cpptrace::microfmt::format(" {}: .snippets(true);", line + 3)
310312
)
@@ -319,9 +321,10 @@ TEST(FormatterTest, Snippets) {
319321
cpptrace::microfmt::format("#0 0x" ADDR_PREFIX "00000001 in foo() at {}:{}:20", __FILE__, line),
320322
cpptrace::microfmt::format(" {}: unsigned line = __LINE__ + 1;", line - 1),
321323
cpptrace::microfmt::format(
322-
" {}: trace.frames.push_back({0x1, 0x1001, {line}, {{20}}, __FILE__, \"foo()\", false});",
324+
" > {}: trace.frames.push_back({0x1, 0x1001, {line}, {{20}}, __FILE__, \"foo()\", false});",
323325
line
324326
),
327+
cpptrace::microfmt::format(" ^"),
325328
cpptrace::microfmt::format(
326329
" {}: trace.frames.push_back({0x2, 0x1002, {line + 1}, {{20}}, __FILE__, \"foo()\", false});",
327330
line + 1
@@ -333,9 +336,10 @@ TEST(FormatterTest, Snippets) {
333336
line
334337
),
335338
cpptrace::microfmt::format(
336-
" {}: trace.frames.push_back({0x2, 0x1002, {line + 1}, {{20}}, __FILE__, \"foo()\", false});",
339+
" > {}: trace.frames.push_back({0x2, 0x1002, {line + 1}, {{20}}, __FILE__, \"foo()\", false});",
337340
line + 1
338341
),
342+
cpptrace::microfmt::format(" ^"),
339343
cpptrace::microfmt::format(" {}: auto formatter = cpptrace::formatter{{}}", line + 2)
340344
)
341345
);

0 commit comments

Comments
 (0)