1 // Author: Max Howell <max.howell@methylblue.com>, (C) 2003-5
2 // Copyright: See COPYING file that comes with this distribution
13 #include <Q3ValueList>
16 #include <QApplication>
19 #include "amarok_export.h"
22 #define __PRETTY_FUNCTION__ __FUNCTION__
27 * @short kdebug with indentation functionality and convenience macros
28 * @author Max Howell <max.howell@methylblue.com>
32 * #define DEBUG_PREFIX "Blah"
37 * Debug::Block myBlock( __PRETTY_FUNCTION__ );
39 * debug() << "output1" << endl;
40 * debug() << "output2" << endl;
45 * app: BEGIN: void function()
48 * app: END: void function(): Took 0.1s
57 extern AMAROK_EXPORT QMutex mutex
; // defined in app.cpp
59 // we can't use a statically instantiated QCString for the indent, because
60 // static namespaces are unique to each dlopened library. So we piggy back
61 // the QCString on the KApplication instance
63 #define qOApp reinterpret_cast<QObject*>(qApp)
64 class Indent
: QObject
66 friend QByteArray
&modifieableIndent();
67 Indent() : QObject( qOApp
) { setObjectName( "DEBUG_indent" ); }
71 inline QByteArray
&modifieableIndent()
73 QObject
* o
= qOApp
? qOApp
->findChild
<QObject
*>( "DEBUG_indent" ) : 0;
74 QByteArray
&ret
= (o
? static_cast<Indent
*>( o
) : new Indent
)->m_string
;
78 inline QByteArray
indent()
80 return modifieableIndent();
86 static inline kndbgstream
debug() { return kndbgstream(); }
87 static inline kndbgstream
warning() { return kndbgstream(); }
88 static inline kndbgstream
error() { return kndbgstream(); }
89 static inline kndbgstream
fatal() { return kndbgstream(); }
91 typedef kndbgstream DebugStream
;
96 #define AMK_PREFIX "[" DEBUG_PREFIX "] "
107 static inline kdbgstream
debug() { mutex
.lock(); QByteArray ind
= indent(); mutex
.unlock(); return kdbgstream( ind
.data(), 0, KDEBUG_INFO
) << AMK_PREFIX
; }
108 static inline kdbgstream
warning() { mutex
.lock(); QByteArray ind
= indent(); mutex
.unlock(); return kdbgstream( ind
.data(), 0, KDEBUG_WARN
) << AMK_PREFIX
<< "[WARNING!] "; }
109 static inline kdbgstream
error() { mutex
.lock(); QByteArray ind
= indent(); mutex
.unlock(); return kdbgstream( ind
.data(), 0, KDEBUG_ERROR
) << AMK_PREFIX
<< "[ERROR!] "; }
110 static inline kdbgstream
fatal() { mutex
.lock(); QByteArray ind
= indent(); mutex
.unlock(); return kdbgstream( ind
.data(), 0, KDEBUG_FATAL
) << AMK_PREFIX
; }
112 typedef kdbgstream DebugStream
;
117 typedef kndbgstream NoDebugStream
;
121 using Debug::warning
;
124 using Debug::DebugStream
;
126 /// Standard function announcer
127 #define DEBUG_FUNC_INFO { Debug::mutex.lock(); kDebug() << Debug::indent() << k_funcinfo << endl; Debug::mutex.unlock(); }
130 #define DEBUG_LINE_INFO { Debug::mutex.lock(); kDebug() << Debug::indent() << k_funcinfo << "Line: " << __LINE__ << endl; Debug::mutex.unlock(); }
132 /// Convenience macro for making a standard Debug::Block
133 #define DEBUG_BLOCK Debug::Block uniquelyNamedStackAllocatedStandardBlock( __PRETTY_FUNCTION__ );
135 /// Use this to remind yourself to finish the implementation of a function
136 #define AMAROK_NOTIMPLEMENTED warning() << "NOT-IMPLEMENTED: " << __PRETTY_FUNCTION__ << endl;
138 /// Use this to alert other developers to stop using a function
139 #define AMAROK_DEPRECATED warning() << "DEPRECATED: " << __PRETTY_FUNCTION__ << endl;
145 * @class Debug::Block
146 * @short Use this to label sections of your code
152 * Debug::Block myBlock( "section" );
154 * debug() << "output1" << endl;
155 * debug() << "output2" << endl;
160 * app: BEGIN: section
161 * app: [prefix] output1
162 * app: [prefix] output2
163 * app: END: section - Took 0.1s
173 Block( const char *label
)
177 gettimeofday( &m_start
, 0 );
179 kDebug() << "BEGIN: " << label
<< "\n";
180 Debug::modifieableIndent() += " ";
188 gettimeofday( &end
, 0 );
190 end
.tv_sec
-= m_start
.tv_sec
;
191 if( end
.tv_usec
< m_start
.tv_usec
) {
192 // Manually carry a one from the seconds field.
193 end
.tv_usec
+= 1000000;
196 end
.tv_usec
-= m_start
.tv_usec
;
198 double duration
= double(end
.tv_sec
) + (double(end
.tv_usec
) / 1000000.0);
200 Debug::modifieableIndent().truncate( Debug::indent().length() - 2 );
201 kDebug() << "END__: " << m_label
202 << " - Took " << QString::number( duration
, 'g', 2 ) << "s\n";
209 * @name Debug::stamp()
210 * @short To facilitate crash/freeze bugs, by making it easy to mark code that has been processed
222 * Will output (assuming the crash occurs in function2()
232 debug() << "| Stamp: " << ++n
<< endl
;
243 * @short You can pass anything to this and it will output it as a list
245 * debug() << (Debug::List() << anInt << aString << aQStringList << aDouble) << endl;
248 typedef Q3ValueList
<QVariant
> List
;