From 25a614bc3e573909b5801d3d21c4af46e5f7fa51 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Tue, 14 Sep 2021 20:37:35 +0100 Subject: [PATCH] Add SDL_asprintf and SDL_vasprintf --- include/SDL_stdinc.h | 2 ++ src/dynapi/SDL_dynapi.c | 6 ++++ src/dynapi/SDL_dynapi_overrides.h | 2 ++ src/dynapi/SDL_dynapi_procs.h | 4 +++ src/stdlib/SDL_string.c | 56 +++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index f66f4eab7..17edc8511 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -566,6 +566,8 @@ extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vasprintf(char **strp, const char *fmt, va_list ap); #ifndef HAVE_M_PI #ifndef M_PI diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c index 013dbc90d..4dc16b126 100644 --- a/src/dynapi/SDL_dynapi.c +++ b/src/dynapi/SDL_dynapi.c @@ -89,6 +89,12 @@ static void SDL_InitDynamicAPI(void); va_end(ap); \ return retval; \ } \ + _static int SDLCALL SDL_asprintf##name(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \ + int retval; va_list ap; initcall; va_start(ap, fmt); \ + retval = jump_table.SDL_vasprintf(strp, fmt, ap); \ + va_end(ap); \ + return retval; \ + } \ _static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \ va_list ap; initcall; va_start(ap, fmt); \ jump_table.SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); \ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index b28b5b8d1..77f434729 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -820,3 +820,5 @@ #define SDL_RenderGeometry SDL_RenderGeometry_REAL #define SDL_RenderGeometryRaw SDL_RenderGeometryRaw_REAL #define SDL_RenderSetVSync SDL_RenderSetVSync_REAL +#define SDL_asprintf SDL_asprintf_REAL +#define SDL_vasprintf SDL_vasprintf_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 9887e623c..c383ea675 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -885,3 +885,7 @@ SDL_DYNAPI_PROC(void*,SDL_GetTextureUserData,(SDL_Texture *a),(a),return) SDL_DYNAPI_PROC(int,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(int,SDL_RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const int *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) SDL_DYNAPI_PROC(int,SDL_RenderSetVSync,(SDL_Renderer *a, int b),(a,b),return) +#if !SDL_DYNAPI_PROC_NO_VARARGS +SDL_DYNAPI_PROC(int,SDL_asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),return) +#endif +SDL_DYNAPI_PROC(int,SDL_vasprintf,(char **a, const char *b, va_list c),(a,b,c),return) diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 76005e204..cb0b84660 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -1911,4 +1911,60 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, #undef TEXT_AND_LEN_ARGS #endif /* HAVE_VSNPRINTF */ +int +SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + int retval; + + va_start(ap, fmt); + retval = SDL_vasprintf(strp, fmt, ap); + va_end(ap); + + return retval; +} + +int +SDL_vasprintf(char **strp, const char *fmt, va_list ap) +{ + int retval; + int size = 100; /* Guess we need no more than 100 bytes */ + char *p, *np; + va_list aq; + + *strp = NULL; + + p = (char *)SDL_malloc(size); + if (p == NULL) + return -1; + + while (1) { + /* Try to print in the allocated space */ + va_copy(aq, ap); + retval = SDL_vsnprintf(p, size, fmt, aq); + va_end(aq); + + /* Check error code */ + if (retval < 0) + return retval; + + /* If that worked, return the string */ + if (retval < size) { + *strp = p; + return retval; + } + + /* Else try again with more space */ + size = retval + 1; /* Precisely what is needed */ + + np = (char *)SDL_realloc(p, size); + if (np == NULL) { + SDL_free(p); + return -1; + } else { + p = np; + } + } +} + /* vi: set ts=4 sw=4 expandtab: */