Initial source commit

This commit is contained in:
Tony Bark 2025-10-03 02:19:59 -04:00
commit f1384c11ee
335 changed files with 52715 additions and 0 deletions

View file

@ -0,0 +1,156 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-March-30 Jason Rohrer
* Wrapped our dynamically allocated static member in a statically
* allocated class to avoid memory leaks at program termination.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "AppLog.h"
#include "Log.h"
#include <stdlib.h>
// wrap our static member in a statically allocated class
LogPointerWrapper AppLog::mLogPointerWrapper( new PrintLog );
LogPointerWrapper::LogPointerWrapper( Log *inLog )
: mLog( inLog ) {
}
LogPointerWrapper::~LogPointerWrapper() {
if( mLog != NULL ) {
delete mLog;
}
}
void AppLog::criticalError( const char *inString ) {
mLogPointerWrapper.mLog->logString(
inString, Log::CRITICAL_ERROR_LEVEL );
}
void AppLog::criticalError( const char *inLoggerName, const char *inString ) {
mLogPointerWrapper.mLog->logString(
inLoggerName, inString, Log::CRITICAL_ERROR_LEVEL );
}
void AppLog::error( const char *inString ) {
mLogPointerWrapper.mLog->logString( inString, Log::ERROR_LEVEL );
}
void AppLog::error( const char *inLoggerName, const char *inString ) {
mLogPointerWrapper.mLog->logString(
inLoggerName, inString, Log::ERROR_LEVEL );
}
void AppLog::warning( const char *inString ) {
mLogPointerWrapper.mLog->logString( inString, Log::WARNING_LEVEL );
}
void AppLog::warning( const char *inLoggerName, const char *inString ) {
mLogPointerWrapper.mLog->logString(
inLoggerName, inString, Log::WARNING_LEVEL );
}
void AppLog::info( const char *inString ) {
mLogPointerWrapper.mLog->logString( inString, Log::INFO_LEVEL );
}
void AppLog::info( const char *inLoggerName, const char *inString ) {
mLogPointerWrapper.mLog->logString(
inLoggerName, inString, Log::INFO_LEVEL );
}
void AppLog::detail( const char *inString ) {
mLogPointerWrapper.mLog->logString( inString, Log::DETAIL_LEVEL );
}
void AppLog::detail( const char *inLoggerName, const char *inString ) {
mLogPointerWrapper.mLog->logString(
inLoggerName, inString, Log::DETAIL_LEVEL );
}
void AppLog::trace( const char *inString ) {
mLogPointerWrapper.mLog->logString( inString, Log::TRACE_LEVEL );
}
void AppLog::trace( const char *inLoggerName, const char *inString ) {
mLogPointerWrapper.mLog->logString(
inLoggerName, inString, Log::TRACE_LEVEL );
}
void AppLog::setLog( Log *inLog ) {
int currentLoggingLevel = getLoggingLevel();
if( inLog != mLogPointerWrapper.mLog ) {
delete mLogPointerWrapper.mLog;
}
mLogPointerWrapper.mLog = inLog;
setLoggingLevel( currentLoggingLevel );
}
Log *AppLog::getLog() {
return mLogPointerWrapper.mLog;
}
void AppLog::setLoggingLevel( int inLevel ) {
mLogPointerWrapper.mLog->setLoggingLevel( inLevel );
}
int AppLog::getLoggingLevel() {
return mLogPointerWrapper.mLog->getLoggingLevel();
}

167
minorGems/util/log/AppLog.h Normal file
View file

