$include (..\lib\compStch.ext) /* *============================================================================ * 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 * * Permission to use for any purpose, modify, copy, and make enhancements * and derivative works of the software is granted if attribution is given to * R.M. Gillmore, dba the ACME Software Deli, as the author * * While the ACME Software Deli does not work for money, there is nonetheless * a significant amount of work involved. The ACME Software Deli maintains the * rights to all code written, though it may be used and distributed as long as * the following conditions are maintained. * * 1. The copyright statement at the top of each code block is maintained in * your distribution. * 2. You do not identify yourself as the ACME Software Deli * 3. Any changes made to the software are sent to the ACME Software Deli *============================================================================ */ loggerModule: do; $if not noID declare IDString (*) byte data ( '@(#)logger.p86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 ); $endif $set ( LOGGING ) $include (..\lib\comnDefs.ext) $set (loggerSource) $include (..\lib\fileIO.ext) $include (..\lib\prtfEng.ext) $include (..\lib\string.ext) $include (..\lib\date.ext) $include (..\lib\logger.ext) $include (..\lib\debugHlp.ext) $include (..\lib\parmData.ext) declare fatalErrorString (*) char data ( 'FATAL', 0 ), errorString (*) char data ( 'ERROR', 0 ), warningString (*) char data ( 'WARNING', 0 ), routineString (*) char data ( 'ROUTINE', 0 ), debugString (*) char data ( 'DEBUG', 0 ); declare logLevelStringMap (*) pointer data ( @fatalErrorString, @errorString, @warningString, @routineString, @debugString ); declare logfileHandle word, logfileOpen boolean, currentLogLevel logLevel_t, initialized boolean; initializeLogging: procedure reentrant; $if LOGGING if ( initialized ) then if ( logfileOpen ) then call closeLogFile; logfileHandle = stdout; logfileOpen = FALSE; currentLogLevel = WARNING; initialized = TRUE; $else return; $endif end initializeLogging; openLogFile: procedure( fileNamePtr ) reentrant public; declare fileNamePtr pointer; $if LOGGING if ( not initialized ) then call initializeLogging; call closeLogFile; logfileHandle = fopen( fileNamePtr, @( 'w', 0 ) ); if ( errno = 0 ) then logfileOpen = TRUE; else logfileHandle = stdout; $else return; $endif end openLogFile; closeLogFile: procedure reentrant public; $if LOGGING if ( logfileOpen ) then do; call fclose( logfileHandle ); logfileHandle = stdout; logfileOpen = FALSE; end; $else return; $endif end closeLogFile; changeLogLevel: procedure ( newLogLevel ) reentrant public; declare newLogLevel logLevel_t; $if LOGGING if ( not initialized ) then call initializeLogging; currentLogLevel = newLogLevel; $else return; $endif end changeLogLevel; /* * ============================================================================ * Function: pauseInLog * * Description: This function writes a prompt string to the console, then * flushes the console input device buffer and waits for a * keystroke * ============================================================================ */ pauseInLog: procedure( logAtLevel ) reentrant public; declare logAtLevel logLevel_t, keyDoesntMatter integer; $if LOGGING if ( logAtLevel <= currentLogLevel ) then do; call printStringAsciiZ( @( 'Press Any Key to Continue', 0 ) ); keyDoesntMatter = ci; end; $else return; $endif end pauseInLog; /* * addToLog is a variadic procedure. In C, the interface would * appear thusly: * * void * addToLog( logLevel_t logLevel, char * functionName, char * formatString, ... ); * * its call is like that of printf (indeed, the fprintEngine is used to * do the work of creating the log entry) */ addToLogEngine: procedure ( firstArg ) reentrant public; declare firstArg word, logAtLevel logLevel_t, parameterData paramDataStruct, actualBasePtr pointer; $if LOGGING actualBasePtr = build$ptr( selector( stackBase ), stackPtr ); actualBasePtr = @firstArg; if ( not initialized ) then call initializeLogging; call initParamData( actualBasePtr, @parameterData ); call GetWord( @parameterData, @logAtLevel ); if ( logAtLevel <= currentLogLevel ) then do; declare reportString ( 1024 ) char, reportStringLength word, fwriteReturned word, dateString (45) char, tm tmStruct, loggingLocation pointer, loggingLine integer; /* * get the date and time from the system for use in the report */ call currentTime( @tm ); call ascTime( @tm, @dateString ); /* * we need to report the location, also */ call getPointer( @parameterData, @loggingLocation ); call getInteger( @parameterData, @loggingLine ); /* * create the header (logger-generated) part of the log entry */ call sprintf( @reportString, @( '[%s]%s#%d::<%s> ', 0 ), logLevelStringMap( logAtLevel ), loggingLocation, loggingLine, @dateString ); reportStringLength = strlen( @reportString ); /* * add the part that the caller has specified */ call sprintfEngine( @reportString( reportStringLength ), @parameterData ); call strcat( @reportString, @( CR, LF, 0 ) ); /* * write to the log file (stdout is allowed) */ reportStringLength = strlen( @reportString ); fwriteReturned = fwrite( logfileHandle, @reportString, reportStringLength ); end; $else return; $endif end addToLogEngine; declare addToLog pointer public data ( @addToLogEngine ); end loggerModule;