diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ad7a66..ef3981b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.24) project(BLT) -set(CMAKE_PROJECT_VERSION 0.1a) +set(CMAKE_PROJECT_VERSION 0.2a) set(CMAKE_CXX_STANDARD 17) option(BUILD_STD "Build the BLT standard utilities." ON) diff --git a/cmake-build-release/CMakeFiles/clion-Release-log.txt b/cmake-build-release/CMakeFiles/clion-Release-log.txt index 867b415..8fad002 100644 --- a/cmake-build-release/CMakeFiles/clion-Release-log.txt +++ b/cmake-build-release/CMakeFiles/clion-Release-log.txt @@ -4,7 +4,7 @@ Standard Files /home/brett/Documents/code/c++/BLT/src/blt/std/logging.cpp;/home/ Profiler Files /home/brett/Documents/code/c++/BLT/src/blt/profiling/profiler.cpp Source: /home/brett/Documents/code/c++/BLT Current Source: /home/brett/Documents/code/c++/BLT -BLT 0.1a Successfully included! +BLT 0.2a Successfully included! BLT tests included! -- Configuring done -- Generating done diff --git a/design.txt b/design.txt index d6d2418..619f32d 100644 --- a/design.txt +++ b/design.txt @@ -1,3 +1,4 @@ -Utility classes start with captials (IE classes which are purely static) +//Utility classes start with captials (IE classes which are purely static) +Utility classes are namespaces all lower case. everything else is camel cased underscore to conform to what most of the C libs seem to use Template types should be capital camel case diff --git a/include/blt/std/logging.h b/include/blt/std/logging.h index 98f0d8c..0a21997 100644 --- a/include/blt/std/logging.h +++ b/include/blt/std/logging.h @@ -7,15 +7,69 @@ #ifndef BLT_TESTS_LOGGING_H #define BLT_TESTS_LOGGING_H -namespace blt { - void logToConsoleAndFile(const char* format, ...); - void logToConsole(const char* format, ...); - void logToFile(const char* format, ...); - void logToConsoleAndFile(const char* prefix, const char* format, ...); - void logToConsole(const char* prefix, const char* format, ...); - void logToFile(const char* prefix, const char* format, ...); +namespace blt::logging { + + enum LOG_LEVEL { + TRACE = 0, DEBUG = 1, INFO = 2, WARN = 3, ERROR = 4, FATAL = 5 + }; + + struct LOG_PROPERTIES { + bool m_useColor = true; + bool m_logToConsole = true; + bool m_logToFile = true; + + explicit constexpr LOG_PROPERTIES(bool useColor, bool logToConsole, bool logToFile): + m_useColor(useColor), m_logToConsole(logToConsole), m_logToFile(logToFile) {} + + explicit constexpr LOG_PROPERTIES() = default; + }; + + void init(LOG_PROPERTIES properties); + void log(LOG_LEVEL level, bool auto_line, const char* format, ...); } -#define BLT +#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_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...) +#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_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); +#endif #endif //BLT_TESTS_LOGGING_H diff --git a/include/blt/std/string.h b/include/blt/std/string.h index f4fb470..7961dc7 100644 --- a/include/blt/std/string.h +++ b/include/blt/std/string.h @@ -13,7 +13,7 @@ #include #include -namespace blt::String { +namespace blt::string { static inline bool starts_with(const std::string& string, const std::string& search){ if (search.length() > string.length()) diff --git a/src/blt/std/logging.cpp b/src/blt/std/logging.cpp index 2e4d199..d2fca39 100644 --- a/src/blt/std/logging.cpp +++ b/src/blt/std/logging.cpp @@ -5,36 +5,133 @@ */ #include #include +#include +#include +#include // https://en.cppreference.com/w/cpp/utility/variadic // https://medium.com/swlh/variadic-functions-3419c287a0d2 // https://publications.gbdirect.co.uk//c_book/chapter9/stdarg.html // https://cplusplus.com/reference/cstdio/printf/ -void blt::logToConsoleAndFile(const char* prefix, const char* format, ...) { -} - -void blt::logToConsole(const char* prefix, const char* format, ...) { - va_list args; - va_start(args, format); +namespace blt::logging { - va_end(args); + 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(); + } + + const char* levelColors[6] = { + "\033[97m", + "\033[36m", + "\033[92m", + "\033[93m", + "\033[91m", + "\033[97;41m" + }; + + const char* levelNames[6] = { + "[Trace]: ", + "[Debug]: ", + "[Info]: ", + "[Warn]: ", + "[Error]: ", + "[Fatal]: ", + }; + + // by default everything is enabled + LOG_PROPERTIES BLT_LOGGING_PROPERTIES{true, true, true}; + + void init(LOG_PROPERTIES properties) { + BLT_LOGGING_PROPERTIES = properties; + } + + void log(LOG_LEVEL level, bool auto_line, const char* format, ...) { + va_list args; + va_start(args, format); + + std::stringstream finalOutput; + auto formattedString = applyFormat(format, args); + + if (BLT_LOGGING_PROPERTIES.m_useColor) + finalOutput << levelColors[level]; + finalOutput << levelNames[level]; + finalOutput << formattedString; + if (BLT_LOGGING_PROPERTIES.m_useColor) + finalOutput << "\033[0m"; + + std::string outputString = finalOutput.str(); + + if (BLT_LOGGING_PROPERTIES.m_logToConsole) { + if (level > WARN) + std::cerr << outputString; + else + std::cout << outputString; + } + + va_end(args); + } } -void blt::logToFile(const char* prefix, const char* format, ...) { - -} - -void blt::logToConsoleAndFile(const char* format, ...) { - -} - -void blt::logToConsole(const char* format, ...) { - -} - -void blt::logToFile(const char* format, ...) { - -} diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 912419b..c1a1db1 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -1,10 +1,26 @@ #include "binary_trees.h" #include "blt/std/string.h" +#include "blt/std/logging.h" int main() { binaryTreeTest(); + BLT_TRACE("Hello World!\n"); + BLT_DEBUG("Hello World!\n"); + 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!"); + std::string hello = "superSexyMax"; - std::cout << "String starts with: " << blt::String::contains(hello, "superSexyMaxE") << "\n"; + std::cout << "String starts with: " << blt::string::contains(hello, "superSexyMaxE") << "\n"; + } \ No newline at end of file