21#define KDE_EXTENDED_DEBUG_OUTPUT
23#ifndef QT_NO_CAST_FROM_ASCII
24#define QT_NO_CAST_FROM_ASCII
26#ifndef QT_NO_CAST_TO_ASCII
27#define QT_NO_CAST_TO_ASCII
34#include <QThreadStorage>
71#include <QtCore/QFile>
72#include <QtCore/QHash>
73#include <QtCore/QObject>
74#include <QtCore/QChar>
75#include <QtCore/QCoreApplication>
93#define HAVE_BACKTRACE (1)
99#define HAVE_BACKTRACE_DEMANGLE
116 bool isSequential()
const {
return true; }
119 qint64 writeData(
const char *,
qint64 len) {
return len; }
122class KSyslogDebugStream:
public KNoDebugStream
130 const QByteArray buf(data, len);
131 syslog(m_priority,
"%s", buf.constData());
135 void setPriority(
int priority) { m_priority = priority; }
140class KFileDebugStream:
public KNoDebugStream
148 if (
aOutputFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)) {
149 QByteArray buf = QByteArray::fromRawData(data, len);
156 void setFileName(
const QString&
fn) { m_fileName =
fn; }
161class KMessageBoxDebugStream:
public KNoDebugStream
169 QString msg = QString::fromLatin1(data, len);
174 void setCaption(
const QString& h) { m_caption = h; }
179class KLineEndStrippingDebugStream:
public KNoDebugStream
185 QByteArray buf = QByteArray::fromRawData(data, len);
195 MessageBoxOutput = 1,
199 DefaultOutput = QtOutput,
204 inline Area() { clear(); }
205 void clear(OutputMode
set = Unknown)
207 for (
int i = 0; i < 4; ++i) {
208 logFileName[i].clear();
220 :
config(0), kDebugDBusIface(0), m_disableAll(
false), m_seenMainComponent(
false)
241 for (
int i = 0; i < 8; i++) {
242 m_nullOutputYesNoCache[i] = -1;
250 delete kDebugDBusIface;
258 Area &areaData = cache[0];
263 m_seenMainComponent =
true;
265 areaData.name =
qApp ?
qAppName().toUtf8() : QByteArray(
"unnamed app");
266 m_seenMainComponent =
false;
270 for (
int i = 0; i < 8; i++) {
271 m_nullOutputYesNoCache[i] = -1;
275 if (filename.isEmpty()) {
278 QFile file(filename);
279 if (!file.open(QIODevice::ReadOnly)) {
280 qWarning(
"Couldn't open %s", filename.toLocal8Bit().constData());
287 while (!file.atEnd()) {
288 const QByteArray line = file.readLine().trimmed();
294 unsigned char ch=line[i];
299 if (
ch <
'0' ||
ch >
'9') {
306 }
while (
ch >=
'0' &&
ch <=
'9' && i < line.length());
308 unsigned int number = line.left(i).toUInt();
310 while (i < line.length() && line[i] <=
' ')
314 areaData.name = line.mid(i);
315 cache.insert(number, areaData);
320 inline int level(QtMsgType type)
358 const int mode =
cg.readEntry(key,
int(
enableByDefault ? DefaultOutput : NoOutput));
359 return OutputMode(mode);
362 QString logFileName(QtMsgType type,
unsigned int area)
371 aKey =
"InfoFilename";
374 aKey =
"WarnFilename";
377 aKey =
"FatalFilename";
381 aKey =
"ErrorFilename";
398 Cache::Iterator areaData(QtMsgType type,
unsigned int num,
bool enableByDefault =
true)
400 if (!cache.contains(0)) {
407 m_seenMainComponent =
true;
410 Cache::Iterator
it = cache.find(
num);
411 if (
it == cache.end()) {
427 const int lev = level(type);
429 if (
it->mode[
lev] == Unknown)
431 if (
it->mode[
lev] == FileOutput &&
it->logFileName[
lev].isEmpty())
432 it->logFileName[
lev] = logFileName(type,
num);
441 if (!filewriter.hasLocalData())
442 filewriter.setLocalData(
new KFileDebugStream);
443 filewriter.localData()->setFileName(fileName);
444 QDebug result(filewriter.localData());
448 QDebug setupMessageBoxWriter(QtMsgType type,
const QByteArray &
areaName)
450 if (!messageboxwriter.hasLocalData())
451 messageboxwriter.setLocalData(
new KMessageBoxDebugStream);
452 QDebug result(messageboxwriter.localData());
473 messageboxwriter.localData()->setCaption(QString::fromLatin1(
header));
477 QDebug setupSyslogWriter(QtMsgType type)
479 if (!syslogwriter.hasLocalData())
480 syslogwriter.setLocalData(
new KSyslogDebugStream);
481 QDebug result(syslogwriter.localData());
499 syslogwriter.localData()->setPriority(level);
503 QDebug setupQtWriter(QtMsgType type)
514 return QDebug(&lineendstrippingwriter);
517 QDebug printHeader(
QDebug s,
const QByteArray &
areaName,
const char * file,
int line,
const char *funcinfo, QtMsgType type,
bool colored)
519#ifdef KDE_EXTENDED_DEBUG_OUTPUT
526 QByteArray programName;
535 s <<
qPrintable(QDateTime::currentDateTime().time().toString());
541 programName = cache.value(0).name;
542 if (programName.isEmpty()) {
543 if (QCoreApplication::instance())
544 programName = QCoreApplication::instance()->applicationName().toLocal8Bit();
546 programName =
"<unknown program name>";
548 s << programName.constData() <<
"(" << unsigned(
getpid()) <<
")";
556 if (m_indentString.hasLocalData()) {
557 s << m_indentString.localData()->toLatin1().constData();
561 s <<
' ' << file <<
':' << line <<
' ';
575 QByteArray info = funcinfo;
576 int pos = info.indexOf(
'(');
578 "Bug in kDebug(): I don't know how to parse this function name");
579 while (info.at(pos - 1) ==
' ')
581 pos = info.indexOf(
'(', pos + 1);
588 index = info.indexOf(
"<unnamed>::", index);
592 if ( info.at(index-1) !=
':' )
593 info.insert(index,
' ');
595 index +=
strlen(
"<unnamed>::");
597 pos = info.lastIndexOf(
' ');
601 pos < info.lastIndexOf(
">::"))
606 if (pos + 1 == info.length())
608 s <<
" " << funcinfo;
610 s <<
" " << info.constData() + pos + 1;
612 s <<
" " << funcinfo;
628 const char *funcinfo)
632 Cache::Iterator
it = areaData(type,
area);
633 OutputMode mode =
it->mode[level(type)];
635 QString file =
it->logFileName[level(type)];
646 s = setupFileWriter(file);
648 case MessageBoxOutput:
649 s = setupMessageBoxWriter(type,
areaName);
652 s = setupSyslogWriter(type);
660 s = setupQtWriter(type);
678 const QString key = QString::fromLatin1(
"InfoOutput");
679 if (!
cg.hasKey(key)) {
680 cg.writeEntry(key,
int(
enabled ? KDebugPrivate::QtOutput : KDebugPrivate::NoOutput));
691 bool m_seenMainComponent;
692 int m_nullOutputYesNoCache[8];
694 KNoDebugStream devnull;
699 KLineEndStrippingDebugStream lineendstrippingwriter;
707#ifdef HAVE_BACKTRACE_DEMANGLE
708 const int len =
strlen(name);
709 QByteArray in = QByteArray::fromRawData(name, len);
730 return QString::fromLatin1(name);
748 for (
int i = 0; i <
n; ++i)
767 qCritical().nospace() <<
"kDebugStream called after destruction (from "
768 << (funcinfo ? funcinfo :
"")
769 << (file ?
" file " :
" unknown file")
771 <<
" line " << line <<
")";
795 s.nospace() <<
"KUrl(" << url.
prettyUrl() <<
")";
807 KDebugPrivate::Cache::Iterator
it = d->cache.begin(),
808 end = d->cache.end();
809 for ( ;
it != end; ++
it)
812 for (
int i = 0; i < 8; i++) {
813 d->m_nullOutputYesNoCache[i] = -1;
834 int *entries = d->m_nullOutputYesNoCache;
835 for (
int i = 0; i < 8; i += 2) {
836 if (entries[i] ==
area) {
837 return entries[i + 1];
843 const bool ret =
it->mode[d->level(type)] == KDebugPrivate::NoOutput;
847 int *entries = d->m_nullOutputYesNoCache;
865 KDebugPrivate::Area areaData;
873#ifndef KDE_NO_DEBUG_OUTPUT
875class KDebug::Block::Private
882 : m_label(0), m_area(
area), d(0)
904 const double duration = m_startTime.elapsed() / 1000.0;
912 << d->m_label.constData()
913 <<
qPrintable(QString::fromLatin1(
"[Took: %3s]").arg(QString::number(
duration,
'g', 2)));
917 << d->m_label.constData()
918 <<
qPrintable(QString::fromLatin1(
"[DELAY Took (quite long) %3s]").arg(QString::number(
duration,
'g', 2)));
bool hasGroup(const QString &group) const
Returns true if the specified group is known about.
KConfigGroup group(const QByteArray &group)
Returns an object for the named subgroup.
A class for one specific group in a KConfig object.
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
The central class of the KDE configuration data system.
@ NoGlobals
Cascade to system settings, but omit user's globals.
A class representing a date and time with an associated time zone.
bool isDateOnly() const
Returns whether the instance represents a date/time or a date-only value.
QString toString(const QString &format) const
Returns the date/time as a string.
@ QtTextDate
Same format as Qt::TextDate (i.e.
@ ISODate
ISO 8601 format, i.e.
D-Bus interface to KDebug.
Block(const char *label, int area=KDE_DEFAULT_DEBUG_AREA)
static bool hasNullOutput(QtMsgType type, bool condition, int area, bool enableByDefault)
static int registerArea(const QByteArray &areaName, bool enabled=true)
static bool hasNullOutputQtDebugMsg(int area=KDE_DEFAULT_DEBUG_AREA)
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is just for convenience.
Represents and parses a URL.
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string in human-friendly format.
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
QDebug operator<<(QDebug s, const KDateTime &time)
QDebug kDebugStream(QtMsgType level, int area, const char *file, int line, const char *funcinfo)
QString kRealBacktrace(int levels)
Date/times with associated time zone.
QDebug perror(QDebug s, KDebugTag)
bool kde_kdebug_enable_dbus_interface
static QString maybeDemangledName(char *name)
const KComponentData & mainComponent()
Returns the global component data.
KSharedConfigPtr config()
Returns the general config object.
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
Display a long message of a certain type.
@ Information
Information message.