panda3d/pandatool/src/maxegg/maxLogger.cxx
2006-01-13 18:38:07 +00:00

370 lines
13 KiB
C++
Executable File

#include "maxLogger.h"
/* Globals & Static Members
*/
Logger *Logger::globalLoggingInstance = 0;
/* Error Logger Member Functions
*/
Logger::Logger()
{
VoidEverything();
LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, "A new, void Logging instance has been created." );
}
Logger::Logger( LoggingPipeType toWhere, char *additionalStringInfo )
{
VoidEverything();
SetPipeInstance( toWhere, additionalStringInfo );
sprintf( GetLogString(), "A new, piped logging instance has been created with data '%s'.", additionalStringInfo );
LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, GetLogString() );
}
Logger::~Logger()
{
//Send message telling everyone we're going away.
LogInstance( LLOGGING, SAT_MEDIUM_LEVEL, "Error logger shutting down!" );
//If we've got an open file, close that muthafugga!
if ( ( myLogDestination == PIPE_TO_FILE ) && myFileOutputLog.is_open() )
myFileOutputLog.close();
VoidEverything();
}
/* Public, Static Member Functions
*/
void Logger::FunctionEntry( char *newFunctionName )
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->FunctionEntryInstance( newFunctionName );
}
void Logger::FunctionExit()
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->FunctionExitInstance();
}
int Logger::GetHierarchyLevel()
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
return globalLoggingInstance->GetHierarchyLevelInstance();
else return 0;
}
char * Logger::GetLogString()
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
return globalLoggingInstance->GetLogStringInstance();
else return 0;
}
void Logger::Log( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription )
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->LogInstance( whichSystem, whichErrorKind, errorDescription );
}
void Logger::SetCurrentFunctionName( char *newFunctionName )
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->SetCurrentFunctionNameInstance( newFunctionName );
}
void Logger::SetHierarchyLevel( unsigned int newIndentLevel )
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->SetHierarchyLevelInstance( newIndentLevel );
}
void Logger::SetOneErrorMask( SystemType whichType, long int whichErrors )
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->SetOneErrorMaskInstance( whichType, whichErrors );
}
void Logger::SetPipe( LoggingPipeType toWhere, char *additionalStringInfo )
{
if ( !globalLoggingInstance )
globalLoggingInstance = new Logger();
if ( globalLoggingInstance )
globalLoggingInstance->SetPipeInstance( toWhere, additionalStringInfo );
}
/* Private Member Functions
*/
void Logger::FunctionEntryInstance( char *newFunctionName )
{
SetCurrentFunctionNameInstance( newFunctionName );
SetHierarchyLevelInstance( GetHierarchyLevelInstance() + 1 );
}
void Logger::FunctionExitInstance()
{
char endMsg[64];
SetHierarchyLevelInstance( GetHierarchyLevelInstance() - 1 );
if ( myFunctionNames.back() )
{
if ( myWrittenHierarchyLevel >= myHierarchyLevel )
{
sprintf( endMsg, "#END {%s}", myFunctionNames.back() );
WriteToPipe( endMsg );
//LogInstance( LLOGGING, this->SAT_HIGH_LEVEL, GetLogStringInstance());
--myWrittenHierarchyLevel;
}
free( (void *)myFunctionNames.back() );
myFunctionNames.pop_back();
}
}
int Logger::GetHierarchyLevelInstance()
{
return myHierarchyLevel;
}
char * Logger::GetLogStringInstance()
{
return myLogString;
}
void Logger::LogInstance( SystemType whichSystem, SystemAspectType whichErrorKind, char *errorDescription )
{
unsigned int i;
char *typeBuf;
char beginMsg[64];
if ( !errorDescription )
return;
if ( !( (int)whichErrorKind & myErrorMasks[(int)whichSystem] ) )
return;
typeBuf = (char *)malloc( strlen( errorDescription ) + 64 );
if ( !typeBuf )
return;
typeBuf = strcpy( typeBuf, errorDescription );
switch( whichErrorKind )
{
case SAT_NONE:
break;
case SAT_NULL_ERROR:
strcat( typeBuf, " - (***!!!NULL ERROR!!!***, " );
break;
case SAT_CRITICAL_ERROR:
strcat( typeBuf, " - (***!!!CRITICAL ERROR!!!***, " );
break;
case SAT_PARAMETER_INVALID_ERROR:
strcat( typeBuf, " - (***PARAMETER ERROR***, " );
break;
case SAT_OTHER_ERROR:
strcat( typeBuf, " - (***OTHER ERROR***, " );
break;
case SAT_HIGH_LEVEL:
strcat( typeBuf, " - (---HIGH LEVEL---, " );
break;
case SAT_MEDIUM_LEVEL:
strcat( typeBuf, " - (MEDIUM LEVEL, " );
break;
case SAT_LOW_LEVEL:
strcat( typeBuf, " - (LOW LEVEL, " );
break;
case SAT_DEBUG_SPAM_LEVEL:
strcat( typeBuf, " - (SPAM LEVEL, " );
break;
case SAT_ALL:
strcat( typeBuf, " - (ALL INCLUSIVE, " );
break;
}
switch( whichSystem )
{
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM1:
strcat( typeBuf, "SYS_ONE)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM2:
strcat( typeBuf, "SYS_TWO)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM3:
strcat( typeBuf, "SYS_THREE)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4:
strcat( typeBuf, "SYS_FOUR)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM5:
strcat( typeBuf, "SYS_FIVE)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM6:
strcat( typeBuf, "SYS_SIX)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM7:
strcat( typeBuf, "SYS_SEVEN)" );
break;
case ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM8:
strcat( typeBuf, "SYS_EIGHT)" );
break;
}
//Now that we've created the correct logging line to print, we need to worry
//about function entries and exits. Only do this if we're not writing to a dialog box.
if ( myLogDestination != PIPE_TO_DIALOG_BOX )
{
unsigned int tempHierarchyLevel = myHierarchyLevel;
i = 0;
for( CharStarVectorIterator hierarchyDepthIterator = myFunctionNames.begin();
hierarchyDepthIterator != myFunctionNames.end();
++hierarchyDepthIterator )
{
++i;
//Since we're writing some output, we need to print all function headings
//leading up to this output, bumping up our written hierarchy level to match
//the "actual" level.
//If we've reached a function level that's deeper than what we've written out already...
if ( i > myWrittenHierarchyLevel )
{
myHierarchyLevel = myWrittenHierarchyLevel;
sprintf( beginMsg, "#BEGIN {%s}", *hierarchyDepthIterator );
WriteToPipe( beginMsg );
myHierarchyLevel = tempHierarchyLevel;
++myWrittenHierarchyLevel;
}
}
}
WriteToPipe( typeBuf );
free(typeBuf);
}
void Logger::SetCurrentFunctionNameInstance( char *newFunctionName )
{
char *newBuf;
//No FunctionEntry Instance allowed...that function uses this!
if ( !newFunctionName )
{
LogInstance( LLOGGING, SAT_NULL_ERROR, "newFunctionName is null!" );
return;
}
newBuf = strdup( newFunctionName );
myFunctionNames.push_back( newBuf );
}
void Logger::SetHierarchyLevelInstance( unsigned int newIndentLevel )
{
myHierarchyLevel = newIndentLevel;
}
void Logger::SetOneErrorMaskInstance( SystemType whichType, long int whichErrors )
{
if ( ( (int)whichType < 0 ) || ( (int)whichType >= MY_MAX_NUM_SYSTEMS ) )
{
LogInstance( LLOGGING, SAT_PARAMETER_INVALID_ERROR, "whichType is out of bounds!" );
return;
}
//Now that the sanity check is out of the way, let us change the error mask!
myErrorMasks[(int)whichType] = whichErrors;
sprintf( GetLogStringInstance(), "Set error mask for system with ID %x to %x.", (int)whichType, whichErrors );
LogInstance( LLOGGING, SAT_LOW_LEVEL, GetLogStringInstance() );
}
void Logger::SetPipeInstance( LoggingPipeType toWhere, char *additionalStringInfo )
{
myLogDestination = toWhere;
switch( myLogDestination )
{
case PIPE_TO_FILE:
if ( myFileOutputLog.is_open() )
myFileOutputLog.close();
if ( additionalStringInfo )
myFileOutputLog.open( additionalStringInfo, ofstream::out | ofstream::trunc );
else
myFileOutputLog.open( "Kens_Logger_Log_File.txt", ofstream::out | ofstream::trunc );
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to file." );
break;
case PIPE_TO_COUT:
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to cout." );
break;
case PIPE_TO_CERR:
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to cerr." );
break;
case PIPE_TO_DIALOG_BOX:
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to dialog box." );
break;
case PIPE_TO_DEV_NULL:
LogInstance( LLOGGING, SAT_LOW_LEVEL, "Error output piped to dev null." );
break;
}
}
void Logger::VoidEverything()
{
myLogDestination = PIPE_TO_DEV_NULL;
myHierarchyLevel = 0;
myWrittenHierarchyLevel = 0;
//(Get rid of the stack of called functions.)
for (CharStarVectorIterator it = myFunctionNames.begin(); it < myFunctionNames.end(); it++) {
if (*it)
free ((void *)(*it));
}
myFunctionNames.erase( myFunctionNames.begin(), myFunctionNames.end() );
//Make it so that our logger blindly accepts all logs...
for( int i = 0; i < MY_MAX_NUM_SYSTEMS; ++i )
SetOneErrorMaskInstance( (SystemType)i, (long int)SAT_ALL );
//...but pipes them all to /dev/null. Mwahaha! The irony!
strncpy( myLogString, "No Error", LOGGER_STRING_BUFFER_SIZE - 1 );
}
void Logger::WriteToPipe( char *textToPipe )
{
switch( myLogDestination )
{
case PIPE_TO_FILE:
if ( myFileOutputLog.is_open() )
{
for (unsigned int i = 0; i < myHierarchyLevel; ++i )
myFileOutputLog << " ";
myFileOutputLog << textToPipe << endl;
myFileOutputLog.flush();
}
break;
case PIPE_TO_COUT:
cout << "(" << textToPipe << ")" << endl;
break;
case PIPE_TO_CERR:
cerr << "(" << textToPipe << ")" << endl;
break;
case PIPE_TO_DIALOG_BOX:
MessageBox( NULL, textToPipe, "Logger", MB_OK );
break;
case PIPE_TO_DEV_NULL:
break;
}
}