/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation * * SPDX-License-Identifier: Apache-2.0 */ #include "util/log.h" #include "util/math.h" #include "util/string.h" #include "util/time.h" #include #ifdef _MSC_VER # define snprintf _snprintf #endif CCL_NAMESPACE_BEGIN LogLevel LOG_LEVEL = LOG_LEVEL_INFO_IMPORTANT; static LogFunction LOG_FUNCTION; static double LOG_START_TIME = time_dt(); const char *log_level_to_string(const LogLevel level) { switch (level) { case LOG_LEVEL_FATAL: case LOG_LEVEL_DFATAL: return "FATAL"; case LOG_LEVEL_ERROR: case LOG_LEVEL_DERROR: return "ERROR"; case LOG_LEVEL_WARNING: case LOG_LEVEL_DWARNING: return "WARNING"; case LOG_LEVEL_INFO_IMPORTANT: case LOG_LEVEL_INFO: return "INFO"; case LOG_LEVEL_DEBUG: return "DEBUG"; case LOG_LEVEL_TRACE: return "TRACE"; case LOG_LEVEL_UNKNOWN: return "UNKNOWN"; } return ""; } LogLevel log_string_to_level(const string &str) { const std::string str_lower = string_to_lower(str); if (str_lower == "fatal") { return LOG_LEVEL_FATAL; } if (str_lower == "error") { return LOG_LEVEL_ERROR; } if (str_lower == "warning") { return LOG_LEVEL_WARNING; } if (str_lower == "info") { return LOG_LEVEL_INFO; } if (str_lower == "debug") { return LOG_LEVEL_DEBUG; } if (str_lower == "trace") { return LOG_LEVEL_TRACE; } return LOG_LEVEL_UNKNOWN; } void log_init(const LogFunction func) { LOG_FUNCTION = func; LOG_START_TIME = time_dt(); } void log_level_set(const LogLevel level) { LOG_LEVEL = level; } void log_level_set(const std::string &level) { const LogLevel new_level = log_string_to_level(level); if (new_level == LOG_LEVEL_UNKNOWN) { LOG_ERROR << "Unknown log level specified: " << level; return; } LOG_LEVEL = new_level; } static void log_default(const LogLevel level, const std::string &time_str, const char *msg) { if (level >= LOG_LEVEL_INFO) { printf("%s | %s\n", time_str.c_str(), msg); } else { fflush(stdout); fprintf(stderr, "%s | %s: %s\n", time_str.c_str(), log_level_to_string(level), msg); } } void _log_message(const LogLevel level, const char *file_line, const char *func, const char *msg) { assert(level <= LOG_LEVEL); if (LOG_FUNCTION) { LOG_FUNCTION(level, file_line, func, msg); return; } const std::string time_str = time_human_readable_from_seconds(time_dt() - LOG_START_TIME); if (strchr(msg, '\n') == nullptr) { log_default(level, time_str, msg); return; } vector lines; string_split(lines, msg, "\n", false); for (const string &line : lines) { log_default(level, time_str, line.c_str()); } if (level == LOG_LEVEL_FATAL || level == LOG_LEVEL_DFATAL) { abort(); } } std::ostream &operator<<(std::ostream &os, const int2 &value) { os << "(" << value.x << ", " << value.y << ")"; return os; } std::ostream &operator<<(std::ostream &os, const float3 &value) { os << "(" << value.x << ", " << value.y << ", " << value.z << ")"; return os; } std::ostream &operator<<(std::ostream &os, const float4 &value) { os << "(" << value.x << ", " << value.y << ", " << value.z << ", " << value.w << ")"; return os; } CCL_NAMESPACE_END