Browse Source
1. Backports SDL2 logging. 2. Adds a `--verbose` flag. 3. As an example, adds logging priority and category to a few log calls.pull/1294/merge
8 changed files with 295 additions and 45 deletions
@ -0,0 +1,78 @@ |
|||||||
|
#include "./console.h" |
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32) |
||||||
|
#include <cstddef> |
||||||
|
#include <cstdio> |
||||||
|
|
||||||
|
// Suppress definitions of `min` and `max` macros by <windows.h>:
|
||||||
|
#define NOMINMAX 1 |
||||||
|
#define WIN32_LEAN_AND_MEAN |
||||||
|
#include <windows.h> |
||||||
|
|
||||||
|
namespace devilution { |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
HANDLE GetStderrHandle() |
||||||
|
{ |
||||||
|
static HANDLE handle = NULL; |
||||||
|
if (handle == NULL) { |
||||||
|
if (AttachConsole(ATTACH_PARENT_PROCESS)) { |
||||||
|
handle = GetStdHandle(STD_ERROR_HANDLE); |
||||||
|
} |
||||||
|
} |
||||||
|
return handle; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void printInConsole(const char *fmt, ...) |
||||||
|
{ |
||||||
|
HANDLE handle = GetStderrHandle(); |
||||||
|
if (handle == NULL) |
||||||
|
return; |
||||||
|
|
||||||
|
char message[4096]; |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
std::vsnprintf(message, sizeof(message), fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
|
||||||
|
WriteConsole(handle, message, strlen(message), NULL, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
void printInConsoleV(const char *fmt, va_list ap) |
||||||
|
{ |
||||||
|
HANDLE handle = GetStderrHandle(); |
||||||
|
if (handle == NULL) |
||||||
|
return; |
||||||
|
|
||||||
|
char message[4096]; |
||||||
|
std::vsnprintf(message, sizeof(message), fmt, ap); |
||||||
|
|
||||||
|
if (handle == NULL) |
||||||
|
return; |
||||||
|
WriteConsole(handle, message, strlen(message), NULL, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace devilution
|
||||||
|
#else |
||||||
|
#include <cstdio> |
||||||
|
|
||||||
|
namespace devilution { |
||||||
|
|
||||||
|
void printInConsole(const char *fmt, ...) |
||||||
|
{ |
||||||
|
std::va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
std::vfprintf(stderr, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void printInConsoleV(const char *fmt, std::va_list ap) |
||||||
|
{ |
||||||
|
std::vfprintf(stderr, fmt, ap); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace devilution
|
||||||
|
#endif |
||||||
@ -0,0 +1,162 @@ |
|||||||
|
#include "./sdl2_to_1_2_backports.h" |
||||||
|
|
||||||
|
#include <cstddef> |
||||||
|
|
||||||
|
#include "./console.h" |
||||||
|
|
||||||
|
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL |
||||||
|
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN |
||||||
|
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO |
||||||
|
#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
// We use the same names of these structs as the SDL2 implementation:
|
||||||
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
|
struct SDL_LogLevel { |
||||||
|
int category; |
||||||
|
SDL_LogPriority priority; |
||||||
|
SDL_LogLevel *next; |
||||||
|
}; |
||||||
|
|
||||||
|
SDL_LogLevel *SDL_loglevels; // NOLINT(readability-identifier-naming)
|
||||||
|
SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY; // NOLINT(readability-identifier-naming)
|
||||||
|
SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY; // NOLINT(readability-identifier-naming)
|
||||||
|
SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; // NOLINT(readability-identifier-naming)
|
||||||
|
SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY; // NOLINT(readability-identifier-naming)
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||||
|
const char *const SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = { |
||||||
|
nullptr, |
||||||
|
"VERBOSE", |
||||||
|
"DEBUG", |
||||||
|
"INFO", |
||||||
|
"WARN", |
||||||
|
"ERROR", |
||||||
|
"CRITICAL" |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void SDL_LogSetAllPriority(SDL_LogPriority priority) |
||||||
|
{ |
||||||
|
for (SDL_LogLevel *entry = SDL_loglevels; entry != nullptr; entry = entry->next) { |
||||||
|
entry->priority = priority; |
||||||
|
} |
||||||
|
SDL_default_priority = priority; |
||||||
|
SDL_assert_priority = priority; |
||||||
|
SDL_application_priority = priority; |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogSetPriority(int category, SDL_LogPriority priority) |
||||||
|
{ |
||||||
|
SDL_LogLevel *entry; |
||||||
|
for (entry = SDL_loglevels; entry != nullptr; entry = entry->next) { |
||||||
|
if (entry->category == category) { |
||||||
|
entry->priority = priority; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
entry = static_cast<SDL_LogLevel *>(SDL_malloc(sizeof(*entry))); |
||||||
|
if (entry != nullptr) { |
||||||
|
entry->category = category; |
||||||
|
entry->priority = priority; |
||||||
|
entry->next = SDL_loglevels; |
||||||
|
SDL_loglevels = entry; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
SDL_LogPriority SDL_LogGetPriority(int category) |
||||||
|
{ |
||||||
|
for (SDL_LogLevel *entry = SDL_loglevels; entry != nullptr; entry = entry->next) { |
||||||
|
if (entry->category == category) { |
||||||
|
return entry->priority; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
switch (category) { |
||||||
|
case SDL_LOG_CATEGORY_TEST: |
||||||
|
return SDL_test_priority; |
||||||
|
case SDL_LOG_CATEGORY_APPLICATION: |
||||||
|
return SDL_application_priority; |
||||||
|
case SDL_LOG_CATEGORY_ASSERT: |
||||||
|
return SDL_assert_priority; |
||||||
|
default: |
||||||
|
return SDL_default_priority; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_Log(const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogVerbose(int category, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogDebug(int category, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogInfo(int category, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogWarn(int category, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogError(int category, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogCritical(int category, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogMessage(int category, SDL_LogPriority priority, const char *fmt, ...) |
||||||
|
{ |
||||||
|
va_list ap; |
||||||
|
va_start(ap, fmt); |
||||||
|
SDL_LogMessageV(category, priority, fmt, ap); |
||||||
|
va_end(ap); |
||||||
|
} |
||||||
|
|
||||||
|
void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap) |
||||||
|
{ |
||||||
|
if (static_cast<int>(priority) < 0 || priority >= SDL_NUM_LOG_PRIORITIES || priority < SDL_LogGetPriority(category)) |
||||||
|
return; |
||||||
|
|
||||||
|
::devilution::printInConsole("%s: ", SDL_priority_prefixes[priority]); |
||||||
|
::devilution::printInConsoleV(fmt, ap); |
||||||
|
::devilution::printInConsole("\n"); |
||||||
|
} |
||||||
Loading…
Reference in new issue