summaryrefslogtreecommitdiffstats
path: root/kdecore/kdebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdecore/kdebug.cpp')
-rw-r--r--kdecore/kdebug.cpp596
1 files changed, 0 insertions, 596 deletions
diff --git a/kdecore/kdebug.cpp b/kdecore/kdebug.cpp
deleted file mode 100644
index ed1a3d60d..000000000
--- a/kdecore/kdebug.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/* This file is part of the KDE libraries
- Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
- 2002 Holger Freyther (freyther@kde.org)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#include "kdebug.h"
-
-#ifdef NDEBUG
-#undef kdDebug
-#undef kdBacktrace
-#endif
-
-#include "kdebugdcopiface.h"
-
-#include "kapplication.h"
-#include "kglobal.h"
-#include "kinstance.h"
-#include "kstandarddirs.h"
-
-#include <tqmessagebox.h>
-#include <klocale.h>
-#include <tqfile.h>
-#include <tqintdict.h>
-#include <tqstring.h>
-#include <tqdatetime.h>
-#include <tqpoint.h>
-#include <tqrect.h>
-#include <tqregion.h>
-#include <tqstringlist.h>
-#include <tqpen.h>
-#include <tqbrush.h>
-#include <tqsize.h>
-
-#include <kurl.h>
-
-#include <stdlib.h> // abort
-#include <unistd.h> // getpid
-#include <stdarg.h> // vararg stuff
-#include <ctype.h> // isprint
-#include <syslog.h>
-#include <errno.h>
-#include <string.h>
-#include <kconfig.h>
-#include "kstaticdeleter.h"
-#include <config.h>
-
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-#endif
-
-class KDebugEntry;
-
-class KDebugEntry
-{
-public:
- KDebugEntry (int n, const TQCString& d) {number=n; descr=d;}
- unsigned int number;
- TQCString descr;
-};
-
-static TQIntDict<KDebugEntry> *KDebugCache;
-
-static KStaticDeleter< TQIntDict<KDebugEntry> > kdd;
-
-static TQCString getDescrFromNum(unsigned int _num)
-{
- if (!KDebugCache) {
- kdd.setObject(KDebugCache, new TQIntDict<KDebugEntry>( 601 ));
- // Do not call this deleter from ~KApplication
- KGlobal::unregisterStaticDeleter(&kdd);
- KDebugCache->setAutoDelete(true);
- }
-
- KDebugEntry *ent = KDebugCache->find( _num );
- if ( ent )
- return ent->descr;
-
- if ( !KDebugCache->isEmpty() ) // areas already loaded
- return TQCString();
-
- TQString filename(locate("config","kdebug.areas"));
- if (filename.isEmpty())
- return TQCString();
-
- TQFile file(filename);
- if (!file.open(IO_ReadOnly)) {
- qWarning("Couldn't open %s", filename.local8Bit().data());
- file.close();
- return TQCString();
- }
-
- uint lineNumber=0;
- TQCString line(1024);
- int len;
-
- while (( len = file.readLine(line.data(),line.size()-1) ) > 0) {
- int i=0;
- ++lineNumber;
-
- while (line[i] && line[i] <= ' ')
- i++;
-
- unsigned char ch=line[i];
-
- if ( !ch || ch =='#' || ch =='\n')
- continue; // We have an eof, a comment or an empty line
-
- if (ch < '0' && ch > '9') {
- qWarning("Syntax error: no number (line %u)",lineNumber);
- continue;
- }
-
- const int numStart=i;
- do {
- ch=line[++i];
- } while ( ch >= '0' && ch <= '9');
-
- const TQ_ULONG number =line.mid(numStart,i).toULong();
-
- while (line[i] && line[i] <= ' ')
- i++;
-
- KDebugCache->insert(number, new KDebugEntry(number, line.mid(i, len-i-1)));
- }
- file.close();
-
- ent = KDebugCache->find( _num );
- if ( ent )
- return ent->descr;
-
- return TQCString();
-}
-
-enum DebugLevels {
- KDEBUG_INFO= 0,
- KDEBUG_WARN= 1,
- KDEBUG_ERROR= 2,
- KDEBUG_FATAL= 3
-};
-
-
-struct kDebugPrivate {
- kDebugPrivate() :
- oldarea(0), config(0) { }
-
- ~kDebugPrivate() { delete config; }
-
- TQCString aAreaName;
- unsigned int oldarea;
- KConfig *config;
-};
-
-static kDebugPrivate *kDebug_data = 0;
-static KStaticDeleter<kDebugPrivate> pcd;
-static KStaticDeleter<KDebugDCOPIface> dcopsd;
-static KDebugDCOPIface* kDebugDCOPIface = 0;
-
-static void kDebugBackend( unsigned short nLevel, unsigned int nArea, const char *data)
-{
- if ( !kDebug_data )
- {
- pcd.setObject(kDebug_data, new kDebugPrivate());
- // Do not call this deleter from ~KApplication
- KGlobal::unregisterStaticDeleter(&pcd);
-
- // create the dcop interface if it has not been created yet
- if (!kDebugDCOPIface)
- {
- kDebugDCOPIface = dcopsd.setObject(kDebugDCOPIface, new KDebugDCOPIface);
- }
- }
-
- if (!kDebug_data->config && KGlobal::_instance )
- {
- kDebug_data->config = new KConfig("kdebugrc", false, false);
- kDebug_data->config->setGroup("0");
-
- //AB: this is necessary here, otherwise all output with area 0 won't be
- //prefixed with anything, unless something with area != 0 is called before
- if ( KGlobal::_instance )
- kDebug_data->aAreaName = KGlobal::instance()->instanceName();
- }
-
- if (kDebug_data->config && kDebug_data->oldarea != nArea) {
- kDebug_data->config->setGroup( TQString::number(static_cast<int>(nArea)) );
- kDebug_data->oldarea = nArea;
- if ( nArea > 0 && KGlobal::_instance )
- kDebug_data->aAreaName = getDescrFromNum(nArea);
- if ((nArea == 0) || kDebug_data->aAreaName.isEmpty())
- if ( KGlobal::_instance )
- kDebug_data->aAreaName = KGlobal::instance()->instanceName();
- }
-
- int nPriority = 0;
- TQString aCaption;
-
- /* Determine output */
-
- TQString key;
- switch( nLevel )
- {
- case KDEBUG_INFO:
- key = "InfoOutput";
- aCaption = "Info";
- nPriority = LOG_INFO;
- break;
- case KDEBUG_WARN:
- key = "WarnOutput";
- aCaption = "Warning";
- nPriority = LOG_WARNING;
- break;
- case KDEBUG_FATAL:
- key = "FatalOutput";
- aCaption = "Fatal Error";
- nPriority = LOG_CRIT;
- break;
- case KDEBUG_ERROR:
- default:
- /* Programmer error, use "Error" as default */
- key = "ErrorOutput";
- aCaption = "Error";
- nPriority = LOG_ERR;
- break;
- }
-
- // if no output mode is specified default to no debug output
- short nOutput = kDebug_data->config ? kDebug_data->config->readNumEntry(key, 4) : 4;
-
- // If the application doesn't have a TQApplication object it can't use
- // a messagebox.
- if (!kapp && (nOutput == 1))
- nOutput = 2;
- else if ( nOutput == 4 && nLevel != KDEBUG_FATAL )
- return;
-
- const int BUFSIZE = 4096;
- char buf[BUFSIZE];
- if ( !kDebug_data->aAreaName.isEmpty() ) {
- strlcpy( buf, kDebug_data->aAreaName.data(), BUFSIZE );
- strlcat( buf, ": ", BUFSIZE );
- strlcat( buf, data, BUFSIZE );
- }
- else
- strlcpy( buf, data, BUFSIZE );
-
-
- // Output
- switch( nOutput )
- {
- case 0: // File
- {
- const char* aKey;
- switch( nLevel )
- {
- case KDEBUG_INFO:
- aKey = "InfoFilename";
- break;
- case KDEBUG_WARN:
- aKey = "WarnFilename";
- break;
- case KDEBUG_FATAL:
- aKey = "FatalFilename";
- break;
- case KDEBUG_ERROR:
- default:
- aKey = "ErrorFilename";
- break;
- }
- TQFile aOutputFile( kDebug_data->config->readPathEntry(aKey, "kdebug.dbg") );
- aOutputFile.open( (TQIODevice_OpenModeFlag)((int)IO_WriteOnly | (int)IO_Append | (int)IO_Raw) );
- aOutputFile.writeBlock( buf, strlen( buf ) );
- aOutputFile.close();
- break;
- }
- case 1: // Message Box
- {
- // Since we are in tdecore here, we cannot use KMsgBox and use
- // TQMessageBox instead
- if ( !kDebug_data->aAreaName.isEmpty() )
- aCaption += TQString("(%1)").arg( QString(kDebug_data->aAreaName) );
- TQMessageBox::warning( 0L, aCaption, data, i18n("&OK") );
- break;
- }
- case 2: // Shell
- {
- write( 2, buf, strlen( buf ) ); //fputs( buf, stderr );
- break;
- }
- case 3: // syslog
- {
- syslog( nPriority, "%s", buf);
- break;
- }
- }
-
- // check if we should abort
- if( ( nLevel == KDEBUG_FATAL )
- && ( !kDebug_data->config || kDebug_data->config->readNumEntry( "AbortFatal", 1 ) ) )
- abort();
-}
-
-kdbgstream &perror( kdbgstream &s) { return s << TQString(TQString::fromLocal8Bit(strerror(errno))); }
-kdbgstream kdDebug(int area) { return kdbgstream(area, KDEBUG_INFO); }
-kdbgstream kdDebug(bool cond, int area) { if (cond) return kdbgstream(area, KDEBUG_INFO); else return kdbgstream(0, 0, false); }
-
-kdbgstream kdError(int area) { return kdbgstream("ERROR: ", area, KDEBUG_ERROR); }
-kdbgstream kdError(bool cond, int area) { if (cond) return kdbgstream("ERROR: ", area, KDEBUG_ERROR); else return kdbgstream(0,0,false); }
-kdbgstream kdWarning(int area) { return kdbgstream("WARNING: ", area, KDEBUG_WARN); }
-kdbgstream kdWarning(bool cond, int area) { if (cond) return kdbgstream("WARNING: ", area, KDEBUG_WARN); else return kdbgstream(0,0,false); }
-kdbgstream kdFatal(int area) { return kdbgstream("FATAL: ", area, KDEBUG_FATAL); }
-kdbgstream kdFatal(bool cond, int area) { if (cond) return kdbgstream("FATAL: ", area, KDEBUG_FATAL); else return kdbgstream(0,0,false); }
-
-kdbgstream::kdbgstream(kdbgstream &str)
- : output(str.output), area(str.area), level(str.level), print(str.print)
-{
- str.output.truncate(0);
-}
-
-void kdbgstream::flush() {
- if (output.isEmpty() || !print)
- return;
- kDebugBackend( level, area, output.local8Bit().data() );
- output = TQString::null;
-}
-
-kdbgstream &kdbgstream::form(const char *format, ...)
-{
- char buf[4096];
- va_list arguments;
- va_start( arguments, format );
- vsnprintf( buf, sizeof(buf), format, arguments );
- va_end(arguments);
- *this << buf;
- return *this;
-}
-
-kdbgstream::~kdbgstream() {
- if (!output.isEmpty()) {
- fprintf(stderr, "ASSERT: debug output not ended with \\n\n");
- fprintf(stderr, "%s", kdBacktrace().latin1());
- *this << "\n";
- }
-}
-
-kdbgstream& kdbgstream::operator << (char ch)
-{
- if (!print) return *this;
- if (!isprint(ch))
- output += "\\x" + TQString::number( static_cast<uint>( ch ), 16 ).rightJustify(2, '0');
- else {
- output += ch;
- if (ch == '\n') flush();
- }
- return *this;
-}
-
-kdbgstream& kdbgstream::operator << (TQChar ch)
-{
- if (!print) return *this;
- if (!ch.isPrint())
- output += "\\x" + TQString::number( ch.tqunicode(), 16 ).rightJustify(2, '0');
- else {
- output += ch;
- if (ch == (QChar)'\n') flush();
- }
- return *this;
-}
-
-kdbgstream& kdbgstream::operator << (TQWidget* widget)
-{
- return *this << const_cast< const TQWidget* >( widget );
-}
-
-kdbgstream& kdbgstream::operator << (const TQWidget* widget)
-{
- TQString string, temp;
- // -----
- if(widget==0)
- {
- string=(TQString)"[Null pointer]";
- } else {
- temp.setNum((ulong)widget, 16);
- string=(TQString)"["+widget->className()+" pointer "
- + "(0x" + temp + ")";
- if(widget->name(0)==0)
- {
- string += " to unnamed widget, ";
- } else {
- string += (TQString)" to widget " + widget->name() + ", ";
- }
- string += "geometry="
- + TQString().setNum(widget->width())
- + "x"+TQString().setNum(widget->height())
- + "+"+TQString().setNum(widget->x())
- + "+"+TQString().setNum(widget->y())
- + "]";
- }
- if (!print)
- {
- return *this;
- }
- output += string;
- if (output.tqat(output.length() -1 ) == (QChar)'\n')
- {
- flush();
- }
- return *this;
-}
-/*
- * either use 'output' directly and do the flush if needed
- * or use the TQString operator which calls the char* operator
- *
- */
-kdbgstream& kdbgstream::operator<<( const TQDateTime& time) {
- *this << time.toString();
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQDate& date) {
- *this << TQString(date.toString());
-
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQTime& time ) {
- *this << TQString(time.toString());
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQPoint& p ) {
- *this << "(" << p.x() << ", " << p.y() << ")";
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQSize& s ) {
- *this << "[" << s.width() << "x" << s.height() << "]";
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQRect& r ) {
- *this << "[" << r.x() << "," << r.y() << " - " << r.width() << "x" << r.height() << "]";
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQRegion& reg ) {
- *this<< "[ ";
-
- TQMemArray<TQRect>rs=reg.tqrects();
- for (uint i=0;i<rs.size();++i)
- *this << TQString(TQString("[%1,%2 - %3x%4] ").arg(rs[i].x()).arg(rs[i].y()).arg(rs[i].width()).arg(rs[i].height() )) ;
-
- *this <<"]";
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const KURL& u ) {
- *this << u.prettyURL();
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQStringList& l ) {
- *this << "(";
- *this << l.join(",");
- *this << ")";
-
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQColor& c ) {
- if ( c.isValid() )
- *this << TQString(c.name());
- else
- *this << "(invalid/default)";
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQPen& p ) {
- static const char* const s_penStyles[] = {
- "NoPen", "SolidLine", "DashLine", "DotLine", "DashDotLine",
- "DashDotDotLine" };
- static const char* const s_capStyles[] = {
- "FlatCap", "SquareCap", "RoundCap" };
- *this << "[ style:";
- *this << s_penStyles[ p.style() ];
- *this << " width:";
- *this << p.width();
- *this << " color:";
- if ( p.color().isValid() )
- *this << TQString(p.color().name());
- else
- *this <<"(invalid/default)";
- if ( p.width() > 0 ) // cap style doesn't matter, otherwise
- {
- *this << " capstyle:";
- *this << s_capStyles[ p.capStyle() >> 4 ];
- // join style omitted
- }
- *this <<" ]";
- return *this;
-}
-kdbgstream& kdbgstream::operator<<( const TQBrush& b) {
- static const char* const s_brushStyles[] = {
- "NoBrush", "SolidPattern", "Dense1Pattern", "Dense2Pattern", "Dense3Pattern",
- "Dense4Pattern", "Dense5Pattern", "Dense6Pattern", "Dense7Pattern",
- "HorPattern", "VerPattern", "CrossPattern", "BDiagPattern", "FDiagPattern",
- "DiagCrossPattern" };
-
- *this <<"[ style: ";
- *this <<s_brushStyles[ b.style() ];
- *this <<" color: ";
- // can't use operator<<(str, b.color()) because that terminates a kdbgstream (flushes)
- if ( b.color().isValid() )
- *this << TQString(b.color().name()) ;
- else
- *this <<"(invalid/default)";
- if ( b.pixmap() )
- *this <<" has a pixmap";
- *this <<" ]";
- return *this;
-}
-
-kdbgstream& kdbgstream::operator<<( const TQVariant& v) {
- *this << "[variant: ";
- *this << v.typeName();
- // For now we just attempt a conversion to string.
- // Feel free to switch(v.type()) and improve the output.
- *this << " toString=";
- *this << v.toString();
- *this << "]";
- return *this;
-}
-
-kdbgstream& kdbgstream::operator<<( const TQByteArray& data) {
- if (!print) return *this;
- output += '[';
- unsigned int i = 0;
- unsigned int sz = QMIN( data.size(), 64 );
- for ( ; i < sz ; ++i ) {
- output += TQString::number( (unsigned char) data[i], 16 ).rightJustify(2, '0');
- if ( i < sz )
- output += ' ';
- }
- if ( sz < data.size() )
- output += "...";
- output += ']';
- return *this;
-}
-
-TQString kdBacktrace(int levels)
-{
- TQString s;
-#ifdef HAVE_BACKTRACE
- void* trace[256];
- int n = backtrace(trace, 256);
- if (!n)
- return s;
- char** strings = backtrace_symbols (trace, n);
-
- if ( levels != -1 )
- n = QMIN( n, levels );
- s = "[\n";
-
- for (int i = 0; i < n; ++i)
- s += TQString::number(i) +
- TQString::tqfromLatin1(": ") +
- TQString::tqfromLatin1(strings[i]) + TQString::tqfromLatin1("\n");
- s += "]\n";
- if (strings)
- free (strings);
-#endif
- return s;
-}
-
-TQString kdBacktrace()
-{
- return kdBacktrace(-1 /*all*/);
-}
-
-void kdClearDebugConfig()
-{
- if (kDebug_data) {
- delete kDebug_data->config;
- kDebug_data->config = 0;
- }
-}
-
-
-// Needed for --enable-final
-#ifdef NDEBUG
-#define kdDebug kndDebug
-#endif