SDL_test: add SDLTest_LogEscapedString

This commit is contained in:
Anonymous Maarten 2024-09-06 03:25:50 +02:00 committed by Anonymous Maarten
parent 6a305e1532
commit ee65176eec
2 changed files with 110 additions and 0 deletions

View File

@ -51,6 +51,16 @@ extern "C" {
*/
void SDLCALL SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
/**
* Prints given prefix and buffer.
* Non-printible characters in the raw data are substituted by printible alternatives.
*
* \param prefix Prefix message.
* \param buffer Raw data to be escaped.
* \param size Number of bytes in buffer.
*/
void SDLCALL SDLTest_LogEscapedString(const char *prefix, const void *buffer, size_t size);
/**
* Prints given message with a timestamp in the TEST category and the ERROR priority.
*

View File

@ -109,3 +109,103 @@ void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
/* Log with timestamp and newline */
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_ERROR, "%s: %s", SDLTest_TimestampToString(time(0)), logMessage);
}
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);
}