OpenTTD Source  1.11.2
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 
89 CStrA ValueStr(TrackdirBits td_bits);
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 
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();
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:83
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