mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-30 16:37:39 +00:00
Added SDL_RWprintf() and SDL_RWvprintf() to do formatted printing to an SDL_rwops stream
Fixes https://github.com/libsdl-org/SDL/issues/2390
This commit is contained in:
parent
52c4e3eab3
commit
f9d11807c0
7 changed files with 133 additions and 2 deletions
|
@ -490,11 +490,56 @@ extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, void *ptr, size_t
|
||||||
* \sa SDL_RWFromConstMem
|
* \sa SDL_RWFromConstMem
|
||||||
* \sa SDL_RWFromFile
|
* \sa SDL_RWFromFile
|
||||||
* \sa SDL_RWFromMem
|
* \sa SDL_RWFromMem
|
||||||
|
* \sa SDL_RWprint
|
||||||
* \sa SDL_RWread
|
* \sa SDL_RWread
|
||||||
* \sa SDL_RWseek
|
* \sa SDL_RWseek
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size);
|
extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print to an SDL_RWops data stream.
|
||||||
|
*
|
||||||
|
* This function does formatted printing to the stream.
|
||||||
|
*
|
||||||
|
* \param context a pointer to an SDL_RWops structure
|
||||||
|
* \param fmt a printf() style format string
|
||||||
|
* \param ... additional parameters matching % tokens in the `fmt` string, if any
|
||||||
|
* \returns the number of bytes written, or 0 on error; call SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_RWclose
|
||||||
|
* \sa SDL_RWFromConstMem
|
||||||
|
* \sa SDL_RWFromFile
|
||||||
|
* \sa SDL_RWFromMem
|
||||||
|
* \sa SDL_RWread
|
||||||
|
* \sa SDL_RWseek
|
||||||
|
* \sa SDL_RWwrite
|
||||||
|
*/
|
||||||
|
extern DECLSPEC size_t SDLCALL SDL_RWprintf(SDL_RWops *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print to an SDL_RWops data stream.
|
||||||
|
*
|
||||||
|
* This function does formatted printing to the stream.
|
||||||
|
*
|
||||||
|
* \param context a pointer to an SDL_RWops structure
|
||||||
|
* \param fmt a printf() style format string
|
||||||
|
* \param ap a variable argument list
|
||||||
|
* \returns the number of bytes written, or 0 on error; call SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_RWclose
|
||||||
|
* \sa SDL_RWFromConstMem
|
||||||
|
* \sa SDL_RWFromFile
|
||||||
|
* \sa SDL_RWFromMem
|
||||||
|
* \sa SDL_RWread
|
||||||
|
* \sa SDL_RWseek
|
||||||
|
* \sa SDL_RWwrite
|
||||||
|
*/
|
||||||
|
extern DECLSPEC size_t SDLCALL SDL_RWvprintf(SDL_RWops *context, const char *fmt, va_list ap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close and free an allocated SDL_RWops structure.
|
* Close and free an allocated SDL_RWops structure.
|
||||||
*
|
*
|
||||||
|
|
|
@ -144,6 +144,16 @@ static void SDL_InitDynamicAPI(void);
|
||||||
va_end(ap); \
|
va_end(ap); \
|
||||||
return retval; \
|
return retval; \
|
||||||
} \
|
} \
|
||||||
|
_static size_t SDLCALL SDL_RWprintf##name(SDL_RWops *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
||||||
|
{ \
|
||||||
|
size_t retval; \
|
||||||
|
va_list ap; \
|
||||||
|
initcall; \
|
||||||
|
va_start(ap, fmt); \
|
||||||
|
retval = jump_table.SDL_RWvprintf(context, fmt, ap); \
|
||||||
|
va_end(ap); \
|
||||||
|
return retval; \
|
||||||
|
} \
|
||||||
_static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
_static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
||||||
{ \
|
{ \
|
||||||
va_list ap; \
|
va_list ap; \
|
||||||
|
@ -285,6 +295,16 @@ static int SDLCALL SDL_swprintf_LOGSDLCALLS(SDL_OUT_Z_CAP(maxlen) wchar_t *buf,
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
_static size_t SDLCALL SDL_RWprintf_LOGSDLCALLS(SDL_RWops *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||||
|
{
|
||||||
|
size_t retval;
|
||||||
|
va_list ap;
|
||||||
|
SDL_Log_REAL("SDL3CALL SDL_RWprintf");
|
||||||
|
va_start(ap, fmt);
|
||||||
|
retval = SDL_RWvprintf_REAL(context, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
static void SDLCALL SDL_Log_LOGSDLCALLS(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
static void SDLCALL SDL_Log_LOGSDLCALLS(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
|
@ -922,6 +922,8 @@ SDL3_0.0.0 {
|
||||||
SDL_ClearProperty;
|
SDL_ClearProperty;
|
||||||
SDL_EnterAppMainCallbacks;
|
SDL_EnterAppMainCallbacks;
|
||||||
SDL_CleanupEvent;
|
SDL_CleanupEvent;
|
||||||
|
SDL_RWprintf;
|
||||||
|
SDL_RWvprintf;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -947,3 +947,5 @@
|
||||||
#define SDL_ClearProperty SDL_ClearProperty_REAL
|
#define SDL_ClearProperty SDL_ClearProperty_REAL
|
||||||
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
|
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
|
||||||
#define SDL_CleanupEvent SDL_CleanupEvent_REAL
|
#define SDL_CleanupEvent SDL_CleanupEvent_REAL
|
||||||
|
#define SDL_RWprintf SDL_RWprintf_REAL
|
||||||
|
#define SDL_RWvprintf SDL_RWvprintf_REAL
|
||||||
|
|
|
@ -43,6 +43,7 @@ SDL_DYNAPI_PROC(int,SDL_asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char
|
||||||
SDL_DYNAPI_PROC(int,SDL_snprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, SDL_PRINTF_FORMAT_STRING const char *c, ...),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_snprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, SDL_PRINTF_FORMAT_STRING const char *c, ...),(a,b,c),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_swprintf,(SDL_OUT_Z_CAP(b) wchar_t *a, size_t b, SDL_PRINTF_FORMAT_STRING const wchar_t *c, ...),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_swprintf,(SDL_OUT_Z_CAP(b) wchar_t *a, size_t b, SDL_PRINTF_FORMAT_STRING const wchar_t *c, ...),(a,b,c),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_sscanf,(const char *a, SDL_SCANF_FORMAT_STRING const char *b, ...),(a,b),return)
|
SDL_DYNAPI_PROC(int,SDL_sscanf,(const char *a, SDL_SCANF_FORMAT_STRING const char *b, ...),(a,b),return)
|
||||||
|
SDL_DYNAPI_PROC(size_t,SDL_RWprintf,(SDL_RWops *a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),return)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SDL_CreateThread
|
#ifdef SDL_CreateThread
|
||||||
|
@ -979,3 +980,4 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetWindowProperties,(SDL_Window *a),(a),ret
|
||||||
SDL_DYNAPI_PROC(int,SDL_ClearProperty,(SDL_PropertiesID a, const char *b),(a,b),return)
|
SDL_DYNAPI_PROC(int,SDL_ClearProperty,(SDL_PropertiesID a, const char *b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_EnterAppMainCallbacks,(int a, char *b[], SDL_AppInit_func c, SDL_AppIterate_func d, SDL_AppEvent_func e, SDL_AppQuit_func f),(a,b,c,d,e,f),return)
|
SDL_DYNAPI_PROC(int,SDL_EnterAppMainCallbacks,(int a, char *b[], SDL_AppInit_func c, SDL_AppIterate_func d, SDL_AppEvent_func e, SDL_AppQuit_func f),(a,b,c,d,e,f),return)
|
||||||
SDL_DYNAPI_PROC(void,SDL_CleanupEvent,(SDL_Event *a),(a),)
|
SDL_DYNAPI_PROC(void,SDL_CleanupEvent,(SDL_Event *a),(a),)
|
||||||
|
SDL_DYNAPI_PROC(size_t,SDL_RWvprintf,(SDL_RWops *a, const char *b, va_list c),(a,b,c),return)
|
||||||
|
|
|
@ -808,6 +808,35 @@ size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size)
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t SDL_RWprintf(SDL_RWops *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int size;
|
||||||
|
char *string = NULL;
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
size = SDL_vasprintf(&string, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
bytes = SDL_RWwrite(context, string, size);
|
||||||
|
SDL_free(string);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SDL_RWvprintf(SDL_RWops *context, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
char *string = NULL;
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
|
size = SDL_vasprintf(&string, fmt, ap);
|
||||||
|
|
||||||
|
bytes = SDL_RWwrite(context, string, size);
|
||||||
|
SDL_free(string);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
int SDL_RWclose(SDL_RWops *context)
|
int SDL_RWclose(SDL_RWops *context)
|
||||||
{
|
{
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
|
@ -110,11 +110,11 @@ static void testGenericRWopsValidations(SDL_RWops *rw, SDL_bool write)
|
||||||
SDLTest_AssertPass("Call to SDL_RWseek succeeded");
|
SDLTest_AssertPass("Call to SDL_RWseek succeeded");
|
||||||
SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (SDL_RW_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
|
SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (SDL_RW_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
|
||||||
|
|
||||||
/* Test write. */
|
/* Test write */
|
||||||
s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString) - 1);
|
s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString) - 1);
|
||||||
SDLTest_AssertPass("Call to SDL_RWwrite succeeded");
|
SDLTest_AssertPass("Call to SDL_RWwrite succeeded");
|
||||||
if (write) {
|
if (write) {
|
||||||
SDLTest_AssertCheck(s == sizeof(RWopsHelloWorldTestString) - 1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int)s);
|
SDLTest_AssertCheck(s == sizeof(RWopsHelloWorldTestString) - 1, "Verify result of writing with SDL_RWwrite, expected %i, got %i", (int)sizeof(RWopsHelloWorldTestString) - 1, (int)s);
|
||||||
} else {
|
} else {
|
||||||
SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s);
|
SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,37 @@ static void testGenericRWopsValidations(SDL_RWops *rw, SDL_bool write)
|
||||||
SDLTest_AssertPass("Call to SDL_RWseek succeeded");
|
SDLTest_AssertPass("Call to SDL_RWseek succeeded");
|
||||||
SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (SDL_RW_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
|
SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (SDL_RW_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
|
||||||
|
|
||||||
|
/* Test read */
|
||||||
|
s = SDL_RWread(rw, buf, sizeof(RWopsHelloWorldTestString) - 1);
|
||||||
|
SDLTest_AssertPass("Call to SDL_RWread succeeded");
|
||||||
|
SDLTest_AssertCheck(
|
||||||
|
s == (sizeof(RWopsHelloWorldTestString) - 1),
|
||||||
|
"Verify result from SDL_RWread, expected %i, got %i",
|
||||||
|
(int)(sizeof(RWopsHelloWorldTestString) - 1),
|
||||||
|
(int)s);
|
||||||
|
SDLTest_AssertCheck(
|
||||||
|
SDL_memcmp(buf, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString) - 1) == 0,
|
||||||
|
"Verify read bytes match expected string, expected '%s', got '%s'", RWopsHelloWorldTestString, buf);
|
||||||
|
|
||||||
|
/* Test seek back to start */
|
||||||
|
i = SDL_RWseek(rw, 0, SDL_RW_SEEK_SET);
|
||||||
|
SDLTest_AssertPass("Call to SDL_RWseek succeeded");
|
||||||
|
SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (SDL_RW_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
|
||||||
|
|
||||||
|
/* Test printf */
|
||||||
|
s = SDL_RWprintf(rw, "%s", RWopsHelloWorldTestString);
|
||||||
|
SDLTest_AssertPass("Call to SDL_RWprintf succeeded");
|
||||||
|
if (write) {
|
||||||
|
SDLTest_AssertCheck(s == sizeof(RWopsHelloWorldTestString) - 1, "Verify result of writing with SDL_RWprintf, expected %i, got %i", (int)sizeof(RWopsHelloWorldTestString) - 1, (int)s);
|
||||||
|
} else {
|
||||||
|
SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int)s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test seek back to start */
|
||||||
|
i = SDL_RWseek(rw, 0, SDL_RW_SEEK_SET);
|
||||||
|
SDLTest_AssertPass("Call to SDL_RWseek succeeded");
|
||||||
|
SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (SDL_RW_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
|
||||||
|
|
||||||
/* Test read */
|
/* Test read */
|
||||||
s = SDL_RWread(rw, buf, sizeof(RWopsHelloWorldTestString) - 1);
|
s = SDL_RWread(rw, buf, sizeof(RWopsHelloWorldTestString) - 1);
|
||||||
SDLTest_AssertPass("Call to SDL_RWread succeeded");
|
SDLTest_AssertPass("Call to SDL_RWread succeeded");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue