Make the ServiceListDelegate use less handcoded values and more general variables...
[amarok.git] / src / debug.h
blob7fadaedccdd78a6e5ecdadd041bfde2f89cdb85f
1 // Author: Max Howell <max.howell@methylblue.com>, (C) 2003-5
2 // Author: Mark Kretschmann <kretschmann@kde.org>, (C) 2007
3 // Copyright: See COPYING file that comes with this distribution
4 //
6 #ifndef AMAROK_DEBUG_H
7 #define AMAROK_DEBUG_H
9 // We always want debug output available at runtime
10 #undef QT_NO_DEBUG_OUTPUT
11 #undef KDE_NO_DEBUG_OUTPUT
13 #include <KConfig>
14 #include <kdebug.h>
15 #include <QApplication>
16 #include <QMutex>
17 #include <QObject>
19 #include <iostream>
20 #include <sys/time.h>
22 #include "amarok_export.h"
24 #ifdef _WIN32
25 #define __PRETTY_FUNCTION__ __FUNCTION__
26 #endif
28 /**
29 * @namespace Debug
30 * @short kdebug with indentation functionality and convenience macros
31 * @author Max Howell <max.howell@methylblue.com>
33 * Usage:
35 * #define DEBUG_PREFIX "Blah"
36 * #include "debug.h"
38 * void function()
39 * {
40 * Debug::Block myBlock( __PRETTY_FUNCTION__ );
42 * debug() << "output1" << endl;
43 * debug() << "output2" << endl;
44 * }
46 * Will output:
48 * app: BEGIN: void function()
49 * app: [Blah] output1
50 * app: [Blah] output2
51 * app: END: void function(): Took 0.1s
53 * @see Block
54 * @see CrashHelper
55 * @see ListStream
58 namespace Debug
60 extern AMAROK_EXPORT QMutex mutex; // defined in app.cpp
62 // we can't use a statically instantiated QCString for the indent, because
63 // static namespaces are unique to each dlopened library. So we piggy back
64 // the QCString on the KApplication instance
66 #define qOApp reinterpret_cast<QObject*>(qApp)
67 class Indent : QObject
69 friend QString &modifieableIndent();
70 Indent() : QObject( qOApp ) { setObjectName( "DEBUG_indent" ); }
71 QString m_string;
74 inline QString &modifieableIndent()
76 QObject* o = qOApp ? qOApp->findChild<QObject*>( "DEBUG_indent" ) : 0;
77 QString &ret = (o ? static_cast<Indent*>( o ) : new Indent)->m_string;
78 return ret;
81 inline QString indent()
83 return modifieableIndent();
86 inline bool debugEnabled()
88 KConfigGroup config = KGlobal::config()->group( "General" );
89 const bool debug = config.readEntry( "Debug Enabled", false );
91 return debug;
94 inline kdbgstream dbgstream()
96 return debugEnabled() ? kdbgstream( QtDebugMsg ) : kDebugDevNull();
99 #undef qApp
101 #ifndef DEBUG_PREFIX
102 #define AMK_PREFIX ""
103 #else
104 #define AMK_PREFIX "[" DEBUG_PREFIX "]"
105 #endif
107 //from kdebug.h
108 enum DebugLevels {
109 KDEBUG_INFO = 0,
110 KDEBUG_WARN = 1,
111 KDEBUG_ERROR = 2,
112 KDEBUG_FATAL = 3
116 static inline kdbgstream debug() { mutex.lock(); QString ind = indent(); mutex.unlock(); return dbgstream() << qPrintable( ind + AMK_PREFIX ); }
117 static inline kdbgstream warning() { mutex.lock(); QString ind = indent(); mutex.unlock(); return dbgstream() << qPrintable( ind + AMK_PREFIX + " [WARNING!]" ); }
118 static inline kdbgstream error() { mutex.lock(); QString ind = indent(); mutex.unlock(); return dbgstream() << qPrintable( ind + AMK_PREFIX + " [ERROR!]" ); }
119 static inline kdbgstream fatal() { mutex.lock(); QString ind = indent(); mutex.unlock(); return dbgstream() << qPrintable( ind + AMK_PREFIX ); }
121 typedef kdbgstream DebugStream;
123 #undef AMK_PREFIX
125 typedef kndbgstream NoDebugStream;
128 using Debug::debug;
129 using Debug::warning;
130 using Debug::error;
131 using Debug::fatal;
132 using Debug::DebugStream;
134 /// Standard function announcer
135 #define DEBUG_FUNC_INFO { Debug::mutex.lock(); kDebug() << Debug::indent() ; Debug::mutex.unlock(); }
137 /// Announce a line
138 #define DEBUG_LINE_INFO { Debug::mutex.lock(); kDebug() << Debug::indent() << "Line: " << __LINE__; Debug::mutex.unlock(); }
140 /// Convenience macro for making a standard Debug::Block
141 #define DEBUG_BLOCK Debug::Block uniquelyNamedStackAllocatedStandardBlock( __PRETTY_FUNCTION__ );
143 /// Use this to remind yourself to finish the implementation of a function
144 #define AMAROK_NOTIMPLEMENTED warning() << "NOT-IMPLEMENTED: " << __PRETTY_FUNCTION__ << endl;
146 /// Use this to alert other developers to stop using a function
147 #define AMAROK_DEPRECATED warning() << "DEPRECATED: " << __PRETTY_FUNCTION__ << endl;
150 namespace Debug
153 * @class Debug::Block
154 * @short Use this to label sections of your code
156 * Usage:
158 * void function()
160 * Debug::Block myBlock( "section" );
162 * debug() << "output1" << endl;
163 * debug() << "output2" << endl;
166 * Will output:
168 * app: BEGIN: section
169 * app: [prefix] output1
170 * app: [prefix] output2
171 * app: END: section - Took 0.1s
175 class Block
177 timeval m_start;
178 const char *m_label;
180 public:
181 Block( const char *label )
182 : m_label( label )
184 if( !debugEnabled() ) return;
186 mutex.lock();
187 gettimeofday( &m_start, 0 );
189 kDebug() << "BEGIN:" << label;
190 Debug::modifieableIndent() += " ";
191 mutex.unlock();
194 ~Block()
196 if( !debugEnabled() ) return;
198 mutex.lock();
199 timeval end;
200 gettimeofday( &end, 0 );
202 end.tv_sec -= m_start.tv_sec;
203 if( end.tv_usec < m_start.tv_usec) {
204 // Manually carry a one from the seconds field.
205 end.tv_usec += 1000000;
206 end.tv_sec--;
208 end.tv_usec -= m_start.tv_usec;
210 double duration = double(end.tv_sec) + (double(end.tv_usec) / 1000000.0);
212 Debug::modifieableIndent().truncate( Debug::indent().length() - 2 );
213 kDebug() << "END__:" << m_label
214 << "- Took" << qPrintable( QString::number( duration, 'g', 2 ) + "s" );
215 mutex.unlock();
221 * @name Debug::stamp()
222 * @short To facilitate crash/freeze bugs, by making it easy to mark code that has been processed
224 * Usage:
227 * Debug::stamp();
228 * function1();
229 * Debug::stamp();
230 * function2();
231 * Debug::stamp();
234 * Will output (assuming the crash occurs in function2()
236 * app: Stamp: 1
237 * app: Stamp: 2
241 inline void stamp()
243 static int n = 0;
244 debug() << "| Stamp: " << ++n << endl;
249 #include <QVariant>
251 namespace Debug
254 * @class Debug::List
255 * @short You can pass anything to this and it will output it as a list
257 * debug() << (Debug::List() << anInt << aString << aQStringList << aDouble) << endl;
260 typedef QList<QVariant> List;
263 #endif