Rename some struct members for clarity
[openal-soft.git] / core / logging.cpp
blob34a95e5adcbcd4d06f94b90cd62aa9da46d6f513
2 #include "config.h"
4 #include "logging.h"
6 #include <cstdarg>
7 #include <cstdio>
8 #include <string>
10 #include "alspan.h"
11 #include "strutils.h"
12 #include "vector.h"
15 #if defined(_WIN32)
16 #define WIN32_LEAN_AND_MEAN
17 #include <windows.h>
18 #elif defined(__ANDROID__)
19 #include <android/log.h>
20 #endif
22 void al_print(LogLevel level, FILE *logfile, const char *fmt, ...)
24 /* Kind of ugly since string literals are const char arrays with a size
25 * that includes the null terminator, which we want to exclude from the
26 * span.
28 auto prefix = al::as_span("[ALSOFT] (--) ").first<14>();
29 switch(level)
31 case LogLevel::Disable: break;
32 case LogLevel::Error: prefix = al::as_span("[ALSOFT] (EE) ").first<14>(); break;
33 case LogLevel::Warning: prefix = al::as_span("[ALSOFT] (WW) ").first<14>(); break;
34 case LogLevel::Trace: prefix = al::as_span("[ALSOFT] (II) ").first<14>(); break;
37 al::vector<char> dynmsg;
38 std::array<char,256> stcmsg{};
40 char *str{stcmsg.data()};
41 auto prefend1 = std::copy_n(prefix.begin(), prefix.size(), stcmsg.begin());
42 al::span<char> msg{prefend1, stcmsg.end()};
44 std::va_list args, args2;
45 va_start(args, fmt);
46 va_copy(args2, args);
47 const int msglen{std::vsnprintf(msg.data(), msg.size(), fmt, args)};
48 if(msglen >= 0 && static_cast<size_t>(msglen) >= msg.size()) UNLIKELY
50 dynmsg.resize(static_cast<size_t>(msglen)+prefix.size() + 1u);
52 str = dynmsg.data();
53 auto prefend2 = std::copy_n(prefix.begin(), prefix.size(), dynmsg.begin());
54 msg = {prefend2, dynmsg.end()};
56 std::vsnprintf(msg.data(), msg.size(), fmt, args2);
58 va_end(args2);
59 va_end(args);
61 if(gLogLevel >= level)
63 fputs(str, logfile);
64 fflush(logfile);
66 #if defined(_WIN32) && !defined(NDEBUG)
67 /* OutputDebugStringW has no 'level' property to distinguish between
68 * informational, warning, or error debug messages. So only print them for
69 * non-Release builds.
71 std::wstring wstr{utf8_to_wstr(str)};
72 OutputDebugStringW(wstr.c_str());
73 #elif defined(__ANDROID__)
74 auto android_severity = [](LogLevel l) noexcept
76 switch(l)
78 case LogLevel::Trace: return ANDROID_LOG_DEBUG;
79 case LogLevel::Warning: return ANDROID_LOG_WARN;
80 case LogLevel::Error: return ANDROID_LOG_ERROR;
81 /* Should not happen. */
82 case LogLevel::Disable:
83 break;
85 return ANDROID_LOG_ERROR;
87 __android_log_print(android_severity(level), "openal", "%s", str);
88 #endif