OpenTTD Source  12.0-beta2
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 #include <string>
16 
17 #include "../direction_type.h"
18 #include "../signal_type.h"
19 #include "../tile_type.h"
20 #include "../track_type.h"
21 
23 template <typename T> struct ArrayT;
24 
26 template <typename T, size_t N> struct ArrayT<T[N]> {
27  static const size_t length = N;
28  typedef T item_t;
29 };
30 
31 
36 template <typename E, typename T>
37 inline typename ArrayT<T>::item_t ItemAtT(E idx, const T &t, typename ArrayT<T>::item_t t_unk)
38 {
39  if ((size_t)idx >= ArrayT<T>::length) {
40  return t_unk;
41  }
42  return t[idx];
43 }
44 
50 template <typename E, typename T>
51 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)
52 {
53  if ((size_t)idx < ArrayT<T>::length) {
54  return t[idx];
55  }
56  if (idx == idx_inv) {
57  return t_inv;
58  }
59  return t_unk;
60 }
61 
68 template <typename E, typename T>
69 inline std::string ComposeNameT(E value, T &t, const char *t_unk, E val_inv, const char *name_inv)
70 {
71  std::string out;
72  if (value == val_inv) {
73  out = name_inv;
74  } else if (value == 0) {
75  out = "<none>";
76  } else {
77  for (size_t i = 0; i < ArrayT<T>::length; i++) {
78  if ((value & (1 << i)) == 0) continue;
79  out += (!out.empty() ? "+" : "");
80  out += t[i];
81  value &= ~(E)(1 << i);
82  }
83  if (value != 0) {
84  out += (!out.empty() ? "+" : "");
85  out += t_unk;
86  }
87  }
88  return out;
89 }
90 
91 std::string ValueStr(Trackdir td);
92 std::string ValueStr(TrackdirBits td_bits);
93 std::string ValueStr(DiagDirection dd);
94 std::string ValueStr(SignalType t);
95 
97 struct DumpTarget {
98 
100  struct KnownStructKey {
101  size_t m_type_id;
102  const void *m_ptr;
103 
104  KnownStructKey(size_t type_id, const void *ptr)
105  : m_type_id(type_id)
106  , m_ptr(ptr)
107  {}
108 
109  bool operator<(const KnownStructKey &other) const
110  {
111  if ((size_t)m_ptr < (size_t)other.m_ptr) return true;
112  if ((size_t)m_ptr > (size_t)other.m_ptr) return false;
113  if (m_type_id < other.m_type_id) return true;
114  return false;
115  }
116  };
117 
118  typedef std::map<KnownStructKey, std::string> KNOWN_NAMES;
119 
120  std::string m_out;
121  int m_indent;
122  std::stack<std::string> m_cur_struct;
123  KNOWN_NAMES m_known_names;
124 
125  DumpTarget()
126  : m_indent(0)
127  {}
128 
129  static size_t& LastTypeId();
130  std::string GetCurrentStructName();
131  bool FindKnownName(size_t type_id, const void *ptr, std::string &name);
132 
133  void WriteIndent();
134 
135  void WriteValue(const char *name, int value);
136  void WriteValue(const char *name, const char *value_str);
137  void WriteTile(const char *name, TileIndex t);
138 
140  template <typename E> void WriteEnumT(const char *name, E e)
141  {
142  WriteValue(name, ValueStr(e).c_str());
143  }
144 
145  void BeginStruct(size_t type_id, const char *name, const void *ptr);
146  void EndStruct();
147 
149  template <typename S> void WriteStructT(const char *name, const S *s)
150  {
151  static size_t type_id = ++LastTypeId();
152 
153  if (s == nullptr) {
154  /* No need to dump nullptr struct. */
155  WriteValue(name, "<null>");
156  return;
157  }
158  std::string known_as;
159  if (FindKnownName(type_id, s, known_as)) {
160  /* We already know this one, no need to dump it. */
161  std::string known_as_str = std::string("known_as.") + name;
162  WriteValue(name, known_as_str.c_str());
163  } else {
164  /* Still unknown, dump it */
165  BeginStruct(type_id, name, s);
166  s->Dump(*this);
167  EndStruct();
168  }
169  }
170 };
171 
172 #endif /* DBG_HELPERS_H */
DumpTarget::FindKnownName
bool FindKnownName(size_t type_id, const void *ptr, std::string &name)
Find the given instance in our anti-recursion repository.
Definition: dbg_helpers.cpp:94
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:83
DumpTarget::LastTypeId
static size_t & LastTypeId()
Keep track of the last assigned type_id.
Definition: dbg_helpers.cpp:73
ComposeNameT
std::string 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:69
DumpTarget::WriteIndent
void WriteIndent()
Write some leading spaces into the output.
Definition: dbg_helpers.cpp:106
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:140
DumpTarget::EndStruct
void EndStruct()
Close structure '}<LF>'.
Definition: dbg_helpers.cpp:162
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:37
DumpTarget::GetCurrentStructName
std::string GetCurrentStructName()
Return structured name of the current class/structure.
Definition: dbg_helpers.cpp:80
DumpTarget::m_known_names
KNOWN_NAMES m_known_names
map of known object instances and their structured names
Definition: dbg_helpers.h:123
DumpTarget::WriteTile
void WriteTile(const char *name, TileIndex t)
Write name & TileIndex to the output.
Definition: dbg_helpers.cpp:129
DumpTarget::KnownStructKey
Used as a key into map of known object instances.
Definition: dbg_helpers.h:100
SignalType
SignalType
Type of signal, i.e.
Definition: signal_type.h:23
DumpTarget::m_cur_struct
std::stack< std::string > m_cur_struct
here we will track the current structure name
Definition: dbg_helpers.h:122
ValueStr
std::string ValueStr(Trackdir td)
Return name of given Trackdir.
Definition: dbg_helpers.cpp:26
ArrayT
Helper template class that provides C array length and item type.
Definition: dbg_helpers.h:23
DumpTarget::m_indent
int m_indent
current indent/nesting level
Definition: dbg_helpers.h:121
DumpTarget
Class that represents the dump-into-string target.
Definition: dbg_helpers.h:97
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:149
DumpTarget::WriteValue
void WriteValue(const char *name, int value)
Write 'name = value' with indent and new-line.
Definition: dbg_helpers.cpp:115
DumpTarget::m_out
std::string m_out
the output string
Definition: dbg_helpers.h:120
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:138
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:70