Skip to content

Commit

Permalink
Added SDL_OutputDebug(), SDL_OutputDebugV(), and SDL_OutputDebugString()
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Oct 13, 2024
1 parent b766c82 commit 814f611
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 25 deletions.
66 changes: 58 additions & 8 deletions include/SDL3/SDL_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fm
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -265,7 +265,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogTrace(int category, SDL_PRINTF_FORMAT_ST
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -288,7 +288,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -312,7 +312,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_ST
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -336,7 +336,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STR
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -360,7 +360,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STR
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -384,7 +384,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_ST
*
* \param category the category of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -409,7 +409,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT
* \param category the category of the message.
* \param priority the priority of the message.
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the **fmt** string,
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
Expand Down Expand Up @@ -503,6 +503,56 @@ extern SDL_DECLSPEC void SDLCALL SDL_GetLogOutputFunction(SDL_LogOutputFunction
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetLogOutputFunction(SDL_LogOutputFunction callback, void *userdata);

/**
* Output a line of text to the default debug output for the platform.
*
* The text should not include any newline characters, those will be automatically added as needed for the current platform.
*
* \param fmt a printf() style message format string.
* \param ... additional parameters matching % tokens in the `fmt` string,
* if any.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.1.6.
*
* \sa SDL_OutputDebugString
* \sa SDL_OutputDebugV
*/
extern SDL_DECLSPEC void SDLCALL SDL_OutputDebug(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3);

/**
* Output a line of text to the default debug output for the platform.
*
* The text should not include any newline characters, those will be automatically added as needed for the current platform.
*
* \param fmt a printf() style message format string.
* \param ap a variable argument list.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.1.6.
*
* \sa SDL_OutputDebug
* \sa SDL_OutputDebugString
*/
extern SDL_DECLSPEC void SDLCALL SDL_OutputDebugV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(3);

/**
* Output a line of text to the default debug output for the platform.
*
* The text should not include any newline characters, those will be automatically added as needed for the current platform.
*
* \param message a line of text in UTF-8 format.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.1.6.
*
* \sa SDL_OutputDebug
* \sa SDL_OutputDebugV
*/
extern SDL_DECLSPEC void SDLCALL SDL_OutputDebugString(const char *message);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
Expand Down
91 changes: 75 additions & 16 deletions src/SDL_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,55 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_S
}
}

#if defined(SDL_PLATFORM_WIN32) && !defined(SDL_PLATFORM_GDK)
void SDL_OutputDebug(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
SDL_OutputDebugV(fmt, ap);
va_end(ap);
}

void SDL_OutputDebugV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
{
char *message = NULL;
char stack_buf[SDL_MAX_LOG_MESSAGE_STACK];
size_t len_plus_term;
int len;
va_list aq;

// Render into stack buffer
va_copy(aq, ap);
len = SDL_vsnprintf(stack_buf, sizeof(stack_buf), fmt, aq);
va_end(aq);

if (len < 0) {
return;
}

// If message truncated, allocate and re-render
if (len >= sizeof(stack_buf) && SDL_size_add_check_overflow(len, 1, &len_plus_term)) {
// Allocate exactly what we need, including the zero-terminator
message = (char *)SDL_malloc(len_plus_term);
if (!message) {
return;
}
va_copy(aq, ap);
len = SDL_vsnprintf(message, len_plus_term, fmt, aq);
va_end(aq);
} else {
message = stack_buf;
}

SDL_OutputDebugString(message);

// Free only if dynamically allocated
if (message != stack_buf) {
SDL_free(message);
}
}

#if defined(SDL_PLATFORM_WINDOWS) && !defined(SDL_PLATFORM_GDK)
enum {
CONSOLE_UNATTACHED = 0,
CONSOLE_ATTACHED_CONSOLE = 1,
Expand All @@ -642,8 +690,7 @@ enum {
static HANDLE stderrHandle = NULL;
#endif

static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
const char *message)
static void SDL_OutputDebugStringWithPrefix(const char *prefix, const char *message)
{
#if defined(SDL_PLATFORM_WINDOWS)
// Way too many allocations here, urgh
Expand Down Expand Up @@ -694,9 +741,9 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
}
}
#endif // !defined(SDL_PLATFORM_GDK)
length = SDL_strlen(GetLogPriorityPrefix(priority)) + SDL_strlen(message) + 1 + 1 + 1;
length = SDL_strlen(prefix) + SDL_strlen(message) + 1 + 1 + 1;
output = SDL_small_alloc(char, length, &isstack);
(void)SDL_snprintf(output, length, "%s%s\r\n", GetLogPriorityPrefix(priority), message);
(void)SDL_snprintf(output, length, "%s%s\r\n", prefix, message);
tstr = WIN_UTF8ToString(output);

