# dbg_helpers.h

Go to the documentation of this file.

    00001 /* $Id: dbg_helpers.h 15711 2009-03-14 18:16:29Z rubidium $ */
    00002
    00005 #ifndef DBG_HELPERS_H
    00006 #define DBG_HELPERS_H
    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       /* No need to dump NULL struct. */
    00150       WriteLine("%s = <null>", name);
    00151       return;
    00152     }
    00153     CStrA known_as;
    00154     if (FindKnownName(type_id, s, known_as)) {
    00155       /* We already know this one, no need to dump it. */
    00156       WriteLine("%s = known_as.%s", name, known_as.Data());
    00157     } else {
    00158       /* Still unknown, dump it */
    00159       BeginStruct(type_id, name, s);
    00160       s->Dump(*this);
    00161       EndStruct();
    00162     }
    00163   }
    00164 };
    00165
    00166 #endif /* DBG_HELPERS_H */