Files
mars-flaim/ftk/src/ftklog.cpp

403 lines
9.5 KiB
C++

//------------------------------------------------------------------------------
// Desc: Contains routines for logging messages from within FLAIM.
// Tabs: 3
//
// Copyright (c) 2001-2007 Novell, Inc. All Rights Reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version 2.1
// of the License.
//
// This library 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
// Library Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; 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$
//------------------------------------------------------------------------------
#include "ftksys.h"
static F_MUTEX gv_hLoggerMutex = F_MUTEX_NULL;
static FLMUINT gv_uiPendingLogMessages = 0;
static IF_LoggerClient * gv_pLogger = NULL;
/***************************************************************************
Desc:
***************************************************************************/
class FLMEXP F_LogPrintfClient : public IF_PrintfClient
{
public:
#define MAX_LOG_BUF_CHARS 255
F_LogPrintfClient( IF_LogMessageClient * pLogMsg)
{
m_pLogMsg = pLogMsg;
m_pLogMsg->AddRef();
m_uiCharOffset = 0;
m_eCurrentForeColor = FLM_BLACK;
m_eCurrentBackColor = FLM_WHITE;
}
virtual ~F_LogPrintfClient()
{
if( m_pLogMsg)
{
if( m_uiCharOffset)
{
flushLogBuffer();
}
m_pLogMsg->Release();
m_pLogMsg = NULL;
}
}
FINLINE FLMINT FLMAPI outputChar(
char cChar,
FLMUINT uiCount)
{
FLMUINT uiTmpCount;
FLMINT iBytesOutput = (FLMINT)uiCount;
while( uiCount)
{
uiTmpCount = uiCount;
if( m_uiCharOffset + uiTmpCount > MAX_LOG_BUF_CHARS)
{
uiTmpCount = MAX_LOG_BUF_CHARS - m_uiCharOffset;
}
f_memset( &m_szLogBuf [m_uiCharOffset], cChar, uiTmpCount);
m_uiCharOffset += uiTmpCount;
uiCount -= uiTmpCount;
if (m_uiCharOffset == MAX_LOG_BUF_CHARS)
{
flushLogBuffer();
}
}
return( iBytesOutput);
}
FINLINE FLMINT FLMAPI outputChar(
char cChar)
{
m_szLogBuf[ m_uiCharOffset++] = cChar;
if( m_uiCharOffset == MAX_LOG_BUF_CHARS)
{
flushLogBuffer();
}
return( 1);
}
FINLINE FLMINT FLMAPI outputStr(
const char * pszStr,
FLMUINT uiLen)
{
FLMUINT uiTmpLen;
FLMINT iBytesOutput = (FLMINT)uiLen;
while( uiLen)
{
uiTmpLen = uiLen;
if( m_uiCharOffset + uiTmpLen > MAX_LOG_BUF_CHARS)
{
uiTmpLen = MAX_LOG_BUF_CHARS - m_uiCharOffset;
}
f_memcpy( &m_szLogBuf [m_uiCharOffset], pszStr, uiTmpLen);
m_uiCharOffset += uiTmpLen;
uiLen -= uiTmpLen;
pszStr += uiTmpLen;
if (m_uiCharOffset == MAX_LOG_BUF_CHARS)
{
flushLogBuffer();
}
}
return( iBytesOutput);
}
FLMINT FLMAPI colorFormatter(
char cFormatChar,
eColorType eColor,
FLMUINT uiFlags);
private:
void flushLogBuffer( void);
char m_szLogBuf[ MAX_LOG_BUF_CHARS + 1];
FLMUINT m_uiCharOffset;
IF_LogMessageClient * m_pLogMsg;
eColorType m_eCurrentForeColor;
eColorType m_eCurrentBackColor;
};
/****************************************************************************
Desc: Main entry point for printf functionality.
****************************************************************************/
void f_logPrintf(
IF_LogMessageClient * pLogMessage,
const char * pszFormatStr, ...)
{
f_va_list args;
F_LogPrintfClient printfClient( pLogMessage);
f_va_start( args, pszFormatStr);
f_vprintf( &printfClient, pszFormatStr, &args);
f_va_end( args);
}
/****************************************************************************
Desc:
****************************************************************************/
void f_logPrintf(
eLogMessageSeverity msgSeverity,
const char * pszFormatStr, ...)
{
f_va_list args;
IF_LogMessageClient * pLogMsg = NULL;
if( (pLogMsg = f_beginLogMessage( 0, msgSeverity)) != NULL)
{
F_LogPrintfClient printfClient( pLogMsg);
f_va_start( args, pszFormatStr);
f_vprintf( &printfClient, pszFormatStr, &args);
f_va_end( args);
f_endLogMessage( &pLogMsg);
}
}
/****************************************************************************
Desc: Printf routine that accepts a va_list argument
****************************************************************************/
void FLMAPI f_logVPrintf(
IF_LogMessageClient * pLogMessage,
const char * pszFormatStr,
f_va_list * args)
{
F_LogPrintfClient printfClient( pLogMessage);
f_vprintf( &printfClient, pszFormatStr, args);
}
/****************************************************************************
Desc: Returns an IF_LogMessageClient object if logging is enabled for the
specified message type
****************************************************************************/
IF_LogMessageClient * FLMAPI f_beginLogMessage(
FLMUINT uiMsgType,
eLogMessageSeverity eMsgSeverity)
{
IF_LogMessageClient * pNewMsg = NULL;
f_mutexLock( gv_hLoggerMutex);
if( !gv_pLogger)
{
goto Exit;
}
if( (pNewMsg = gv_pLogger->beginMessage( uiMsgType, eMsgSeverity)) != NULL)
{
gv_uiPendingLogMessages++;
}
Exit:
f_mutexUnlock( gv_hLoggerMutex);
return( pNewMsg);
}
/****************************************************************************
Desc: Logs information about an error
****************************************************************************/
void FLMAPI f_logError(
RCODE rc,
const char * pszDoing,
const char * pszFileName,
FLMINT iLineNumber)
{
IF_LogMessageClient * pLogMsg = NULL;
if( (pLogMsg = f_beginLogMessage( 0, F_ERR_MESSAGE)) != NULL)
{
pLogMsg->changeColor( FLM_YELLOW, FLM_BLACK);
if( pszFileName)
{
f_logPrintf( pLogMsg,
"Error %s: %e, File=%s, Line=%d.",
pszDoing, rc, pszFileName, (int)iLineNumber);
}
else
{
f_logPrintf( pLogMsg, "Error %s: %e.", pszDoing, rc);
}
f_endLogMessage( &pLogMsg);
}
}
/****************************************************************************
Desc: Ends a logging message
****************************************************************************/
void FLMAPI f_endLogMessage(
IF_LogMessageClient ** ppLogMessage)
{
if( *ppLogMessage)
{
f_mutexLock( gv_hLoggerMutex);
f_assert( gv_uiPendingLogMessages);
(*ppLogMessage)->endMessage();
(*ppLogMessage)->Release();
*ppLogMessage = NULL;
gv_uiPendingLogMessages--;
f_mutexUnlock( gv_hLoggerMutex);
}
}
/****************************************************************************
Desc: Initialize the toolkit logger
****************************************************************************/
RCODE f_loggerInit( void)
{
RCODE rc = NE_FLM_OK;
if( RC_BAD( rc = f_mutexCreate( &gv_hLoggerMutex)))
{
goto Exit;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Shutdown the toolkit logger
****************************************************************************/
void f_loggerShutdown( void)
{
if( gv_pLogger)
{
gv_pLogger->Release();
gv_pLogger = NULL;
}
if( gv_hLoggerMutex != F_MUTEX_NULL)
{
f_mutexDestroy( &gv_hLoggerMutex);
}
}
/****************************************************************************
Desc: Set the toolkit logger client
****************************************************************************/
void f_setLoggerClient(
IF_LoggerClient * pLogger)
{
f_mutexLock( gv_hLoggerMutex);
if( gv_pLogger)
{
gv_pLogger->Release();
}
if( (gv_pLogger = pLogger) != NULL)
{
gv_pLogger->AddRef();
}
f_mutexUnlock( gv_hLoggerMutex);
}
/****************************************************************************
Desc: Output the current log buffer - only called when logging.
****************************************************************************/
void F_LogPrintfClient::flushLogBuffer( void)
{
if( m_uiCharOffset)
{
m_szLogBuf[ m_uiCharOffset] = 0;
m_pLogMsg->appendString( m_szLogBuf);
m_uiCharOffset = 0;
}
}
/****************************************************************************
Desc: Change colors - may only push or pop a color on to the color stack.
****************************************************************************/
FLMINT FLMAPI F_LogPrintfClient::colorFormatter(
char cFormatChar,
eColorType eColor,
FLMUINT uiFlags)
{
// Color formatting is ignored if there is not a log message object.
if( m_pLogMsg)
{
// Before changing colors, output the current log buffer.
flushLogBuffer();
if( cFormatChar == 'F') // Foreground color
{
if( uiFlags & FLM_PRINTF_PLUS_FLAG)
{
m_pLogMsg->pushForegroundColor();
}
else if( uiFlags & FLM_PRINTF_MINUS_FLAG)
{
m_pLogMsg->popForegroundColor();
}
else if( m_eCurrentForeColor != eColor)
{
m_eCurrentForeColor = eColor;
m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor);
}
}
else // cFormatChar == 'B' - background color
{
if( uiFlags & FLM_PRINTF_PLUS_FLAG)
{
m_pLogMsg->pushBackgroundColor();
}
else if( uiFlags & FLM_PRINTF_MINUS_FLAG)
{
m_pLogMsg->popBackgroundColor();
}
else if( m_eCurrentBackColor != eColor)
{
m_eCurrentBackColor = eColor;
m_pLogMsg->changeColor( m_eCurrentForeColor, m_eCurrentBackColor);
}
}
}
return( 0);
}