Files
mars-flaim/xflaim/src/flog.cpp
dsandersoremutah c55dab446f Renamed version4 to flaim and version5 to xflaim
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2006-01-27 21:06:39 +00:00

503 lines
13 KiB
C++

//------------------------------------------------------------------------------
// Desc: Contains routines for logging messages from within FLAIM.
//
// Tabs: 3
//
// Copyright (c) 2001-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 3113 2006-01-19 13:20:35 -0700 (Thu, 19 Jan 2006) dsanders $
//------------------------------------------------------------------------------
#include "flaimsys.h"
FSTATIC void flmLogProcessFormatString(
FLMUINT uiLen,
IF_LogMessageClient * pLogMessage, ...);
FSTATIC void flmLogParsePrintfArgs(
FLMBYTE * pszFormat,
f_va_list * args,
IF_LogMessageClient * pLogMessage);
FSTATIC void flmLogStringFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args);
FSTATIC void flmLogNumberFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args);
FSTATIC void flmLogErrorFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args);
FSTATIC void flmLogColorFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args);
FSTATIC void flmLogCharFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args);
FSTATIC void flmLogNotHandledFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args);
/****************************************************************************
Desc: Handle text portions of the format string
****************************************************************************/
FSTATIC void flmLogProcessFormatString(
FLMUINT uiLen,
IF_LogMessageClient * pLogMessage, ...)
{
f_va_list args;
f_va_start( args, pLogMessage);
if( uiLen)
{
flmLogStringFormatter( 0, uiLen, uiLen, 0, pLogMessage, &args);
}
f_va_end(args);
}
/****************************************************************************
Desc: Parse arguments in format string, calling appropriate handlers
****************************************************************************/
FSTATIC void flmLogParsePrintfArgs(
FLMBYTE * pszFormat,
f_va_list * args,
IF_LogMessageClient * pLogMessage)
{
FLMBYTE ucChar;
FLMUINT uiFlags;
FLMUINT uiWidth;
FLMUINT uiPrecision;
FLMBYTE * pszTextStart = pszFormat;
while( (ucChar = *pszFormat++) != 0)
{
if( ucChar != '%')
{
// Handle invalid characters
if( ucChar < ASCII_SPACE || ucChar > ASCII_TILDE)
{
uiWidth = (FLMUINT)(pszFormat - pszTextStart - 1);
if( uiWidth)
{
flmLogProcessFormatString( uiWidth,
pLogMessage, pszTextStart);
}
// 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);
flmLogProcessFormatString( uiWidth, pLogMessage, pszTextStart);
flmSprintfProcessFieldInfo( &pszFormat, &uiWidth,
&uiPrecision, &uiFlags, args);
ucChar = (unsigned char)*pszFormat++;
switch( ucChar)
{
case '%':
case 'c':
flmLogCharFormatter( ucChar, uiWidth,
uiPrecision, uiFlags, pLogMessage, args);
break;
case 'C':
flmLogColorFormatter( ucChar, uiWidth,
uiPrecision, uiFlags, pLogMessage, args);
break;
case 'd':
case 'o':
case 'u':
case 'x':
case 'X':
flmLogNumberFormatter( ucChar, uiWidth,
uiPrecision, uiFlags, pLogMessage, args);
break;
case 's':
case 'S':
flmLogStringFormatter( ucChar, uiWidth,
uiPrecision, uiFlags, pLogMessage, args);
break;
case 'e':
flmLogErrorFormatter( ucChar, uiWidth,
uiPrecision, uiFlags, pLogMessage, args);
break;
default:
flmLogNotHandledFormatter( ucChar, uiWidth,
uiPrecision, uiFlags, pLogMessage, args);
break;
}
pszTextStart = pszFormat;
}
flmLogProcessFormatString( (FLMUINT)(pszFormat - pszTextStart - 1),
pLogMessage, pszTextStart);
}
/****************************************************************************
Desc: Default string formatter.
****************************************************************************/
FSTATIC void flmLogStringFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args)
{
FLMBYTE ucOutputBuf[ 128];
FLMBYTE * pszDest = &ucOutputBuf[ 0];
FLMUINT uiMaxLen = sizeof( ucOutputBuf) - 1;
void * pAllocBuf = NULL;
F_SPRINTF_INFO info;
if( uiWidth >= uiMaxLen)
{
// Need to allocate a temporary buffer
uiMaxLen = uiWidth;
if (RC_BAD( f_alloc( (FLMUINT)(uiMaxLen + 1), &pAllocBuf)))
{
uiWidth = uiMaxLen;
}
else
{
pszDest = (FLMBYTE *)pAllocBuf;
}
}
f_memset( &info, 0, sizeof( info));
info.pszDestStr = pszDest;
flmSprintfStringFormatter( ucFormatChar, uiWidth, uiPrecision,
uiFlags, &info, args);
pLogMessage->appendString( (char *)pszDest);
if( pAllocBuf)
{
f_free( &pAllocBuf);
}
}
/****************************************************************************
Desc: Default number formatter.
****************************************************************************/
FSTATIC void flmLogNumberFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args)
{
FLMBYTE ucOutputBuf[ 128];
F_SPRINTF_INFO info;
f_memset( &info, 0, sizeof( info));
info.pszDestStr = &ucOutputBuf[ 0];
flmSprintfNumberFormatter( ucFormatChar, uiWidth,
uiPrecision, uiFlags, &info, args);
pLogMessage->appendString( (char *)ucOutputBuf);
}
/****************************************************************************
Desc: Default error formatter.
****************************************************************************/
FSTATIC void flmLogErrorFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args)
{
FLMBYTE ucOutputBuf[ 128];
F_SPRINTF_INFO info;
f_memset( &info, 0, sizeof( info));
info.pszDestStr = &ucOutputBuf[ 0];
flmSprintfErrorFormatter( ucFormatChar, uiWidth,
uiPrecision, uiFlags, &info, args);
pLogMessage->appendString( (char *)ucOutputBuf);
}
/****************************************************************************
Desc: Color formatter
****************************************************************************/
FSTATIC void flmLogColorFormatter(
FLMBYTE, // ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * // args
)
{
if( uiFlags & FLM_PRINTF_PLUS_FLAG)
{
// Push a color onto the stack
if( !uiWidth)
{
// Foreground
pLogMessage->pushForegroundColor();
}
else
{
// Background
pLogMessage->pushBackgroundColor();
}
}
else if( uiFlags & FLM_PRINTF_MINUS_FLAG)
{
// Pop a color from the color stack
if( !uiWidth)
{
// Foreground
pLogMessage->popForegroundColor();
}
else
{
// Background
pLogMessage->popBackgroundColor();
}
}
else
{
eColorType eForeground = (eColorType)(uiWidth + 1);
eColorType eBackground = (eColorType)(uiPrecision + 1);
// Set a new foreground and/or background color
if( eForeground >= XFLM_NUM_COLORS || eBackground >= XFLM_NUM_COLORS)
{
goto Exit;
}
pLogMessage->changeColor( eForeground, eBackground);
}
Exit:
return;
}
/****************************************************************************
Desc: Default character formatter.
Prints the character specified by VALUE in 'c', or the '%' character.
Format: %[flags][width][.prec]'c'
flags = <not used>
width = <not used>
prec = <not used>
****************************************************************************/
FSTATIC void flmLogCharFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args)
{
FLMBYTE ucOutputBuf[ 32];
F_SPRINTF_INFO info;
f_memset( &info, 0, sizeof( info));
info.pszDestStr = &ucOutputBuf[ 0];
flmSprintfCharFormatter( ucFormatChar, uiWidth,
uiPrecision, uiFlags, &info, args);
pLogMessage->appendString( (char *)ucOutputBuf);
}
/****************************************************************************
Desc: Unhandled format strings
****************************************************************************/
FSTATIC void flmLogNotHandledFormatter(
FLMBYTE ucFormatChar,
FLMUINT uiWidth,
FLMUINT uiPrecision,
FLMUINT uiFlags,
IF_LogMessageClient * pLogMessage,
f_va_list * args)
{
FLMBYTE ucOutputBuf[ 64];
F_SPRINTF_INFO info;
f_memset( &info, 0, sizeof( info));
info.pszDestStr = &ucOutputBuf[ 0];
flmSprintfNotHandledFormatter( ucFormatChar, uiWidth,
uiPrecision, uiFlags, &info, args);
pLogMessage->appendString( (char *)ucOutputBuf);
}
/****************************************************************************
Desc: Main entry point for printf functionality.
****************************************************************************/
void flmLogPrintf(
IF_LogMessageClient * pLogMessage,
const char * szFormatStr, ...)
{
f_va_list args;
f_va_start( args, szFormatStr);
flmLogParsePrintfArgs( (FLMBYTE *)szFormatStr, &args, pLogMessage);
f_va_end( args);
}
/****************************************************************************
Desc: Printf routine that accepts a va_list argument
****************************************************************************/
void flmLogVPrintf(
IF_LogMessageClient * pLogMessage,
const char * szFormatStr,
f_va_list * args)
{
flmLogParsePrintfArgs( (FLMBYTE *)szFormatStr, args, pLogMessage);
}
/****************************************************************************
Desc: Returns an IF_LogMessageClient object if logging is enabled for the
specified message type
****************************************************************************/
IF_LogMessageClient * flmBeginLogMessage(
eLogMessageType eMsgType)
{
IF_LogMessageClient * pNewMsg = NULL;
f_mutexLock( gv_XFlmSysData.hLoggerMutex);
if( !gv_XFlmSysData.pLogger)
{
goto Exit;
}
if( (pNewMsg = gv_XFlmSysData.pLogger->beginMessage( eMsgType)) != NULL)
{
gv_XFlmSysData.uiPendingLogMessages++;
}
Exit:
f_mutexUnlock( gv_XFlmSysData.hLoggerMutex);
return( pNewMsg);
}
/****************************************************************************
Desc: Logs information about an error
****************************************************************************/
void flmLogError(
RCODE rc,
const char * pszDoing,
const char * pszFileName,
FLMINT iLineNumber)
{
FLMBYTE * pszMsgBuf = NULL;
IF_LogMessageClient * pLogMsg = NULL;
if( (pLogMsg = flmBeginLogMessage( XFLM_GENERAL_MESSAGE)) != NULL)
{
if( RC_OK( f_alloc( 512, &pszMsgBuf)))
{
if( pszFileName)
{
f_sprintf( (char *)pszMsgBuf,
"Error %s: %e, File=%s, Line=%d.",
pszDoing, rc, pszFileName, (int)iLineNumber);
}
else
{
f_sprintf( (char *)pszMsgBuf, "Error %s: %e.", pszDoing, rc);
}
pLogMsg->changeColor( XFLM_YELLOW, XFLM_BLACK);
pLogMsg->appendString( (char *)pszMsgBuf);
}
flmEndLogMessage( &pLogMsg);
}
if( pszMsgBuf)
{
f_free( &pszMsgBuf);
}
}
/****************************************************************************
Desc: Ends a logging message
****************************************************************************/
void flmEndLogMessage(
IF_LogMessageClient ** ppLogMessage)
{
if( *ppLogMessage)
{
f_mutexLock( gv_XFlmSysData.hLoggerMutex);
flmAssert( gv_XFlmSysData.uiPendingLogMessages);
(*ppLogMessage)->endMessage();
(*ppLogMessage)->Release();
*ppLogMessage = NULL;
gv_XFlmSysData.uiPendingLogMessages--;
f_mutexUnlock( gv_XFlmSysData.hLoggerMutex);
}
}