@ -0,0 +1,167 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-March-30 Jason Rohrer
* Wrapped our dynamically allocated static member in a statically
* allocated class to avoid memory leaks at program termination.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "minorGems/common.h"
#ifndef APP_LOG_INCLUDED
#define APP_LOG_INCLUDED
#include "Log.h"
#include "PrintLog.h"
// internally used class
class LogPointerWrapper;
/**
* A singleton wrapper for implementations of the Log interface.
*
* This class should be the interface for log-access for applications.
*
* @author Jason Rohrer
*/
class AppLog {
public:
/**
* These log errors at various levels.
*
* All char* parameters must be \0-terminated and destroyed by caller.
*/
static void criticalError( const char *inString );
static void criticalError( const char *inLoggerName,
const char *inString );
static void error( const char *inString );
static void error( const char *inLoggerName, const char *inString );
static void warning( const char *inString );
static void warning( const char *inLoggerName, const char *inString );
static void info( const char *inString );
static void info( const char *inLoggerName, const char *inString );
static void detail( const char *inString );
static void detail( const char *inLoggerName, const char *inString );
static void trace( const char *inString );
static void trace( const char *inLoggerName, const char *inString );
/**
* Sets the log to use.
* Note that this call destroys the current log.
*
* @param inLog the log to use.
* Will be destroyed by this class.
*/
static void setLog( Log *inLog );
/**
* Gets the log being used.
*
* @return the log being used.
* Will be destroyed by this class.
*/
static Log *getLog();
/**
* Sets the logging level of the current log.
*
* Messages with levels above the current level will not be logged.
*
* @param inLevel one of the defined logging levels.
*/
static void setLoggingLevel( int inLevel );
/**
* Gets the logging level of the current log.
*
* Messages with levels above the current level will not be logged.
*
* @return one of the defined logging levels.
*/
static int getLoggingLevel();
protected:
// note that all static objects
// are destroyed at program termination
//static Log *mLog;
static LogPointerWrapper mLogPointerWrapper;
};
/**
* Wrapper for static member pointer to ensure
* deletion of static member object at program termination.
*/
class LogPointerWrapper {
public:
/**
* Constructor allows specification of the object
* to wrap and destroy at program termination.
*
* @param inLog the log object to wrap.
* Will be destroyed at program termination if non-NULL.
*/
LogPointerWrapper( Log *inLog );
/**
* Destructor will get called at program termination
* if the object is statically allocated.
*/
~LogPointerWrapper();
Log *mLog;
};
#endif

View file

@ -0,0 +1,146 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-March-13 Jason Rohrer
* Added a flush after every write.
*
* 2002-April-8 Jason Rohrer
* Changed to be thread-safe.
*
* 2002-November-5 Jason Rohrer
* Added support for backing up logs and deleting old log data.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "FileLog.h"
#include "PrintLog.h"
#include "minorGems/util/stringUtils.h"
#include "minorGems/io/file/File.h"
#include <stdio.h>
#include <time.h>
const char *FileLog::mDefaultLogFileName = "default.log";
FileLog::FileLog( const char *inFileName, unsigned long inSecondsBetweenBackups )
: mLogFile( NULL ),
mLogFileName( stringDuplicate( inFileName ) ),
mSecondsBetweenBackups( inSecondsBetweenBackups ),
mTimeOfLastBackup( time( NULL ) ) {
mLogFile = fopen( mLogFileName, "a" );
if( mLogFile == NULL ) {
printf( "Log file %s failed to open.\n", mLogFileName );
printf( "Writing log to default file: %s\n",
mDefaultLogFileName );
// switch to default log file name
delete [] mLogFileName;
mLogFileName = stringDuplicate( mDefaultLogFileName );
mLogFile = fopen( mLogFileName, "a" );
if( mLogFile == NULL ) {
printf( "Default log file %s failed to open.\n",
mLogFileName );
}
}
}
FileLog::~FileLog() {
if( mLogFile != NULL ) {
fclose( mLogFile );
}
delete [] mLogFileName;
}
void FileLog::logString( const char *inLoggerName, const char *inString,
int inLevel ) {
if( mLogFile != NULL ) {
if( inLevel <= mLoggingLevel ) {
char *message = PrintLog::generateLogMessage( inLoggerName,
inString,
inLevel );
mLock->lock();
fprintf( mLogFile, "%s\n", message );
fflush( mLogFile );
if( time( NULL ) - mTimeOfLastBackup > mSecondsBetweenBackups ) {
makeBackup();
}
mLock->unlock();
delete [] message;
}
}
}
void FileLog::makeBackup() {
fclose( mLogFile );
File *currentLogFile = new File( NULL, mLogFileName );
char *backupFileName = new char[ strlen( mLogFileName ) + 10 ];
sprintf( backupFileName, "%s.backup", mLogFileName );
File *backupLogFile = new File( NULL, backupFileName );
delete [] backupFileName;
// copy into backup log file, which will overwrite it
currentLogFile->copy( backupLogFile );
delete currentLogFile;
delete backupLogFile;
// clear main log file and start writing to it again
mLogFile = fopen( mLogFileName, "w" );
if( mLogFile == NULL ) {
printf( "Log file %s failed to open.\n", mLogFileName );
}
mTimeOfLastBackup = time( NULL );
}