// Output to debugger
Expand All @@ -723,26 +770,21 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
SDL_small_free(output, isstack);
}
#elif defined(SDL_PLATFORM_ANDROID)
{
char tag[32];

SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
__android_log_write(SDL_android_priority[priority], tag, message);
}
__android_log_write(ANDROID_LOG_DEBUG, "SDL", message);
#elif defined(SDL_PLATFORM_APPLE) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))
/* Technically we don't need Cocoa/UIKit, but that's where this function is defined for now.
*/
extern void SDL_NSLog(const char *prefix, const char *text);
{
SDL_NSLog(GetLogPriorityPrefix(priority), message);
SDL_NSLog(prefix, message);
return;
}
#elif defined(SDL_PLATFORM_PSP) || defined(SDL_PLATFORM_PS2)
{
FILE *pFile;
pFile = fopen("SDL_Log.txt", "a");
if (pFile) {
(void)fprintf(pFile, "%s%s\n", GetLogPriorityPrefix(priority), message);
(void)fprintf(pFile, "%s%s\n", prefix, message);
(void)fclose(pFile);
}
}
Expand All @@ -751,7 +793,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
FILE *pFile;
pFile = fopen("ux0:/data/SDL_Log.txt", "a");
if (pFile) {
(void)fprintf(pFile, "%s%s\n", GetLogPriorityPrefix(priority), message);
(void)fprintf(pFile, "%s%s\n", prefix, message);
(void)fclose(pFile);
}
}
Expand All @@ -760,15 +802,32 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
FILE *pFile;
pFile = fopen("sdmc:/3ds/SDL_Log.txt", "a");
if (pFile) {
(void)fprintf(pFile, "%s%s\n", GetLogPriorityPrefix(priority), message);
(void)fprintf(pFile, "%s%s\n", prefix, message);
(void)fclose(pFile);
}
}
#endif
#if defined(HAVE_STDIO_H) && \
!(defined(SDL_PLATFORM_APPLE) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))) && \
!(defined(SDL_PLATFORM_WIN32))
(void)fprintf(stderr, "%s%s\n", GetLogPriorityPrefix(priority), message);
(void)fprintf(stderr, "%s%s\n", prefix, message);
#endif
}

void SDL_OutputDebugString(const char *message)
{
SDL_OutputDebugStringWithPrefix("", message);
}

static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, const char *message)
{
#ifdef SDL_PLATFORM_ANDROID
char tag[32];

SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
__android_log_write(SDL_android_priority[priority], tag, message);
#else
SDL_OutputDebugStringWithPrefix(GetLogPriorityPrefix(priority), message);
#endif
}

Expand Down
18 changes: 17 additions & 1 deletion src/dynapi/SDL_dynapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,15 @@ static void SDL_InitDynamicAPI(void);
if (str != buf) { \
jump_table.SDL_free(str); \
} \
return false; \
return false; \
} \
_static void SDLCALL SDL_OutputDebug##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
{ \
va_list ap; \
initcall; \
va_start(ap, fmt); \
jump_table.SDL_OutputDebugV(fmt, ap); \
va_end(ap); \
} \
_static int SDLCALL SDL_sscanf##name(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) \
{ \
Expand Down Expand Up @@ -238,6 +246,14 @@ static bool SDLCALL SDL_SetError_LOGSDLCALLS(SDL_PRINTF_FORMAT_STRING const char
va_end(ap);
return SDL_SetError_REAL("%s", buf);
}
static void SDLCALL SDL_OutputDebug_LOGSDLCALLS(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
SDL_Log_REAL("SDL3CALL SDL_OutputDebug");
va_start(ap, fmt);
SDL_OutputDebugV_REAL(fmt, ap);
va_end(ap);
}
static int SDLCALL SDL_sscanf_LOGSDLCALLS(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...)
{
int result;
Expand Down
3 changes: 3 additions & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,9 @@ SDL3_0.0.0 {
SDL_DelayPrecise;
SDL_CalculateGPUTextureFormatSize;
SDL_SetErrorV;
SDL_OutputDebug;
SDL_OutputDebugV;
SDL_OutputDebugString;
# extra symbols go here (don't modify this line)
local: *;
};
3 changes: 3 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -1205,3 +1205,6 @@
#define SDL_DelayPrecise SDL_DelayPrecise_REAL
#define SDL_CalculateGPUTextureFormatSize SDL_CalculateGPUTextureFormatSize_REAL
#define SDL_SetErrorV SDL_SetErrorV_REAL
#define SDL_OutputDebug SDL_OutputDebug_REAL
#define SDL_OutputDebugV SDL_OutputDebugV_REAL
#define SDL_OutputDebugString SDL_OutputDebugString_REAL
5 changes: 5 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1211,3 +1211,8 @@ SDL_DYNAPI_PROC(Uint32,SDL_StepBackUTF8,(const char *a, const char **b),(a,b),re
SDL_DYNAPI_PROC(void,SDL_DelayPrecise,(Uint64 a),(a),)
SDL_DYNAPI_PROC(Uint32,SDL_CalculateGPUTextureFormatSize,(SDL_GPUTextureFormat a, Uint32 b, Uint32 c, Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_SetErrorV,(SDL_PRINTF_FORMAT_STRING const char *a,va_list b),(a,b),return)
#ifndef SDL_DYNAPI_PROC_NO_VARARGS
SDL_DYNAPI_PROC(void,SDL_OutputDebug,(SDL_PRINTF_FORMAT_STRING const char *a,...),(a),)
#endif
SDL_DYNAPI_PROC(void,SDL_OutputDebugV,(SDL_PRINTF_FORMAT_STRING const char *a,va_list b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_OutputDebugString,(const char *a),(a),)

0 comments on commit 814f611

Please sign in to comment.