From 6fd8e5ee43dd0f87eb4e57b86e84770fcd95db25 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Thu, 17 Aug 2023 00:35:58 -0600 Subject: Added StormLib, nlohmann, BinaryTools and CLI11 --- lib/StormLib/test/TLogHelper.cpp | 462 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100644 lib/StormLib/test/TLogHelper.cpp (limited to 'lib/StormLib/test/TLogHelper.cpp') diff --git a/lib/StormLib/test/TLogHelper.cpp b/lib/StormLib/test/TLogHelper.cpp new file mode 100644 index 0000000..3a82368 --- /dev/null +++ b/lib/StormLib/test/TLogHelper.cpp @@ -0,0 +1,462 @@ +/*****************************************************************************/ +/* TLogHelper.cpp Copyright (c) Ladislav Zezula 2013 */ +/*---------------------------------------------------------------------------*/ +/* Helper class for reporting StormLib tests */ +/* This file should be included directly from StormTest.cpp using #include */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 26.11.13 1.00 Lad The first version of TLogHelper.cpp */ +/*****************************************************************************/ + +//----------------------------------------------------------------------------- +// Definition of the TLogHelper class + +class TLogHelper +{ + public: + + TLogHelper(const char * szNewMainTitle = NULL, const TCHAR * szNewSubTitle1 = NULL, const TCHAR * szNewSubTitle2 = NULL); + ~TLogHelper(); + +#if defined(UNICODE) || defined(UNICODE) + // TCHAR-based functions. They are only needed on UNICODE builds. + // On ANSI builds is TCHAR = char, so we don't need them at all + int PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine); + void PrintProgress(const TCHAR * szFormat, ...); + void PrintMessage(const TCHAR * szFormat, ...); + int PrintErrorVa(const TCHAR * szFormat, ...); + int PrintError(const TCHAR * szFormat, const TCHAR * szFileName = NULL); +#endif // defined(UNICODE) || defined(UNICODE) + + // ANSI functions + DWORD PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine); + void PrintProgress(const char * szFormat, ...); + void PrintMessage(const char * szFormat, ...); + DWORD PrintErrorVa(const char * szFormat, ...); + DWORD PrintError(const char * szFormat, const char * szFileName = NULL); + + // Print final verdict + DWORD PrintVerdict(DWORD dwErrCode = ERROR_SUCCESS); + + const char * UserString; + unsigned int UserCount; + unsigned int UserTotal; + bool bDontPrintResult; + + protected: + +#if defined(UNICODE) || defined(UNICODE) + TCHAR * CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat); +#endif + char * CopyFormatCharacter(char * szBuffer, const char *& szFormat); + int GetConsoleWidth(); + + const char * szMainTitle; // Title of the text (usually name) + const TCHAR * szSubTitle1; // Title of the text (can be name of the tested file) + const TCHAR * szSubTitle2; // Title of the text (can be name of the tested file) + size_t nTextLength; // Length of the previous progress message + bool bMessagePrinted; +}; + +//----------------------------------------------------------------------------- +// String replacements for format strings + +#ifdef _MSC_VER +#define I64u_t _T("%I64u") +#define I64u_a "%I64u" +#define I64X_t _T("%I64X") +#define I64X_a "%I64X" +#else +#define I64u_t _T("%llu") +#define I64u_a "%llu" +#define I64X_t _T("%llX") +#define I64X_a "%llX" +#endif + +//----------------------------------------------------------------------------- +// Constructor and destructor + + +TLogHelper::TLogHelper(const char * szNewMainTitle, const TCHAR * szNewSubTitle1, const TCHAR * szNewSubTitle2) +{ + TCHAR szMainTitleT[0x80]; + + UserString = ""; + UserCount = 1; + UserTotal = 1; + + // Fill the test line structure + szMainTitle = szNewMainTitle; + szSubTitle1 = szNewSubTitle1; + szSubTitle2 = szNewSubTitle2; + nTextLength = 0; + bMessagePrinted = false; + bDontPrintResult = false; + + // Copy the UNICODE main title + StringCopy(szMainTitleT, _countof(szMainTitleT), szMainTitle); + + // Print the initial information + if(szMainTitle != NULL) + { + if(szSubTitle1 != NULL && szSubTitle2 != NULL) + _tprintf(_T("Running %s (%s+%s) ..."), szMainTitleT, szSubTitle1, szSubTitle2); + else if(szSubTitle1 != NULL) + _tprintf(_T("Running %s (%s) ..."), szMainTitleT, szSubTitle1); + else + _tprintf(_T("Running %s ..."), szMainTitleT); + } +} + +TLogHelper::~TLogHelper() +{ + // Print a verdict, if no verdict was printed yet + if(bMessagePrinted == false) + { + PrintVerdict(ERROR_SUCCESS); + } + +#if defined(_MSC_VER) && defined(_DEBUG) + if(_CrtDumpMemoryLeaks()) + { + PrintMessage(_T("Memory leak(s) detected.\n")); + } +#endif // _MSC_VER +} + +//----------------------------------------------------------------------------- +// TCHAR-based functions. They are only needed on UNICODE builds. +// On ANSI builds is TCHAR = char, so we don't need them at all + +#if defined(UNICODE) || defined(UNICODE) +int TLogHelper::PrintWithClreol(const TCHAR * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine) +{ + TCHAR szFormatBuff[0x200]; + TCHAR szMessage[0x200]; + TCHAR * szBuffer = szFormatBuff; + int nRemainingWidth; + int nConsoleWidth = GetConsoleWidth(); + int nLength = 0; + int nError = GetLastError(); + + // Always start the buffer with '\r' + *szBuffer++ = '\r'; + + // Print the prefix, if needed + if(szMainTitle != NULL && bPrintPrefix) + { + while(szMainTitle[nLength] != 0) + *szBuffer++ = szMainTitle[nLength++]; + + *szBuffer++ = ':'; + *szBuffer++ = ' '; + } + + // Copy the message format itself. Replace %s with "%s", unless it's (%s) + if(szFormat != NULL) + { + while(szFormat[0] != 0) + { + szBuffer = CopyFormatCharacter(szBuffer, szFormat); + } + } + + // Append the last error + if(bPrintLastError) + { + nLength = _stprintf(szBuffer, _T(" (error code: %u)"), nError); + szBuffer += nLength; + } + + // Create the result string + szBuffer[0] = 0; + nLength = _vstprintf(szMessage, szFormatBuff, argList); + szBuffer = szMessage + nLength; + + // Shall we pad the string? + if(nLength < nConsoleWidth) + { + // Calculate the remaining width + nRemainingWidth = nConsoleWidth - nLength - 1; + + // Pad the string with spaces to fill it up to the end of the line + for(int i = 0; i < nRemainingWidth; i++) + *szBuffer++ = 0x20; + } + + // Put the newline, if requested + *szBuffer++ = bPrintEndOfLine ? '\n' : 0; + *szBuffer = 0; + + // Remember if we printed a message + if(bPrintEndOfLine) + bMessagePrinted = true; + + // Spit out the text in one single printf + _tprintf(_T("%s"), szMessage); + return nError; +} + +void TLogHelper::PrintProgress(const TCHAR * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, false); + va_end(argList); +} + +void TLogHelper::PrintMessage(const TCHAR * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, true); + va_end(argList); +} + +int TLogHelper::PrintErrorVa(const TCHAR * szFormat, ...) +{ + va_list argList; + int nResult; + + va_start(argList, szFormat); + nResult = PrintWithClreol(szFormat, argList, true, true, true); + va_end(argList); + + return nResult; +} + +int TLogHelper::PrintError(const TCHAR * szFormat, const TCHAR * szFileName) +{ + return PrintErrorVa(szFormat, szFileName); +} +#endif // defined(UNICODE) || defined(UNICODE) + +//----------------------------------------------------------------------------- +// ANSI functions + +DWORD TLogHelper::PrintWithClreol(const char * szFormat, va_list argList, bool bPrintPrefix, bool bPrintLastError, bool bPrintEndOfLine) +{ + char szFormatBuff[0x200]; + char szMessage[0x200]; + char * szBuffer = szFormatBuff; + int nRemainingWidth; + int nConsoleWidth = GetConsoleWidth(); + int nLength = 0; + DWORD dwErrCode = GetLastError(); + + // Always start the buffer with '\r' + *szBuffer++ = '\r'; + + // Print the prefix, if needed + if(szMainTitle != NULL && bPrintPrefix) + { + while(szMainTitle[nLength] != 0) + *szBuffer++ = (char)szMainTitle[nLength++]; + + *szBuffer++ = ':'; + *szBuffer++ = ' '; + } + + // Copy the message format itself. Replace %s with "%s", unless it's (%s) + if(szFormat != NULL) + { + while(szFormat[0] != 0) + { + szBuffer = CopyFormatCharacter(szBuffer, szFormat); + } + } + + // Append the last error + if(bPrintLastError) + { + nLength = sprintf(szBuffer, " (error code: %u)", dwErrCode); + szBuffer += nLength; + } + + // Create the result string + szBuffer[0] = 0; + nLength = vsprintf(szMessage, szFormatBuff, argList); + + // Shall we pad the string? + szBuffer = szMessage + nLength; + if(nLength < nConsoleWidth) + { + // Calculate the remaining width + nRemainingWidth = nConsoleWidth - nLength - 1; + + // Pad the string with spaces to fill it up to the end of the line + for(int i = 0; i < nRemainingWidth; i++) + *szBuffer++ = 0x20; + } + + // Put the newline, if requested + *szBuffer++ = bPrintEndOfLine ? '\n' : '\r'; + *szBuffer = 0; + + // Remember if we printed a message + if(bPrintEndOfLine) + bMessagePrinted = true; + + // Spit out the text in one single printf + printf("%s", szMessage); + return dwErrCode; +} + +void TLogHelper::PrintProgress(const char * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, false); + va_end(argList); +} + +void TLogHelper::PrintMessage(const char * szFormat, ...) +{ + va_list argList; + + va_start(argList, szFormat); + PrintWithClreol(szFormat, argList, true, false, true); + va_end(argList); +} + +DWORD TLogHelper::PrintErrorVa(const char * szFormat, ...) +{ + va_list argList; + DWORD dwErrCode; + + va_start(argList, szFormat); + dwErrCode = PrintWithClreol(szFormat, argList, true, true, true); + va_end(argList); + + return dwErrCode; +} + +DWORD TLogHelper::PrintError(const char * szFormat, const char * szFileName) +{ + return PrintErrorVa(szFormat, szFileName); +} + +//----------------------------------------------------------------------------- +// Print final verdict + +DWORD TLogHelper::PrintVerdict(DWORD dwErrCode) +{ + LPCTSTR szSaveSubTitle1 = szSubTitle1; + LPCTSTR szSaveSubTitle2 = szSubTitle2; + TCHAR szSaveMainTitle[0x80]; + + // Set both to NULL so they won't be printed + StringCopy(szSaveMainTitle, _countof(szSaveMainTitle), szMainTitle); + szSubTitle1 = NULL; + szSubTitle2 = NULL; + szMainTitle = NULL; + + // Print the final information + if(szSaveMainTitle[0] != 0) + { + if(bDontPrintResult == false) + { + LPCTSTR szVerdict = (dwErrCode == ERROR_SUCCESS) ? _T("succeeded") : _T("failed"); + + if(szSaveSubTitle1 != NULL && szSaveSubTitle2 != NULL) + PrintMessage(_T("%s (%s+%s) %s."), szSaveMainTitle, szSaveSubTitle1, szSaveSubTitle2, szVerdict); + else if(szSaveSubTitle1 != NULL) + PrintMessage(_T("%s (%s) %s."), szSaveMainTitle, szSaveSubTitle1, szVerdict); + else + PrintMessage(_T("%s %s."), szSaveMainTitle, szVerdict); + } + else + { + PrintProgress(" "); + printf("\r"); + } + } + + // Return the error code so the caller can pass it fuhrter + return dwErrCode; +} + +//----------------------------------------------------------------------------- +// Protected functions + +#ifdef _UNICODE +TCHAR * TLogHelper::CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat) +{ +// static LPCTSTR szStringFormat = _T("\"%s\""); + static LPCTSTR szStringFormat = _T("%s"); + static LPCTSTR szUint64Format = I64u_t; + + // String format + if(szFormat[0] == '%') + { + if(szFormat[1] == 's') + { + _tcscpy(szBuffer, szStringFormat); + szFormat += 2; + return szBuffer + _tcslen(szStringFormat); + } + + // Replace %I64u with the proper platform-dependent suffix + if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u') + { + _tcscpy(szBuffer, szUint64Format); + szFormat += 5; + return szBuffer + _tcslen(szUint64Format); + } + } + + // Copy the character as-is + *szBuffer++ = *szFormat++; + return szBuffer; +} +#endif + +char * TLogHelper::CopyFormatCharacter(char * szBuffer, const char *& szFormat) +{ + static const char * szStringFormat = "\"%s\""; + static const char * szUint64Format = I64u_a; + + // String format + if(szFormat[0] == '%') + { + if(szFormat[1] == 's') + { + strcpy(szBuffer, szStringFormat); + szFormat += 2; + return szBuffer + strlen(szStringFormat); + } + + // Replace %I64u with the proper platform-dependent suffix + if(szFormat[1] == 'I' && szFormat[2] == '6' && szFormat[3] == '4' && szFormat[4] == 'u') + { + strcpy(szBuffer, szUint64Format); + szFormat += 5; + return szBuffer + strlen(szUint64Format); + } + } + + // Copy the character as-is + *szBuffer++ = *szFormat++; + return szBuffer; +} + +int TLogHelper::GetConsoleWidth() +{ +#ifdef STORMLIB_WINDOWS + + CONSOLE_SCREEN_BUFFER_INFO ScreenInfo; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ScreenInfo); + return (int)(ScreenInfo.srWindow.Right - ScreenInfo.srWindow.Left); + +#else + + // On non-Windows platforms, we assume that width of the console line + // is 80 characters + return 120; + +#endif +} -- cgit v1.2.3