@@ -64,6 +64,7 @@ CPPTRACE_BEGIN_NAMESPACE
64
64
address_mode addresses = address_mode::raw;
65
65
path_mode paths = path_mode::full;
66
66
bool snippets = false ;
67
+ bool break_before_filename = false ;
67
68
int context_lines = 2 ;
68
69
bool columns = true ;
69
70
symbol_mode symbols = symbol_mode::full;
@@ -106,13 +107,17 @@ CPPTRACE_BEGIN_NAMESPACE
106
107
void transform (std::function<stacktrace_frame(stacktrace_frame)> transform) {
107
108
options.transform = std::move (transform);
108
109
}
110
+ void break_before_filename (bool do_break) {
111
+ options.break_before_filename = do_break;
112
+ }
109
113
110
114
std::string format (
111
115
const stacktrace_frame& frame,
112
- detail::optional<bool > color_override = detail::nullopt
116
+ detail::optional<bool > color_override = detail::nullopt,
117
+ size_t filename_indent = 0
113
118
) const {
114
119
std::ostringstream oss;
115
- print_internal (oss, frame, color_override.value_or (options.color == color_mode::always));
120
+ print_internal (oss, frame, color_override.value_or (options.color == color_mode::always), filename_indent );
116
121
return std::move (oss).str ();
117
122
}
118
123
@@ -128,17 +133,19 @@ CPPTRACE_BEGIN_NAMESPACE
128
133
void print (
129
134
std::ostream& stream,
130
135
const stacktrace_frame& frame,
131
- detail::optional<bool > color_override = detail::nullopt
136
+ detail::optional<bool > color_override = detail::nullopt,
137
+ size_t filename_indent = 0
132
138
) const {
133
- print_internal (stream, frame, color_override);
139
+ print_internal (stream, frame, color_override, filename_indent );
134
140
stream << " \n " ;
135
141
}
136
142
void print (
137
143
std::FILE* file,
138
144
const stacktrace_frame& frame,
139
- detail::optional<bool > color_override = detail::nullopt
145
+ detail::optional<bool > color_override = detail::nullopt,
146
+ size_t filename_indent = 0
140
147
) const {
141
- auto str = format (frame, color_override);
148
+ auto str = format (frame, color_override, filename_indent );
142
149
str += " \n " ;
143
150
std::fwrite (str.data (), 1 , str.size (), file);
144
151
}
@@ -206,15 +213,15 @@ CPPTRACE_BEGIN_NAMESPACE
206
213
return do_color;
207
214
}
208
215
209
- void print_internal (std::ostream& stream, const stacktrace_frame& input_frame, detail::optional<bool > color_override) const {
216
+ void print_internal (std::ostream& stream, const stacktrace_frame& input_frame, detail::optional<bool > color_override, size_t col_indent ) const {
210
217
bool color = should_do_color (stream, color_override);
211
218
maybe_ensure_virtual_terminal_processing (stream, color);
212
219
detail::optional<stacktrace_frame> transformed_frame;
213
220
if (options.transform ) {
214
221
transformed_frame = options.transform (input_frame);
215
222
}
216
223
const stacktrace_frame& frame = options.transform ? transformed_frame.unwrap () : input_frame;
217
- write_frame (stream, frame, color);
224
+ write_frame (stream, frame, color, col_indent );
218
225
}
219
226
220
227
void print_internal (std::ostream& stream, const stacktrace& trace, detail::optional<bool > color_override) const {
@@ -223,6 +230,7 @@ CPPTRACE_BEGIN_NAMESPACE
223
230
write_trace (stream, trace, color);
224
231
}
225
232
233
+
226
234
void write_trace (std::ostream& stream, const stacktrace& trace, bool color) const {
227
235
if (!options.header .empty ()) {
228
236
stream << options.header << ' \n ' ;
@@ -245,11 +253,12 @@ CPPTRACE_BEGIN_NAMESPACE
245
253
counter++;
246
254
continue ;
247
255
}
248
- microfmt::print (stream, " #{<{}} " , frame_number_width, counter);
256
+
257
+ size_t filename_indent = write_frame_number (stream, frame_number_width, counter);
249
258
if (filter_out_frame) {
250
259
microfmt::print (stream, " (filtered)" );
251
260
} else {
252
- write_frame (stream, frame, color);
261
+ write_frame (stream, frame, color, filename_indent );
253
262
if (frame.line .has_value () && !frame.filename .empty () && options.snippets ) {
254
263
auto snippet = detail::get_snippet (
255
264
frame.filename ,
@@ -270,29 +279,45 @@ CPPTRACE_BEGIN_NAMESPACE
270
279
}
271
280
}
272
281
273
- void write_frame (std::ostream& stream, const stacktrace_frame& frame, color_setting color) const {
274
- write_address (stream, frame, color);
282
+ // / Write the frame number, and return the number of characters written
283
+ size_t write_frame_number (std::ostream& stream, unsigned int frame_number_width, size_t counter) const
284
+ {
285
+ microfmt::print (stream, " #{<{}} " , frame_number_width, counter);
286
+ return 2 + frame_number_width;
287
+ }
288
+
289
+ void write_frame (std::ostream& stream, const stacktrace_frame& frame, color_setting color, size_t col) const {
290
+ col += write_address (stream, frame, color);
275
291
if (frame.is_inline || options.addresses != address_mode::none) {
276
292
stream << ' ' ;
293
+ col += 1 ;
277
294
}
278
295
if (!frame.symbol .empty ()) {
279
296
write_symbol (stream, frame, color);
280
297
}
281
298
if (!frame.symbol .empty () && !frame.filename .empty ()) {
282
- stream << ' ' ;
299
+ if (options.break_before_filename ) {
300
+ microfmt::print (stream, " \n {<{}}" , col, " " );
301
+ } else {
302
+ stream << ' ' ;
303
+ }
283
304
}
284
305
if (!frame.filename .empty ()) {
285
306
write_source_location (stream, frame, color);
286
307
}
287
308
}
288
309
289
- void write_address (std::ostream& stream, const stacktrace_frame& frame, color_setting color) const {
310
+ // / Write the address of the frame, return the number of characters written
311
+ size_t write_address (std::ostream& stream, const stacktrace_frame& frame, color_setting color) const {
290
312
if (frame.is_inline ) {
291
313
microfmt::print (stream, " {<{}}" , 2 * sizeof (frame_ptr) + 2 , " (inlined)" );
314
+ return 2 * sizeof (frame_ptr) + 2 ;
292
315
} else if (options.addresses != address_mode::none) {
293
316
auto address = options.addresses == address_mode::raw ? frame.raw_address : frame.object_address ;
294
317
microfmt::print (stream, " {}0x{>{}:0h}{}" , color.blue (), 2 * sizeof (frame_ptr), address, color.reset ());
318
+ return 2 * sizeof (frame_ptr) + 2 ;
295
319
}
320
+ return 0 ;
296
321
}
297
322
298
323
void write_symbol (std::ostream& stream, const stacktrace_frame& frame, color_setting color) const {
@@ -399,13 +424,20 @@ CPPTRACE_BEGIN_NAMESPACE
399
424
pimpl->transform (std::move (transform));
400
425
return *this ;
401
426
}
427
+ formatter& formatter::break_before_filename (bool do_break) {
428
+ pimpl->break_before_filename (do_break);
429
+ return *this ;
430
+ }
402
431
403
432
std::string formatter::format (const stacktrace_frame& frame) const {
404
433
return pimpl->format (frame);
405
434
}
406
435
std::string formatter::format (const stacktrace_frame& frame, bool color) const {
407
436
return pimpl->format (frame, color);
408
437
}
438
+ std::string formatter::format (const stacktrace_frame& frame, bool color, size_t filename_indent) const {
439
+ return pimpl->format (frame, color, filename_indent);
440
+ }
409
441
410
442
std::string formatter::format (const stacktrace& trace) const {
411
443
return pimpl->format (trace);
@@ -445,12 +477,18 @@ CPPTRACE_BEGIN_NAMESPACE
445
477
void formatter::print (std::ostream& stream, const stacktrace_frame& frame, bool color) const {
446
478
pimpl->print (stream, frame, color);
447
479
}
480
+ void formatter::print (std::ostream& stream, const stacktrace_frame& frame, bool color, size_t filename_indent) const {
481
+ pimpl->print (stream, frame, color, filename_indent);
482
+ }
448
483
void formatter::print (std::FILE* file, const stacktrace_frame& frame) const {
449
484
pimpl->print (file, frame);
450
485
}
451
486
void formatter::print (std::FILE* file, const stacktrace_frame& frame, bool color) const {
452
487
pimpl->print (file, frame, color);
453
488
}
489
+ void formatter::print (std::FILE* file, const stacktrace_frame& frame, bool color, size_t filename_indent) const {
490
+ pimpl->print (file, frame, color, filename_indent);
491
+ }
454
492
455
493
const formatter& get_default_formatter () {
456
494
static formatter formatter;
0 commit comments