Atlas - SDL_test_log.c
Home / ext / SDL / src / test Lines: 2 | Size: 7107 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2026 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21 22/* 23 Used by the test framework and test cases. 24*/ 25 26/* quiet windows compiler warnings */ 27#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) 28#define _CRT_SECURE_NO_WARNINGS 29#endif 30#include <SDL3/SDL_test.h> 31 32#include <time.h> /* Needed for localtime() */ 33 34bool SDLTest_Time = true; 35 36/* work around compiler warning on older GCCs. */ 37#if (defined(__GNUC__) && (__GNUC__ <= 2)) 38static size_t strftime_gcc2_workaround(char *s, size_t max, const char *fmt, const struct tm *tm) 39{ 40 return strftime(s, max, fmt, tm); 41} 42#ifdef strftime 43#undef strftime 44#endif 45#define strftime strftime_gcc2_workaround 46#endif 47 48/** 49 * Converts unix timestamp to its ascii representation in localtime 50 * 51 * Note: Uses a static buffer internally, so the return value 52 * isn't valid after the next call of this function. If you 53 * want to retain the return value, make a copy of it. 54 * 55 * \param timestamp A Timestamp, i.e. time(0) 56 * 57 * \return Ascii representation of the timestamp in localtime in the format '08/23/01 14:55:02' 58 */ 59static const char *SDLTest_TimestampToString(const time_t timestamp) 60{ 61 time_t copy; 62 static char buffer[64]; 63 struct tm *local; 64 size_t result = 0; 65 66 if (!SDLTest_Time) { 67 return ""; 68 } 69 70 SDL_memset(buffer, 0, sizeof(buffer)); 71 copy = timestamp; 72 local = localtime(©); 73 result = strftime(buffer, sizeof(buffer), "%x %X", local); 74 if (result == 0) { 75 return ""; 76 } 77 78 return buffer; 79} 80 81/* 82 * Prints given message with a timestamp in the TEST category and given priority. 83 */ 84static void SDLTest_LogMessageV(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) 85{ 86 char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH]; 87 88 /* Print log message into a buffer */ 89 SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); 90 (void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, ap); 91 92 /* Log with timestamp and newline. Messages with lower priority are slightly indented. */ 93 if (priority > SDL_LOG_PRIORITY_INFO) { 94 SDL_LogMessage(SDL_LOG_CATEGORY_TEST, priority, "%s: %s", SDLTest_TimestampToString(time(NULL)), logMessage); 95 } else { 96 SDL_LogMessage(SDL_LOG_CATEGORY_TEST, priority, " %s: %s", SDLTest_TimestampToString(time(NULL)), logMessage); 97 } 98} 99 100/* 101 * Prints given message with a timestamp in the TEST category and given priority. 102 */ 103void SDLTest_LogMessage(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) 104{ 105 va_list ap; 106 107 va_start(ap, fmt); 108 SDLTest_LogMessageV(priority, fmt, ap); 109 va_end(ap); 110} 111 112/* 113 * Prints given message with a timestamp in the TEST category and INFO priority. 114 */ 115void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) 116{ 117 va_list ap; 118 119 va_start(ap, fmt); 120 SDLTest_LogMessageV(SDL_LOG_PRIORITY_INFO, fmt, ap); 121 va_end(ap); 122} 123 124/* 125 * Prints given message with a timestamp in the TEST category and the ERROR priority. 126 */ 127void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) 128{ 129 va_list ap; 130 131 va_start(ap, fmt); 132 SDLTest_LogMessageV(SDL_LOG_PRIORITY_ERROR, fmt, ap); 133 va_end(ap); 134} 135 136static char nibble_to_char(Uint8 nibble) 137{ 138 if (nibble < 0xa) { 139 return '0' + nibble; 140 } else { 141 return 'a' + nibble - 10; 142 } 143} 144 145void SDLTest_LogEscapedString(const char *prefix, const void *buffer, size_t size) 146{ 147 const Uint8 *data = buffer; 148 char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH]; 149 150 if (data) { 151 size_t i; 152 size_t pos = 0; 153 #define NEED_X_CHARS(N) \ 154 if (pos + (N) > sizeof(logMessage) - 2) { \ 155 break; \ 156 } 157 158 logMessage[pos++] = '"'; 159 for (i = 0; i < size; i++) { 160 Uint8 c = data[i]; 161 size_t pos_start = pos; 162 switch (c) { 163 case '\0': 164 NEED_X_CHARS(2); 165 logMessage[pos++] = '\\'; 166 logMessage[pos++] = '0'; 167 break; 168 case '"': 169 NEED_X_CHARS(2); 170 logMessage[pos++] = '\\'; 171 logMessage[pos++] = '"'; 172 break; 173 case '\n': 174 NEED_X_CHARS(2); 175 logMessage[pos++] = '\\'; 176 logMessage[pos++] = 'n'; 177 break; 178 case '\r': 179 NEED_X_CHARS(2); 180 logMessage[pos++] = '\\'; 181 logMessage[pos++] = 'r'; 182 break; 183 case '\t': 184 NEED_X_CHARS(2); 185 logMessage[pos++] = '\\'; 186 logMessage[pos++] = 't'; 187 break; 188 case '\f': 189 NEED_X_CHARS(2); 190 logMessage[pos++] = '\\'; 191 logMessage[pos++] = 'f'; 192 break; 193 case '\b': 194 NEED_X_CHARS(2); 195 logMessage[pos++] = '\\'; 196 logMessage[pos++] = 'b'; 197 break; 198 case '\\': 199 NEED_X_CHARS(2); 200 logMessage[pos++] = '\\'; 201 logMessage[pos++] = '\\'; 202 break; 203 default: 204 if (SDL_isprint(c)) { 205 NEED_X_CHARS(1); 206 logMessage[pos++] = c; 207 } else { 208 NEED_X_CHARS(4); 209 logMessage[pos++] = '\\'; 210 logMessage[pos++] = 'x'; 211 logMessage[pos++] = nibble_to_char(c >> 4); 212 logMessage[pos++] = nibble_to_char(c & 0xf); 213 } 214 break; 215 } 216 if (pos == pos_start) { 217 break; 218 } 219 } 220 if (i < size) { 221 logMessage[sizeof(logMessage) - 4] = '.'; 222 logMessage[sizeof(logMessage) - 3] = '.'; 223 logMessage[sizeof(logMessage) - 2] = '.'; 224 logMessage[sizeof(logMessage) - 1] = '\0'; 225 } else { 226 logMessage[pos++] = '"'; 227 logMessage[pos] = '\0'; 228 } 229 } else { 230 SDL_strlcpy(logMessage, "(nil)", sizeof(logMessage)); 231 } 232 233 SDLTest_Log("%s%s", prefix, logMessage); 234} 235[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.