//------------------------------------------------------------------------- // Desc: Message logging. // Tabs: 3 // // Copyright (c) 2001-2003,2005-2006 Novell, Inc. All Rights Reserved. // // This program is free software; you can redistribute it and/or // modify it under the terms of version 2 of the GNU General Public // License as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, contact Novell, Inc. // // To contact Novell about this file by physical or electronic mail, // you may find current contact information at www.novell.com // // $Id: flog.cpp 12331 2006-01-23 10:19:55 -0700 (Mon, 23 Jan 2006) ahodgkinson $ //------------------------------------------------------------------------- #include "flaimsys.h" // Static functions FSTATIC void flmLogProcessFieldInfo( const char ** ppszFormat, FLMUINT * puiWidth, FLMUINT * puiPrecision, FLMUINT * puiFlags, f_va_list * args); FSTATIC RCODE flmLogProcessFormatString( FLMUINT uiLen, F_LogMessage * pLogMessage, ...); FSTATIC RCODE flmLogParsePrintfArgs( const char * pszFormat, f_va_list * args, F_LogMessage * pLogMessage); FSTATIC RCODE flmLogStringFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); FSTATIC FLMUINT flmLogPrintNumber( FLMUINT uiNumber, FLMUINT uiBase, char * pszBuffer); FSTATIC RCODE flmLogNumberFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); FSTATIC RCODE flmLogErrorFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); FSTATIC RCODE flmLogColorFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); FSTATIC RCODE flmLogCharFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); FSTATIC RCODE flmLogNotHandledFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); // Percent formating prefixes #define P_NONE 0 #define P_MINUS 1 #define P_PLUS 2 #define P_POUND 3 // Width and precision flags #define MINUS_FLAG 0x0001 #define PLUS_FLAG 0x0002 #define SPACE_FLAG 0x0004 #define POUND_FLAG 0x0008 #define ZERO_FLAG 0x0010 #define SHORT_FLAG 0x0020 #define LONG_FLAG 0x0040 #define DOUBLE_FLAG 0x0080 // Format handlers typedef RCODE (*FORMATHANDLER)( FLMBYTE ucFormatChar, FLMUINT uiWdth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args); typedef struct FORMATTERTABLE { FORMATHANDLER formatTextHandler; FORMATHANDLER percentHandler; FORMATHANDLER lowerCaseHandlers[ 26]; FORMATHANDLER upperCaseHandlers[ 26]; } FORMATTERTABLE; /**************************************************************************** Desc: Default formatter table ****************************************************************************/ FSTATIC FORMATTERTABLE flmLogFormatHandlers = { flmLogStringFormatter, flmLogCharFormatter, { /* a */ flmLogNotHandledFormatter, /* b */ flmLogNotHandledFormatter, /* c */ flmLogCharFormatter, /* d */ flmLogNumberFormatter, /* e */ flmLogErrorFormatter, /* f */ flmLogNotHandledFormatter, /* g */ flmLogNotHandledFormatter, /* h */ flmLogNotHandledFormatter, /* i */ flmLogNotHandledFormatter, /* j */ flmLogNotHandledFormatter, /* k */ flmLogNotHandledFormatter, /* l */ flmLogNotHandledFormatter, /* m */ flmLogNotHandledFormatter, /* n */ flmLogNotHandledFormatter, /* o */ flmLogNumberFormatter, /* p */ flmLogNotHandledFormatter, /* q */ flmLogNotHandledFormatter, /* r */ flmLogNotHandledFormatter, /* s */ flmLogStringFormatter, /* t */ flmLogNotHandledFormatter, /* u */ flmLogNumberFormatter, /* v */ flmLogNotHandledFormatter, /* w */ flmLogNotHandledFormatter, /* x */ flmLogNumberFormatter, /* y */ flmLogNotHandledFormatter, /* z */ flmLogNotHandledFormatter, }, { /* A */ flmLogNotHandledFormatter, /* B */ flmLogNotHandledFormatter, /* C */ flmLogColorFormatter, /* D */ flmLogNotHandledFormatter, /* E */ flmLogErrorFormatter, /* F */ flmLogNotHandledFormatter, /* G */ flmLogNotHandledFormatter, /* H */ flmLogNotHandledFormatter, /* I */ flmLogNotHandledFormatter, /* J */ flmLogNotHandledFormatter, /* K */ flmLogNotHandledFormatter, /* L */ flmLogNotHandledFormatter, /* M */ flmLogNotHandledFormatter, /* N */ flmLogNotHandledFormatter, /* O */ flmLogNotHandledFormatter, /* P */ flmLogNotHandledFormatter, /* Q */ flmLogNotHandledFormatter, /* R */ flmLogNotHandledFormatter, /* S */ flmLogStringFormatter, /* T */ flmLogNotHandledFormatter, /* U */ flmLogNotHandledFormatter, /* V */ flmLogNotHandledFormatter, /* W */ flmLogNotHandledFormatter, /* X */ flmLogNumberFormatter, /* Y */ flmLogNotHandledFormatter, /* Z */ flmLogNotHandledFormatter, } }; /**************************************************************************** Desc: *ppszFormat points to text following a '%' sign. Process legal field information. Leave *ppszFormat pointing at the format specifier char. ****************************************************************************/ FSTATIC void flmLogProcessFieldInfo( const char ** ppszFormat, FLMUINT * puiWidth, FLMUINT * puiPrecision, FLMUINT * puiFlags, f_va_list * args) { const char * pszTmp = *ppszFormat; /* process flags */ *puiFlags = 0; while( *pszTmp == '-' || *pszTmp == '+' || *pszTmp == ' ' || *pszTmp == '#' || *pszTmp == '0') { switch( *pszTmp) { case '-': *puiFlags |= MINUS_FLAG; break; case '+': *puiFlags |= PLUS_FLAG; break; case ' ': *puiFlags |= SPACE_FLAG; break; case '#': *puiFlags |= POUND_FLAG; break; case '0': *puiFlags |= ZERO_FLAG; break; } pszTmp++; } /* process width */ *puiWidth = 0; if( *pszTmp == '*') { *puiWidth = f_va_arg( *args, unsigned int); pszTmp++; } else while( *pszTmp >= '0' && *pszTmp <= '9') { *puiWidth = (*puiWidth * 10) + (*pszTmp - '0'); pszTmp++; } /* process precision */ *puiPrecision = 0; if( *pszTmp == '.') { pszTmp++; if( *pszTmp == '*') { *puiPrecision = f_va_arg( *args, unsigned int); pszTmp++; } else while( *pszTmp >= '0' && *pszTmp <= '9') { *puiPrecision = (*puiPrecision * 10) + (*pszTmp - '0'); pszTmp++; } } /* size modifiers */ switch( *pszTmp) { case 'L': *puiFlags |= DOUBLE_FLAG; pszTmp++; break; case 'l': *puiFlags |= LONG_FLAG; pszTmp++; break; case 'h': *puiFlags |= SHORT_FLAG; pszTmp++; break; } *ppszFormat = pszTmp; } /**************************************************************************** Desc: Handle text portions of the format string ****************************************************************************/ FSTATIC RCODE flmLogProcessFormatString( FLMUINT uiLen, F_LogMessage * pLogMessage, ...) { RCODE rc = FERR_OK; f_va_list args; f_va_start( args, pLogMessage); if( uiLen && flmLogFormatHandlers.formatTextHandler) { rc = flmLogFormatHandlers.formatTextHandler( 0, uiLen, uiLen, 0, pLogMessage, (f_va_list *)&args); } f_va_end(args); return( rc); } /**************************************************************************** Desc: Parse arguments in format string, calling appropriate handlers ****************************************************************************/ FSTATIC RCODE flmLogParsePrintfArgs( const char * pszFormat, f_va_list * args, F_LogMessage * pLogMessage) { RCODE rc = FERR_OK; FLMBYTE ucChar; FLMUINT uiFlags; FLMUINT uiWidth; FLMUINT uiPrecision; const char * pszTextStart = pszFormat; FORMATHANDLER fnHandler; while( (ucChar = *pszFormat++) != 0) { if( ucChar != '%') { // Handle invalid characters if( ucChar < ASCII_SPACE || ucChar > ASCII_TILDE) { uiWidth = (FLMUINT)(pszFormat - pszTextStart - 1); if( uiWidth) { if( RC_BAD( rc = flmLogProcessFormatString( uiWidth, pLogMessage, pszTextStart))) { goto Exit; } } // Only call newline() if ASCII_NEWLINE character. // We will skip ASCII_CR characters if( ucChar == ASCII_NEWLINE) { pLogMessage->newline(); } pszTextStart = pszFormat; } continue; } uiWidth = (FLMUINT)(pszFormat - pszTextStart - 1); if( RC_BAD( rc = flmLogProcessFormatString( uiWidth, pLogMessage, pszTextStart))) { goto Exit; } flmLogProcessFieldInfo( &pszFormat, &uiWidth, &uiPrecision, &uiFlags, args); if( (ucChar = *pszFormat++) >= 'a' && ucChar <= 'z') { fnHandler = flmLogFormatHandlers.lowerCaseHandlers[ ucChar - 'a']; } else if( ucChar >= 'A' && ucChar <= 'Z') { fnHandler = flmLogFormatHandlers.upperCaseHandlers[ ucChar - 'A']; } else if( ucChar == '%') { fnHandler = flmLogFormatHandlers.percentHandler; } else { fnHandler = flmLogNotHandledFormatter; } if( RC_BAD( rc = fnHandler( ucChar, uiWidth, uiPrecision, uiFlags, pLogMessage, args))) { goto Exit; } pszTextStart = pszFormat; } if( RC_BAD( rc = flmLogProcessFormatString( (FLMUINT)(pszFormat - pszTextStart - 1), pLogMessage, pszTextStart))) { goto Exit; } Exit: return( rc); } /**************************************************************************** Desc: Default string formatter. Prints the ascii string specified by ADDRESS in 's'. Prints length preceeded string specified by ADDRESS in 'S'. Prints unicode string specified by ADDRESS in 'U'. Format: %[flags][width][.prec]'s'|'S'|'U' flags = '-' left justifies if string length < width width = minimum number of characters to print prec = maximum number of characters to print ****************************************************************************/ FSTATIC RCODE flmLogStringFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args) { RCODE rc = FERR_OK; const char * pszNullPointerStr = ""; FLMUINT uiLength; FLMUINT uiCount; char szOutputBuf[ 128]; char * pszDest = &szOutputBuf[ 0]; FLMUINT uiMaxLen = sizeof( szOutputBuf) - 1; const char * pszString = f_va_arg( *args, char *); void * pAllocBuf = NULL; if( uiWidth >= uiMaxLen) { // Need to allocate a temporary buffer uiMaxLen = uiWidth; if( RC_BAD( rc = f_alloc( (FLMUINT)(uiMaxLen + 1), &pAllocBuf))) { goto Exit; } pszDest = (char *)pAllocBuf; } if( !pszString) { uiLength = f_strlen( pszNullPointerStr); } else if( ucFormatChar == 'S') { uiLength = (FLMUINT)(*pszString); pszString++; } else { uiLength = ucFormatChar == 0 ? uiWidth : f_strlen( pszString); } if( uiPrecision > 0 && uiLength > uiPrecision) { uiLength = uiPrecision; } uiCount = uiWidth - uiLength; if( uiLength < uiWidth && !(uiFlags & MINUS_FLAG)) { // right justify f_memset( pszDest, ' ', uiCount); pszDest += uiCount; } if( !pszString) { f_memcpy( pszDest, pszNullPointerStr, uiLength); } else { f_memcpy( pszDest, pszString, uiLength); } pszDest += uiLength; // left justify if( uiLength < uiWidth && (uiFlags & MINUS_FLAG)) { f_memset( pszDest, ' ', uiCount); pszDest += uiCount; } *pszDest = 0; pLogMessage->appendString( szOutputBuf); Exit: if( pAllocBuf) { f_free( &pAllocBuf); } return( rc); } /**************************************************************************** Desc: This is used by printf to output numbers. It uses recursion to separate the numbers down to individual digits and then calls PrintDigit to output each digit. ****************************************************************************/ FSTATIC FLMUINT flmLogPrintNumber( FLMUINT uiNumber, FLMUINT uiBase, char * pszBuffer) { FLMBYTE ucChar = (FLMBYTE)( uiNumber % uiBase); FLMUINT uiIndex = uiNumber / uiBase; uiIndex = uiIndex ? flmLogPrintNumber( uiIndex, uiBase, pszBuffer) : 0; pszBuffer[ uiIndex] = (FLMBYTE)(ucChar > 9 ? ucChar + 'a' - 10 : ucChar + '0'); return( uiIndex + 1); } /**************************************************************************** Desc: Default number formatter. Prints the number specified by VALUE in 'd', 'o', 'u', 'x', or 'X' Format: %[flags][width][.prec]'E' flags = 'h' value is uint16 'l' value is uint32 '-' left align result '+' print plus sign if positive '#' print '0x' in front of hex numbers '0' zero-fill width = minimum number of characters to print prec = maximum number of characters to print (truncates or rounds) ****************************************************************************/ FSTATIC RCODE flmLogNumberFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args) { FLMUINT uiPrefix = P_NONE; FLMUINT uiLength; FLMUINT uiBase = 10; FLMUINT uiLoop; char szNumberBuf[ 32]; char szOutputBuf[ 128]; char * pszDest = &szOutputBuf[ 0]; FLMUINT uiMaxLen = sizeof( szOutputBuf) - 1; char * pszTmp; FLMUINT uiArg; if( uiFlags & SHORT_FLAG) { uiArg = (FLMUINT)f_va_arg( *args, int); } else if( uiFlags & LONG_FLAG) { uiArg = (FLMUINT)f_va_arg( *args, long int); } else { uiArg = (FLMUINT)f_va_arg( *args, int); } switch( ucFormatChar) { case 'd': if( (long)uiArg < 0) { // handle negatives uiPrefix = P_MINUS; if( uiWidth > 0) { uiWidth--; } uiArg = (FLMUINT)(-((long)uiArg)); } else if( uiFlags & PLUS_FLAG) { uiPrefix = P_PLUS; if( uiWidth > 0) { uiWidth--; } } break; case 'o': uiBase = 8; break; case 'x': case 'X': if( (uiFlags & POUND_FLAG) != 0 && uiArg) { uiPrefix = P_POUND; if( uiWidth > 1) { uiWidth -= 2; } } uiBase = 16; break; } uiLength = flmLogPrintNumber( uiArg, uiBase, szNumberBuf); szNumberBuf[ uiLength] = 0; if( ucFormatChar == 'X') { pszTmp = &szNumberBuf[ 0]; while( *pszTmp) { if( (*pszTmp >= 'a') && (*pszTmp <= 'z')) { *pszTmp = (FLMBYTE)((*pszTmp - 'a') + 'A'); } pszTmp++; } } if( uiWidth < uiLength) { uiWidth = uiLength; } if( uiFlags & ZERO_FLAG) { // zero fill uiPrecision = uiWidth; } else if( !(uiFlags & MINUS_FLAG)) { // right justify while( uiWidth > uiLength && uiWidth > uiPrecision && uiMaxLen > 0) { *pszDest++ = ' '; uiMaxLen--; uiWidth--; } } // handle the prefix if any if( uiMaxLen) { switch( uiPrefix) { case P_MINUS: *pszDest++ = '-'; uiMaxLen--; break; case P_PLUS: *pszDest++ = '+'; uiMaxLen--; break; case P_POUND: *pszDest++ = '0'; uiMaxLen--; *pszDest++ = ucFormatChar; uiMaxLen--; break; } } // handle the precision while( uiLength < uiPrecision && uiMaxLen) { *pszDest++ = '0'; uiMaxLen--; uiPrecision--; uiWidth--; } // print the number for( uiLoop = uiLength, pszTmp = &szNumberBuf[ 0]; uiLoop > 0 && uiMaxLen; uiLoop--, uiMaxLen--) { *pszDest++ = *pszTmp++; } if( uiFlags & MINUS_FLAG) { // left justify while( uiLength < uiWidth && uiMaxLen > 0) { *pszDest++ = ' '; uiMaxLen--; uiWidth--; } } *pszDest = 0; pLogMessage->appendString( szOutputBuf); return( FERR_OK); } /**************************************************************************** Desc: Default error formatter. ****************************************************************************/ FSTATIC RCODE flmLogErrorFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args) { RCODE rc = FERR_OK; char szOutputBuf[ 128]; FLMUINT uiErrorCode = (FLMUINT)f_va_arg( *args, unsigned); F_UNREFERENCED_PARM( ucFormatChar); F_UNREFERENCED_PARM( uiWidth); F_UNREFERENCED_PARM( uiPrecision); F_UNREFERENCED_PARM( uiFlags); if( uiErrorCode < 0x0000FFFF) { f_sprintf( szOutputBuf, "%s (0x%4.4X, %u)", FlmErrorString( (RCODE)uiErrorCode), (unsigned)uiErrorCode, (unsigned)uiErrorCode); } else { f_sprintf( szOutputBuf, "0x%8.8X, %d", (unsigned)uiErrorCode, (unsigned)uiErrorCode); } pLogMessage->appendString( szOutputBuf); return( rc); } /**************************************************************************** Desc: Color formatter ****************************************************************************/ FSTATIC RCODE flmLogColorFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args) { RCODE rc = FERR_OK; F_UNREFERENCED_PARM( ucFormatChar); F_UNREFERENCED_PARM( args); if( uiFlags & PLUS_FLAG) { // Push a color onto the stack if( !uiWidth) { // Foreground pLogMessage->pushForegroundColor(); } else { // Background pLogMessage->pushBackgroundColor(); } } else if( uiFlags & MINUS_FLAG) { // Pop a color from the color stack if( !uiWidth) { // Foreground pLogMessage->popForegroundColor(); } else { // Background pLogMessage->popBackgroundColor(); } } else { FlmColorType eForeground = (FlmColorType)(uiWidth + 1); FlmColorType eBackground = (FlmColorType)(uiPrecision + 1); // Set a new foreground and/or background color if( eForeground >= FLM_NUM_COLORS || eBackground >= FLM_NUM_COLORS) { goto Exit; } pLogMessage->setColor( eForeground, eBackground); } Exit: return( rc); } /**************************************************************************** Desc: Default character formatter. Prints the character specified by VALUE in 'c', or the '%' character. Format: %[flags][width][.prec]'c' flags = width = prec = ****************************************************************************/ FSTATIC RCODE flmLogCharFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args) { char ucCharBuf[ 2]; F_UNREFERENCED_PARM( uiWidth); F_UNREFERENCED_PARM( uiPrecision); F_UNREFERENCED_PARM( uiFlags); ucCharBuf[ 0] = (FLMBYTE)((ucFormatChar == '%') ? '%' : f_va_arg( *args, int)); ucCharBuf[ 1] = 0; pLogMessage->appendString( ucCharBuf); return( FERR_OK); } /**************************************************************************** Desc: Unhandled format strings ****************************************************************************/ FSTATIC RCODE flmLogNotHandledFormatter( FLMBYTE ucFormatChar, FLMUINT uiWidth, FLMUINT uiPrecision, FLMUINT uiFlags, F_LogMessage * pLogMessage, f_va_list * args) { F_UNREFERENCED_PARM( ucFormatChar); F_UNREFERENCED_PARM( uiWidth); F_UNREFERENCED_PARM( uiPrecision); F_UNREFERENCED_PARM( uiFlags); F_UNREFERENCED_PARM( args); pLogMessage->appendString( ""); return( FERR_OK); } /**************************************************************************** Desc: Main entry point for printf functionality. ****************************************************************************/ void flmLogPrintf( F_LogMessage * pLogMessage, const char * szFormatStr, ...) { f_va_list args; f_va_start( args, szFormatStr); (void)flmLogParsePrintfArgs( szFormatStr, (f_va_list *)&args, pLogMessage); f_va_end( args); } /**************************************************************************** Desc: Printf routine that accepts a va_list argument ****************************************************************************/ void flmLogVPrintf( F_LogMessage * pLogMessage, const char * szFormatStr, f_va_list * args) { (void)flmLogParsePrintfArgs( szFormatStr, args, pLogMessage); } /**************************************************************************** Desc: Returns an F_LogMessage object if logging is enabled for the specified message type ****************************************************************************/ F_LogMessage * flmBeginLogMessage( FlmLogMessageType eMsgType, FlmLogMessageSeverity eMsgSeverity) { F_LogMessage * pNewMsg = NULL; if( gv_FlmSysData.pLogger) { pNewMsg = gv_FlmSysData.pLogger->beginMessage( eMsgType, eMsgSeverity); } return( pNewMsg); } /**************************************************************************** Desc: F_Logger constructor ****************************************************************************/ F_Logger::F_Logger() { m_hMutex = F_MUTEX_NULL; m_bSetupCalled = FALSE; m_pbEnabledList = NULL; } /**************************************************************************** Desc: F_Logger destructor ****************************************************************************/ F_Logger::~F_Logger() { if (m_hMutex != F_MUTEX_NULL) { f_mutexUnlock( m_hMutex); f_mutexDestroy( &m_hMutex); } if( m_pbEnabledList) { f_free( &m_pbEnabledList); } } /**************************************************************************** Desc: Set up the logger object ****************************************************************************/ RCODE F_Logger::setupLogger( void) { RCODE rc = FERR_OK; flmAssert( !m_bSetupCalled); if( RC_BAD( rc = f_mutexCreate( &m_hMutex))) { goto Exit; } if (RC_BAD( rc = f_calloc( ((FLMUINT)FLM_NUM_MESSAGE_TYPES) * sizeof( FLMBOOL), &m_pbEnabledList))) { goto Exit; } m_bSetupCalled = TRUE; Exit: if( RC_BAD( rc)) { if( m_hMutex != F_MUTEX_NULL) { f_mutexDestroy( &m_hMutex); } if( m_pbEnabledList) { f_free( &m_pbEnabledList); } } return( rc); } /**************************************************************************** Desc: Returns TRUE if the logger has been set up ****************************************************************************/ FLMBOOL F_Logger::loggerIsSetup( void) { return( m_bSetupCalled); } /**************************************************************************** Desc: Turns logging on for a specific message type ****************************************************************************/ void F_Logger::enableMessageType( FlmLogMessageType eMsgType) { FLMUINT uiSlot = (FLMUINT)eMsgType; flmAssert( m_bSetupCalled); if( uiSlot < ((FLMUINT)FLM_NUM_MESSAGE_TYPES)) { m_pbEnabledList[ uiSlot] = TRUE; } } /**************************************************************************** Desc: Turns logging on for all message types ****************************************************************************/ void F_Logger::enableAllMessageTypes( void) { FLMUINT uiLoop; flmAssert( m_bSetupCalled); for( uiLoop = 0; uiLoop < ((FLMUINT)FLM_NUM_MESSAGE_TYPES); uiLoop++) { m_pbEnabledList[ uiLoop] = TRUE; } } /**************************************************************************** Desc: Turs logging off for a specific message type ****************************************************************************/ void F_Logger::disableMessageType( FlmLogMessageType eMsgType) { FLMUINT uiSlot = (FLMUINT)eMsgType; flmAssert( m_bSetupCalled); if( uiSlot < ((FLMUINT)FLM_NUM_MESSAGE_TYPES)) { m_pbEnabledList[ uiSlot] = FALSE; } } /**************************************************************************** Desc: Turns logging off for all message types ****************************************************************************/ void F_Logger::disableAllMessageTypes( void) { flmAssert( m_bSetupCalled); f_memset( m_pbEnabledList, 0, ((FLMUINT)FLM_NUM_MESSAGE_TYPES) * sizeof( FLMBOOL)); } /**************************************************************************** Desc: Returns TRUE if the specified message type is being logged ****************************************************************************/ FLMBOOL F_Logger::messageTypeEnabled( FlmLogMessageType eMsgType) { FLMUINT uiSlot = (FLMUINT)eMsgType; flmAssert( m_bSetupCalled); if( uiSlot < ((FLMUINT)FLM_NUM_MESSAGE_TYPES)) { return( m_pbEnabledList[ uiSlot]); } return( FALSE); } /**************************************************************************** Desc: ****************************************************************************/ void F_Logger::lockLogger( void) { flmAssert( m_bSetupCalled); f_mutexLock( m_hMutex); } /**************************************************************************** Desc: ****************************************************************************/ void F_Logger::unlockLogger( void) { flmAssert( m_bSetupCalled); f_mutexUnlock( m_hMutex); } /**************************************************************************** Desc: Pushes the current foreground color onto the color stack ****************************************************************************/ void F_LogMessage::pushForegroundColor( void) { if( m_uiForeColors < F_MAX_COLOR_STACK_SIZE) { m_eForeColors[ F_MAX_COLOR_STACK_SIZE - (++m_uiForeColors)] = m_eCurrentForeColor; } else { m_uiForeColors++; } } /**************************************************************************** Desc: Pushes the current background color onto the color stack ****************************************************************************/ void F_LogMessage::pushBackgroundColor( void) { if( m_uiBackColors < F_MAX_COLOR_STACK_SIZE) { m_eBackColors[ F_MAX_COLOR_STACK_SIZE - (++m_uiBackColors)] = m_eCurrentBackColor; } else { m_uiBackColors++; } } /**************************************************************************** Desc: Pops the foreground color off of the top of the color stack ****************************************************************************/ void F_LogMessage::popForegroundColor( void) { FlmColorType eForeColor = m_eCurrentForeColor; // Pop a color from the color stack if( m_uiForeColors) { if( m_uiForeColors <= F_MAX_COLOR_STACK_SIZE) { eForeColor = m_eForeColors[ F_MAX_COLOR_STACK_SIZE - m_uiForeColors]; } m_uiForeColors--; } setColor( eForeColor, m_eCurrentBackColor); } /**************************************************************************** Desc: Pops the background color off of the top of the color stack ****************************************************************************/ void F_LogMessage::popBackgroundColor( void) { FlmColorType eBackColor = m_eCurrentBackColor; // Pop a color from the color stack if( m_uiBackColors) { if( m_uiBackColors <= F_MAX_COLOR_STACK_SIZE) { eBackColor = m_eBackColors[ F_MAX_COLOR_STACK_SIZE - m_uiBackColors]; } m_uiBackColors--; } setColor( m_eCurrentForeColor, eBackColor); } /**************************************************************************** Desc: Sets the foreground and background colors of a message ****************************************************************************/ void F_LogMessage::setColor( FlmColorType eForeColor, FlmColorType eBackColor) { if( eForeColor != m_eCurrentForeColor || eBackColor != m_eCurrentBackColor) { m_eCurrentForeColor = eForeColor; m_eCurrentBackColor = eBackColor; changeColor( m_eCurrentForeColor, m_eCurrentBackColor); } } /**************************************************************************** Desc: Ends a logging message ****************************************************************************/ void flmEndLogMessage( F_LogMessage ** ppLogMessage) { if( *ppLogMessage) { (*ppLogMessage)->endMessage(); (*ppLogMessage)->Release(); *ppLogMessage = NULL; } }