sl@0: /* sl@0: * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: sl@0: #ifndef FEATMGRDEBUG_H sl@0: #define FEATMGRDEBUG_H sl@0: sl@0: sl@0: // INCLUDES sl@0: #include sl@0: sl@0: // Enable macros to support error and/or info logging sl@0: #ifdef _DEBUG sl@0: //#define FEATMGR_INFO_LOG_ENABLED sl@0: //#define FEATMGR_ERROR_LOG_ENABLED sl@0: #define FEATMGR_TIMESTAMP_ENABLED sl@0: #endif // _DEBUG sl@0: sl@0: sl@0: /** sl@0: * Prefix trace macro to complete tracing with component name. sl@0: * Returns TDesC which can be used directly with RDebug or RFileLogger. sl@0: */ sl@0: #define PREFIX( aMsg ) TPtrC( (const TText*)L"[EFM]: " L##aMsg ) sl@0: sl@0: /** sl@0: * Prefix error trace sl@0: */ sl@0: #define ERROR_PREFIX( aMsg ) PREFIX( "[ERROR]: " L##aMsg ) sl@0: sl@0: /** sl@0: * Prefix macro for strings sl@0: */ sl@0: #define _PREFIX_CHAR( aMsg ) (const char*)"[EFM]: " ##aMsg sl@0: sl@0: // Info logging sl@0: #ifdef FEATMGR_INFO_LOG_ENABLED sl@0: sl@0: #define INFO_LOG( aMsg ) { RDebug::Print( PREFIX( aMsg ) ); } sl@0: sl@0: #define INFO_LOG1( aMsg, aArg1 )\ sl@0: { RDebug::Print( PREFIX( aMsg ), aArg1 ); } sl@0: sl@0: #define INFO_LOG2( aMsg, aArg1, aArg2 )\ sl@0: { RDebug::Print( PREFIX( aMsg ), aArg1, aArg2 ); } sl@0: sl@0: #define INFO_LOG3( aMsg, aArg1, aArg2, aArg3 )\ sl@0: { RDebug::Print( PREFIX( aMsg ), aArg1, aArg2, aArg3 ); } sl@0: sl@0: #define FUNC( aMsg, aP1 )\ sl@0: {\ sl@0: RDebug::Printf( aMsg, aP1 );\ sl@0: }\ sl@0: // Function log object sl@0: _LIT8( KFuncNameTerminator, "(" ); sl@0: _LIT8( KFuncLeavePattern, "L" ); sl@0: sl@0: class TFuncLog sl@0: { sl@0: public: sl@0: sl@0: static void Cleanup( TAny* aPtr ) sl@0: { sl@0: TFuncLog* self = static_cast< TFuncLog* >( aPtr ); sl@0: self->iLeft = ETrue; sl@0: FUNC( _PREFIX_CHAR("%S-LEAVE"), &self->iFunc ); // Leave detected sl@0: } sl@0: sl@0: inline TFuncLog( const char* aFunc ) : sl@0: iFunc( aFunc ? _S8( aFunc ) : _S8("") ), sl@0: iLeft( EFalse ), sl@0: iCleanupItem( Cleanup, this ), sl@0: iCanLeave( EFalse ) sl@0: { sl@0: TInt pos( iFunc.Find( KFuncNameTerminator ) ); sl@0: if( pos != KErrNotFound ) sl@0: { sl@0: iFunc.Set( iFunc.Left( pos ) ); sl@0: iCanLeave = !iFunc.Right( KFuncLeavePattern().Length() ).Compare( KFuncLeavePattern ); sl@0: if ( iCanLeave ) sl@0: { sl@0: CleanupStack::PushL( iCleanupItem ); // Ignore warnings sl@0: } sl@0: } sl@0: FUNC( _PREFIX_CHAR("%S-START"), &iFunc ); sl@0: } sl@0: sl@0: inline ~TFuncLog() sl@0: { sl@0: if ( !iLeft ) sl@0: { sl@0: if ( iCanLeave ) sl@0: { sl@0: CleanupStack::Pop( this ); // Pop the cleanup item sl@0: } sl@0: FUNC( _PREFIX_CHAR("%S-END"), &iFunc ); // Normally finished sl@0: } sl@0: } sl@0: sl@0: private: // Data sl@0: sl@0: TPtrC8 iFunc; sl@0: TBool iLeft; sl@0: TCleanupItem iCleanupItem; sl@0: TBool iCanLeave; sl@0: }; sl@0: sl@0: #define FUNC_LOG TFuncLog _fl( __PRETTY_FUNCTION__ ); sl@0: sl@0: #else // FEATMGR_INFO_LOG_ENABLED sl@0: sl@0: #define INFO_LOG( aMsg ) sl@0: sl@0: #define INFO_LOG1( aMsg, aArg1 ) sl@0: sl@0: #define INFO_LOG2( aMsg, aArg1, aArg2 ) sl@0: sl@0: #define INFO_LOG3( aMsg, aArg1, aArg2, aArg3 ) sl@0: sl@0: #define FUNC_LOG sl@0: sl@0: #endif // FEATMGR_INFO_LOG_ENABLED sl@0: sl@0: // Timestamp logging sl@0: #ifdef FEATMGR_TIMESTAMP_ENABLED sl@0: sl@0: #define TIMESTAMP( aCaption )\ sl@0: {\ sl@0: TTime t;\ sl@0: t.HomeTime();\ sl@0: TDateTime dt = t.DateTime();\ sl@0: _LIT( KCaption, aCaption );\ sl@0: RDebug::Print( PREFIX("[TIMESTAMP] %S %d:%02d:%02d.%d us"),\ sl@0: &KCaption, dt.Hour(), dt.Minute(), dt.Second(), dt.MicroSecond() );\ sl@0: } sl@0: sl@0: #else sl@0: sl@0: #define TIMESTAMP( aCaption ) sl@0: sl@0: #endif // FEATMGR_TIMESTAMP_ENABLED sl@0: sl@0: // Error logging sl@0: #ifdef FEATMGR_ERROR_LOG_ENABLED sl@0: sl@0: #define ERROR_LOG( aMsg )\ sl@0: {RDebug::Print( ERROR_PREFIX( aMsg ) ); } sl@0: sl@0: #define ERROR_LOG1( aMsg, aArg1 )\ sl@0: {RDebug::Print( ERROR_PREFIX( aMsg ), aArg1 ); } sl@0: sl@0: #define ERROR_LOG2( aMsg, aArg1, aArg2 )\ sl@0: { RDebug::Print( ERROR_PREFIX( aMsg ), aArg1, aArg2 ); } sl@0: sl@0: #define ERROR_LOG3( aMsg, aArg1, aArg2, aArg3 )\ sl@0: { RDebug::Print( ERROR_PREFIX( aMsg ), aArg1, aArg2, aArg3 ); } sl@0: sl@0: #define LOG_IF_ERROR( aErr, aMsg )\ sl@0: if ( ( aErr ) != KErrNone )\ sl@0: { RDebug::Print( ERROR_PREFIX( aMsg )); } sl@0: sl@0: #define LOG_IF_ERROR1( aErr, aMsg, aArg1 )\ sl@0: if ( ( aErr ) != KErrNone )\ sl@0: { RDebug::Print( ERROR_PREFIX( aMsg ), aArg1 ); } sl@0: sl@0: #define LOG_IF_ERROR2( aErr, aMsg, aArg1, aArg2 )\ sl@0: if ( ( aErr ) != KErrNone )\ sl@0: { RDebug::Print( ERROR_PREFIX( aMsg ), aArg1, aArg2 ); } sl@0: sl@0: #define LOG_IF_ERROR3( aErr, aMsg, aArg1, aArg2, aArg3 )\ sl@0: if ( ( aErr ) != KErrNone )\ sl@0: { RDebug::Print( ERROR_PREFIX( aMsg ), aArg1, aArg2, aArg3 ); } sl@0: sl@0: #else // FEATMGR_ERROR_LOG_ENABLED sl@0: sl@0: #define ERROR_LOG( aMsg ) sl@0: sl@0: #define ERROR_LOG1( aMsg, aArg1 ) sl@0: sl@0: #define ERROR_LOG2( aMsg, aArg1, aArg2 ) sl@0: sl@0: #define ERROR_LOG3( aMsg, aArg1, aArg2, aArg3 ) sl@0: sl@0: // Remove compiler warning sl@0: #define LOG_IF_ERROR( aErr, aMsg ) ( aErr ) = ( aErr ); sl@0: sl@0: #define LOG_IF_ERROR1( aErr, aMsg, aArg1 ) ( aErr ) = ( aErr ); sl@0: sl@0: #define LOG_IF_ERROR2( aErr, aMsg, aArg1, aArg2 ) ( aErr ) = ( aErr ); sl@0: sl@0: #define LOG_IF_ERROR3( aErr, aMsg, aArg1, aArg2, aArg3 ) ( aErr ) = ( aErr ); sl@0: sl@0: #endif // FEATMGR_ERROR_LOG_ENABLED sl@0: sl@0: sl@0: #endif // FEATMGRDEBUG_H sl@0: sl@0: // End of File