diff --git a/include/blt/std/logging.h b/include/blt/std/logging.h index dbb0673..d050942 100644 --- a/include/blt/std/logging.h +++ b/include/blt/std/logging.h @@ -7,6 +7,8 @@ #ifndef BLT_TESTS_LOGGING_H #define BLT_TESTS_LOGGING_H +#include + namespace blt::logging { enum LOG_LEVEL { @@ -26,51 +28,47 @@ namespace blt::logging { }; void init(LOG_PROPERTIES properties); - void log(LOG_LEVEL level, bool auto_line, const char* format, ...); + void log(const std::string& format, LOG_LEVEL level, int auto_line, ...); + void log(int i, LOG_LEVEL level, int auto_line); + void log(long i, LOG_LEVEL level, int auto_line); + void log(unsigned int i, LOG_LEVEL level, int auto_line); + void log(unsigned long i, LOG_LEVEL level, int auto_line); + void log(char i, LOG_LEVEL level, int auto_line); + void log(unsigned char i, LOG_LEVEL level, int auto_line); + void log(short i, LOG_LEVEL level, int auto_line); + void log(unsigned short i, LOG_LEVEL level, int auto_line); + void log(float f, LOG_LEVEL level, int auto_line); + void log(double f, LOG_LEVEL level, int auto_line); } #ifdef BLT_DISABLE_LOGGING - #define BLT_TRACE(format) - #define BLT_DEBUG(format) - #define BLT_INFO(format) - #define BLT_WARN(format) - #define BLT_ERROR(format) - #define BLT_FATAL(format) + #define BLT_TRACE(format, args...) + #define BLT_DEBUG(format, args...) + #define BLT_INFO(format, args...) + #define BLT_WARN(format, args...) + #define BLT_ERROR(format, args...) + #define BLT_FATAL(format, args...) - #define BLT_TRACE_FMT(format, args...) - #define BLT_DEBUG_FMT(format, args...) - #define BLT_INFO_FMT(format, args...) - #define BLT_WARN_FMT(format, args...) - #define BLT_ERROR_FMT(format, args...) - #define BLT_FATAL_FMT(format, args...) + #define BLT_TRACE_LN(format, args...) + #define BLT_DEBUG_LN(format, args...) + #define BLT_INFO_LN(format, args...) + #define BLT_WARN_LN(format, args...) + #define BLT_ERROR_LN(format, args...) + #define BLT_FATAL_LN(format, args...) #else - #define BLT_TRACE(format) log(blt::logging::TRACE, false, format); - #define BLT_DEBUG(format) log(blt::logging::DEBUG, false, format); - #define BLT_INFO(format) log(blt::logging::INFO, false, format); - #define BLT_WARN(format) log(blt::logging::WARN, false, format); - #define BLT_ERROR(format) log(blt::logging::ERROR, false, format); - #define BLT_FATAL(format) log(blt::logging::FATAL, false, format); + #define BLT_TRACE(format, ...) log(format, blt::logging::TRACE, false, ##__VA_ARGS__); + #define BLT_DEBUG(format, ...) log(format, blt::logging::DEBUG, false, ##__VA_ARGS__); + #define BLT_INFO(format, ...) log(format, blt::logging::INFO, false, ##__VA_ARGS__); + #define BLT_WARN(format, ...) log(format, blt::logging::WARN, false, ##__VA_ARGS__); + #define BLT_ERROR(format, ...) log(format, blt::logging::ERROR, false, ##__VA_ARGS__); + #define BLT_FATAL(format, ...) log(format, blt::logging::FATAL, false, ##__VA_ARGS__); - #define BLT_TRACE_FMT(format, args...) log(blt::logging::TRACE, false, format, args); - #define BLT_DEBUG_FMT(format, args...) log(blt::logging::DEBUG, false, format, args); - #define BLT_INFO_FMT(format, args...) log(blt::logging::INFO, false, format, args); - #define BLT_WARN_FMT(format, args...) log(blt::logging::WARN, false, format, args); - #define BLT_ERROR_FMT(format, args...) log(blt::logging::ERROR, false, format, args); - #define BLT_FATAL_FMT(format, args...) log(blt::logging::FATAL, false, format, args); - - #define BLT_TRACE_LN(format) log(blt::logging::TRACE, true, format); - #define BLT_DEBUG_LN(format) log(blt::logging::DEBUG, true, format); - #define BLT_INFO_LN(format) log(blt::logging::INFO, true, format); - #define BLT_WARN_LN(format) log(blt::logging::WARN, true, format); - #define BLT_ERROR_LN(format) log(blt::logging::ERROR, true, format); - #define BLT_FATAL_LN(format) log(blt::logging::FATAL, true, format); - - #define BLT_TRACE_FMT_LN(format, args...) log(blt::logging::TRACE, true, format, args); - #define BLT_DEBUG_FMT_LN(format, args...) log(blt::logging::DEBUG, true, format, args); - #define BLT_INFO_FMT_LN(format, args...) log(blt::logging::INFO, true, format, args); - #define BLT_WARN_FMT_LN(format, args...) log(blt::logging::WARN, true, format, args); - #define BLT_ERROR_FMT_LN(format, args...) log(blt::logging::ERROR, true, format, args); - #define BLT_FATAL_FMT_LN(format, args...) log(blt::logging::FATAL, true, format, args); + #define BLT_TRACE_LN(format, ...) log(format, blt::logging::TRACE, true, ##__VA_ARGS__); + #define BLT_DEBUG_LN(format, ...) log(format, blt::logging::DEBUG, true, ##__VA_ARGS__); + #define BLT_INFO_LN(format, ...) log(format, blt::logging::INFO, true, ##__VA_ARGS__); + #define BLT_WARN_LN(format, ...) log(format, blt::logging::WARN, true, ##__VA_ARGS__); + #define BLT_ERROR_LN(format, ...) log(format, blt::logging::ERROR, true, ##__VA_ARGS__); + #define BLT_FATAL_LN(format, ...) log(format, blt::logging::FATAL, true, ##__VA_ARGS__); #endif #endif //BLT_TESTS_LOGGING_H diff --git a/src/blt/std/logging.cpp b/src/blt/std/logging.cpp index a9443c2..e7974b8 100644 --- a/src/blt/std/logging.cpp +++ b/src/blt/std/logging.cpp @@ -9,6 +9,7 @@ #include #include #include +#include "blt/std/string.h" // https://en.cppreference.com/w/cpp/utility/variadic // https://medium.com/swlh/variadic-functions-3419c287a0d2 @@ -18,69 +19,10 @@ namespace blt::logging { - inline std::string applyFormat(const char* format, va_list args) { - std::stringstream output; - char currentCharacter; - while ((currentCharacter = *format) != '\0') { - if (currentCharacter == '%') { - char nextCharacter = *(++format); - if (nextCharacter == '\0') - break; - switch (nextCharacter) { - case 'd': - case 'i': - output << static_cast(va_arg(args, int)); - break; - case 'u': - output << static_cast(va_arg(args, unsigned int)); - break; - case 'o': - // TODO octal - break; - case 'x': - case 'X': - // TODO hex - break; - case 'f': - case 'F': - output << va_arg(args, double); - case 'e': - case 'E': - // TODO: scientific notation - break; - case 'g': - case 'G': - // TODO: shortest representation - output << va_arg(args, double); - break; - case 'a': - case 'A': - output << va_arg(args, double); - break; - case 'c': - output << va_arg(args, int); - break; - case 's': - output << va_arg(args, const char*); - break; - case 'p': - output << va_arg(args, void*); - break; - case 'n': - va_arg(args, int*); - break; - case '%': - output << '%'; - break; - default: - output << nextCharacter; - break; - } - } else - output << currentCharacter; - ++format; - } - return output.str(); + void applyFormatting(const std::string& format, std::string& output, va_list& args){ + char formattedChars[format.length()]; + vsprintf(formattedChars, format.c_str(), args); + output = std::string(formattedChars); } const char* levelColors[6] = { @@ -108,38 +50,84 @@ namespace blt::logging { BLT_LOGGING_PROPERTIES = properties; } - void log(LOG_LEVEL level, bool auto_line, const char* format, ...) { - va_list args; - va_start(args, format); - - auto formattedString = applyFormat(format, args); - bool hasEndingLinefeed = formattedString[formattedString.length()-1] == '\n'; - - if (hasEndingLinefeed) - formattedString = formattedString.substr(0, formattedString.length()-1); - + inline void log(const std::string& str, bool hasEndingLinefeed, LOG_LEVEL level, int auto_line){ std::string outputString = System::getTimeStringLog(); outputString += levelNames[level]; - - if (BLT_LOGGING_PROPERTIES.m_useColor) + outputString += str; + + if (BLT_LOGGING_PROPERTIES.m_useColor) { outputString = levelColors[level] + outputString; - - outputString += formattedString; - - if (BLT_LOGGING_PROPERTIES.m_useColor) outputString += "\033[0m"; + } + if (hasEndingLinefeed || auto_line) outputString += "\n"; - + if (BLT_LOGGING_PROPERTIES.m_logToConsole) { if (level > WARN) std::cerr << outputString; else std::cout << outputString; } + } + + void log(const std::string& format, LOG_LEVEL level, int auto_line, ...) { + va_list args; + va_start(args, auto_line); + + std::string formattedString; + applyFormatting(format, formattedString, args); + + bool hasEndingLinefeed = formattedString[formattedString.length()-1] == '\n'; + + if (hasEndingLinefeed) + formattedString = formattedString.substr(0, formattedString.length()-1); + + log(formattedString, hasEndingLinefeed, level, auto_line); va_end(args); } + + void log(int i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(long i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned int i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned long i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(char i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned char i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(short i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(unsigned short i, LOG_LEVEL level, int auto_line) { + log(std::to_string(i), false, level, true); + } + + void log(float f, LOG_LEVEL level, int auto_line) { + log(std::to_string(f), false, level, true); + } + + void log(double f, LOG_LEVEL level, int auto_line) { + log(std::to_string(f), false, level, true); + } + } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index f76b899..45616b7 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -9,19 +9,22 @@ int main() { binaryTreeTest(); - BLT_TRACE("Hello World!\n"); - BLT_DEBUG("Hello World!\n"); + BLT_TRACE(10); + BLT_TRACE(10.5); + + BLT_TRACE("Hello %d World!\n", 50); + BLT_DEBUG("Hello %E World!\n", 1205200.0); BLT_INFO("Hello World!\n"); BLT_WARN("Hello World!\n"); BLT_ERROR("Hello World!\n"); BLT_FATAL("Hello World!\n"); - BLT_TRACE_LN("Hello World!\n"); - BLT_DEBUG_LN("Hello World!\n"); - BLT_INFO_LN("Hello World!\n"); - BLT_WARN_LN("Hello World!"); - BLT_ERROR_LN("Hello World!"); - BLT_FATAL_LN("Hello World!"); + BLT_TRACE_LN("Goodbye World!\n"); + BLT_DEBUG_LN("Goodbye World!\n"); + BLT_INFO_LN("Goodbye World!\n"); + BLT_WARN_LN("Goodbye World!"); + BLT_ERROR_LN("Goodbye World!"); + BLT_FATAL_LN("Goodbye World!"); std::string hello = "superSexyMax"; std::cout << "String starts with: " << blt::string::contains(hello, "superSexyMaxE") << "\n";