dbg_helpers.h

Go to the documentation of this file.
00001 /* $Id: dbg_helpers.h 19127 2010-02-14 13:01:33Z frosch $ */
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 <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 CDECL WriteLine(const char *format, ...) WARN_FORMAT(2, 3);
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       /* No need to dump NULL struct. */
00160       WriteLine("%s = <null>", name);
00161       return;
00162     }
00163     CStrA known_as;
00164     if (FindKnownName(type_id, s, known_as)) {
00165       /* We already know this one, no need to dump it. */
00166       WriteLine("%s = known_as.%s", name, known_as.Data());
00167     } else {
00168       /* Still unknown, dump it */
00169       BeginStruct(type_id, name, s);
00170       s->Dump(*this);
00171       EndStruct();
00172     }
00173   }
00174 };
00175 
00176 #endif /* DBG_HELPERS_H */

Generated on Sat Jun 19 17:14:49 2010 for OpenTTD by  doxygen 1.6.1