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