28 #include "kdebugdcopiface.h"
30 #include "kapplication.h"
32 #include "kinstance.h"
33 #include "kstandarddirs.h"
35 #include <tqmessagebox.h>
38 #include <tqintdict.h>
40 #include <tqdatetime.h>
44 #include <tqstringlist.h>
59 #include "kstaticdeleter.h"
71 KDebugEntry (
int n,
const TQCString& d) {number=n; descr=d;}
76 static TQIntDict<KDebugEntry> *KDebugCache;
80 static TQCString getDescrFromNum(
unsigned int _num)
83 kdd.
setObject(KDebugCache,
new TQIntDict<KDebugEntry>( 601 ));
86 KDebugCache->setAutoDelete(
true);
89 KDebugEntry *ent = KDebugCache->find( _num );
93 if ( !KDebugCache->isEmpty() )
96 TQString filename(
locate(
"config",
"kdebug.areas"));
97 if (filename.isEmpty())
100 TQFile file(filename);
101 if (!file.open(IO_ReadOnly)) {
102 qWarning(
"Couldn't open %s", filename.local8Bit().data());
108 TQCString line(1024);
111 while (( len = file.readLine(line.data(),line.size()-1) ) > 0) {
115 while (line[i] && line[i] <=
' ')
118 unsigned char ch=line[i];
120 if ( !ch || ch ==
'#' || ch ==
'\n')
123 if (ch < '0' && ch >
'9') {
124 qWarning(
"Syntax error: no number (line %u)",lineNumber);
128 const int numStart=i;
131 }
while ( ch >=
'0' && ch <=
'9');
133 const TQ_ULONG number =line.mid(numStart,i).toULong();
135 while (line[i] && line[i] <=
' ')
138 KDebugCache->insert(number,
new KDebugEntry(number, line.mid(i, len-i-1)));
142 ent = KDebugCache->find( _num );
157 struct kDebugPrivate {
159 oldarea(0), config(0) { }
161 ~kDebugPrivate() {
delete config; }
164 unsigned int oldarea;
168 static kDebugPrivate *kDebug_data = 0;
173 static void kDebugBackend(
unsigned short nLevel,
unsigned int nArea,
const char *data)
177 pcd.
setObject(kDebug_data,
new kDebugPrivate());
182 if (!kDebugDCOPIface)
188 if (!kDebug_data->config && KGlobal::_instance )
190 kDebug_data->config =
new KConfig(
"kdebugrc",
false,
false);
191 kDebug_data->config->setGroup(
"0");
195 if ( KGlobal::_instance )
199 if (kDebug_data->config && kDebug_data->oldarea != nArea) {
200 kDebug_data->config->setGroup( TQString::number(static_cast<int>(nArea)) );
201 kDebug_data->oldarea = nArea;
202 if ( nArea > 0 && KGlobal::_instance )
203 kDebug_data->aAreaName = getDescrFromNum(nArea);
204 if ((nArea == 0) || kDebug_data->aAreaName.isEmpty())
205 if ( KGlobal::_instance )
220 nPriority = LOG_INFO;
224 aCaption =
"Warning";
225 nPriority = LOG_WARNING;
229 aCaption =
"Fatal Error";
230 nPriority = LOG_CRIT;
242 short nOutput = kDebug_data->config ? kDebug_data->config->readNumEntry(key, 4) : 4;
246 if (!kapp && (nOutput == 1))
248 else if ( nOutput == 4 && nLevel != KDEBUG_FATAL )
251 const int BUFSIZE = 4096;
253 if ( !kDebug_data->aAreaName.isEmpty() ) {
254 strlcpy( buf, kDebug_data->aAreaName.data(), BUFSIZE );
255 strlcat( buf,
": ", BUFSIZE );
256 strlcat( buf, data, BUFSIZE );
259 strlcpy( buf, data, BUFSIZE );
271 aKey =
"InfoFilename";
274 aKey =
"WarnFilename";
277 aKey =
"FatalFilename";
281 aKey =
"ErrorFilename";
284 TQFile aOutputFile( kDebug_data->config->readPathEntry(aKey,
"kdebug.dbg") );
285 aOutputFile.open( (TQIODevice_OpenModeFlag)((
int)IO_WriteOnly | (
int)IO_Append | (
int)IO_Raw) );
286 aOutputFile.writeBlock( buf, strlen( buf ) );
294 if ( !kDebug_data->aAreaName.isEmpty() )
295 aCaption += TQString(
"(%1)").arg( QString(kDebug_data->aAreaName) );
296 TQMessageBox::warning( 0L, aCaption, data,
i18n(
"&OK") );
301 write( 2, buf, strlen( buf ) );
306 syslog( nPriority,
"%s", buf);
312 if( ( nLevel == KDEBUG_FATAL )
313 && ( !kDebug_data->config || kDebug_data->config->readNumEntry(
"AbortFatal", 1 ) ) )
317 kdbgstream &perror(
kdbgstream &s) {
return s << TQString(TQString::fromLocal8Bit(strerror(errno))); }
329 : output(str.output), area(str.area), level(str.level), print(str.print)
331 str.output.truncate(0);
335 if (output.isEmpty() || !print)
337 kDebugBackend( level, area, output.local8Bit().data() );
338 output = TQString::null;
345 va_start( arguments, format );
346 vsnprintf( buf,
sizeof(buf), format, arguments );
352 kdbgstream::~kdbgstream() {
353 if (!output.isEmpty()) {
354 fprintf(stderr,
"ASSERT: debug output not ended with \\n\n");
355 TQString backtrace = kdBacktrace();
356 if (backtrace.ascii() != NULL) {
357 fprintf(stderr,
"%s", backtrace.latin1());
365 if (!print)
return *
this;
367 output +=
"\\x" + TQString::number( static_cast<uint>( ch ), 16 ).rightJustify(2,
'0');
370 if (ch ==
'\n')
flush();
377 if (!print)
return *
this;
379 output +=
"\\x" + TQString::number( ch.unicode(), 16 ).rightJustify(2,
'0');
382 if (ch == QChar(
'\n'))
flush();
389 return *this << const_cast< const TQWidget* >( widget );
394 TQString string, temp;
398 string=(TQString)
"[Null pointer]";
400 temp.setNum((ulong)widget, 16);
401 string=(TQString)
"["+widget->className()+
" pointer "
402 +
"(0x" + temp +
")";
403 if(widget->name(0)==0)
405 string +=
" to unnamed widget, ";
407 string += (TQString)
" to widget " + widget->name() +
", ";
409 string +=
"geometry="
410 + TQString().setNum(widget->width())
411 +
"x"+TQString().setNum(widget->height())
412 +
"+"+TQString().setNum(widget->x())
413 +
"+"+TQString().setNum(widget->y())
421 if (output.at(output.length() -1 ) == QChar(
'\n'))
433 *
this << time.toString();
437 *
this << TQString(date.toString());
442 *
this << TQString(time.toString());
446 *
this <<
"(" << p.x() <<
", " << p.y() <<
")";
450 *
this <<
"[" << s.width() <<
"x" << s.height() <<
"]";
454 *
this <<
"[" << r.x() <<
"," << r.y() <<
" - " << r.width() <<
"x" << r.height() <<
"]";
460 TQMemArray<TQRect>rs=reg.rects();
461 for (uint i=0;i<rs.size();++i)
462 *
this << TQString(TQString(
"[%1,%2 - %3x%4] ").arg(rs[i].x()).arg(rs[i].y()).arg(rs[i].width()).arg(rs[i].height() )) ;
473 *
this << l.join(
",");
480 *
this << TQString(c.name());
482 *
this <<
"(invalid/default)";
486 static const char*
const s_penStyles[] = {
487 "NoPen",
"SolidLine",
"DashLine",
"DotLine",
"DashDotLine",
489 static const char*
const s_capStyles[] = {
490 "FlatCap",
"SquareCap",
"RoundCap" };
492 *
this << s_penStyles[ p.style() ];
496 if ( p.color().isValid() )
497 *
this << TQString(p.color().name());
499 *
this <<
"(invalid/default)";
502 *
this <<
" capstyle:";
503 *
this << s_capStyles[ p.capStyle() >> 4 ];
510 static const char*
const s_brushStyles[] = {
511 "NoBrush",
"SolidPattern",
"Dense1Pattern",
"Dense2Pattern",
"Dense3Pattern",
512 "Dense4Pattern",
"Dense5Pattern",
"Dense6Pattern",
"Dense7Pattern",
513 "HorPattern",
"VerPattern",
"CrossPattern",
"BDiagPattern",
"FDiagPattern",
514 "DiagCrossPattern" };
517 *
this <<s_brushStyles[ b.style() ];
520 if ( b.color().isValid() )
521 *
this << TQString(b.color().name()) ;
523 *
this <<
"(invalid/default)";
525 *
this <<
" has a pixmap";
531 *
this <<
"[variant: ";
532 *
this << v.typeName();
535 *
this <<
" toString=";
536 *
this << v.toString();
542 if (!print)
return *
this;
545 unsigned int sz = QMIN( data.size(), 64 );
546 for ( ; i < sz ; ++i ) {
547 output += TQString::number( (
unsigned char) data[i], 16 ).rightJustify(2,
'0');
551 if ( sz < data.size() )
560 #ifdef HAVE_BACKTRACE
562 int n = backtrace(trace, 256);
565 char** strings = backtrace_symbols (trace, n);
568 n = QMIN( n, levels );
571 for (
int i = 0; i < n; ++i)
572 s += TQString::number(i) +
573 TQString::fromLatin1(
": ") +
574 TQString::fromLatin1(strings[i]) + TQString::fromLatin1(
"\n");
590 delete kDebug_data->config;
591 kDebug_data->config = 0;
598 #define kdDebug kndDebug