1 // Author: Max Howell <max.howell@methylblue.com>, (C) 2003-5
2 // Copyright: See COPYING file that comes with this distribution
9 #include <QApplication>
16 #include "amarok_export.h"
19 #define __PRETTY_FUNCTION__ __FUNCTION__
24 * @short kdebug with indentation functionality and convenience macros
25 * @author Max Howell <max.howell@methylblue.com>
29 * #define DEBUG_PREFIX "Blah"
34 * Debug::Block myBlock( __PRETTY_FUNCTION__ );
36 * debug() << "output1" << endl;
37 * debug() << "output2" << endl;
42 * app: BEGIN: void function()
45 * app: END: void function(): Took 0.1s
54 extern AMAROK_EXPORT QMutex mutex
; // defined in app.cpp
56 // we can't use a statically instantiated QCString for the indent, because
57 // static namespaces are unique to each dlopened library. So we piggy back
58 // the QCString on the KApplication instance
60 #define qOApp reinterpret_cast<QObject*>(qApp)
61 class Indent
: QObject
63 friend QString
&modifieableIndent();
64 Indent() : QObject( qOApp
) { setObjectName( "DEBUG_indent" ); }
68 inline QString
&modifieableIndent()
70 QObject
* o
= qOApp
? qOApp
->findChild
<QObject
*>( "DEBUG_indent" ) : 0;
71 QString
&ret
= (o
? static_cast<Indent
*>( o
) : new Indent
)->m_string
;
75 inline QString
indent()
77 return modifieableIndent();
83 static inline kndbgstream
debug() { return kndbgstream(); }
84 static inline kndbgstream
warning() { return kndbgstream(); }
85 static inline kndbgstream
error() { return kndbgstream(); }
86 static inline kndbgstream
fatal() { return kndbgstream(); }
88 typedef kndbgstream DebugStream
;
93 #define AMK_PREFIX "[" DEBUG_PREFIX "] "
104 static inline kdbgstream
debug() { mutex
.lock(); QString ind
= indent(); mutex
.unlock(); return kdbgstream( QtDebugMsg
) << ind
+ AMK_PREFIX
; }
105 static inline kdbgstream
warning() { mutex
.lock(); QString ind
= indent(); mutex
.unlock(); return kdbgstream( QtDebugMsg
) << ind
+ AMK_PREFIX
<< "[WARNING!] "; }
106 static inline kdbgstream
error() { mutex
.lock(); QString ind
= indent(); mutex
.unlock(); return kdbgstream( QtDebugMsg
) << ind
+ AMK_PREFIX
<< "[ERROR!] "; }
107 static inline kdbgstream
fatal() { mutex
.lock(); QString ind
= indent(); mutex
.unlock(); return kdbgstream( QtDebugMsg
) << ind
+ AMK_PREFIX
; }
109 typedef kdbgstream DebugStream
;
114 typedef kndbgstream NoDebugStream
;
118 using Debug::warning
;
121 using Debug::DebugStream
;
123 /// Standard function announcer
124 #define DEBUG_FUNC_INFO { Debug::mutex.lock(); kDebug() << Debug::indent() << k_funcinfo << endl; Debug::mutex.unlock(); }
127 #define DEBUG_LINE_INFO { Debug::mutex.lock(); kDebug() << Debug::indent() << k_funcinfo << "Line: " << __LINE__ << endl; Debug::mutex.unlock(); }
129 /// Convenience macro for making a standard Debug::Block
130 #define DEBUG_BLOCK Debug::Block uniquelyNamedStackAllocatedStandardBlock( __PRETTY_FUNCTION__ );
132 /// Use this to remind yourself to finish the implementation of a function
133 #define AMAROK_NOTIMPLEMENTED warning() << "NOT-IMPLEMENTED: " << __PRETTY_FUNCTION__ << endl;
135 /// Use this to alert other developers to stop using a function
136 #define AMAROK_DEPRECATED warning() << "DEPRECATED: " << __PRETTY_FUNCTION__ << endl;
142 * @class Debug::Block
143 * @short Use this to label sections of your code
149 * Debug::Block myBlock( "section" );
151 * debug() << "output1" << endl;
152 * debug() << "output2" << endl;
157 * app: BEGIN: section
158 * app: [prefix] output1
159 * app: [prefix] output2
160 * app: END: section - Took 0.1s
170 Block( const char *label
)
174 gettimeofday( &m_start
, 0 );
176 kDebug() << "BEGIN: " << label
<< "\n";
177 Debug::modifieableIndent() += " ";
185 gettimeofday( &end
, 0 );
187 end
.tv_sec
-= m_start
.tv_sec
;
188 if( end
.tv_usec
< m_start
.tv_usec
) {
189 // Manually carry a one from the seconds field.
190 end
.tv_usec
+= 1000000;
193 end
.tv_usec
-= m_start
.tv_usec
;
195 double duration
= double(end
.tv_sec
) + (double(end
.tv_usec
) / 1000000.0);
197 Debug::modifieableIndent().truncate( Debug::indent().length() - 2 );
198 kDebug() << "END__: " << m_label
199 << " - Took " << QString::number( duration
, 'g', 2 ) << "s\n";
206 * @name Debug::stamp()
207 * @short To facilitate crash/freeze bugs, by making it easy to mark code that has been processed
219 * Will output (assuming the crash occurs in function2()
229 debug() << "| Stamp: " << ++n
<< endl
;
240 * @short You can pass anything to this and it will output it as a list
242 * debug() << (Debug::List() << anInt << aString << aQStringList << aDouble) << endl;
245 typedef QList
<QVariant
> List
;