dbg_helpers.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef DBG_HELPERS_H
00013 #define DBG_HELPERS_H
00014
00015 #include <new>
00016 #include <map>
00017 #include <stack>
00018
00019 #include "blob.hpp"
00020 #include "str.hpp"
00021
00023 template <typename T> struct ArrayT;
00024
00026 template <typename T, size_t N> struct ArrayT<T[N]> {
00027 static const size_t length = N;
00028 typedef T item_t;
00029 };
00030
00031
00036 template <typename E, typename T>
00037 inline typename ArrayT<T>::item_t ItemAtT(E idx, const T &t, typename ArrayT<T>::item_t t_unk)
00038 {
00039 if ((size_t)idx >= ArrayT<T>::length) {
00040 return t_unk;
00041 }
00042 return t[idx];
00043 }
00044
00050 template <typename E, typename T>
00051 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)
00052 {
00053 if ((size_t)idx < ArrayT<T>::length) {
00054 return t[idx];
00055 }
00056 if (idx == idx_inv) {
00057 return t_inv;
00058 }
00059 return t_unk;
00060 }
00061
00068 template <typename E, typename T>
00069 inline CStrA ComposeNameT(E value, T &t, const char *t_unk, E val_inv, const char *name_inv)
00070 {
00071 CStrA out;
00072 if (value == val_inv) {
00073 out = name_inv;
00074 } else if (value == 0) {
00075 out = "<none>";
00076 } else {
00077 for (size_t i = 0; i < ArrayT<T>::length; i++) {
00078 if ((value & (1 << i)) == 0) continue;
00079 out.AddFormat("%s%s", (out.Size() > 0 ? "+" : ""), t[i]);
00080 value &= ~(E)(1 << i);
00081 }
00082 if (value != 0) out.AddFormat("%s%s", (out.Size() > 0 ? "+" : ""), t_unk);
00083 }
00084 return out.Transfer();
00085 }
00086
00087 CStrA ValueStr(Trackdir td);
00088 CStrA ValueStr(TrackdirBits td_bits);
00089 CStrA ValueStr(DiagDirection dd);
00090 CStrA ValueStr(SignalType t);
00091
00093 struct DumpTarget {
00094
00096 struct KnownStructKey {
00097 size_t m_type_id;
00098 const void *m_ptr;
00099
00100 KnownStructKey(size_t type_id, const void *ptr)
00101 : m_type_id(type_id)
00102 , m_ptr(ptr)
00103 {}
00104
00105 KnownStructKey(const KnownStructKey &src)
00106 {
00107 m_type_id = src.m_type_id;
00108 m_ptr = src.m_ptr;
00109 }
00110
00111 bool operator < (const KnownStructKey &other) const
00112 {
00113 if ((size_t)m_ptr < (size_t)other.m_ptr) return true;
00114 if ((size_t)m_ptr > (size_t)other.m_ptr) return false;
00115 if (m_type_id < other.m_type_id) return true;
00116 return false;
00117 }
00118 };
00119
00120 typedef std::map<KnownStructKey, CStrA> KNOWN_NAMES;
00121
00122 CStrA m_out;
00123 int m_indent;
00124 std::stack<CStrA> m_cur_struct;
00125 KNOWN_NAMES m_known_names;
00126
00127 DumpTarget()
00128 : m_indent(0)
00129 {}
00130
00131 static size_t& LastTypeId();
00132 CStrA GetCurrentStructName();
00133 bool FindKnownName(size_t type_id, const void *ptr, CStrA &name);
00134
00135 void WriteIndent();
00136
00137 void WriteLine(const char *format, ...);
00138 void WriteValue(const char *name, const char *value_str);
00139 void WriteTile(const char *name, TileIndex t);
00140
00142 template <typename E> void WriteEnumT(const char *name, E e)
00143 {
00144 WriteValue(name, ValueStr(e).Data());
00145 }
00146
00147 void BeginStruct(size_t type_id, const char *name, const void *ptr);
00148 void EndStruct();
00149
00151 template <typename S> void WriteStructT(const char *name, const S *s)
00152 {
00153 static size_t type_id = ++LastTypeId();
00154
00155 if (s == NULL) {
00156
00157 WriteLine("%s = <null>", name);
00158 return;
00159 }
00160 CStrA known_as;
00161 if (FindKnownName(type_id, s, known_as)) {
00162
00163 WriteLine("%s = known_as.%s", name, known_as.Data());
00164 } else {
00165
00166 BeginStruct(type_id, name, s);
00167 s->Dump(*this);
00168 EndStruct();
00169 }
00170 }
00171 };
00172
00173 #endif