View file

@ -0,0 +1,95 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-November-5 Jason Rohrer
* Added support for backing up logs and deleting old log data.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "minorGems/common.h"
#ifndef FILE_LOG_INCLUDED
#define FILE_LOG_INCLUDED
#include "PrintLog.h"
#include <stdio.h>
/**
* A file-based implementation of the Log interface.
*
* @author Jason Rohrer
*/
class FileLog : public PrintLog {
public:
/**
* Constructs a file log.
*
* @param inFileName the name of the file to write log messages to.
* Must be destroyed by caller.
* @param inSecondsBetweenBackups the number of seconds to wait
* before making a backup of the current log file (deleting any
* old backups), clearing the current log file, and starting
* a fresh log in the current log file. Defaults to 3600
* seconds (one hour). Backup logs are saved to inFileName.bakup
*/
FileLog( const char *inFileName,
unsigned long inSecondsBetweenBackups = 3600 );
virtual ~FileLog();
/**
* Makes a backup of the current log file, deletes old backups,
* and clears the current log file.
*/
void makeBackup();
// overrides PrintLog::logString
virtual void logString( const char *inLoggerName, const char *inString,
int inLevel );
protected:
FILE *mLogFile;
char *mLogFileName;
unsigned long mSecondsBetweenBackups;
unsigned long mTimeOfLastBackup;
static const char *mDefaultLogFileName;
};
#endif

View file

@ -0,0 +1,32 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*/
#include "Log.h"
const int Log::DEACTIVATE_LEVEL = 0;
const int Log::CRITICAL_ERROR_LEVEL = 1;
const int Log::ERROR_LEVEL = 2;
const int Log::WARNING_LEVEL = 3;
const int Log::INFO_LEVEL = 4;
const int Log::DETAIL_LEVEL = 5;
const int Log::TRACE_LEVEL = 6;
Log::~Log() {
}

126
minorGems/util/log/Log.h Normal file
View file

@ -0,0 +1,126 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-March-29 Jason Rohrer
* Added Fortify inclusion.
*
* 2010-April-5 Jason Rohrer
* Printf-like functionality.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "minorGems/common.h"
#ifndef LOG_INCLUDED
#define LOG_INCLUDED
#ifdef FORTIFY
#include "minorGems/util/development/fortify/fortify.h"
#endif
/**
* An interface for a class that can perform logging functions.
*
* @author Jason Rohrer
*/
class Log {
public:
// These levels were copied from the JLog framework
// by Todd Lauinger
static const int DEACTIVATE_LEVEL;
static const int CRITICAL_ERROR_LEVEL;
static const int ERROR_LEVEL;
static const int WARNING_LEVEL;
static const int INFO_LEVEL;
static const int DETAIL_LEVEL;
static const int TRACE_LEVEL;
// provided so that virtual deletes work properly
virtual ~Log();
/**
* Sets the logging level of the current log.
*
* Messages with levels above the current level will not be logged.
*
* @param inLevel one of the defined logging levels.
*/
virtual void setLoggingLevel( int inLevel ) = 0;
/**
* Gets the logging level of the current log.
*
* Messages with levels above the current level will not be logged.
*
* @return one of the defined logging levels.
*/
virtual int getLoggingLevel() = 0;
/**
* Logs a string in this log under the default logger name.
*
* @param inString the string to log as a \0-terminated string.
* Must be destroyed by caller.
* @param inLevel the level to log inString at.
*/
virtual void logString( const char *inString, int inLevel ) = 0;
/**
* Logs a string in this log, specifying a logger name.
*
* @param inLoggerName the name of the logger
* as a \0-terminated string.
* Must be destroyed by caller.
* @param inString the string to log as a \0-terminated string.
* Must be destroyed by caller.
* @param inLevel the level to log inString at.
*/
virtual void logString( const char *inLoggerName, const char *inString,
int inLevel ) = 0;
virtual void logPrintf( int inLevel, const char* inFormatString, ... )
= 0;
virtual void logNPrintf( const char *inLoggerName,
int inLevel, const char* inFormatString, ... )
= 0;
};
#endif

View file

