#ifndef __DEBUG_IPP__
#define __DEBUG_IPP__
#include "Debug.hpp"
#include "String.hpp"
#include "platform/Platform.hpp"
#include "exceptions/InternalError.hpp"
extern "C"
{
void ( *oldTerminateHandler )( void );
void ( *oldUnexpectedHandler )( void );
void terminateHandler( void );
void unexpectedHandler( void );
}
#if !defined( INLINE_GETLOGGER )
INLINE Debug *Debug::getLogger( const Top * const )
{
if( logger == nil )
{
logger = new Debug();
}
return logger;
}
#endif
INLINE Debug::Debug()
{
oldTerminateHandler = set_terminate( terminateHandler );
oldUnexpectedHandler = set_unexpected( unexpectedHandler );
totalMessagesLogged = 0;
}
INLINE void Debug::log( const char *const aMessage, ... )
{
va_list args;
va_start( args, aMessage );
Platform::getInstance() -> rawErrorPrintf
( "\n[%s] ", Platform::getInstance() -> getTimeStampString() );
Platform::getInstance() -> rawErrorVPrintf( aMessage, args );
va_end(args);
}
INLINE void Debug::logObject( const Top *anObject,
String ( Top::*aMethod )() const )
{
char *formatted;
formatted = ( anObject ->* aMethod )().getChars();
test_( formatted != NULL );
Platform::getInstance() -> rawErrorPrintf( "\n%s", formatted );
delete []formatted;
}
INLINE void Debug::logObject( const char *const aMessage,
const Top *anObject,
String ( Top::*aMethod )() const )
{
char *formatted;
formatted = ( anObject ->* aMethod )().getChars();
test_( formatted != NULL );
Platform::getInstance() -> rawErrorVPrintf( "\n", NIL );
Platform::getInstance() -> rawErrorPrintf( aMessage, formatted );
delete []formatted;
}
INLINE void Debug::logString( const char *const aMessage, String aString )
{
char *formatted;
formatted = aString.getChars();
test_( formatted != NULL );
Platform::getInstance() -> rawErrorVPrintf( "\n", NIL );
Platform::getInstance() -> rawErrorPrintf( aMessage, formatted );
delete []formatted;
}
INLINE void Debug::panic( const char *const aMessage )
{
Platform::getInstance() ->
rawErrorPrintf( "A serious error `%s' occurred. Choosing suicide...",
aMessage );
if( shouldDropCore )
{
Platform::getInstance() -> suicide();
}
else if( attachDebuggerOnError )
{
Platform::getInstance() -> attachDebugger();
}
else
{
Platform::getInstance() -> exitImmediate( -1 );
}
}
INLINE void Debug::dumpCore()
{
Platform::getInstance() -> suicide();
}
INLINE void Debug::assertion( boolean aCondition,
const char *const aMessage,
const char *const aConditionAsString,
const char *const aFunction,
const char *const aFileName,
const Index aLineNo )
{
if( !aCondition )
{
log( "Assertion `%s' (%s) failed in %s (%s:%li)",
aMessage, aConditionAsString, aFunction, aFileName, aLineNo );
if( assertionFailsAreFatal )
{
panic( "Assertion failed" );
}
else if( attachDebuggerOnError )
{
Platform::getInstance() -> attachDebugger();
}
}
}
INLINE void Debug::testCondition( boolean aCondition,
const char *const aMessage,
const char *const aConditionAsString,
const char *const aFunction,
const char *const aFileName,
const Index aLineNo )
{
if( !aCondition )
{
log( "Condition `%s' (%s) not met in %s (%s:%li)",
aMessage, aConditionAsString, aFunction, aFileName, aLineNo );
if( attachDebuggerOnError )
{
Platform::getInstance() -> attachDebugger();
}
else
{
throw ( new InternalError( aMessage, null ) );
}
}
}
INLINE void Debug::preCondition( boolean aCondition,
const char *const aMessage,
const char *const aConditionAsString,
const char *const aFunction,
const char *const aFileName,
const Index aLineNo )
{
testCondition( aCondition, aMessage, aConditionAsString, aFunction, aFileName, aLineNo );
}
INLINE void Debug::postCondition( boolean aCondition,
const char *const aMessage,
const char *const aConditionAsString,
const char *const aFunction,
const char *const aFileName,
const Index aLineNo )
{
testCondition( aCondition, aMessage, aConditionAsString, aFunction, aFileName, aLineNo );
}
INLINE void Debug::exception( Exception *anEx )
{
logString( "Exception description: %s", anEx -> getFullDescription() );
}
#if defined(_INLINE)
#include "../src/String.ipp"
#endif
#endif