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 */

Generated on Wed Jun 3 19:05:11 2009 for OpenTTD by  doxygen 1.5.6