#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <SDL3/SDL_test.h>
#include <time.h>
#if (defined(__GNUC__) && (__GNUC__ <= 2))
static size_t strftime_gcc2_workaround(char *s, size_t max, const char *fmt, const struct tm *tm)
{
return strftime(s, max, fmt, tm);
}
#ifdef strftime
#undef strftime
#endif
#define strftime strftime_gcc2_workaround
#endif
static const char *SDLTest_TimestampToString(const time_t timestamp)
{
time_t copy;
static char buffer[64];
struct tm *local;
size_t result = 0;
SDL_memset(buffer, 0, sizeof(buffer));
copy = timestamp;
local = localtime(©);
result = strftime(buffer, sizeof(buffer), "%x %X", local);
if (result == 0) {
return "";
}
return buffer;
}
static void SDLTest_LogMessageV(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
{
char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH);
(void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, ap);
if (priority > SDL_LOG_PRIORITY_INFO) {
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, priority, "%s: %s", SDLTest_TimestampToString(time(NULL)), logMessage);
} else {
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, priority, " %s: %s", SDLTest_TimestampToString(time(NULL)), logMessage);
}
}
void SDLTest_LogMessage(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
SDLTest_LogMessageV(priority, fmt, ap);
va_end(ap);
}
void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
SDLTest_LogMessageV(SDL_LOG_PRIORITY_INFO, fmt, ap);
va_end(ap);
}
void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
SDLTest_LogMessageV(SDL_LOG_PRIORITY_ERROR, fmt, ap);
va_end(ap);
}
static char nibble_to_char(Uint8 nibble)
{
if (nibble < 0xa) {
return '0' + nibble;
} else {
return 'a' + nibble - 10;
}
}
void SDLTest_LogEscapedString(const char *prefix, const void *buffer, size_t size)
{
const Uint8 *data = buffer;
char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
if (data) {
size_t i;
size_t pos = 0;
#define NEED_X_CHARS(N) \
if (pos + (N) > sizeof(logMessage) - 2) { \
break; \
}
logMessage[pos++] = '"';
for (i = 0; i < size; i++) {
Uint8 c = data[i];
size_t pos_start = pos;
switch (c) {
case '\0':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = '0';
break;
case '"':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = '"';
break;
case '\n':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'n';
break;
case '\r':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'r';
break;
case '\t':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 't';
break;
case '\f':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'f';
break;
case '\b':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = 'b';
break;
case '\\':
NEED_X_CHARS(2);
logMessage[pos++] = '\\';
logMessage[pos++] = '\\';
break;
default:
if (SDL_isprint(c)) {
NEED_X_CHARS(1);
logMessage[pos++] = c;
} else {
NEED_X_CHARS(4);
logMessage[pos++] = '\\';
logMessage[pos++] = 'x';
logMessage[pos++] = nibble_to_char(c >> 4);
logMessage[pos++] = nibble_to_char(c & 0xf);
}
break;
}
if (pos == pos_start) {
break;
}
}
if (i < size) {
logMessage[sizeof(logMessage) - 4] = '.';
logMessage[sizeof(logMessage) - 3] = '.';
logMessage[sizeof(logMessage) - 2] = '.';
logMessage[sizeof(logMessage) - 1] = '\0';
} else {
logMessage[pos++] = '"';
logMessage[pos] = '\0';
}
} else {
SDL_strlcpy(logMessage, "(nil)", sizeof(logMessage));
}
SDLTest_Log("%s%s", prefix, logMessage);
}