File: backtrace.hpp

package info (click to toggle)
rgbds 1.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 20,164 kB
  • sloc: cpp: 19,048; asm: 6,208; yacc: 2,405; sh: 1,784; makefile: 213; ansic: 14
file content (89 lines) | stat: -rw-r--r-- 2,101 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// SPDX-License-Identifier: MIT

#ifndef RGBDS_BACKTRACE_HPP
#define RGBDS_BACKTRACE_HPP

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <vector>

#include "style.hpp"

#define TRACE_SEPARATOR  "<-"
#define NODE_SEPARATOR   "::"
#define REPT_NODE_PREFIX "REPT~"

struct Tracing {
	uint64_t depth = 0;
	bool collapse = false;
	bool loud = false;
};

extern Tracing tracing;

bool trace_ParseTraceDepth(char const *arg);

template<typename NodeT, typename NameFnT, typename LineNoFnT>
void trace_PrintBacktrace(std::vector<NodeT> const &stack, NameFnT getName, LineNoFnT getLineNo) {
	size_t n = stack.size();
	if (n == 0) {
		return; // LCOV_EXCL_LINE
	}

	auto printLocation = [&](size_t i) {
		NodeT const &item = stack[n - i - 1];
		style_Reset(stderr);
		if (!tracing.collapse) {
			fputs("   ", stderr); // Just three spaces; the fourth will be printed next
		}
		fprintf(stderr, " %s ", i == 0 ? "at" : TRACE_SEPARATOR);
		style_Set(stderr, STYLE_CYAN, true);
		fputs(getName(item), stderr);
		style_Set(stderr, STYLE_CYAN, false);
		fprintf(stderr, "(%" PRIu32 ")", getLineNo(item));
		if (!tracing.collapse) {
			putc('\n', stderr);
		}
	};

	if (tracing.collapse) {
		fputs("   ", stderr); // Just three spaces; the fourth will be handled by the loop
	}

	if (tracing.depth == 0 || static_cast<size_t>(tracing.depth) >= n) {
		for (size_t i = 0; i < n; ++i) {
			printLocation(i);
		}
	} else {
		size_t last = tracing.depth / 2;
		size_t first = tracing.depth - last;
		size_t skipped = n - tracing.depth;
		for (size_t i = 0; i < first; ++i) {
			printLocation(i);
		}
		style_Reset(stderr);

		if (tracing.collapse) {
			fputs(" " TRACE_SEPARATOR, stderr);
		} else {
			fputs("   ", stderr); // Just three spaces; the fourth will be printed next
		}
		fprintf(stderr, " ...%zu more%s", skipped, last ? "..." : "");
		if (!tracing.collapse) {
			putc('\n', stderr);
		}

		for (size_t i = n - last; i < n; ++i) {
			printLocation(i);
		}
	}

	if (tracing.collapse) {
		putc('\n', stderr);
	}
	style_Reset(stderr);
}

#endif // RGBDS_BACKTRACE_HPP