Important Update:
- LogCore:
- Implement ReadLogLevel() & ReadLogOutput() methods
Standardised handling of logging parameters
- Split Log/Output in config to: Log/Output & Log/Options
- LogOutput (Show) param: first nibble = format, second nibble = options
- Replace Format constants (OUT_XXX) with enum ELogOutput
- Add loRaw format - raw untouched output
- Replace OUT_CRLF with OUT_NOCRLF - Replace \r\n with "."
- Improved Binary output method
- Simplified Log->Output() method
- FunctionCore, ApplicationCore:
- Replace reading of LogConfig with new methods in LogCore
This commit is contained in:
@@ -33,7 +33,7 @@ CApplication::CApplication( EDebugLevel pLogLevel )
|
||||
// Create output logger
|
||||
Log = new CLogCore( stdout );
|
||||
LogLevel = pLogLevel;
|
||||
LogOutput = OUT_NORMAL;
|
||||
LogOutput = loNormal;
|
||||
|
||||
// Create Configuration
|
||||
DataTree = new CDataMember();
|
||||
@@ -206,52 +206,18 @@ bool CApplication::SetLogParam( EDebugLevel pDebugLevel, int pOutputDisplay )
|
||||
bool CApplication::InitApplication()
|
||||
{
|
||||
CDataMember * CoreConfig;
|
||||
CDataMember * ItemConfig;
|
||||
CDataMember * LogConfig;
|
||||
CDataMember * SelectConfig;
|
||||
EDebugLevel pLogLevel;
|
||||
int pLogOutput;
|
||||
char * TempStr;
|
||||
|
||||
// Get Core definition
|
||||
CoreConfig = Definition->GetChild( "Core", true );
|
||||
|
||||
// Get debug level
|
||||
pLogLevel = dlNone;
|
||||
TempStr = (char*)CoreConfig->GetChStr( "Log/Level", "Medium", true );
|
||||
if (TempStr)
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Low" ))
|
||||
pLogLevel = dlLow;
|
||||
else if (!strcasecmp( TempStr, "Medium" ))
|
||||
pLogLevel = dlMedium;
|
||||
else if (!strcasecmp( TempStr, "High" ))
|
||||
pLogLevel = dlHigh;
|
||||
}
|
||||
|
||||
// Set debug output
|
||||
pLogOutput = 0;
|
||||
ItemConfig = CoreConfig->GetChild( "Log/Output[0]", true ); // Create first element if not exist
|
||||
while (ItemConfig)
|
||||
{
|
||||
if ((TempStr = (char*)ItemConfig->GetStr( "Normal" ))) // Set default value "Normal" if not set
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Normal")) // Normal ASCII -> Unless "AsIs", print special chars as "."
|
||||
pLogOutput |= OUT_NORMAL;
|
||||
else if (!strcasecmp( TempStr, "Bin")) // Print as Binary value ('1' and '0')
|
||||
pLogOutput |= OUT_BIN;
|
||||
else if (!strcasecmp( TempStr, "Hex")) // Print as Hexadecimal value (0-9,A-F)
|
||||
pLogOutput |= OUT_HEX;
|
||||
else if (!strcasecmp( TempStr, "Count")) // Print number of characters
|
||||
pLogOutput |= OUT_COUNT;
|
||||
else if (!strcasecmp( TempStr, "AsIs")) // Use with "Normal" -> Do not print special chars as "."
|
||||
pLogOutput |= OUT_ASIS;
|
||||
else if (!strcasecmp( TempStr, "CRLF")) // Add \r\n at end of line if not present
|
||||
pLogOutput |= OUT_CRLF;
|
||||
else
|
||||
pLogOutput |= OUT_NORMAL;
|
||||
}
|
||||
ItemConfig = ItemConfig->GetNextPeer();
|
||||
}
|
||||
// Configure Logging/Debugging
|
||||
LogConfig = CoreConfig->GetChild( "Log", true );
|
||||
pLogLevel = Log->ReadLogLevel( LogConfig );
|
||||
pLogOutput = Log->ReadLogOutput( LogConfig );
|
||||
SetLogParam( pLogLevel, pLogOutput );
|
||||
|
||||
// Configure Selector
|
||||
|
||||
@@ -117,8 +117,6 @@ CDataMember::~CDataMember()
|
||||
// Destroy member
|
||||
if (Name)
|
||||
free( Name );
|
||||
if (Value)
|
||||
free( Value );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -356,9 +354,11 @@ bool CDataMember::SetValuePtr( EDataType pType, const char * pValue, int pLen )
|
||||
|
||||
bool CDataMember::SetValue( EDataType pType, const char * pValue, int pLen )
|
||||
{
|
||||
// Clear & Update Type
|
||||
Clear();
|
||||
Type = pType;
|
||||
|
||||
// Set new primitive value
|
||||
if ((pType == jtString) || (pType == jtFloat) || (pType == jtInt) || (pType == jtBool))
|
||||
{
|
||||
Len = (pLen == -1)? strlen(pValue) : pLen;
|
||||
|
||||
@@ -44,7 +44,7 @@ CFunctionCore::CFunctionCore( const char * pName, const char * pType ) : Type( p
|
||||
// Logging
|
||||
Log = Application->Log;
|
||||
LogLevel = dlNone;
|
||||
LogOutput = OUT_NORMAL;
|
||||
LogOutput = loNormal;
|
||||
|
||||
// Stored output
|
||||
StoredOutput = NULL;
|
||||
@@ -102,53 +102,19 @@ CFunctionCore::~CFunctionCore()
|
||||
bool CFunctionCore::Init( CDataMember * FunctionConfig )
|
||||
{
|
||||
// Load configuration
|
||||
CDataMember * ItemConfig;
|
||||
CDataMember * LogConfig;
|
||||
CDataMember * ChannelConfig;
|
||||
EDebugLevel pLogLevel;
|
||||
int pLogOutput;
|
||||
char * TempStr;
|
||||
|
||||
// Validate
|
||||
if (!FunctionConfig )
|
||||
return false;
|
||||
|
||||
// Get debug level
|
||||
pLogLevel = dlNone;
|
||||
TempStr = (char*)FunctionConfig->GetChStr( "Log/Level", "Medium", true );
|
||||
if (TempStr)
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Low" ))
|
||||
pLogLevel = dlLow;
|
||||
else if (!strcasecmp( TempStr, "Medium" ))
|
||||
pLogLevel = dlMedium;
|
||||
else if (!strcasecmp( TempStr, "High" ))
|
||||
pLogLevel = dlHigh;
|
||||
}
|
||||
|
||||
// Set debug output
|
||||
pLogOutput = 0;
|
||||
ItemConfig = FunctionConfig->GetChild( "Log/Output[0]", true ); // Create first element if not exist
|
||||
while (ItemConfig)
|
||||
{
|
||||
if ((TempStr = (char*)ItemConfig->GetStr( "Normal" ))) // Set default value "Normal" if not set
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Normal")) // Normal ASCII -> Unless "AsIs", print special chars as "."
|
||||
pLogOutput |= OUT_NORMAL;
|
||||
else if (!strcasecmp( TempStr, "Bin")) // Print as Binary value ('1' and '0')
|
||||
pLogOutput |= OUT_BIN;
|
||||
else if (!strcasecmp( TempStr, "Hex")) // Print as Hexadecimal value (0-9,A-F)
|
||||
pLogOutput |= OUT_HEX;
|
||||
else if (!strcasecmp( TempStr, "Count")) // Print number of characters
|
||||
pLogOutput |= OUT_COUNT;
|
||||
else if (!strcasecmp( TempStr, "AsIs")) // Use with "Normal" -> Do not print special chars as "."
|
||||
pLogOutput |= OUT_ASIS;
|
||||
else if (!strcasecmp( TempStr, "CRLF")) // Add \r\n at end of line if not present
|
||||
pLogOutput |= OUT_CRLF;
|
||||
else
|
||||
pLogOutput |= OUT_NORMAL;
|
||||
}
|
||||
ItemConfig = ItemConfig->GetNextPeer();
|
||||
}
|
||||
// Configure Logging/Debugging
|
||||
LogConfig = FunctionConfig->GetChild( "Log", true );
|
||||
pLogLevel = Log->ReadLogLevel( LogConfig );
|
||||
pLogOutput = Log->ReadLogOutput( LogConfig );
|
||||
SetLogParam( pLogLevel, pLogOutput );
|
||||
|
||||
// Load Channels
|
||||
|
||||
142
LogCore.cpp
142
LogCore.cpp
@@ -16,7 +16,9 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Global vars
|
||||
char LogStr[1000]; // Temporary var to create log messages, globally available to save on memory operations
|
||||
char LogStr[1000]; // Temporary var to create log messages, globally available to save on memory operations
|
||||
|
||||
const char * LogOutputName[] = { "None", "Raw", "Normal", "Hex", "Bin" };
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -26,6 +28,79 @@ CLogCore::CLogCore( FILE * pOutputFile )
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
EDebugLevel CLogCore::ReadLogLevel( CDataMember * LogConfig )
|
||||
{
|
||||
char * TempStr;
|
||||
EDebugLevel LogLevel;
|
||||
|
||||
// Get debug level
|
||||
LogLevel = dlNone;
|
||||
TempStr = (char*)LogConfig->GetChStr( "Level", "Medium", true );
|
||||
if (TempStr)
|
||||
{
|
||||
if (!strcasecmp( TempStr, "None" ))
|
||||
LogLevel = dlNone;
|
||||
else if (!strcasecmp( TempStr, "Low" ))
|
||||
LogLevel = dlLow;
|
||||
else if (!strcasecmp( TempStr, "Medium" ))
|
||||
LogLevel = dlMedium;
|
||||
else if (!strcasecmp( TempStr, "High" ))
|
||||
LogLevel = dlHigh;
|
||||
else
|
||||
LogLevel = dlMedium;
|
||||
}
|
||||
return LogLevel;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// ls nibble = format, ms nibble = options.
|
||||
int CLogCore::ReadLogOutput( CDataMember * LogConfig )
|
||||
{
|
||||
CDataMember * ItemConfig;
|
||||
char * TempStr;
|
||||
|
||||
ELogOutput LogOutput = loNone;
|
||||
int LogOutOpt = 0;
|
||||
|
||||
// Get Output format
|
||||
LogOutput = loNone;
|
||||
TempStr = (char*)LogConfig->GetChStr( "Output", "Normal", true );
|
||||
if (TempStr)
|
||||
{
|
||||
if (!strcasecmp( TempStr, "None" )) // Do not print output (may use option OUT_COUNT)
|
||||
LogOutput = loNone;
|
||||
else if (!strcasecmp( TempStr, "Raw" )) // Print all output as is
|
||||
LogOutput = loRaw;
|
||||
else if (!strcasecmp( TempStr, "Normal" )) // Print normal, but replace special chars with "."
|
||||
LogOutput = loNormal;
|
||||
else if (!strcasecmp( TempStr, "Bin" )) // Print as Binary value ('1' and '0')
|
||||
LogOutput = loBin;
|
||||
else if (!strcasecmp( TempStr, "Hex" )) // Print as Hexadecimal value (0-9,A-F)
|
||||
LogOutput = loHex;
|
||||
else
|
||||
LogOutput = loNormal;
|
||||
}
|
||||
|
||||
// Set debug output
|
||||
ItemConfig = LogConfig->GetChElement( "Options", 0, true );
|
||||
while (ItemConfig)
|
||||
{
|
||||
if ((TempStr = (char*)ItemConfig->GetStr( "Normal" )))
|
||||
{
|
||||
if (!strcasecmp( TempStr, "Count" )) // Print number of characters
|
||||
LogOutOpt |= OUT_COUNT;
|
||||
else if (!strcasecmp( TempStr, "NoCRLF" )) // With Normal, replace CR/LF with "."
|
||||
LogOutOpt |= OUT_NOCRLF;
|
||||
}
|
||||
ItemConfig = ItemConfig->GetNextPeer();
|
||||
}
|
||||
|
||||
// Combine Output format & options
|
||||
LogOutOpt = (LogOutput | LogOutOpt)? (LogOutput | LogOutOpt) : loNormal;
|
||||
return LogOutOpt;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CLogCore::Message( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Format, ... )
|
||||
{
|
||||
va_list ArgPtr;
|
||||
@@ -53,12 +128,15 @@ bool CLogCore::Message( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CLogCore::Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show, const char * Buffer, int Len, const char * Format, ... )
|
||||
bool CLogCore::Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short OutputFormat, const char * Buffer, int Len, const char * Format, ... )
|
||||
{
|
||||
va_list ArgPtr;
|
||||
int OutFormat = OutputFormat & 0x0F;
|
||||
bool ShowCount = OutputFormat & OUT_COUNT;
|
||||
bool NoCrLf = OutputFormat & OUT_NOCRLF;
|
||||
|
||||
// Validate values
|
||||
if (!Buffer || !(Show & (OUT_COUNT | OUT_NORMAL | OUT_HEX | OUT_BIN)))
|
||||
if (!Buffer || (!OutFormat && !ShowCount))
|
||||
return false;
|
||||
|
||||
// Check debug level
|
||||
@@ -83,46 +161,39 @@ bool CLogCore::Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short
|
||||
}
|
||||
|
||||
// Show byte count
|
||||
if (Show & OUT_COUNT)
|
||||
if (ShowCount)
|
||||
{
|
||||
// Print byte count
|
||||
fprintf( OutputFile, " [%d] ", Len );
|
||||
|
||||
// EOL if only count wanted
|
||||
if (Show & OUT_COUNT) {
|
||||
fprintf( OutputFile, "\n" );
|
||||
}
|
||||
if (!OutFormat) fprintf( OutputFile, "\n" ); // EOL if only count wanted
|
||||
}
|
||||
|
||||
// Show Normal output
|
||||
if (Show & OUT_NORMAL)
|
||||
// Show output
|
||||
if (OutFormat == loRaw)
|
||||
{
|
||||
if (Show & OUT_ASIS) {
|
||||
// Print entire buffer as is (line feeds included)
|
||||
fprintf( OutputFile, "%s", Buffer );
|
||||
}
|
||||
else {
|
||||
// Ignore \r\n
|
||||
for (int i=0; i<Len; i++) {
|
||||
if ((Buffer[i] < 32) || (Buffer[i] > 126)) {
|
||||
if ((Show & OUT_CRLF) && ((Buffer[i] == '\r') || (Buffer[i] == '\n')))
|
||||
fprintf( OutputFile, "%c", Buffer[i] );
|
||||
else
|
||||
fprintf( OutputFile, "." );
|
||||
}
|
||||
else {
|
||||
// Print entire buffer as is (line feeds included)
|
||||
fprintf( OutputFile, "%.*s\n", Len, Buffer );
|
||||
}
|
||||
else if (OutFormat == loNormal)
|
||||
{
|
||||
// Ignore \r\n
|
||||
for (int i=0; i<Len; i++) {
|
||||
if ((Buffer[i] < 32) || (Buffer[i] > 126)) {
|
||||
if (((Buffer[i] == '\r') || (Buffer[i] == '\n')) && !NoCrLf)
|
||||
fprintf( OutputFile, "%c", Buffer[i] );
|
||||
}
|
||||
else
|
||||
fprintf( OutputFile, "." );
|
||||
}
|
||||
else {
|
||||
fprintf( OutputFile, "%c", Buffer[i] );
|
||||
}
|
||||
}
|
||||
// Add EOL if not present or ignored
|
||||
if (!(Show & (OUT_ASIS | OUT_CRLF)) || (Buffer[Len-1] != '\n')) {
|
||||
if (NoCrLf || (Buffer[Len-1] != '\n')) {
|
||||
fprintf( OutputFile, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
// Show Hex output
|
||||
if (Show & OUT_HEX)
|
||||
else if (OutFormat == loHex)
|
||||
{
|
||||
// Print Hex values of individual bytes
|
||||
for (int i=0; i<Len; i++) {
|
||||
@@ -130,14 +201,13 @@ bool CLogCore::Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short
|
||||
}
|
||||
fprintf( OutputFile, "\n" );
|
||||
}
|
||||
|
||||
// Show Binary output
|
||||
if (Show & OUT_BIN) {
|
||||
else if (OutFormat == loBin)
|
||||
{
|
||||
// Print each byte as 8-bit binary
|
||||
for (int i=0; i<Len; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
fprintf( OutputFile, "%d", (bool)((Buffer[i] << j) & 0x80) );
|
||||
}
|
||||
fprintf( OutputFile, "%c%c%c%c%c%c%c%c ",
|
||||
(Buffer[i] & 0x80)?'1':'0', (Buffer[i] & 0x40)?'1':'0', (Buffer[i] & 0x20)?'1':'0', (Buffer[i] & 0x10)?'1':'0',
|
||||
(Buffer[i] & 0x08)?'1':'0', (Buffer[i] & 0x04)?'1':'0', (Buffer[i] & 0x02)?'1':'0', (Buffer[i] & 0x01)?'1':'0' );
|
||||
}
|
||||
fprintf( OutputFile, "\n" );
|
||||
}
|
||||
|
||||
18
LogCore.h
18
LogCore.h
@@ -12,21 +12,18 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// redA Libraries
|
||||
/* none */
|
||||
#include "DataTreeCore.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Debug options
|
||||
// Debug options: LogOutput --> First nibble = output format, second nibble = output options
|
||||
const short
|
||||
OUT_COUNT = 1, // Show Length of String
|
||||
OUT_NORMAL = 2, // Show ASCII output (replace non-printable characters (incl. CR/LF with ".")
|
||||
OUT_HEX = 4, // Show HEX output
|
||||
OUT_BIN = 8, // Show BINARY output
|
||||
OUT_CRLF = 16, // with OUT_NORMAL - do not replace CR/LF with "."
|
||||
OUT_ASIS = 32; // with OUT_NORMAL - do not replace any non-printable character with "."
|
||||
OUT_COUNT = 16, // Show Character count
|
||||
OUT_NOCRLF = 32; // with OUT_NORMAL, show \r\n as "."
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
typedef enum { loNone = 0, loRaw = 1, loNormal = 2, loHex = 3, loBin = 4 } ELogOutput;
|
||||
typedef enum { dlNone = 0, dlLow = 1, dlMedium = 2, dlHigh = 3 } EDebugLevel;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -39,8 +36,11 @@ private:
|
||||
public:
|
||||
CLogCore( FILE * pOutputFile );
|
||||
|
||||
EDebugLevel ReadLogLevel( CDataMember * LogConfig );
|
||||
int ReadLogOutput( CDataMember * LogConfig );
|
||||
|
||||
bool Message( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Format, ... );
|
||||
bool Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show, const char * Buffer, int Len, const char * Format, ... );
|
||||
bool Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short OutputFormat, const char * Buffer, int Len, const char * Format, ... );
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user