OpenTTD Source 20260621-master-g720d10536d
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef DBG_HELPERS_H
11#define DBG_HELPERS_H
12
13#include <stack>
14
15#include "../direction_type.h"
16#include "../signal_type.h"
17#include "../tile_type.h"
18#include "../track_type.h"
19#include "../core/format.hpp"
20
29template <typename E>
30inline std::string_view ItemAt(E idx, std::span<const std::string_view> names, std::string_view unknown_name)
31{
32 if (static_cast<size_t>(idx) >= std::size(names)) {
33 return unknown_name;
34 }
35 return names[to_underlying(idx)];
36}
37
49template <typename E>
50inline std::string_view ItemAt(E idx, std::span<const std::string_view> names, std::string_view unknown_name, E invalid_index, std::string_view invalid_name)
51{
52 if (idx == invalid_index) {
53 return invalid_name;
54 }
55 return ItemAt(idx, names, unknown_name);
56}
57
67template <typename Tbitset>
68inline std::string ComposeName(Tbitset value, std::span<const std::string_view> names, std::string_view unknown_name)
69{
70 if (value.None()) return "<none>";
71
72 std::string out;
73 for (auto index : value) {
74 if (!out.empty()) out += "+";
75 out += to_underlying(index) < std::size(names) ? names[to_underlying(index)] : unknown_name;
76 }
77 return out;
78}
79
92template <typename Tbitset>
93inline std::string ComposeName(Tbitset value, std::span<const std::string_view> names, std::string_view unknown_name, Tbitset invalid_value, std::string_view invalid_name)
94{
95 if (value == invalid_value) return std::string{invalid_name};
96 return ComposeName(value, names, unknown_name);
97}
98
99std::string ValueStr(Trackdir td);
100std::string ValueStr(TrackdirBits td_bits);
101std::string ValueStr(DiagDirection dd);
102std::string ValueStr(SignalType t);
103
108 size_t type_id;
109 const void *ptr;
110
116 KnownStructKey(size_t type_id, const void *ptr) : type_id(type_id), ptr(ptr) {}
117
118 bool operator<(const KnownStructKey &other) const
119 {
120 if (reinterpret_cast<size_t>(this->ptr) < reinterpret_cast<size_t>(other.ptr)) return true;
121 if (reinterpret_cast<size_t>(this->ptr) > reinterpret_cast<size_t>(other.ptr)) return false;
122 if (this->type_id < other.type_id) return true;
123 return false;
124 }
125 };
126
128 using KnownNamesMap = std::map<KnownStructKey, std::string>;
129
130 std::string output_buffer;
131 int indent = 0;
132 std::stack<std::string> cur_struct;
134
135 static size_t NewTypeId();
136 std::string GetCurrentStructName();
137 std::optional<std::string> FindKnownAsName(size_t type_id, const void *ptr);
138
139 void WriteIndent();
140
146 void WriteValue(std::string_view name, const auto &value)
147 {
148 this->WriteIndent();
149 format_append(this->output_buffer, "{} = {}\n", name, value);
150 }
151
152 void WriteTile(std::string_view name, TileIndex t);
153
159 template <typename E> void WriteEnumT(std::string_view name, E e)
160 {
161 this->WriteValue(name, ValueStr(e));
162 }
163
164 void BeginStruct(size_t type_id, std::string_view name, const void *ptr);
165 void EndStruct();
166
172 template <typename S> void WriteStructT(std::string_view name, const S *s)
173 {
174 static const size_t type_id = this->NewTypeId();
175
176 if (s == nullptr) {
177 /* No need to dump nullptr struct. */
178 this->WriteValue(name, "<null>");
179 return;
180 }
181 if (auto known_as = this->FindKnownAsName(type_id, s); known_as.has_value()) {
182 /* We already know this one, no need to dump it. */
183 this->WriteValue(name, *known_as);
184 } else {
185 /* Still unknown, dump it */
186 this->BeginStruct(type_id, name, s);
187 s->Dump(*this);
188 this->EndStruct();
189 }
190 }
191
197 template <typename S> void WriteStructT(std::string_view name, const std::deque<S> *s)
198 {
199 static const size_t type_id = this->NewTypeId();
200
201 if (s == nullptr) {
202 /* No need to dump nullptr struct. */
203 this->WriteValue(name, "<null>");
204 return;
205 }
206 if (auto known_as = this->FindKnownAsName(type_id, s); known_as.has_value()) {
207 /* We already know this one, no need to dump it. */
208 this->WriteValue(name, *known_as);
209 } else {
210 /* Still unknown, dump it */
211 this->BeginStruct(type_id, name, s);
212 size_t num_items = s->size();
213 this->WriteValue("num_items", num_items);
214 for (size_t i = 0; i < num_items; i++) {
215 const auto &item = (*s)[i];
216 this->WriteStructT(fmt::format("item[{}]", i), &item);
217 }
218 this->EndStruct();
219 }
220 }
221};
222
223#endif /* DBG_HELPERS_H */
std::string ValueStr(Trackdir td)
Return name of given Trackdir.
std::string_view ItemAt(E idx, std::span< const std::string_view > names, std::string_view unknown_name)
Helper template function that returns item of array at given index or unknown_name when index is out ...
Definition dbg_helpers.h:30
std::string ComposeName(Tbitset value, std::span< const std::string_view > names, std::string_view unknown_name)
Helper template function that returns compound bitfield name that is concatenation of names of each s...
Definition dbg_helpers.h:68
Different types to 'show' directions.
DiagDirection
Enumeration for diagonal directions.
#define S
Climate sub-tropic.
Definition engines.h:95
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
String formatting functions and helpers.
Types and classes related to signals.
SignalType
Type of signal, i.e.
Definition signal_type.h:24
Used as a key into map of known object instances.
const void * ptr
Pointer to the structure.
KnownStructKey(size_t type_id, const void *ptr)
Create the key.
size_t type_id
Unique identifier of the type.
Class that represents the dump-into-string target.
std::map< KnownStructKey, std::string > KnownNamesMap
Mapping of the KnownStructKey to the name for that structure.
KnownNamesMap known_names
Map of known object instances and their structured names.
std::stack< std::string > cur_struct
Tracker of the current structure name.
void WriteTile(std::string_view name, TileIndex t)
Write name & TileIndex to the output.
void BeginStruct(size_t type_id, std::string_view name, const void *ptr)
Open new structure (one level deeper than the current one) 'name = {<LF>'.
int indent
Current indent/nesting level.
void WriteStructT(std::string_view name, const std::deque< S > *s)
Dump nested object (or only its name if this instance is already known).
std::string GetCurrentStructName()
Return structured name of the current class/structure.
std::string output_buffer
The output string.
void WriteStructT(std::string_view name, const S *s)
Dump nested object (or only its name if this instance is already known).
std::optional< std::string > FindKnownAsName(size_t type_id, const void *ptr)
Find the given instance in our anti-recursion repository.
void WriteEnumT(std::string_view name, E e)
Dump given enum value (as a number and as named value).
void WriteIndent()
Write some leading spaces into the output.
void EndStruct()
Close structure '}<LF>'.
void WriteValue(std::string_view name, const auto &value)
Write 'name = value' with indent and new-line.
static size_t NewTypeId()
Create a new type_id.
Types related to tiles.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
All types related to tracks.
EnumBitSet< Trackdir, uint16_t > TrackdirBits
Bitset of Trackdir elements.
Definition track_type.h:93
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:63