#pragma once #include "utils.hpp" #include "colors.hpp" #include "types.hpp" #include #include // #include #if __cplusplus > 201703L // #include #else #endif // #include // #include /* TODO: Allow setting the logging *prefix* TODO: Write log information to file */ namespace gdpm::log { enum level_e : int{ NONE = 0, ERROR = 1, INFO = 2, DEBUG = 3, WARNING = 4, }; enum flag_opt { PRINT_STDOUT = 0b00000001, PRINT_STDERR = 0b00000010 }; struct prefix { string contents = ""; string enclosing_start = "]"; string enclosing_end = "["; }; static int level = INFO; static prefix prefix = {}; static string suffix = ""; static string path = ""; static std::bitset<8> flags = PRINT_STDOUT | PRINT_STDERR; static bool print_to_stdout; static bool print_to_stderr; inline constexpr level_e to_level(int l){ return static_cast(l); } inline constexpr int to_int(const level_e& l){ return static_cast(l); } inline constexpr void set_flag(uint8_t flag, bool value){ (value) ? flags.set(flag) : flags.reset(flag); } inline constexpr bool get_flag(uint8_t flag){ return flags.test(flag); } inline constexpr void set_prefix_if(const std::string& v, bool predicate = prefix.contents.empty()){ prefix.contents = (predicate) ? v : prefix.contents; } inline constexpr void set_suffix_if(const std::string& v, bool predicate = suffix.empty()){ suffix = (predicate) ? v : suffix; } inline constexpr const char* get_info_prefix() { return "[INFO {}] "; } inline constexpr const char* get_error_prefix() { return "[ERROR {}] "; } inline constexpr const char* get_debug_prefix() { return "[DEBUG {}] "; } inline constexpr const char* get_warning_prefix() { return "[WARN {}] "; } static void vlog(fmt::string_view format, fmt::format_args args){ fmt::vprint(format, args); } static void vlog(FILE *fp, fmt::string_view format, fmt::format_args args){ fmt::vprint(fp, format, args); } template static constexpr void info(const S& format, Args&&...args){ if(log::level < to_int(log::INFO)) return; #if GDPM_LOG_LEVEL > NONE set_prefix_if(fmt::format( get_info_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( fmt::format("{}{}{}{}{}", GDPM_COLOR_LOG_INFO, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif } template static constexpr void info_n(const S& format, Args&&...args){ if(log::level < to_int(log::INFO)) return; #if GDPM_LOG_LEVEL > INFO set_prefix_if(fmt::format(get_info_prefix(), utils::timestamp()), true); set_suffix_if("", true); vlog( fmt::format("{}{}{}{}{}", GDPM_COLOR_LOG_INFO, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif } template static constexpr void error(const S& format, Args&&...args){ if(log::level < to_int(log::ERROR)) return; #if GDPM_LOG_LEVEL > ERROR set_prefix_if(std::format(get_error_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( std::format("{}{}{}{}{}", GDPM_COLOR_LOG_ERROR, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif } template static constexpr void debug(const S& format, Args&&...args){ if(log::level < to_int(log::DEBUG)) return; #if GDPM_LOG_LEVEL > DEBUG set_prefix_if(std::format(get_debug_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( std::format("{}{}{}", GDPM_COLOR_LOG_DEBUG, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif } template static constexpr void warn(const S& format, Args&&...args){ if(log::level < to_int(log::WARNING)) return; #if GDPM_LOG_LEVEL > WARN set_prefix_if(std::format(get_warning_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( std::format("{}{}{}", GDPM_COLOR_LOG_WARNING, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif } template static constexpr void print(const S& format, Args&&...args){ vlog( std::format("{}", format), fmt::make_format_args(args...) ); } template static constexpr void println(const S& format, Args&&...args){ vlog( std::format("{}\n", format), fmt::make_format_args(args...) ); } template static constexpr void println(const string& format = ""){ println(format); } }