dbg_helpers.h

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
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       /* No need to dump NULL struct. */
00157       WriteLine("%s = <null>", name);
00158       return;
00159     }
00160     CStrA known_as;
00161     if (FindKnownName(type_id, s, known_as)) {
00162       /* We already know this one, no need to dump it. */
00163       WriteLine("%s = known_as.%s", name, known_as.Data());
00164     } else {
00165       /* Still unknown, dump it */
00166       BeginStruct(type_id, name, s);
00167       s->Dump(*this);
00168       EndStruct();
00169     }
00170   }
00171 };
00172 
00173 #endif /* DBG_HELPERS_H */

Generated on Wed Dec 30 20:40:03 2009 for OpenTTD by  doxygen 1.5.6