From d770d9f6cb6f0c78eb164445e6c2f4a0e7e81e5e Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Sun, 25 Nov 2018 18:24:36 +0200 Subject: [PATCH] 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 --- ApplicationCore.cpp | 46 ++------------ DataTreeCore.cpp | 4 +- FunctionCore.cpp | 46 ++------------ LogCore.cpp | 142 +++++++++++++++++++++++++++++++++----------- LogCore.h | 18 +++--- 5 files changed, 129 insertions(+), 127 deletions(-) diff --git a/ApplicationCore.cpp b/ApplicationCore.cpp index 02dc1c4..66c9411 100644 --- a/ApplicationCore.cpp +++ b/ApplicationCore.cpp @@ -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 diff --git a/DataTreeCore.cpp b/DataTreeCore.cpp index 3122248..b3995c3 100644 --- a/DataTreeCore.cpp +++ b/DataTreeCore.cpp @@ -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; diff --git a/FunctionCore.cpp b/FunctionCore.cpp index afb9d1f..8b323ca 100644 --- a/FunctionCore.cpp +++ b/FunctionCore.cpp @@ -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 diff --git a/LogCore.cpp b/LogCore.cpp index 4e3b72a..fa83d9b 100644 --- a/LogCore.cpp +++ b/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 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 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 // 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, ... ); }; //---------------------------------------------------------------------------