debug.h

Go to the documentation of this file.
00001 
00007 /*
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2.1 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00021 */
00022 
00023 #ifndef OMGUI_DEBUG_H
00024 #define OMGUI_DEBUG_H
00025 
00026 #include <iostream>
00027 #include <sstream>
00028 
00029 // userful headers for output manipulation
00030 #include <iomanip>
00031 
00032 #ifdef _MSC_VER
00033 #include <crtdbg.h>
00034 #endif
00035 
00036 // windows headers are anoying and #define ERROR so get rid of it if needed
00037 #ifdef ERROR
00038 #undef ERROR
00039 #endif
00040 
00041 namespace omgui {
00042 
00059 class DebugReport
00060 {
00061 public:
00062     enum REPORT_TYPE {
00063         MESSAGE,
00064         ERROR
00065     };
00066 
00067     DebugReport(REPORT_TYPE report_type = MESSAGE, const char *file = 0, int line = 0, const char *module = 0)
00068 #ifdef _DEBUG
00069         : m_type(report_type), m_line(line), m_file(file), m_module(module)
00070 #endif
00071     { }
00072 
00073 #ifdef _DEBUG
00074     ~DebugReport() { flush(); }
00075 #endif
00076 
00081     template<typename T> friend const DebugReport &operator << (const DebugReport &r, const T &t)
00082     {
00083 #ifdef _DEBUG
00084         r.m_ss << t;
00085 #endif
00086         return r;
00087     }
00088 
00092     friend const DebugReport &operator << (const DebugReport &r, std::ios_base& (*func)(std::ios_base&))
00093     {
00094 #ifdef _DEBUG
00095         r.m_ss << func;
00096 #endif
00097         return r;
00098     }
00099 
00103     friend const DebugReport &operator << (const DebugReport &r, std::basic_ostream<char, std::char_traits<char> >& (*func)(std::basic_ostream<char, std::char_traits<char> >&) )
00104     {
00105 #ifdef _DEBUG
00106         r.flush();
00107 #endif
00108         return r;
00109     }
00110 
00114     friend const DebugReport &operator << (const DebugReport &r, std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& (*func)(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >&) )
00115     {
00116 #ifdef _DEBUG
00117         r.flush();
00118 #endif
00119         return r;
00120     }
00121 
00122 #ifdef _DEBUG
00123 private:
00124     mutable std::stringstream m_ss;
00125     int m_type, m_line;
00126     const char *m_file, *m_module;
00127 
00131     std::ostream &get_ostream() const
00132     {
00133         switch(m_type)
00134         {
00135         case MESSAGE:
00136             return std::cout;
00137         case ERROR:
00138             return std::cerr;
00139         default:
00140             return std::cout;
00141         }
00142     }
00143 
00147     void flush() const
00148     {
00149         if( !m_ss.str().empty() )
00150         {
00151 
00152 #ifdef _MSC_VER // Visual Studio debug output
00153 
00154             int type;
00155             switch(m_type)
00156             {
00157             case MESSAGE:
00158                 type = _CRT_WARN;
00159                 break;
00160             case ERROR:
00161                 type = _CRT_ERROR;
00162                 break;
00163             default:
00164                 type = _CRT_WARN;
00165             }
00166 
00167             // if _CRT_ERROR is used and "Retry" is selected, break
00168             if( ::_CrtDbgReport(type, m_file, m_line, m_module, "%s\n", m_ss.str().c_str()) == 1 )
00169                 ::_CrtDbgBreak();
00170 
00171 #else // !_MSC_VER Debug output for other compilers
00172 
00173             std::ostream &out = get_ostream();
00174 
00175             if( m_file )
00176             {
00177                 if( m_line )
00178                     out << m_file << "(" << m_line << ")";
00179                 else
00180                     out << m_file;
00181                 out << ": ";
00182             }
00183 
00184             out << m_ss.str() << "\n";
00185 
00186 #endif // _MSC_VER
00187 
00188             m_ss.str("");
00189         }
00190     }
00191 #endif // _DEBUG
00192 
00193 public:
00194     /*
00195         stringstreams have a private copy ctor, so we need to write
00196         our own
00197     */
00198     DebugReport(const DebugReport &r)
00199 #ifdef _DEBUG
00200         : m_type(r.m_type),
00201         m_line(r.m_line),
00202         m_file(r.m_file),
00203         m_module(r.m_module)
00204     {
00205         m_ss.str(r.m_ss.str());
00206     }
00207 #else 
00208     { }
00209 #endif
00210 };
00211 
00212 } // omgui
00213 
00214 #endif // OMGUI_DEBUG_H

doxygen SourceForge.net Logo