From 11304d02942e9fa493e4e80943a828f9c65f6772 Mon Sep 17 00:00:00 2001 From: mickeyl Date: Fri, 28 Mar 2003 15:11:52 +0000 Subject: skeleton and the start of libopie2, please read README, ROADMAP and STATUS and comment... --- (limited to 'libopie2/opiecore/odebug.cpp') 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 @@ +/* + This file is part of the Opie Project + (C) 2003 Michael 'Mickey' Lauer (mickey@tm.informatik.uni-frankfurt.de) + Inspired by the KDE debug classes, which are + (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) + (C) 2002 Holger Freyther (freyther@kde.org) + =. + .=l. +           .>+-= + _;:,     .>    :=|. This program is free software; you can +.> <`_,   >  .   <= redistribute it and/or modify it under +:`=1 )Y*s>-.--   : the terms of the GNU Library General Public +.="- .-=="i,     .._ License as published by the Free Software + - .   .-<_>     .<> Foundation; either version 2 of the License, +     ._= =}       : or (at your option) any later version. +    .%`+i>       _;_. +    .i_,=:_.      -`: 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +// Include this header without OPIE_NO_DEBUG defined to avoid having the oDebugInfo +// functions inlined to noops (which would then conflict with their definition here). + +#include + +#ifdef OPIE_NO_DEBUG +#undef odDebug +#undef odBacktrace +#endif + +/* OPIE */ + +#include +#include +#include + +/* QT */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* UNIX */ + +#include // abort +#include // getpid +#include // vararg stuff +#include // isprint +#include +#include +#include + +#ifndef OPIE_NO_BACKTRACE +#include +#endif + + +/*====================================================================================== + * debug levels + *======================================================================================*/ + +enum DebugLevels { + ODEBUG_INFO = 0, + ODEBUG_WARN = 1, + ODEBUG_ERROR = 2, + ODEBUG_FATAL = 3 +}; + +/*====================================================================================== + * oDebug private data + *======================================================================================*/ + +/*====================================================================================== + * the main debug function + *======================================================================================*/ + +static void oDebugBackend( unsigned short level, unsigned int area, const char *data) +{ + //qDebug( "oDebugBackend: Level=%d, Area=%d, Data=%s", level, area, data ); + + // ML: OPIE doesn't use areacodes at the moment. See the KDE debug classes for an + // ML: example use. I think it's not necessary to implement such a strategy here. + // ML: Comments? + + int priority = 0; + QString caption; + QString lev; + switch( level ) + { + case ODEBUG_INFO: lev = "(Info)"; caption = "Info"; priority = LOG_INFO; break; + case ODEBUG_WARN: lev = "(Warn)"; caption = "Warning"; priority = LOG_WARNING; break; + case ODEBUG_FATAL: lev = "(Fatal)"; caption = "Fatal Error"; priority = LOG_CRIT; break; + default: qDebug( "oDebugBackend: Warning: Unknown debug level! - defaulting to ODEBUG_ERROR." ); + case ODEBUG_ERROR: lev = "(Error)"; caption = "Error"; priority = LOG_ERR; break; + } + + short output = OGlobalSettings::debugMode(); + if (!oApp && (output == 1)) + { + qDebug( "oDebugBackend: Warning: no oapplication object - can't use MsgBox" ); + output = 2; // need an application object to use MsgBox + } + + QString areaName = (oApp) ? oApp->appName() : ""; + + // Output + switch( output ) + { + case -1: // ignore + { + return; + } + case 0: // File + { + QString outputFilename = OGlobalSettings::debugOutput(); + + const int BUFSIZE = 4096; + char buf[BUFSIZE] = ""; + buf[BUFSIZE-1] = '\0'; + int nSize; + + nSize = snprintf( buf, BUFSIZE-1, "%s: %s", (const char*) areaName, data); + + QFile outputFile( outputFilename ); + if ( outputFile.open( IO_WriteOnly | IO_Append ) ) + { + if ( ( nSize == -1 ) || ( nSize >= BUFSIZE ) ) + { + outputFile.writeBlock( buf, BUFSIZE-1 ); + } + else + { + outputFile.writeBlock( buf, nSize ); + } + } + else + { + qDebug( "ODebug: can't write to file '%s' (%s)", (const char*) outputFilename, strerror(errno) ); + } + break; + } // automatic close of file here + + case 1: // Message Box + { + // Since we are in opiecore here, we cannot use OMsgBox and use + // QMessageBox instead + + caption += QString("(") + areaName + ")"; + QMessageBox::warning( 0L, caption, data, ("&OK") ); // tr? + break; + } + + case 2: // Shell + { + FILE *output = stderr; + fprintf( output, "%s: ", (const char*) areaName ); + fputs( data, output); + break; + } + + case 3: // syslog + { + syslog( priority, "%s", data); + break; + } + + case 4: // socket + { + QString destination = OGlobalSettings::debugOutput(); + if ( destination && destination.find(":") != -1 ) + { + QString host = destination.left( destination.find(":") ); + QString port = destination.right( destination.length()-host.length()-1 ); + QHostAddress addr; + addr.setAddress( host ); + // TODO: sanity check the address + QString line; + line.sprintf( "%s: %s", (const char*) areaName, (const char*) data ); + QSocketDevice s( QSocketDevice::Datagram ); + int result = s.writeBlock( (const char*) line, line.length(), addr, port.toInt() ); + if ( result == -1 ) + { + qDebug( "ODebug: can't send to address '%s:%d' (%s)", (const char*) host, port.toInt(), strerror(errno) ); + } + } + break; + } + } + + // check if we should abort + + /* + + if( ( nLevel == ODEBUG_FATAL ) + && ( !oDebug_data->config || oDebug_data->config->readNumEntry( "AbortFatal", 1 ) ) ) + abort(); + + */ +} + +/*====================================================================================== + * odbgstream + *======================================================================================*/ + +odbgstream& perror( odbgstream &s) +{ + return s << QString::fromLocal8Bit(strerror(errno)); +} + +odbgstream odDebug(int area) +{ + return odbgstream(area, ODEBUG_INFO); +} +odbgstream odDebug(bool cond, int area) +{ + if (cond) return odbgstream(area, ODEBUG_INFO); + else return odbgstream(0, 0, false); +} + +odbgstream odError(int area) +{ + return odbgstream("ERROR: ", area, ODEBUG_ERROR); +} + +odbgstream odError(bool cond, int area) +{ + if (cond) return odbgstream("ERROR: ", area, ODEBUG_ERROR); else return odbgstream(0,0,false); +} + +odbgstream odWarning(int area) +{ + return odbgstream("WARNING: ", area, ODEBUG_WARN); +} + +odbgstream odWarning(bool cond, int area) +{ + if (cond) return odbgstream("WARNING: ", area, ODEBUG_WARN); else return odbgstream(0,0,false); +} + +odbgstream odFatal(int area) +{ + return odbgstream("FATAL: ", area, ODEBUG_FATAL); +} + +odbgstream odFatal(bool cond, int area) +{ + if (cond) return odbgstream("FATAL: ", area, ODEBUG_FATAL); else return odbgstream(0,0,false); +} + +odbgstream::odbgstream(unsigned int _area, unsigned int _level, bool _print) + :area(_area), level(_level), print(_print) +{ +} + + +odbgstream::odbgstream(const char * initialString, unsigned int _area, unsigned int _level, bool _print) + :output(QString::fromLatin1(initialString)), area(_area), level(_level), print(_print) +{ +} + + +odbgstream::odbgstream(odbgstream &str) + :output(str.output), area(str.area), level(str.level), print(str.print) +{ + str.output.truncate(0); +} + + +odbgstream::odbgstream(const odbgstream &str) + :output(str.output), area(str.area), level(str.level), print(str.print) +{ +} + +odbgstream& odbgstream::operator<<(bool i) +{ + if (!print) return *this; + output += QString::fromLatin1(i ? "true" : "false"); + return *this; +} + + +odbgstream& odbgstream::operator<<(short i) +{ + if (!print) return *this; + QString tmp; tmp.setNum(i); output += tmp; + return *this; +} + + +odbgstream& odbgstream::operator<<(unsigned short i) +{ + if (!print) return *this; + QString tmp; tmp.setNum(i); output += tmp; + return *this; +} + + +odbgstream& odbgstream::operator<<(unsigned char i) +{ + return operator<<( static_cast( i ) ); +} + + +odbgstream& odbgstream::operator<<(int i) +{ + if (!print) return *this; + QString tmp; tmp.setNum(i); output += tmp; + return *this; +} + + +odbgstream& odbgstream::operator<<(unsigned int i) +{ + if (!print) return *this; + QString tmp; tmp.setNum(i); output += tmp; + return *this; +} + + +odbgstream& odbgstream::operator<<(long i) +{ + if (!print) return *this; + QString tmp; tmp.setNum(i); output += tmp; + return *this; +} + + +odbgstream& odbgstream::operator<<(unsigned long i) +{ + if (!print) return *this; + QString tmp; tmp.setNum(i); output += tmp; + return *this; +} + + +odbgstream& odbgstream::operator<<(const QString& string) +{ + if (!print) return *this; + output += string; + if (output.at(output.length() -1 ) == '\n') + flush(); + return *this; +} + + +odbgstream& odbgstream::operator<<(const char *string) +{ + if (!print) return *this; + output += QString::fromUtf8(string); + if (output.at(output.length() - 1) == '\n') + flush(); + return *this; +} + + +odbgstream& odbgstream::operator<<(const QCString& string) +{ + *this << string.data(); + return *this; +} + + +odbgstream& odbgstream::operator<<(const void * p) +{ + form("%p", p); + return *this; +} + +odbgstream& odbgstream::operator<<(double d) +{ + QString tmp; tmp.setNum(d); output += tmp; + return *this; +} + +/* +odbgstream::odbgstream &form(const char *format, ...) +#ifdef __GNUC__ + __attribute__ ( ( format ( printf, 2, 3 ) ) ) +#endif + ; +*/ + +void odbgstream::flush() +{ + if ( output.isEmpty() || !print ) + { + return; + } + else + { + oDebugBackend( level, area, output.local8Bit().data() ); + output = QString::null; + } +} + +odbgstream& odbgstream::form(const char *format, ...) +{ + char buf[4096]; + va_list arguments; + va_start( arguments, format ); + buf[sizeof(buf)-1] = '\0'; + vsnprintf( buf, sizeof(buf)-1, format, arguments ); + va_end(arguments); + *this << buf; + return *this; +} + +odbgstream::~odbgstream() +{ + if (!output.isEmpty()) + { + fprintf(stderr, "ASSERT: debug output not ended with \\n\n"); + *this << "\n"; + } +} + +odbgstream& odbgstream::operator<<(char ch) +{ + if (!print) return *this; + if (!isprint(ch)) + { + output += "\\x" + QString::number( static_cast( ch ) + 0x100, 16 ).right(2); + } + else + { + output += ch; + if (ch == '\n') flush(); + } + return *this; +} + +odbgstream& odbgstream::operator<<( QWidget* widget ) +{ + QString string, temp; + // ----- + if(widget==0) + { + string=(QString)"[Null pointer]"; + } else + { + temp.setNum((ulong)widget, 16); + string=(QString)"["+widget->className()+" pointer " + "(0x" + temp + ")"; + if(widget->name(0)==0) + { + string += " to unnamed widget, "; + } else + { + string += (QString)" to widget " + widget->name() + ", "; + } + string += "geometry=" + + QString().setNum(widget->width()) + + "x"+QString().setNum(widget->height()) + + "+"+QString().setNum(widget->x()) + + "+"+QString().setNum(widget->y()) + + "]"; + } + if (!print) return *this; + + output += string; + if (output.at(output.length()-1) == '\n') + { + flush(); + } + return *this; +} + +/* + * either use 'output' directly and do the flush if needed + * or use the QString operator which calls the char* operator + * + */ +odbgstream& odbgstream::operator<<( const QDateTime& time) +{ + *this << time.toString(); + return *this; +} + + +odbgstream& odbgstream::operator<<( const QDate& date) +{ + *this << date.toString(); + + return *this; +} + + +odbgstream& odbgstream::operator<<( const QTime& time ) +{ + *this << time.toString(); + return *this; +} + + +odbgstream& odbgstream::operator<<( const QPoint& p ) +{ + *this << "(" << p.x() << ", " << p.y() << ")"; + return *this; +} + + +odbgstream& odbgstream::operator<<( const QSize& s ) +{ + *this << "[" << s.width() << "x" << s.height() << "]"; + return *this; +} + + +odbgstream& odbgstream::operator<<( const QRect& r ) +{ + *this << "[" << r.left() << ", " << r.top() << " - " << r.right() << ", " << r.bottom() << "]"; + return *this; +} + + +odbgstream& odbgstream::operator<<( const QRegion& reg ) +{ + /* Qt2 doesn't have a QMemArray... :( + *this << "[ "; + QMemArrayrs=reg.rects(); + for (uint i=0;iconfig; + oDebug_data->config = 0; + */ +} + +#ifdef OPIE_NO_DEBUG +#define odDebug ondDebug +#define odBacktrace ondBacktrace +#endif -- cgit v0.9.0.2