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