#include "utils/Logs.hpp" #include #include #include #include #include #include #include static void append_hex(std::string &out, std::unsigned_integral auto value) { std::ostringstream buf; if (value < 10) buf << value; else if (value >= decltype(value)(UINTMAX_MAX) - 1) buf << "-" << std::uintmax_t(decltype(value)(-value)); else buf << "0x" << std::hex << std::uintmax_t(value); out += buf.str(); } namespace orbis::logs { void log_class_string::format(std::string &out, const void *arg) { const void *ptr = *reinterpret_cast(arg); append_hex(out, reinterpret_cast(ptr)); } void log_class_string::format_n(std::string &out, const void *arg, std::size_t n) { const char *ptr = reinterpret_cast(arg); const auto addr = reinterpret_cast(ptr); const auto _end = n ? addr + n - 1 : addr; if (addr < 0x10000 || std::max(n, _end) > 0x7fff'ffff'ffff) { out += "{{{{{BAD_ADDR:"; append_hex(out, addr); out += "}}}}}"; return; } while (n--) { const char c = *ptr++; if (!c) break; out += c; } } void log_class_string::format(std::string &out, const void *arg) { const char *ptr = *reinterpret_cast(arg); const auto addr = reinterpret_cast(ptr); if (addr < 0x10000 || addr > 0x7fff'ffff'ffff) { out += "{{{{{BAD_ADDR:"; append_hex(out, addr); out += "}}}}}"; return; } out += ptr; } template <> void log_class_string::format(std::string &out, const void *arg) { out += get_object(arg); } template <> void log_class_string::format(std::string &out, const void *arg) { out += get_object(arg); } template <> void log_class_string>::format(std::string &out, const void *arg) { const std::vector &obj = get_object(arg); out.append(obj.cbegin(), obj.cend()); } template <> void log_class_string::format(std::string &out, const void *arg) { const std::u8string &obj = get_object(arg); out.append(obj.cbegin(), obj.cend()); } template <> void log_class_string::format(std::string &out, const void *arg) { const std::u8string_view &obj = get_object(arg); out.append(obj.cbegin(), obj.cend()); } template <> void log_class_string>::format(std::string &out, const void *arg) { const std::vector &obj = get_object(arg); out.append(obj.cbegin(), obj.cend()); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, static_cast(get_object(arg))); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, get_object(arg)); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, static_cast(get_object(arg))); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, static_cast(get_object(arg))); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, get_object(arg)); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, static_cast(get_object(arg))); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, get_object(arg)); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, static_cast(get_object(arg))); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, get_object(arg)); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, static_cast(get_object(arg))); } template <> void log_class_string::format(std::string &out, const void *arg) { append_hex(out, get_object(arg)); } template <> void log_class_string::format(std::string &out, const void *arg) { std::ostringstream buf(out, std::ios_base::ate); buf << get_object(arg); } template <> void log_class_string::format(std::string &out, const void *arg) { std::ostringstream buf(out, std::ios_base::ate); buf << get_object(arg); } template <> void log_class_string::format(std::string &out, const void *arg) { out += get_object(arg) ? "1" : "0"; } void _orbis_log_print(LogLevel lvl, std::string_view msg, std::string_view names, const log_type_info *sup, ...) { if (lvl > logs_level.load(std::memory_order::relaxed)) { return; } /*constinit thread_local*/ std::string text; /*constinit thread_local*/ std::vector args; std::size_t args_count = 0; for (auto v = sup; v && v->log_string; v++) args_count++; text.reserve(50000); args.resize(args_count); va_list c_args; va_start(c_args, sup); for (const void *&arg : args) arg = va_arg(c_args, const void *); va_end(c_args); text += msg; if (args_count) text += "("; for (std::size_t i = 0; i < args_count; i++) { if (i) text += ", "; names.remove_prefix(names.find_first_not_of(" \t\n\r")); std::string_view name = names.substr(0, names.find_first_of(",")); names.remove_prefix(name.size() + 1); text += name; text += "="; sup[i].log_string(text, args[i]); } if (args_count) text += ")"; const char *color = ""; switch (lvl) { case LogLevel::Always: color = "\e[36;1m"; break; case LogLevel::Fatal: color = "\e[35;1m"; break; case LogLevel::Error: color = "\e[0;31m"; break; case LogLevel::Todo: color = "\e[1;33m"; break; case LogLevel::Success: color = "\e[1;32m"; break; case LogLevel::Warning: color = "\e[0;33m"; break; case LogLevel::Notice: color = ""; break; case LogLevel::Trace: color = ""; break; } static const bool istty = isatty(fileno(stderr)); if (istty) { std::fprintf(stderr, "%s%s\e[0m\n", color, text.c_str()); } else { std::fprintf(stderr, "%s\n", text.c_str()); } } } // namespace orbis::logs