2021-02-24 00:22:28 +01:00
|
|
|
#include <SDL_stdinc.h>
|
2021-02-23 09:54:45 +01:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2023-09-05 19:13:27 +02:00
|
|
|
#ifdef __ANDROID__
|
2023-09-02 22:23:17 +02:00
|
|
|
// forward to SDL logging on Android, since stdout/stderr are /dev/null
|
2023-09-05 19:13:27 +02:00
|
|
|
#define VLOG_USE_SDL 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef VLOG_USE_SDL
|
2023-10-26 00:48:04 +02:00
|
|
|
# include <SDL_log.h>
|
2023-09-05 19:13:27 +02:00
|
|
|
#elif defined(_WIN32)
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
|
|
|
# include <windows.h>
|
2022-11-15 04:34:48 +01:00
|
|
|
#elif defined(__unix__) || defined(__APPLE__)
|
2022-11-15 04:28:12 +01:00
|
|
|
# include <unistd.h>
|
2021-02-24 00:22:28 +01:00
|
|
|
#endif
|
|
|
|
|
2022-11-15 06:51:53 +01:00
|
|
|
#define COLOR(EXPR) (color_enabled && color_supported ? EXPR : "")
|
2021-02-24 00:22:28 +01:00
|
|
|
|
|
|
|
#define Color_RESET COLOR("\x1b[0m")
|
|
|
|
#define Color_BOLD COLOR("\x1b[1m")
|
|
|
|
#define Color_BOLD_YELLOW COLOR("\x1b[1;33m")
|
|
|
|
#define Color_BOLD_RED COLOR("\x1b[1;31m")
|
2021-09-01 23:11:23 +02:00
|
|
|
#define Color_BOLD_GRAY COLOR("\x1b[1;90m")
|
2021-02-24 00:22:28 +01:00
|
|
|
|
2023-09-21 23:49:01 +02:00
|
|
|
#ifdef __ANDROID__
|
|
|
|
const int color_supported = 0;
|
|
|
|
#else
|
2022-11-15 06:51:53 +01:00
|
|
|
static int color_supported = 0;
|
2023-09-21 23:49:01 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static int output_enabled = 1;
|
2022-11-15 06:51:53 +01:00
|
|
|
static int color_enabled = 1;
|
2021-09-01 23:11:23 +02:00
|
|
|
static int debug_enabled = 0;
|
2021-09-01 22:41:06 +02:00
|
|
|
static int info_enabled = 1;
|
|
|
|
static int warn_enabled = 1;
|
|
|
|
static int error_enabled = 1;
|
2021-02-24 00:22:28 +01:00
|
|
|
|
2022-11-15 06:57:01 +01:00
|
|
|
static void check_color_support(void);
|
2021-02-24 00:22:28 +01:00
|
|
|
|
2022-11-15 04:34:48 +01:00
|
|
|
void vlog_init(void)
|
|
|
|
{
|
2023-09-05 19:13:27 +02:00
|
|
|
#ifdef VLOG_USE_SDL
|
2023-09-02 22:23:17 +02:00
|
|
|
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_VERBOSE);
|
|
|
|
#endif
|
2022-11-15 04:34:48 +01:00
|
|
|
check_color_support();
|
|
|
|
}
|
|
|
|
|
2021-09-01 22:41:06 +02:00
|
|
|
void vlog_toggle_output(const int enable_output)
|
|
|
|
{
|
|
|
|
output_enabled = enable_output;
|
|
|
|
}
|
|
|
|
|
2021-09-01 22:28:51 +02:00
|
|
|
void vlog_toggle_color(const int enable_color)
|
|
|
|
{
|
|
|
|
color_enabled = enable_color;
|
|
|
|
}
|
|
|
|
|
2021-09-01 23:11:23 +02:00
|
|
|
void vlog_toggle_debug(const int enable_debug)
|
|
|
|
{
|
|
|
|
debug_enabled = enable_debug;
|
|
|
|
}
|
|
|
|
|
2021-09-01 22:41:06 +02:00
|
|
|
void vlog_toggle_info(const int enable_info)
|
|
|
|
{
|
|
|
|
info_enabled = enable_info;
|
|
|
|
}
|
|
|
|
|
|
|
|
void vlog_toggle_warn(const int enable_warn)
|
|
|
|
{
|
|
|
|
warn_enabled = enable_warn;
|
|
|
|
}
|
|
|
|
|
|
|
|
void vlog_toggle_error(const int enable_error)
|
|
|
|
{
|
|
|
|
error_enabled = enable_error;
|
|
|
|
}
|
|
|
|
|
2022-08-29 19:48:21 +02:00
|
|
|
SDL_PRINTF_VARARG_FUNC(1) void vlog_debug(const char* text, ...)
|
2021-09-01 23:11:23 +02:00
|
|
|
{
|
|
|
|
va_list list;
|
|
|
|
|
|
|
|
if (!output_enabled || !debug_enabled)
|
|
|
|
{
|
2022-08-29 19:48:21 +02:00
|
|
|
return;
|
2021-09-01 23:11:23 +02:00
|
|
|
}
|
|
|
|
|
2023-09-05 19:13:27 +02:00
|
|
|
#ifdef VLOG_USE_SDL
|
2023-09-02 22:23:17 +02:00
|
|
|
va_start(list, text);
|
|
|
|
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, text, list);
|
|
|
|
va_end(list);
|
|
|
|
#else
|
2021-09-01 23:11:23 +02:00
|
|
|
printf(Color_BOLD_GRAY);
|
|
|
|
printf("[DEBUG]");
|
|
|
|
printf(Color_RESET);
|
|
|
|
printf(" ");
|
|
|
|
|
|
|
|
va_start(list, text);
|
2022-08-29 19:48:21 +02:00
|
|
|
vprintf(text, list);
|
2021-09-01 23:11:23 +02:00
|
|
|
va_end(list);
|
|
|
|
|
|
|
|
putchar('\n');
|
2023-09-02 22:23:17 +02:00
|
|
|
#endif
|
2021-09-01 23:11:23 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 19:48:21 +02:00
|
|
|
SDL_PRINTF_VARARG_FUNC(1) void vlog_info(const char* text, ...)
|
2021-02-23 09:54:45 +01:00
|
|
|
{
|
|
|
|
va_list list;
|
|
|
|
|
2021-09-01 22:41:06 +02:00
|
|
|
if (!output_enabled || !info_enabled)
|
|
|
|
{
|
2022-08-29 19:48:21 +02:00
|
|
|
return;
|
2021-09-01 22:41:06 +02:00
|
|
|
}
|
|
|
|
|
2023-09-05 19:13:27 +02:00
|
|
|
#ifdef VLOG_USE_SDL
|
2023-09-02 22:23:17 +02:00
|
|
|
va_start(list, text);
|
|
|
|
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, text, list);
|
|
|
|
va_end(list);
|
|
|
|
#else
|
2021-02-24 00:22:28 +01:00
|
|
|
printf(Color_BOLD);
|
|
|
|
printf("[INFO]");
|
|
|
|
printf(Color_RESET);
|
|
|
|
printf(" ");
|
2021-02-23 09:54:45 +01:00
|
|
|
|
|
|
|
va_start(list, text);
|
2022-08-29 19:48:21 +02:00
|
|
|
vprintf(text, list);
|
2021-02-23 09:54:45 +01:00
|
|
|
va_end(list);
|
|
|
|
|
|
|
|
putchar('\n');
|
2023-09-02 22:23:17 +02:00
|
|
|
#endif
|
2021-02-23 09:54:45 +01:00
|
|
|
}
|
|
|
|
|
2022-08-29 19:48:21 +02:00
|
|
|
SDL_PRINTF_VARARG_FUNC(1) void vlog_warn(const char* text, ...)
|
2021-02-23 09:54:45 +01:00
|
|
|
{
|
|
|
|
va_list list;
|
|
|
|
|
2021-09-01 22:41:06 +02:00
|
|
|
if (!output_enabled || !warn_enabled)
|
|
|
|
{
|
2022-08-29 19:48:21 +02:00
|
|
|
return;
|
2021-09-01 22:41:06 +02:00
|
|
|
}
|
|
|
|
|
2023-09-05 19:13:27 +02:00
|
|
|
#ifdef VLOG_USE_SDL
|
2023-09-02 22:23:17 +02:00
|
|
|
va_start(list, text);
|
|
|
|
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_WARN, text, list);
|
|
|
|
va_end(list);
|
|
|
|
#else
|
2021-02-24 00:22:28 +01:00
|
|
|
fprintf(stderr, Color_BOLD_YELLOW);
|
|
|
|
fprintf(stderr, "[WARN]");
|
|
|
|
fprintf(stderr, Color_RESET);
|
|
|
|
fprintf(stderr, " ");
|
2021-02-23 09:54:45 +01:00
|
|
|
|
|
|
|
va_start(list, text);
|
2022-08-29 19:48:21 +02:00
|
|
|
vfprintf(stderr, text, list);
|
2021-02-23 09:54:45 +01:00
|
|
|
va_end(list);
|
|
|
|
|
|
|
|
fputc('\n', stderr);
|
2023-09-02 22:23:17 +02:00
|
|
|
#endif
|
2021-02-23 09:54:45 +01:00
|
|
|
}
|
|
|
|
|
2022-08-29 19:48:21 +02:00
|
|
|
SDL_PRINTF_VARARG_FUNC(1) void vlog_error(const char* text, ...)
|
2021-02-23 09:54:45 +01:00
|
|
|
{
|
|
|
|
va_list list;
|
|
|
|
|
2021-09-01 22:41:06 +02:00
|
|
|
if (!output_enabled || !error_enabled)
|
|
|
|
{
|
2022-08-29 19:48:21 +02:00
|
|
|
return;
|
2021-09-01 22:41:06 +02:00
|
|
|
}
|
|
|
|
|
2023-09-05 19:13:27 +02:00
|
|
|
#ifdef VLOG_USE_SDL
|
2023-09-02 22:23:17 +02:00
|
|
|
va_start(list, text);
|
|
|
|
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, text, list);
|
|
|
|
va_end(list);
|
|
|
|
#else
|
2021-02-24 00:22:28 +01:00
|
|
|
fprintf(stderr, Color_BOLD_RED);
|
|
|
|
fprintf(stderr, "[ERROR]");
|
|
|
|
fprintf(stderr, Color_RESET);
|
|
|
|
fprintf(stderr, " ");
|
2021-02-23 09:54:45 +01:00
|
|
|
|
|
|
|
va_start(list, text);
|
2022-08-29 19:48:21 +02:00
|
|
|
vfprintf(stderr, text, list);
|
2021-02-23 09:54:45 +01:00
|
|
|
va_end(list);
|
|
|
|
|
|
|
|
fputc('\n', stderr);
|
2023-09-02 22:23:17 +02:00
|
|
|
#endif
|
2021-02-23 09:54:45 +01:00
|
|
|
}
|
2022-11-15 04:34:48 +01:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
void vlog_open_console(void)
|
|
|
|
{
|
|
|
|
static int run_once = 0;
|
|
|
|
if (run_once)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
run_once = 1;
|
|
|
|
|
|
|
|
const BOOL success = AllocConsole();
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
/* Debug, not error, because it might not be an error.
|
|
|
|
* (E.g. there is already an attached console.) */
|
|
|
|
vlog_debug(
|
|
|
|
"Could not open console: AllocConsole() failed with %d",
|
|
|
|
GetLastError()
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-11-15 06:56:02 +01:00
|
|
|
const FILE* handle = freopen("CON", "w", stdout);
|
|
|
|
if (handle == NULL)
|
|
|
|
{
|
|
|
|
vlog_error("Could not redirect STDOUT to console.");
|
|
|
|
}
|
|
|
|
|
|
|
|
handle = freopen("CON", "w", stderr);
|
|
|
|
if (handle == NULL)
|
|
|
|
{
|
|
|
|
vlog_error("Could not redirect STDERR to console.");
|
|
|
|
}
|
2022-11-15 04:34:48 +01:00
|
|
|
|
|
|
|
check_color_support();
|
|
|
|
}
|
|
|
|
#endif /* _WIN32 */
|
2022-11-15 06:57:01 +01:00
|
|
|
|
|
|
|
static void check_color_support(void)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
/* VT100 colors are supported since Windows 10 build 16257,
|
|
|
|
* but it's not enabled by default. So we have to set it. */
|
|
|
|
|
|
|
|
const HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
if (hStdout == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
vlog_error(
|
|
|
|
"Could not set color support: GetStdHandle() failed with %d",
|
|
|
|
GetLastError()
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
|
|
|
|
if (hStderr == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
vlog_error(
|
|
|
|
"Could not enable color support: GetStdHandle() failed with %d",
|
|
|
|
GetLastError()
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const BOOL success = SetConsoleMode(
|
|
|
|
hStdout, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
|
|
|
);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
/* Debug, not error, because it might not be an error.
|
|
|
|
* (E.g. this version of Windows doesn't support VT100 colors.) */
|
|
|
|
vlog_debug(
|
|
|
|
"Could not enable color support: SetConsoleMode() failed with %d",
|
|
|
|
GetLastError()
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
color_supported = 1;
|
2023-09-05 19:13:27 +02:00
|
|
|
#elif (defined(__unix__) || defined(__APPLE__)) && !defined(VLOG_USE_SDL)
|
2022-11-15 06:57:01 +01:00
|
|
|
if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO))
|
|
|
|
{
|
|
|
|
color_supported = 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|