From a567786762e728476c27dd71f4360ac45206463c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 13 Oct 2024 09:26:25 -0700
Subject: [PATCH] Added SDL_SetErrorV()
---
include/SDL3/SDL_error.h | 18 ++++++++++++++++++
src/SDL_error.c | 25 ++++++++++++++++++-------
src/dynapi/SDL_dynapi.sym | 1 +
src/dynapi/SDL_dynapi_overrides.h | 1 +
src/dynapi/SDL_dynapi_procs.h | 1 +
5 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/include/SDL3/SDL_error.h b/include/SDL3/SDL_error.h
index 9256ff2975d94..fd6e652ec2960 100644
--- a/include/SDL3/SDL_error.h
+++ b/include/SDL3/SDL_error.h
@@ -82,9 +82,27 @@ extern "C" {
*
* \sa SDL_ClearError
* \sa SDL_GetError
+ * \sa SDL_SetErrorV
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1);
+/**
+ * Set the SDL error message for the current thread.
+ *
+ * Calling this function will replace any previous error message that was set.
+ *
+ * \param fmt a printf()-style message format string.
+ * \param ap a variable argument list.
+ * \returns false.
+ *
+ * \since This function is available since SDL 3.1.6.
+ *
+ * \sa SDL_ClearError
+ * \sa SDL_GetError
+ * \sa SDL_SetError
+ */
+extern SDL_DECLSPEC bool SDLCALL SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(1);
+
/**
* Set an error indicating that memory allocation failed.
*
diff --git a/src/SDL_error.c b/src/SDL_error.c
index f5cb0c2c1e3dc..dca5a86c7b736 100644
--- a/src/SDL_error.c
+++ b/src/SDL_error.c
@@ -25,18 +25,29 @@
#include "SDL_error_c.h"
bool SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
+{
+ va_list ap;
+ bool result;
+
+ va_start(ap, fmt);
+ result = SDL_SetErrorV(fmt, ap);
+ va_end(ap);
+ return result;
+}
+
+bool SDL_SetErrorV(SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
{
// Ignore call if invalid format pointer was passed
if (fmt) {
- va_list ap;
int result;
SDL_error *error = SDL_GetErrBuf(true);
+ va_list ap2;
error->error = SDL_ErrorCodeGeneric;
- va_start(ap, fmt);
- result = SDL_vsnprintf(error->str, error->len, fmt, ap);
- va_end(ap);
+ va_copy(ap2, ap);
+ result = SDL_vsnprintf(error->str, error->len, fmt, ap2);
+ va_end(ap2);
if (result >= 0 && (size_t)result >= error->len && error->realloc_func) {
size_t len = (size_t)result + 1;
@@ -44,9 +55,9 @@ bool SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
if (str) {
error->str = str;
error->len = len;
- va_start(ap, fmt);
- (void)SDL_vsnprintf(error->str, error->len, fmt, ap);
- va_end(ap);
+ va_copy(ap2, ap);
+ (void)SDL_vsnprintf(error->str, error->len, fmt, ap2);
+ va_end(ap2);
}
}
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 06cc432a93f95..c99ddd0240ff7 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -1179,6 +1179,7 @@ SDL3_0.0.0 {
SDL_StepBackUTF8;
SDL_DelayPrecise;
SDL_CalculateGPUTextureFormatSize;
+ SDL_SetErrorV;
# extra symbols go here (don't modify this line)
local: *;
};
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 6de3884830abf..444d20378bbdb 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -1204,3 +1204,4 @@
#define SDL_StepBackUTF8 SDL_StepBackUTF8_REAL
#define SDL_DelayPrecise SDL_DelayPrecise_REAL
#define SDL_CalculateGPUTextureFormatSize SDL_CalculateGPUTextureFormatSize_REAL
+#define SDL_SetErrorV SDL_SetErrorV_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index e6dcb8b8028ba..c931a4328a46d 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -1210,3 +1210,4 @@ SDL_DYNAPI_PROC(long,SDL_wcstol,(const wchar_t *a, wchar_t **b, int c),(a,b,c),r
SDL_DYNAPI_PROC(Uint32,SDL_StepBackUTF8,(const char *a, const char **b),(a,b),return)
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)