author | mickeyl <mickeyl> | 2003-03-28 15:11:52 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-03-28 15:11:52 (UTC) |
commit | 11304d02942e9fa493e4e80943a828f9c65f6772 (patch) (unidiff) | |
tree | a0223c10c067e1afc70d15c2b82be3f3c15e41ae /libopie2/opiecore/odebug.cpp | |
parent | b271d575fa05cf570a1a829136517761bd47e69b (diff) | |
download | opie-11304d02942e9fa493e4e80943a828f9c65f6772.zip opie-11304d02942e9fa493e4e80943a828f9c65f6772.tar.gz opie-11304d02942e9fa493e4e80943a828f9c65f6772.tar.bz2 |
skeleton and the start of libopie2, please read README, ROADMAP and STATUS and comment...
Diffstat (limited to 'libopie2/opiecore/odebug.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opiecore/odebug.cpp | 628 |
1 files changed, 628 insertions, 0 deletions
diff --git a/libopie2/opiecore/odebug.cpp b/libopie2/opiecore/odebug.cpp new file mode 100644 index 0000000..b4eaf2d --- a/dev/null +++ b/libopie2/opiecore/odebug.cpp | |||
@@ -0,0 +1,628 @@ | |||
1 | /* | ||
2 | This file is part of the Opie Project | ||
3 | (C) 2003 Michael 'Mickey' Lauer (mickey@tm.informatik.uni-frankfurt.de) | ||
4 | Inspired by the KDE debug classes, which are | ||
5 | (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) | ||
6 | (C) 2002 Holger Freyther (freyther@kde.org) | ||
7 | =. | ||
8 | .=l. | ||
9 | .>+-= | ||
10 | _;:, .> :=|. This program is free software; you can | ||
11 | .> <`_, > . <= redistribute it and/or modify it under | ||
12 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | ||
13 | .="- .-=="i, .._ License as published by the Free Software | ||
14 | - . .-<_> .<> Foundation; either version 2 of the License, | ||
15 | ._= =} : or (at your option) any later version. | ||
16 | .%`+i> _;_. | ||
17 | .i_,=:_. -<s. This program is distributed in the hope that | ||
18 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | ||
19 | : .. .:, . . . without even the implied warranty of | ||
20 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | ||
21 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | ||
22 | ..}^=.= = ; Library General Public License for more | ||
23 | ++= -. .` .: details. | ||
24 | : = ...= . :.=- | ||
25 | -. .:....=;==+<; You should have received a copy of the GNU | ||
26 | -_. . . )=. = Library General Public License along with | ||
27 | -- :-=` this library; see the file COPYING.LIB. | ||
28 | If not, write to the Free Software Foundation, | ||
29 | Inc., 59 Temple Place - Suite 330, | ||
30 | Boston, MA 02111-1307, USA. | ||
31 | */ | ||
32 | |||
33 | // Include this header without OPIE_NO_DEBUG defined to avoid having the oDebugInfo | ||
34 | // functions inlined to noops (which would then conflict with their definition here). | ||
35 | |||
36 | #include <opie2/odebug.h> | ||
37 | |||
38 | #ifdef OPIE_NO_DEBUG | ||
39 | #undef odDebug | ||
40 | #undef odBacktrace | ||
41 | #endif | ||
42 | |||
43 | /* OPIE */ | ||
44 | |||
45 | #include <opie2/oapplication.h> | ||
46 | #include <opie2/oglobalsettings.h> | ||
47 | #include <opie2/oconfig.h> | ||
48 | |||
49 | /* QT */ | ||
50 | |||
51 | #include <qbrush.h> | ||
52 | #include <qdatetime.h> | ||
53 | #include <qfile.h> | ||
54 | #include <qhostaddress.h> | ||
55 | #include <qmessagebox.h> | ||
56 | #include <qintdict.h> | ||
57 | #include <qpoint.h> | ||
58 | #include <qrect.h> | ||
59 | #include <qregion.h> | ||
60 | #include <qsize.h> | ||
61 | #include <qsocketdevice.h> | ||
62 | #include <qstring.h> | ||
63 | #include <qstringlist.h> | ||
64 | #include <qtextstream.h> | ||
65 | |||
66 | /* UNIX */ | ||
67 | |||
68 | #include <stdlib.h> // abort | ||
69 | #include <unistd.h> // getpid | ||
70 | #include <stdarg.h> // vararg stuff | ||
71 | #include <ctype.h> // isprint | ||
72 | #include <syslog.h> | ||
73 | #include <errno.h> | ||
74 | #include <string.h> | ||
75 | |||
76 | #ifndef OPIE_NO_BACKTRACE | ||
77 | #include <execinfo.h> | ||
78 | #endif | ||
79 | |||
80 | |||
81 | /*====================================================================================== | ||
82 | * debug levels | ||
83 | *======================================================================================*/ | ||
84 | |||
85 | enum DebugLevels { | ||
86 | ODEBUG_INFO = 0, | ||
87 | ODEBUG_WARN = 1, | ||
88 | ODEBUG_ERROR = 2, | ||
89 | ODEBUG_FATAL = 3 | ||
90 | }; | ||
91 | |||
92 | /*====================================================================================== | ||
93 | * oDebug private data | ||
94 | *======================================================================================*/ | ||
95 | |||
96 | /*====================================================================================== | ||
97 | * the main debug function | ||
98 | *======================================================================================*/ | ||
99 | |||
100 | static void oDebugBackend( unsigned short level, unsigned int area, const char *data) | ||
101 | { | ||
102 | //qDebug( "oDebugBackend: Level=%d, Area=%d, Data=%s", level, area, data ); | ||
103 | |||
104 | // ML: OPIE doesn't use areacodes at the moment. See the KDE debug classes for an | ||
105 | // ML: example use. I think it's not necessary to implement such a strategy here. | ||
106 | // ML: Comments? | ||
107 | |||
108 | int priority = 0; | ||
109 | QString caption; | ||
110 | QString lev; | ||
111 | switch( level ) | ||
112 | { | ||
113 | case ODEBUG_INFO: lev = "(Info)"; caption = "Info"; priority = LOG_INFO; break; | ||
114 | case ODEBUG_WARN: lev = "(Warn)"; caption = "Warning"; priority = LOG_WARNING; break; | ||
115 | case ODEBUG_FATAL: lev = "(Fatal)"; caption = "Fatal Error"; priority = LOG_CRIT; break; | ||
116 | default: qDebug( "oDebugBackend: Warning: Unknown debug level! - defaulting to ODEBUG_ERROR." ); | ||
117 | case ODEBUG_ERROR: lev = "(Error)"; caption = "Error"; priority = LOG_ERR; break; | ||
118 | } | ||
119 | |||
120 | short output = OGlobalSettings::debugMode(); | ||
121 | if (!oApp && (output == 1)) | ||
122 | { | ||
123 | qDebug( "oDebugBackend: Warning: no oapplication object - can't use MsgBox" ); | ||
124 | output = 2; // need an application object to use MsgBox | ||
125 | } | ||
126 | |||
127 | QString areaName = (oApp) ? oApp->appName() : "<unknown>"; | ||
128 | |||
129 | // Output | ||
130 | switch( output ) | ||
131 | { | ||
132 | case -1: // ignore | ||
133 | { | ||
134 | return; | ||
135 | } | ||
136 | case 0: // File | ||
137 | { | ||
138 | QString outputFilename = OGlobalSettings::debugOutput(); | ||
139 | |||
140 | const int BUFSIZE = 4096; | ||
141 | char buf[BUFSIZE] = ""; | ||
142 | buf[BUFSIZE-1] = '\0'; | ||
143 | int nSize; | ||
144 | |||
145 | nSize = snprintf( buf, BUFSIZE-1, "%s: %s", (const char*) areaName, data); | ||
146 | |||
147 | QFile outputFile( outputFilename ); | ||
148 | if ( outputFile.open( IO_WriteOnly | IO_Append ) ) | ||
149 | { | ||
150 | if ( ( nSize == -1 ) || ( nSize >= BUFSIZE ) ) | ||
151 | { | ||
152 | outputFile.writeBlock( buf, BUFSIZE-1 ); | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | outputFile.writeBlock( buf, nSize ); | ||
157 | } | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | qDebug( "ODebug: can't write to file '%s' (%s)", (const char*) outputFilename, strerror(errno) ); | ||
162 | } | ||
163 | break; | ||
164 | } // automatic close of file here | ||
165 | |||
166 | case 1: // Message Box | ||
167 | { | ||
168 | // Since we are in opiecore here, we cannot use OMsgBox and use | ||
169 | // QMessageBox instead | ||
170 | |||
171 | caption += QString("(") + areaName + ")"; | ||
172 | QMessageBox::warning( 0L, caption, data, ("&OK") ); // tr? | ||
173 | break; | ||
174 | } | ||
175 | |||
176 | case 2: // Shell | ||
177 | { | ||
178 | FILE *output = stderr; | ||
179 | fprintf( output, "%s: ", (const char*) areaName ); | ||
180 | fputs( data, output); | ||
181 | break; | ||
182 | } | ||
183 | |||
184 | case 3: // syslog | ||
185 | { | ||
186 | syslog( priority, "%s", data); | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | case 4: // socket | ||
191 | { | ||
192 | QString destination = OGlobalSettings::debugOutput(); | ||
193 | if ( destination && destination.find(":") != -1 ) | ||
194 | { | ||
195 | QString host = destination.left( destination.find(":") ); | ||
196 | QString port = destination.right( destination.length()-host.length()-1 ); | ||
197 | QHostAddress addr; | ||
198 | addr.setAddress( host ); | ||
199 | // TODO: sanity check the address | ||
200 | QString line; | ||
201 | line.sprintf( "%s: %s", (const char*) areaName, (const char*) data ); | ||
202 | QSocketDevice s( QSocketDevice::Datagram ); | ||
203 | int result = s.writeBlock( (const char*) line, line.length(), addr, port.toInt() ); | ||
204 | if ( result == -1 ) | ||
205 | { | ||
206 | qDebug( "ODebug: can't send to address '%s:%d' (%s)", (const char*) host, port.toInt(), strerror(errno) ); | ||
207 | } | ||
208 | } | ||
209 | break; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | // check if we should abort | ||
214 | |||
215 | /* | ||
216 | |||
217 | if( ( nLevel == ODEBUG_FATAL ) | ||
218 | && ( !oDebug_data->config || oDebug_data->config->readNumEntry( "AbortFatal", 1 ) ) ) | ||
219 | abort(); | ||
220 | |||
221 | */ | ||
222 | } | ||
223 | |||
224 | /*====================================================================================== | ||
225 | * odbgstream | ||
226 | *======================================================================================*/ | ||
227 | |||
228 | odbgstream& perror( odbgstream &s) | ||
229 | { | ||
230 | return s << QString::fromLocal8Bit(strerror(errno)); | ||
231 | } | ||
232 | |||
233 | odbgstream odDebug(int area) | ||
234 | { | ||
235 | return odbgstream(area, ODEBUG_INFO); | ||
236 | } | ||
237 | odbgstream odDebug(bool cond, int area) | ||
238 | { | ||
239 | if (cond) return odbgstream(area, ODEBUG_INFO); | ||
240 | else return odbgstream(0, 0, false); | ||
241 | } | ||
242 | |||
243 | odbgstream odError(int area) | ||
244 | { | ||
245 | return odbgstream("ERROR: ", area, ODEBUG_ERROR); | ||
246 | } | ||
247 | |||
248 | odbgstream odError(bool cond, int area) | ||
249 | { | ||
250 | if (cond) return odbgstream("ERROR: ", area, ODEBUG_ERROR); else return odbgstream(0,0,false); | ||
251 | } | ||
252 | |||
253 | odbgstream odWarning(int area) | ||
254 | { | ||
255 | return odbgstream("WARNING: ", area, ODEBUG_WARN); | ||
256 | } | ||
257 | |||
258 | odbgstream odWarning(bool cond, int area) | ||
259 | { | ||
260 | if (cond) return odbgstream("WARNING: ", area, ODEBUG_WARN); else return odbgstream(0,0,false); | ||
261 | } | ||
262 | |||
263 | odbgstream odFatal(int area) | ||
264 | { | ||
265 | return odbgstream("FATAL: ", area, ODEBUG_FATAL); | ||
266 | } | ||
267 | |||
268 | odbgstream odFatal(bool cond, int area) | ||
269 | { | ||
270 | if (cond) return odbgstream("FATAL: ", area, ODEBUG_FATAL); else return odbgstream(0,0,false); | ||
271 | } | ||
272 | |||
273 | odbgstream::odbgstream(unsigned int _area, unsigned int _level, bool _print) | ||
274 | :area(_area), level(_level), print(_print) | ||
275 | { | ||
276 | } | ||
277 | |||
278 | |||
279 | odbgstream::odbgstream(const char * initialString, unsigned int _area, unsigned int _level, bool _print) | ||
280 | :output(QString::fromLatin1(initialString)), area(_area), level(_level), print(_print) | ||
281 | { | ||
282 | } | ||
283 | |||
284 | |||
285 | odbgstream::odbgstream(odbgstream &str) | ||
286 | :output(str.output), area(str.area), level(str.level), print(str.print) | ||
287 | { | ||
288 | str.output.truncate(0); | ||
289 | } | ||
290 | |||
291 | |||
292 | odbgstream::odbgstream(const odbgstream &str) | ||
293 | :output(str.output), area(str.area), level(str.level), print(str.print) | ||
294 | { | ||
295 | } | ||
296 | |||
297 | odbgstream& odbgstream::operator<<(bool i) | ||
298 | { | ||
299 | if (!print) return *this; | ||
300 | output += QString::fromLatin1(i ? "true" : "false"); | ||
301 | return *this; | ||
302 | } | ||
303 | |||
304 | |||
305 | odbgstream& odbgstream::operator<<(short i) | ||
306 | { | ||
307 | if (!print) return *this; | ||
308 | QString tmp; tmp.setNum(i); output += tmp; | ||
309 | return *this; | ||
310 | } | ||
311 | |||
312 | |||
313 | odbgstream& odbgstream::operator<<(unsigned short i) | ||
314 | { | ||
315 | if (!print) return *this; | ||
316 | QString tmp; tmp.setNum(i); output += tmp; | ||
317 | return *this; | ||
318 | } | ||
319 | |||
320 | |||
321 | odbgstream& odbgstream::operator<<(unsigned char i) | ||
322 | { | ||
323 | return operator<<( static_cast<char>( i ) ); | ||
324 | } | ||
325 | |||
326 | |||
327 | odbgstream& odbgstream::operator<<(int i) | ||
328 | { | ||
329 | if (!print) return *this; | ||
330 | QString tmp; tmp.setNum(i); output += tmp; | ||
331 | return *this; | ||
332 | } | ||
333 | |||
334 | |||
335 | odbgstream& odbgstream::operator<<(unsigned int i) | ||
336 | { | ||
337 | if (!print) return *this; | ||
338 | QString tmp; tmp.setNum(i); output += tmp; | ||
339 | return *this; | ||
340 | } | ||
341 | |||
342 | |||
343 | odbgstream& odbgstream::operator<<(long i) | ||
344 | { | ||
345 | if (!print) return *this; | ||
346 | QString tmp; tmp.setNum(i); output += tmp; | ||
347 | return *this; | ||
348 | } | ||
349 | |||
350 | |||
351 | odbgstream& odbgstream::operator<<(unsigned long i) | ||
352 | { | ||
353 | if (!print) return *this; | ||
354 | QString tmp; tmp.setNum(i); output += tmp; | ||
355 | return *this; | ||
356 | } | ||
357 | |||
358 | |||
359 | odbgstream& odbgstream::operator<<(const QString& string) | ||
360 | { | ||
361 | if (!print) return *this; | ||
362 | output += string; | ||
363 | if (output.at(output.length() -1 ) == '\n') | ||
364 | flush(); | ||
365 | return *this; | ||
366 | } | ||
367 | |||
368 | |||
369 | odbgstream& odbgstream::operator<<(const char *string) | ||
370 | { | ||
371 | if (!print) return *this; | ||
372 | output += QString::fromUtf8(string); | ||
373 | if (output.at(output.length() - 1) == '\n') | ||
374 | flush(); | ||
375 | return *this; | ||
376 | } | ||
377 | |||
378 | |||
379 | odbgstream& odbgstream::operator<<(const QCString& string) | ||
380 | { | ||
381 | *this << string.data(); | ||
382 | return *this; | ||
383 | } | ||
384 | |||
385 | |||
386 | odbgstream& odbgstream::operator<<(const void * p) | ||
387 | { | ||
388 | form("%p", p); | ||
389 | return *this; | ||
390 | } | ||
391 | |||
392 | odbgstream& odbgstream::operator<<(double d) | ||
393 | { | ||
394 | QString tmp; tmp.setNum(d); output += tmp; | ||
395 | return *this; | ||
396 | } | ||
397 | |||
398 | /* | ||
399 | odbgstream::odbgstream &form(const char *format, ...) | ||
400 | #ifdef __GNUC__ | ||
401 | __attribute__ ( ( format ( printf, 2, 3 ) ) ) | ||
402 | #endif | ||
403 | ; | ||
404 | */ | ||
405 | |||
406 | void odbgstream::flush() | ||
407 | { | ||
408 | if ( output.isEmpty() || !print ) | ||
409 | { | ||
410 | return; | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | oDebugBackend( level, area, output.local8Bit().data() ); | ||
415 | output = QString::null; | ||
416 | } | ||
417 | } | ||
418 | |||
419 | odbgstream& odbgstream::form(const char *format, ...) | ||
420 | { | ||
421 | char buf[4096]; | ||
422 | va_list arguments; | ||
423 | va_start( arguments, format ); | ||
424 | buf[sizeof(buf)-1] = '\0'; | ||
425 | vsnprintf( buf, sizeof(buf)-1, format, arguments ); | ||
426 | va_end(arguments); | ||
427 | *this << buf; | ||
428 | return *this; | ||
429 | } | ||
430 | |||
431 | odbgstream::~odbgstream() | ||
432 | { | ||
433 | if (!output.isEmpty()) | ||
434 | { | ||
435 | fprintf(stderr, "ASSERT: debug output not ended with \\n\n"); | ||
436 | *this << "\n"; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | odbgstream& odbgstream::operator<<(char ch) | ||
441 | { | ||
442 | if (!print) return *this; | ||
443 | if (!isprint(ch)) | ||
444 | { | ||
445 | output += "\\x" + QString::number( static_cast<uint>( ch ) + 0x100, 16 ).right(2); | ||
446 | } | ||
447 | else | ||
448 | { | ||
449 | output += ch; | ||
450 | if (ch == '\n') flush(); | ||
451 | } | ||
452 | return *this; | ||
453 | } | ||
454 | |||
455 | odbgstream& odbgstream::operator<<( QWidget* widget ) | ||
456 | { | ||
457 | QString string, temp; | ||
458 | // ----- | ||
459 | if(widget==0) | ||
460 | { | ||
461 | string=(QString)"[Null pointer]"; | ||
462 | } else | ||
463 | { | ||
464 | temp.setNum((ulong)widget, 16); | ||
465 | string=(QString)"["+widget->className()+" pointer " + "(0x" + temp + ")"; | ||
466 | if(widget->name(0)==0) | ||
467 | { | ||
468 | string += " to unnamed widget, "; | ||
469 | } else | ||
470 | { | ||
471 | string += (QString)" to widget " + widget->name() + ", "; | ||
472 | } | ||
473 | string += "geometry=" | ||
474 | + QString().setNum(widget->width()) | ||
475 | + "x"+QString().setNum(widget->height()) | ||
476 | + "+"+QString().setNum(widget->x()) | ||
477 | + "+"+QString().setNum(widget->y()) | ||
478 | + "]"; | ||
479 | } | ||
480 | if (!print) return *this; | ||
481 | |||
482 | output += string; | ||
483 | if (output.at(output.length()-1) == '\n') | ||
484 | { | ||
485 | flush(); | ||
486 | } | ||
487 | return *this; | ||
488 | } | ||
489 | |||
490 | /* | ||
491 | * either use 'output' directly and do the flush if needed | ||
492 | * or use the QString operator which calls the char* operator | ||
493 | * | ||
494 | */ | ||
495 | odbgstream& odbgstream::operator<<( const QDateTime& time) | ||
496 | { | ||
497 | *this << time.toString(); | ||
498 | return *this; | ||
499 | } | ||
500 | |||
501 | |||
502 | odbgstream& odbgstream::operator<<( const QDate& date) | ||
503 | { | ||
504 | *this << date.toString(); | ||
505 | |||
506 | return *this; | ||
507 | } | ||
508 | |||
509 | |||
510 | odbgstream& odbgstream::operator<<( const QTime& time ) | ||
511 | { | ||
512 | *this << time.toString(); | ||
513 | return *this; | ||
514 | } | ||
515 | |||
516 | |||
517 | odbgstream& odbgstream::operator<<( const QPoint& p ) | ||
518 | { | ||
519 | *this << "(" << p.x() << ", " << p.y() << ")"; | ||
520 | return *this; | ||
521 | } | ||
522 | |||
523 | |||
524 | odbgstream& odbgstream::operator<<( const QSize& s ) | ||
525 | { | ||
526 | *this << "[" << s.width() << "x" << s.height() << "]"; | ||
527 | return *this; | ||
528 | } | ||
529 | |||
530 | |||
531 | odbgstream& odbgstream::operator<<( const QRect& r ) | ||
532 | { | ||
533 | *this << "[" << r.left() << ", " << r.top() << " - " << r.right() << ", " << r.bottom() << "]"; | ||
534 | return *this; | ||
535 | } | ||
536 | |||
537 | |||
538 | odbgstream& odbgstream::operator<<( const QRegion& reg ) | ||
539 | { | ||
540 | /* Qt2 doesn't have a QMemArray... :( | ||
541 | *this << "[ "; | ||
542 | QMemArray<QRect>rs=reg.rects(); | ||
543 | for (uint i=0;i<rs.size();++i) | ||
544 | *this << QString("[%1, %2 - %3, %4] ").arg(rs[i].left()).arg(rs[i].top()).arg(rs[i].right()).arg(rs[i].bottom() ) ; | ||
545 | *this <<"]"; | ||
546 | */ | ||
547 | return *this; | ||
548 | } | ||
549 | |||
550 | |||
551 | odbgstream& odbgstream::operator<<( const QStringList& l ) | ||
552 | { | ||
553 | *this << "("; | ||
554 | *this << l.join(","); | ||
555 | *this << ")"; | ||
556 | |||
557 | return *this; | ||
558 | } | ||
559 | |||
560 | |||
561 | odbgstream& odbgstream::operator<<( const QColor& c ) | ||
562 | { | ||
563 | if ( c.isValid() ) | ||
564 | *this << c.name(); | ||
565 | else | ||
566 | *this << "(invalid/default)"; | ||
567 | return *this; | ||
568 | } | ||
569 | |||
570 | |||
571 | odbgstream& odbgstream::operator<<( const QBrush& b) | ||
572 | { | ||
573 | static const char* const s_brushStyles[] = { | ||
574 | "NoBrush", "SolidPattern", "Dense1Pattern", "Dense2Pattern", "Dense3Pattern", | ||
575 | "Dense4Pattern", "Dense5Pattern", "Dense6Pattern", "Dense7Pattern", | ||
576 | "HorPattern", "VerPattern", "CrossPattern", "BDiagPattern", "FDiagPattern", | ||
577 | "DiagCrossPattern" }; | ||
578 | |||
579 | *this <<"[ style: "; | ||
580 | *this <<s_brushStyles[ b.style() ]; | ||
581 | *this <<" color: "; | ||
582 | // can't use operator<<(str, b.color()) because that terminates a odbgstream (flushes) | ||
583 | if ( b.color().isValid() ) | ||
584 | *this <<b.color().name() ; | ||
585 | else | ||
586 | *this <<"(invalid/default)"; | ||
587 | if ( b.pixmap() ) | ||
588 | *this <<" has a pixmap"; | ||
589 | *this <<" ]"; | ||
590 | return *this; | ||
591 | } | ||
592 | |||
593 | |||
594 | |||
595 | QString odBacktrace( int levels ) | ||
596 | { | ||
597 | QString s; | ||
598 | #ifndef OPIE_NO_BACKTRACE | ||
599 | void* trace[256]; | ||
600 | int n = backtrace(trace, 256); | ||
601 | char** strings = backtrace_symbols (trace, n); | ||
602 | |||
603 | if ( levels != -1 ) | ||
604 | n = QMIN( n, levels ); | ||
605 | s = "[\n"; | ||
606 | |||
607 | for (int i = 0; i < n; ++i) | ||
608 | s += QString::number(i) + | ||
609 | QString::fromLatin1(": ") + | ||
610 | QString::fromLatin1(strings[i]) + QString::fromLatin1("\n"); | ||
611 | s += "]\n"; | ||
612 | free (strings); | ||
613 | #endif | ||
614 | return s; | ||
615 | } | ||
616 | |||
617 | void odClearDebugConfig() | ||
618 | { | ||
619 | /* | ||
620 | delete oDebug_data->config; | ||
621 | oDebug_data->config = 0; | ||
622 | */ | ||
623 | } | ||
624 | |||
625 | #ifdef OPIE_NO_DEBUG | ||
626 | #define odDebug ondDebug | ||
627 | #define odBacktrace ondBacktrace | ||
628 | #endif | ||