@ -0,0 +1,61 @@
#
# Modification History
#
# 2002-February-25 Jason Rohrer
# Created.
# Changed to be more succinct.
#
GXX=g++
ROOT_PATH = ../../..
DEBUG_ON_FLAG = -g
DEBUG_OFF_FLAG =
DEBUG_FLAG = ${DEBUG_OFF_FLAG}
TIME_PLATFORM_PATH = unix
TIME_PLATFORM = Unix
TIME_O = ${ROOT_PATH}/minorGems/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM}.o
TIME_H = ${ROOT_PATH}/minorGems/system/Time.h
TIME_CPP = ${ROOT_PATH}/minorGems/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM}.cpp
testLog: AppLog.o FileLog.o PrintLog.o Log.o testLog.o ${TIME_O}
${GXX} ${DEBUG_FLAG} -o testLog AppLog.o FileLog.o PrintLog.o Log.o testLog.o ${TIME_O}
clean:
rm -f *.o ${TIME_O}
testLog.o: testLog.cpp AppLog.h FileLog.h Log.h
${GXX} ${DEBUG_FLAG} -o testLog.o -c testLog.cpp
AppLog.o: AppLog.h AppLog.cpp Log.h PrintLog.h
${GXX} ${DEBUG_FLAG} -o AppLog.o -c AppLog.cpp
PrintLog.o: PrintLog.h PrintLog.cpp Log.h PrintLog.h ${TIME_H}
${GXX} ${DEBUG_FLAG} -I${ROOT_PATH} -o PrintLog.o -c PrintLog.cpp
FileLog.o: PrintLog.h FileLog.cpp FileLog.h Log.h
${GXX} ${DEBUG_FLAG} -o FileLog.o -c FileLog.cpp
Log.o: Log.h Log.cpp
${GXX} ${DEBUG_FLAG} -o Log.o -c Log.cpp
${TIME_O}: ${TIME_H} ${TIME_CPP}
${GXX} ${DEBUG_FLAG} -I${ROOT_PATH} -o ${TIME_O} -c ${TIME_CPP}

View file

@ -0,0 +1,209 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-March-11 Jason Rohrer
* Added a missing include.
*
* 2002-April-8 Jason Rohrer
* Fixed a casting, dereferencing Win32 compile bug.
* Changed to be thread-safe.
* Changed to use thread-safe printing function.
*
* 2002-April-8 Jason Rohrer
* Fixed a signed-unsigned mismatch.
*
* 2004-January-11 Jason Rohrer
* Added lock around asctime call.
* Increased scope of lock.
*
* 2004-January-29 Jason Rohrer
* Changed to use ctime instead of localtime and asctime.
* Improved locking scope.
* Changed to use autoSprintf.
*
* 2010-April-5 Jason Rohrer
* Printf-like functionality.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "PrintLog.h"
#include "minorGems/system/Time.h"
#include "minorGems/util/printUtils.h"
#include "minorGems/util/stringUtils.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
const char *PrintLog::mDefaultLoggerName = "general";
PrintLog::PrintLog()
: mLoggingLevel( Log::TRACE_LEVEL ),
mLock( new MutexLock() ) {
}
PrintLog::~PrintLog() {
delete mLock;
}
void PrintLog::setLoggingLevel( int inLevel ) {
mLock->lock();
mLoggingLevel = inLevel;
mLock->unlock();
}
int PrintLog::getLoggingLevel() {
mLock->lock();
int level = mLoggingLevel;
mLock->unlock();
return level;
}
void PrintLog::logString( const char *inString, int inLevel ) {
logString( (char *)mDefaultLoggerName, inString, inLevel );
}
void PrintLog::logString( const char *inLoggerName, const char *inString,
int inLevel ) {
// not thread-safe to read mLoggingLevel here
// without synchronization.
// However, we want logging calls that are above
// our level to execute with nearly no overhead.
// mutex might be too much overhead....
// Besides, not being thread-safe in this case might
// (worst case) result in a missed log entry or
// an extra log entry... but setting the logging level should be rare.
if( inLevel <= mLoggingLevel ) {
char *message = generateLogMessage( inLoggerName,
inString,
inLevel );
threadPrintF( "%s\n", message );
delete [] message;
}
}
void PrintLog::logPrintf( int inLevel, const char* inFormatString, ... ) {
unsigned int bufferSize = 200;
va_list argList;
va_start( argList, inFormatString );
char *buffer = new char[ bufferSize ];
int stringLength =
vsnprintf( buffer, bufferSize, inFormatString, argList );
va_end( argList );
if( stringLength == -1 || stringLength >= (int)bufferSize ) {
// too long!
delete [] buffer;
buffer = stringDuplicate( "Message too long" );
}
logString( (char *)mDefaultLoggerName, buffer, inLevel );
delete [] buffer;
}
void PrintLog::logNPrintf( const char *inLoggerName,
int inLevel,
const char* inFormatString, ... ) {
unsigned int bufferSize = 200;
va_list argList;
va_start( argList, inFormatString );
char *buffer = new char[ bufferSize ];
int stringLength =
vsnprintf( buffer, bufferSize, inFormatString, argList );
va_end( argList );
if( stringLength == -1 || stringLength >= (int)bufferSize ) {
// too long!
delete [] buffer;
buffer = stringDuplicate( "Message too long" );
}
logString( inLoggerName, buffer, inLevel );
delete [] buffer;
}
char *PrintLog::generateLogMessage( const char *inLoggerName,
const char *inString,
int inLevel ) {
unsigned long seconds, milliseconds;
Time::getCurrentTime( &seconds, &milliseconds );
// lock around ctime call, since it returns a static buffer
mLock->lock();
char *dateString = stringDuplicate( ctime( (time_t *)( &seconds ) ) );
// done with static buffer, since we made a copy
mLock->unlock();
// this date string ends with a newline...
// get rid of it
dateString[ strlen(dateString) - 1 ] = '\0';
char *messageBuffer = autoSprintf( "L%d | %s (%ld ms) | %s | %s",
inLevel, dateString, milliseconds,
inLoggerName, inString );
delete [] dateString;
return messageBuffer;
}

