OpenTTD Source: src/misc/dbg_helpers.h Source File

OpenTTD Source 1.11.0-RC1

dbg_helpers.h
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #ifndef DBG_HELPERS_H
11 #define DBG_HELPERS_H
12
13 #include <map>
14 #include <stack>
15
16 #include "str.hpp"
17
18 #include "../direction_type.h"
19 #include "../signal_type.h"
20 #include "../tile_type.h"
21 #include "../track_type.h"
22
24 template <typename T> struct ArrayT;
25
27 template <typename T, size_t N> struct ArrayT<T[N]> {
28 static const size_t length = N;
29 typedef T item_t;
30 };
31
32
37 template <typename E, typename T>
38 inline typename ArrayT<T>::item_t ItemAtT(E idx, const T &t, typename ArrayT<T>::item_t t_unk)
39 {
40 if ((size_t)idx >= ArrayT<T>::length) {
41 return t_unk;
42 }
43 return t[idx];
44 }
45
51 template <typename E, typename T>
52 inline typename ArrayT<T>::item_t ItemAtT(E idx, const T &t, typename ArrayT<T>::item_t t_unk, E idx_inv, typename ArrayT<T>::item_t t_inv)
53 {
54 if ((size_t)idx < ArrayT<T>::length) {
55 return t[idx];
56 }
57 if (idx == idx_inv) {
58 return t_inv;
59 }
60 return t_unk;
61 }
62
69 template <typename E, typename T>
70 inline CStrA ComposeNameT(E value, T &t, const char *t_unk, E val_inv, const char *name_inv)
71 {
72 CStrA out;
73 if (value == val_inv) {
74 out = name_inv;
75 } else if (value == 0) {
76 out = "<none>";
77 } else {
78 for (size_t i = 0; i < ArrayT<T>::length; i++) {
79 if ((value & (1 << i)) == 0) continue;
80 out.AddFormat("%s%s", (out.Size() > 0 ? "+" : ""), (const char*)t[i]);
81 value &= ~(E)(1 << i);
82 }
83 if (value != 0) out.AddFormat("%s%s", (out.Size() > 0 ? "+" : ""), t_unk);
84 }
85 return out.Transfer();
86 }
87
88 CStrA ValueStr(Trackdir td);
89 CStrA ValueStr(TrackdirBits td_bits);
90 CStrA ValueStr(DiagDirection dd);
91 CStrA ValueStr(SignalType t);
92
94 struct DumpTarget {
95
97 struct KnownStructKey {
98 size_t m_type_id;
99 const void *m_ptr;
100
101 KnownStructKey(size_t type_id, const void *ptr)
102 : m_type_id(type_id)
103 , m_ptr(ptr)
104 {}
105
106 KnownStructKey(const KnownStructKey &src)
107 {
108 m_type_id = src.m_type_id;
109 m_ptr = src.m_ptr;
110 }
111
112 bool operator<(const KnownStructKey &other) const
113 {
114 if ((size_t)m_ptr < (size_t)other.m_ptr) return true;
115 if ((size_t)m_ptr > (size_t)other.m_ptr) return false;
116 if (m_type_id < other.m_type_id) return true;
117 return false;
118 }
119 };
120
121 typedef std::map<KnownStructKey, CStrA> KNOWN_NAMES;
122
123 CStrA m_out;
124 int m_indent;
125 std::stack<CStrA> m_cur_struct;
126 KNOWN_NAMES m_known_names;
127
128 DumpTarget()
129 : m_indent(0)
130 {}
131
132 static size_t& LastTypeId();
133 CStrA GetCurrentStructName();
134 bool FindKnownName(size_t type_id, const void *ptr, CStrA &name);
135
136 void WriteIndent();
137
138 void CDECL WriteLine(const char *format, ...) WARN_FORMAT(2, 3);
139 void WriteValue(const char *name, const char *value_str);
140 void WriteTile(const char *name, TileIndex t);
141
143 template <typename E> void WriteEnumT(const char *name, E e)
144 {
145 WriteValue(name, ValueStr(e).Data());
146 }
147
148 void BeginStruct(size_t type_id, const char *name, const void *ptr);
149 void EndStruct();
150
152 template <typename S> void WriteStructT(const char *name, const S *s)
153 {
154 static size_t type_id = ++LastTypeId();
155
156 if (s == nullptr) {
157 /* No need to dump nullptr struct. */
158 WriteLine("%s = <null>", name);
159 return;
160 }
161 CStrA known_as;
162 if (FindKnownName(type_id, s, known_as)) {
163 /* We already know this one, no need to dump it. */
164 WriteLine("%s = known_as.%s", name, known_as.Data());
165 } else {
166 /* Still unknown, dump it */
167 BeginStruct(type_id, name, s);
168 s->Dump(*this);
169 EndStruct();
170 }
171 }
172 };
173
174 #endif /* DBG_HELPERS_H */
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
DumpTarget::LastTypeId
static size_t & LastTypeId()
Keep track of the last assigned type_id.
Definition: dbg_helpers.cpp:77
DumpTarget::WriteIndent
void WriteIndent()
Write some leading spaces into the output.
Definition: dbg_helpers.cpp:110
TrackdirBits
TrackdirBits
Enumeration of bitmasks for the TrackDirs.
Definition: track_type.h:101
DumpTarget::WriteEnumT
void WriteEnumT(const char *name, E e)
Dump given enum value (as a number and as named value)
Definition: dbg_helpers.h:143
CStrA
Blob based case sensitive ANSI/UTF-8 string.
Definition: str.hpp:20
DumpTarget::EndStruct
void EndStruct()
Close structure '}<LF>'.
Definition: dbg_helpers.cpp:170
ItemAtT
ArrayT< T >::item_t ItemAtT(E idx, const T &t, typename ArrayT< T >::item_t t_unk)
Helper template function that returns item of array at given index or t_unk when index is out of boun...
Definition: dbg_helpers.h:38
ValueStr
CStrA ValueStr(Trackdir td)
Return name of given Trackdir.
Definition: dbg_helpers.cpp:23
DumpTarget::WriteLine
void CDECL WriteLine(const char *format,...) WARN_FORMAT(2
Write a line with indent at the beginning and <LF> at the end.
Definition: dbg_helpers.cpp:119
DumpTarget::m_known_names
KNOWN_NAMES m_known_names
map of known object instances and their structured names
Definition: dbg_helpers.h:126
DumpTarget::WriteTile
void WriteTile(const char *name, TileIndex t)
Write name & TileIndex to the output.
Definition: dbg_helpers.cpp:137
DumpTarget::KnownStructKey
Used as a key into map of known object instances.
Definition: dbg_helpers.h:97
SignalType
SignalType
Type of signal, i.e.
Definition: signal_type.h:23
ComposeNameT
CStrA ComposeNameT(E value, T &t, const char *t_unk, E val_inv, const char *name_inv)
Helper template function that returns compound bitfield name that is concatenation of names of each s...
Definition: dbg_helpers.h:70
ArrayT
Helper template class that provides C array length and item type.
Definition: dbg_helpers.h:24
DumpTarget::m_indent
int m_indent
current indent/nesting level
Definition: dbg_helpers.h:124
CBlobT::Size
size_t Size() const
Return number of items in the Blob.
Definition: blob.hpp:382
DumpTarget::FindKnownName
bool FindKnownName(size_t type_id, const void *ptr, CStrA &name)
Find the given instance in our anti-recursion repository.
Definition: dbg_helpers.cpp:98
str.hpp
DumpTarget
Class that represents the dump-into-string target.
Definition: dbg_helpers.h:94
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:77
DumpTarget::WriteStructT
void WriteStructT(const char *name, const S *s)
Dump nested object (or only its name if this instance is already known).
Definition: dbg_helpers.h:152
DumpTarget::m_cur_struct
std::stack< CStrA > m_cur_struct
here we will track the current structure name
Definition: dbg_helpers.h:125
DumpTarget::WriteValue
void CDECL void WriteValue(const char *name, const char *value_str)
Write 'name = value' with indent and new-line.
Definition: dbg_helpers.cpp:130
DumpTarget::GetCurrentStructName
CStrA GetCurrentStructName()
Return structured name of the current class/structure.
Definition: dbg_helpers.cpp:84
DumpTarget::BeginStruct
void BeginStruct(size_t type_id, const char *name, const void *ptr)
Open new structure (one level deeper than the current one) 'name = {<LF>'.
Definition: dbg_helpers.cpp:146
DumpTarget::m_out
CStrA m_out
the output string
Definition: dbg_helpers.h:123
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:70
CBlobT::Data
T * Data()
Return pointer to the first data item - non-const version.
Definition: blob.hpp:356