Avoid a stateful unique_ptr deleter
[openal-soft.git] / core / logging.cpp
blob7ee7ff23a1e20d37d1f954587abbe19c1a31342a
2 #include "config.h"
4 #include "logging.h"
6 #include <cstdarg>
7 #include <cstdio>
8 #include <string>
10 #include "strutils.h"
11 #include "vector.h"
14 #ifdef _WIN32
16 #define WIN32_LEAN_AND_MEAN
17 #include <windows.h>
19 void al_print(LogLevel level, FILE *logfile, const char *fmt, ...)
21 al::vector<char> dynmsg;
22 char stcmsg[256];
23 char *str{stcmsg};
25 std::va_list args, args2;
26 va_start(args, fmt);
27 va_copy(args2, args);
28 const int msglen{std::vsnprintf(str, sizeof(stcmsg), fmt, args)};
29 if(unlikely(msglen >= 0 && static_cast<size_t>(msglen) >= sizeof(stcmsg)))
31 dynmsg.resize(static_cast<size_t>(msglen) + 1u);
32 str = dynmsg.data();
33 std::vsnprintf(str, dynmsg.size(), fmt, args2);
35 va_end(args2);
36 va_end(args);
38 if(gLogLevel >= level)
40 fputs(str, logfile);
41 fflush(logfile);
43 /* OutputDebugStringW has no 'level' property to distinguish between
44 * informational, warning, or error debug messages. So only print them for
45 * non-Release builds.
47 #ifndef NDEBUG
48 std::wstring wstr{utf8_to_wstr(str)};
49 OutputDebugStringW(wstr.c_str());
50 #endif
53 #else
55 #ifdef __ANDROID__
56 #include <android/log.h>
57 #endif
59 void al_print(LogLevel level, FILE *logfile, const char *fmt, ...)
61 al::vector<char> dynmsg;
62 char stcmsg[256];
63 char *str{stcmsg};
65 std::va_list args, args2;
66 va_start(args, fmt);
67 va_copy(args2, args);
68 const int msglen{std::vsnprintf(str, sizeof(stcmsg), fmt, args)};
69 if(unlikely(msglen >= 0 && static_cast<size_t>(msglen) >= sizeof(stcmsg)))
71 dynmsg.resize(static_cast<size_t>(msglen) + 1u);
72 str = dynmsg.data();
73 std::vsnprintf(str, dynmsg.size(), fmt, args2);
75 va_end(args2);
76 va_end(args);
78 if(gLogLevel >= level)
80 std::fputs(str, logfile);
81 std::fflush(logfile);
83 #ifdef __ANDROID__
84 auto android_severity = [](LogLevel l) noexcept
86 switch(l)
88 case LogLevel::Trace: return ANDROID_LOG_DEBUG;
89 case LogLevel::Warning: return ANDROID_LOG_WARN;
90 case LogLevel::Error: return ANDROID_LOG_ERROR;
91 /* Should not happen. */
92 case LogLevel::Disable:
93 break;
95 return ANDROID_LOG_ERROR;
97 __android_log_print(android_severity(level), "openal", "%s", str);
98 #endif
101 #endif