View file

@ -0,0 +1,107 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*
* 2002-April-8 Jason Rohrer
* Changed to be thread-safe.
*
* 2010-April-5 Jason Rohrer
* Printf-like functionality.
*
* 2010-May-14 Jason Rohrer
* String parameters as const to fix warnings.
*/
#include "minorGems/common.h"
#ifndef PRINT_LOG_INCLUDED
#define PRINT_LOG_INCLUDED
#include "Log.h"
#include "minorGems/system/MutexLock.h"
/**
* A console-based implementation of the Log interface.
*
* @author Jason Rohrer
*/
class PrintLog : public Log {
public:
/**
* Constructs a print log.
*/
PrintLog();
virtual ~PrintLog();
// implement the Log interface
virtual void setLoggingLevel( int inLevel );
virtual int getLoggingLevel();
virtual void logString( const char *inString, int inLevel );
virtual void logString( const char *inLoggerName, const char *inString,
int inLevel );
virtual void logPrintf( int inLevel, const char* inFormatString, ... );
virtual void logNPrintf( const char *inLoggerName,
int inLevel, const char* inFormatString,
... );
protected:
int mLoggingLevel;
static const char *mDefaultLoggerName;
MutexLock *mLock;
/**
* Generates a string representation of a log message.
*
* @param inLoggerName the name of the logger
* as a \0-terminated string.
* Must be destroyed by caller.
* @param inString the string to log as a \0-terminated string.
* Must be destroyed by caller.
* @param inLevel the level to log inString at.
*
* @return the log message as a \0-terminated string.
* Must be destroyed by caller.
*/
char *generateLogMessage( const char *inLoggerName,
const char *inString,
int inLevel );
};
#endif

View file

@ -0,0 +1,42 @@
/*
* Modification History
*
* 2002-February-25 Jason Rohrer
* Created.
*/
#include "AppLog.h"
#include "FileLog.h"
#include "Log.h"
int main() {
AppLog::warning( "A test warning" );
AppLog::warning( "Another test warning" );
AppLog::warning( "mainApp", "And Another test warning" );
AppLog::setLoggingLevel( Log::ERROR_LEVEL );
AppLog::warning( "Yet Another test warning" );
AppLog::error( "mainApp", "A test error" );
AppLog::setLog( new FileLog( "test.log" ) );
// this should be skipped
AppLog::warning( "A second test warning" );
// this should not be
AppLog::criticalError( "A critical error" );
AppLog::setLog( new FileLog( "test2.log" ) );
// this should be skipped
AppLog::warning( "A third test warning" );
return 0;
}