-rw-r--r-- | libopie2/opiecore/odebug.cpp | 229 | ||||
-rw-r--r-- | libopie2/opiecore/oglobal.cpp | 9 | ||||
-rw-r--r-- | libopie2/opiecore/oglobal.h | 5 |
3 files changed, 132 insertions, 111 deletions
diff --git a/libopie2/opiecore/odebug.cpp b/libopie2/opiecore/odebug.cpp index f258faa..3bffdd0 100644 --- a/libopie2/opiecore/odebug.cpp +++ b/libopie2/opiecore/odebug.cpp @@ -23,298 +23,307 @@ : = ...= . :.=- -. .:....=;==+<; 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 <opie2/odebug.h> #ifdef OPIE_NO_DEBUG #undef odDebug #undef odBacktrace #endif /* OPIE */ #include <opie2/oapplication.h> #include <opie2/oglobalsettings.h> #include <opie2/oconfig.h> /* QT */ #include <qfile.h> #include <qmessagebox.h> #include <qsocketdevice.h> /* UNIX */ #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> #ifndef OPIE_NO_BACKTRACE #include <execinfo.h> #endif namespace Opie { namespace Core { namespace Internal { -class DebugBackend { -}; - -static DebugBackend *backEnd = 0; -} -static void clean_up_routine() { - delete Internal::backEnd; -} /*====================================================================================== * 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) -{ + + +struct DebugBackend { + DebugBackend() : m_opened( false ), m_file( 0 ) ,m_port( -1 ),m_sock( 0 ) { + m_outp = OGlobalSettings::debugMode(); + } + ~DebugBackend() { + delete m_file; + delete m_sock; + } + void debug( unsigned short level, unsigned int, const QString& data ); + +private: + void debugFile( const QString&, const QString& data ); + void debugMsgB( const QString&, const QString& data ); + void debugShel( const QString&, const QString& data ); + void debugSysl( int, const QString& ); + void debugSock( const QString&, const QString& data ); + QCString line( const QString&, const QString& data ); + bool m_opened : 1; + QFile *m_file; + QHostAddress m_addr; + int m_port; + QSocketDevice *m_sock; + short m_outp; +}; + +void DebugBackend::debug(unsigned short level, unsigned int, const QString& 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)) - { + if (!oApp && (m_outp == 1)) { qDebug( "oDebugBackend: Warning: no oapplication object - can't use MsgBox" ); - output = 2; // need an application object to use MsgBox + m_outp = 2; // need an application object to use MsgBox } // gcc 2.9x is dumb and sucks... can you hear it? //QString areaName = (oApp) ? oApp->appName() : "<unknown>"; QString areaName; if ( oApp ) areaName = oApp->appName(); else areaName = "<unknown>"; - // Output - switch( output ) - { - case -1: // ignore - { + switch( m_outp ) { + case -1: // ignore + return; + case 0: // File + return debugFile( areaName, data ); + case 1: // Message Box + return debugMsgB( areaName, data ); + case 2: + return debugShel( areaName,data ); + case 3: // syslog + return debugSysl( priority, data ); + case 4: // socket + return debugSock( areaName, data ); + } +} + +inline void DebugBackend::debugFile(const QString& area, const QString& data) { + /* something went wrong with the file don't bother.. */ + if ( m_opened && !m_file ) + return; + else if ( !m_opened ) { + m_opened = true; + m_file = new QFile( OGlobalSettings::debugOutput() ); + if (!m_file->open( IO_WriteOnly | IO_Append ) ) { + delete m_file; m_file = 0; + qDebug( "ODebug: can't write to file '%s' (%s)", (const char*)OGlobalSettings::debugOutput(), + strerror(errno) ); 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; - } + /* go to end of file */ + m_file->at( m_file->size() ); + QCString li = line( area, data ); + m_file->writeBlock(li.data(), li.length() ); +} - case 2: // Shell - { - FILE *output = stderr; - fprintf( output, "%s: ", (const char*) areaName ); - fputs( data, output); - break; - } +void DebugBackend::debugMsgB( const QString& area, const QString& data ) { + QMessageBox::warning( 0l, "("+area+")", data, ("Ok") ); +} - case 3: // syslog - { - syslog( priority, "%s", data); - break; - } +void DebugBackend::debugShel( const QString& are, const QString& data ) { + FILE *output = stderr; + fprintf( output, "%s: %s", are.local8Bit().data(), + data.local8Bit().data() ); +} - 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; +void DebugBackend::debugSysl( int prio, const QString& data ) { + ::syslog( prio, "%s", data.local8Bit().data() ); +} + +void DebugBackend::debugSock( const QString& are, const QString& data ) { + if ( m_opened && !m_sock ) + return; + else if ( !m_opened ){ + m_opened = true; + QString destination = OGlobalSettings::debugOutput(); + if ( destination && destination.find(":") != -1 ) { + QString host = destination.left( destination.find(":") ); + m_port = destination.right( destination.length()-host.length()-1 ).toInt(); + m_addr.setAddress( host ); + m_sock = new QSocketDevice( QSocketDevice::Datagram ); + }else{ + m_sock = 0; + return; } } - // check if we should abort - - /* - - if( ( nLevel == ODEBUG_FATAL ) - && ( !oDebug_data->config || oDebug_data->config->readNumEntry( "AbortFatal", 1 ) ) ) - abort(); + QCString li = line( are, data ); + int result = m_sock->writeBlock(li.data(), li.length(), m_addr, m_port ); + if ( result == -1 ) { + qDebug( "ODebug: can't send to address '"+ m_addr.toString() +":%d' (%s)", + m_port, strerror(errno) ); + } +} - */ +QCString DebugBackend::line( const QString& area, const QString& data ) { + QString str = area +":"+data; + return str.local8Bit(); } +static DebugBackend *backEnd = 0; +} +static void clean_up_routine() { + qWarning( "Clean up Debug" ); + delete Internal::backEnd; + Internal::backEnd = 0; +} /*====================================================================================== * odbgstream *======================================================================================*/ odbgstream& perror( odbgstream &s) { return s << QString::fromLocal8Bit(strerror(errno)); } odbgstream odDebug(int area) { - return odbgstream(area, ODEBUG_INFO); + return odbgstream(area, Internal::ODEBUG_INFO); } odbgstream odDebug(bool cond, int area) { - if (cond) return odbgstream(area, ODEBUG_INFO); + if (cond) return odbgstream(area, Internal::ODEBUG_INFO); else return odbgstream(0, 0, false); } odbgstream odError(int area) { - return odbgstream("ERROR: ", area, ODEBUG_ERROR); + return odbgstream("ERROR: ", area, Internal::ODEBUG_ERROR); } odbgstream odError(bool cond, int area) { - if (cond) return odbgstream("ERROR: ", area, ODEBUG_ERROR); else return odbgstream(0,0,false); + if (cond) return odbgstream("ERROR: ", area, Internal::ODEBUG_ERROR); else return odbgstream(0,0,false); } odbgstream odWarning(int area) { - return odbgstream("WARNING: ", area, ODEBUG_WARN); + return odbgstream("WARNING: ", area, Internal::ODEBUG_WARN); } odbgstream odWarning(bool cond, int area) { - if (cond) return odbgstream("WARNING: ", area, ODEBUG_WARN); else return odbgstream(0,0,false); + if (cond) return odbgstream("WARNING: ", area, Internal::ODEBUG_WARN); else return odbgstream(0,0,false); } odbgstream odFatal(int area) { - return odbgstream("FATAL: ", area, ODEBUG_FATAL); + return odbgstream("FATAL: ", area, Internal::ODEBUG_FATAL); } odbgstream odFatal(bool cond, int area) { - if (cond) return odbgstream("FATAL: ", area, ODEBUG_FATAL); else return odbgstream(0,0,false); + if (cond) return odbgstream("FATAL: ", area, Internal::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; } @@ -368,97 +377,101 @@ odbgstream& odbgstream::operator<<(const QString& string) } 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() ); + if ( !Internal::backEnd ) { + Internal::backEnd = new Internal::DebugBackend; + qAddPostRoutine( clean_up_routine ); + } + Internal::backEnd->debug( level, area, output ); 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<uint>( 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 @@ -494,103 +507,101 @@ odbgstream& odbgstream::operator<<( QWidget* widget ) * 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 << "[ "; - QMemArray<QRect>rs=reg.rects(); + QArray<QRect>rs=reg.rects(); for (uint i=0;i<rs.size();++i) *this << QString("[%1, %2 - %3, %4] ").arg(rs[i].left()).arg(rs[i].top()).arg(rs[i].right()).arg(rs[i].bottom() ) ; *this <<"]"; - */ return *this; } odbgstream& odbgstream::operator<<( const QStringList& l ) { *this << "("; *this << l.join(","); *this << ")"; return *this; } odbgstream& odbgstream::operator<<( const QColor& c ) { if ( c.isValid() ) *this << c.name(); else *this << "(invalid/default)"; return *this; } odbgstream& odbgstream::operator<<( const QBrush& 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 odbgstream (flushes) if ( b.color().isValid() ) *this <<b.color().name() ; else *this <<"(invalid/default)"; if ( b.pixmap() ) *this <<" has a pixmap"; *this <<" ]"; return *this; } diff --git a/libopie2/opiecore/oglobal.cpp b/libopie2/opiecore/oglobal.cpp index ea02058..2968a7d 100644 --- a/libopie2/opiecore/oglobal.cpp +++ b/libopie2/opiecore/oglobal.cpp @@ -31,101 +31,110 @@ #include <qtextstream.h> #include <qdir.h> #include <qpe/mimetype.h> #include <qpe/qpeapplication.h> #include <qpe/storage.h> #include <unistd.h> #include <sys/types.h> using namespace Opie::Core; static const char Base64EncMap[64] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F }; static char Base64DecMap[128] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 }; OConfig* OGlobal::_config = 0; OConfig* OGlobal::_qpe_config = 0; +void OGlobal::clean_up() { + qWarning( "Oglobal clean up" ); + delete OGlobal::_config; + delete OGlobal::_qpe_config; + OGlobal::_config = 0; + OGlobal::_qpe_config = 0; +} + OConfig* OGlobal::config() { if ( !OGlobal::_config ) { // odebug classes are reading config, so can't use them here! + qAddPostRoutine( OGlobal::clean_up ); qDebug( "OGlobal::creating global configuration instance." ); OGlobal::_config = new OConfig( "global" ); } return OGlobal::_config; } /** * Return the internal builtin Global::Command object * */ Global::Command* OGlobal::builtinCommands() { return builtin; } /** * Return the internal builtin QGuardedPtr<QWidget> object */ QGuardedPtr<QWidget>* OGlobal::builtinRunning() { return running; } /** * \brief generate a new UUID as QString * Return a new UUID as QString. UUID are global unique * * * @return the UUID or QString::null */ QString OGlobal::generateUuid() { QFile file( "/proc/sys/kernel/random/uuid" ); if (!file.open(IO_ReadOnly ) ) return QString::null; QTextStream stream(&file); return "{" + stream.read().stripWhiteSpace() + "}"; } /** * \brief Encode a QByteArray in base64 * * An Implementation of the RF1521 base64 encoding. * * The boolean argument determines if the encoded data is diff --git a/libopie2/opiecore/oglobal.h b/libopie2/opiecore/oglobal.h index e6a6c46..d79a218 100644 --- a/libopie2/opiecore/oglobal.h +++ b/libopie2/opiecore/oglobal.h @@ -42,118 +42,119 @@ #undef private #endif #include <sys/types.h> //FIXME Is it wise or even necessary to inherit OGlobal from Global? // once we totally skip libqpe it should ideally swallow Global -zecke // You're right. I deleted global as the base class. -mickeyl class QFile; class QString; class DateFormat; namespace Opie { namespace Core { /** *\brief OGlobal contains a list of generic functions * * The class OGlobal contains small utility functions * which might be useful for other applications to use. It features access * to the global device config and specialized functions to get information * out of this config like Weekstart or Owner name. * * @todo ODP implement the things from Global which are good * @author mickey,alwin,zecke * @version 0.1 */ class OGlobal : public Global { public: // how do they relate to our Document Idea /** @name Document System related functions * */ //@{ static bool isAppLnkFileName( const QString& str ); static bool isDocumentFileName( const QString& file ); //@} /** @name File Operations * File operations provided by OGlobal */ //@{ /** the content of TEMP - * reads the environment variable TEMP and returns the content. + * reads the environment variable TEMP and returns the content. * if not set returns "/tmp" * @return a string containing a dir without trailing slash! */ static QString tempDirPath(); /** the content of HOME - * reads the environment variable HOME and returns the content. + * reads the environment variable HOME and returns the content. * if not set returns "/" * @return a string containing a dir without trailing slash! */ static QString homeDirPath(); static QString tempFileName( const QString& ); static bool renameFile( const QString& from, const QString& to ); static bool truncateFile( QFile &f, off_t size ); //@} static QString generateUuid(); /** @name Convert Content * Convert Content of a QByteArray */ //@{ static QByteArray encodeBase64(const QByteArray&, bool insertLF = false ); static QByteArray decodeBase64(const QByteArray& ); //@} //FIXME Do we want to put that into OApplication as in KApplication? -zecke // We already have a per-application config in OApplication // ( accessed through oApp->config() ), but this one is the global one! -mickeyl /** @name Config and Owner related Information * */ //@{ static OConfig* config(); static OConfig* qpe_config(); static QString ownerName(); static bool weekStartsOnMonday(); static bool useAMPM(); #ifdef ODP #error "Fix dateFormat" /** * For Qt3/Qt4 we can use QDate::toString(OGlobal::dateFormat) * See if we need to use the function with String in it * Anyway this is the future * for now still use TimeString! */ #endif static DateFormat dateFormat(); static void setDateFormat( const DateFormat& ); static void setWeekStartsOnMonday( bool ); static void setUseAMPM( bool ); //@} //@{ static Global::Command* builtinCommands(); static QGuardedPtr<QWidget>* builtinRunning(); //@} private: + static void clean_up(); static OConfig* _config; static OConfig* _qpe_config; class Private; Private *d; }; } } #endif // OGLOBAL_H |