From 3a20274ddff20d9c3ea4895353b23ff252954b87 Mon Sep 17 00:00:00 2001 From: Christoph Reichenbach Date: Sat, 4 Jun 2022 20:16:28 +0000 Subject: [PATCH] Refactoring: move GUID operations out of Joystick - SDL_JoystickGUID -> SDL_GUID (though we retain a type alias) - Operations for GUID <-> String ops are now in src/SDL_guid.c and include/SDL_guid.h - The corresponding Joystick operations delegate to SDL_guid.c - Added test/testguid.c --- Makefile.in | 1 + Makefile.os2 | 2 +- Makefile.w32 | 2 +- VisualC-WinRT/SDL-UWP.vcxproj | 2 + VisualC-WinRT/SDL-UWP.vcxproj.filters | 6 + VisualC/SDL/SDL.vcxproj | 2 + VisualC/SDL/SDL.vcxproj.filters | 4 + include/SDL_guid.h | 100 +++++++++++++++ include/SDL_joystick.h | 5 +- src/SDL_guid.c | 91 ++++++++++++++ src/dynapi/SDL2.exports | 2 + src/dynapi/SDL_dynapi_overrides.h | 2 + src/dynapi/SDL_dynapi_procs.h | 2 + src/joystick/SDL_joystick.c | 59 +-------- test/CMakeLists.txt | 54 ++++---- test/Makefile.in | 6 +- test/testguid.c | 169 ++++++++++++++++++++++++++ test/watcom.mif | 2 +- 18 files changed, 422 insertions(+), 89 deletions(-) create mode 100644 include/SDL_guid.h create mode 100644 src/SDL_guid.c create mode 100644 test/testguid.c diff --git a/Makefile.in b/Makefile.in index 7a4b1ac0f..5b063568f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,6 +80,7 @@ HDRS = \ SDL_filesystem.h \ SDL_gamecontroller.h \ SDL_gesture.h \ + SDL_guid.h \ SDL_haptic.h \ SDL_hidapi.h \ SDL_hints.h \ diff --git a/Makefile.os2 b/Makefile.os2 index 5d19272fe..14b4953d4 100644 --- a/Makefile.os2 +++ b/Makefile.os2 @@ -67,7 +67,7 @@ CFLAGS_DLL+= -DSDL_BUILD_MAJOR_VERSION=$(MAJOR_VERSION) CFLAGS_DLL+= -DSDL_BUILD_MINOR_VERSION=$(MINOR_VERSION) CFLAGS_DLL+= -DSDL_BUILD_MICRO_VERSION=$(MICRO_VERSION) -SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c +SRCS = SDL.c SDL_assert.c SDL_error.c SDL_guid.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc32.c SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c SRCS+= SDL_rwops.c SDL_power.c diff --git a/Makefile.w32 b/Makefile.w32 index e9d7264b5..60775f13f 100644 --- a/Makefile.w32 +++ b/Makefile.w32 @@ -43,7 +43,7 @@ CFLAGS_DLL+= -DSDL_BUILD_MICRO_VERSION=$(MICRO_VERSION) RCFLAGS = -q -r -bt=nt $(INCPATH) -SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c +SRCS = SDL.c SDL_assert.c SDL_error.c SDL_guid.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc32.c SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c SRCS+= SDL_rwops.c SDL_power.c diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj index 5ac747d20..80c837972 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj +++ b/VisualC-WinRT/SDL-UWP.vcxproj @@ -45,6 +45,7 @@ + @@ -301,6 +302,7 @@ + diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters index fbb03f22f..af1553ba4 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj.filters +++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters @@ -63,6 +63,9 @@ Header Files + + Header Files + Header Files @@ -633,6 +636,9 @@ Source Files + + Source Files + Source Files diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 679b6781e..aaeda8717 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -234,6 +234,7 @@ + @@ -367,6 +368,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index 582bba4bf..a3d9d5c80 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -231,6 +231,9 @@ API Headers + + API Headers + API Headers @@ -833,6 +836,7 @@ + diff --git a/include/SDL_guid.h b/include/SDL_guid.h new file mode 100644 index 000000000..ba99f3ca2 --- /dev/null +++ b/include/SDL_guid.h @@ -0,0 +1,100 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_guid.h + * + * Include file for handling ::SDL_GUID values. + */ + +#ifndef SDL_guid_h_ +#define SDL_guid_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An SDL_GUID is a 128-bit identifier for an input device that + * identifies that device across runs of SDL programs on the same + * platform. If the device is detached and then re-attached to a + * different port, or if the base system is rebooted, the device + * should still report the same GUID. + * + * GUIDs are as precise as possible but are not guaranteed to + * distinguish physically distinct but equivalent devices. For + * example, two game controllers from the same vendor with the same + * product ID and revision may have the same GUID. + * + * GUIDs may be platform-dependent (i.e., the same device may report + * different GUIDs on different operating systems). + */ +typedef struct { + Uint8 data[16]; +} SDL_GUID; + +/* Function prototypes */ + +/** + * Get an ASCII string representation for a given ::SDL_GUID. + * + * You should supply at least 33 bytes for pszGUID. + * + * \param guid the ::SDL_GUID you wish to convert to string + * \param pszGUID buffer in which to write the ASCII string + * \param cbGUID the size of pszGUID + * + * \since This function is available since SDL 2.tbd. + * + * \sa SDL_GUIDFromString + */ +extern DECLSPEC void SDLCALL SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a GUID string into a ::SDL_GUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID + * \returns a ::SDL_GUID structure. + * + * \since This function is available since SDL 2.tbd. + * + * \sa SDL_GUIDToString + */ +extern DECLSPEC SDL_GUID SDLCALL SDL_GUIDFromString(const char *pchGUID); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_guid_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index 0c7562bb1..60bd470f8 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -43,6 +43,7 @@ #include "SDL_stdinc.h" #include "SDL_error.h" +#include "SDL_guid.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ @@ -69,9 +70,7 @@ struct _SDL_Joystick; typedef struct _SDL_Joystick SDL_Joystick; /* A structure that encodes the stable unique id for a joystick device */ -typedef struct { - Uint8 data[16]; -} SDL_JoystickGUID; +typedef SDL_GUID SDL_JoystickGUID; /** * This is a unique ID for a joystick for the time it is connected to the system, diff --git a/src/SDL_guid.c b/src/SDL_guid.c new file mode 100644 index 000000000..d3529b728 --- /dev/null +++ b/src/SDL_guid.c @@ -0,0 +1,91 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + + +#include "SDL_guid.h" + +/* convert the guid to a printable string */ +void SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID) +{ + static const char k_rgchHexToASCII[] = "0123456789abcdef"; + int i; + + if ((pszGUID == NULL) || (cbGUID <= 0)) { + return; + } + + for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) { + /* each input byte writes 2 ascii chars, and might write a null byte. */ + /* If we don't have room for next input byte, stop */ + unsigned char c = guid.data[i]; + + *pszGUID++ = k_rgchHexToASCII[c >> 4]; + *pszGUID++ = k_rgchHexToASCII[c & 0x0F]; + } + *pszGUID = '\0'; +} + +/*----------------------------------------------------------------------------- + * Purpose: Returns the 4 bit nibble for a hex character + * Input : c - + * Output : unsigned char + *-----------------------------------------------------------------------------*/ +static unsigned char nibble(unsigned char c) +{ + if ((c >= '0') && (c <= '9')) { + return (c - '0'); + } + + if ((c >= 'A') && (c <= 'F')) { + return (c - 'A' + 0x0a); + } + + if ((c >= 'a') && (c <= 'f')) { + return (c - 'a' + 0x0a); + } + + /* received an invalid character, and no real way to return an error */ + /* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */ + return 0; +} + +/* convert the string version of a guid to the struct */ +SDL_GUID SDL_GUIDFromString(const char *pchGUID) +{ + SDL_GUID guid; + int maxoutputbytes= sizeof(guid); + size_t len = SDL_strlen(pchGUID); + Uint8 *p; + size_t i; + + /* Make sure it's even */ + len = (len) & ~0x1; + + SDL_memset(&guid, 0x00, sizeof(guid)); + + p = (Uint8 *)&guid; + for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) { + *p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i+1]); + } + + return guid; +} diff --git a/src/dynapi/SDL2.exports b/src/dynapi/SDL2.exports index 9c6dac42f..8cd2a4bf8 100644 --- a/src/dynapi/SDL2.exports +++ b/src/dynapi/SDL2.exports @@ -843,3 +843,5 @@ ++'_SDL_JoystickAttachVirtualEx'.'SDL2.dll'.'SDL_JoystickAttachVirtualEx' ++'_SDL_GameControllerGetFirmwareVersion'.'SDL2.dll'.'SDL_GameControllerGetFirmwareVersion' ++'_SDL_JoystickGetFirmwareVersion'.'SDL2.dll'.'SDL_JoystickGetFirmwareVersion' +++'_SDL_GUIDToString'.'SDL2.dll'.'SDL_GUIDToString' +++'_SDL_GUIDFromString'.'SDL2.dll'.'SDL_GUIDFromString' diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 3e4c2588a..85ee397d0 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -869,3 +869,5 @@ #define SDL_JoystickAttachVirtualEx SDL_JoystickAttachVirtualEx_REAL #define SDL_GameControllerGetFirmwareVersion SDL_GameControllerGetFirmwareVersion_REAL #define SDL_JoystickGetFirmwareVersion SDL_JoystickGetFirmwareVersion_REAL +#define SDL_GUIDToString SDL_GUIDToString_REAL +#define SDL_GUIDFromString SDL_GUIDFromString_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index f3164760c..db3f86470 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -944,3 +944,5 @@ SDL_DYNAPI_PROC(const char*,SDL_JoystickPath,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(int,SDL_JoystickAttachVirtualEx,(const SDL_VirtualJoystickDesc *a),(a),return) SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetFirmwareVersion,(SDL_GameController *a),(a),return) SDL_DYNAPI_PROC(Uint16,SDL_JoystickGetFirmwareVersion,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(void,SDL_GUIDToString,(SDL_GUID a, char *b, int c),(a,b,c),) +SDL_DYNAPI_PROC(SDL_GUID,SDL_GUIDFromString,(const char *a),(a),return) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index ae4f5dc9b..2d31578e8 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -2735,68 +2735,13 @@ SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick) /* convert the guid to a printable string */ void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID) { - static const char k_rgchHexToASCII[] = "0123456789abcdef"; - int i; - - if ((pszGUID == NULL) || (cbGUID <= 0)) { - return; - } - - for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) { - /* each input byte writes 2 ascii chars, and might write a null byte. */ - /* If we don't have room for next input byte, stop */ - unsigned char c = guid.data[i]; - - *pszGUID++ = k_rgchHexToASCII[c >> 4]; - *pszGUID++ = k_rgchHexToASCII[c & 0x0F]; - } - *pszGUID = '\0'; -} - -/*----------------------------------------------------------------------------- - * Purpose: Returns the 4 bit nibble for a hex character - * Input : c - - * Output : unsigned char - *-----------------------------------------------------------------------------*/ -static unsigned char nibble(unsigned char c) -{ - if ((c >= '0') && (c <= '9')) { - return (c - '0'); - } - - if ((c >= 'A') && (c <= 'F')) { - return (c - 'A' + 0x0a); - } - - if ((c >= 'a') && (c <= 'f')) { - return (c - 'a' + 0x0a); - } - - /* received an invalid character, and no real way to return an error */ - /* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */ - return 0; + SDL_GUIDToString(guid, pszGUID, cbGUID); } /* convert the string version of a joystick guid to the struct */ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) { - SDL_JoystickGUID guid; - int maxoutputbytes= sizeof(guid); - size_t len = SDL_strlen(pchGUID); - Uint8 *p; - size_t i; - - /* Make sure it's even */ - len = (len) & ~0x1; - - SDL_memset(&guid, 0x00, sizeof(guid)); - - p = (Uint8 *)&guid; - for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) { - *p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i+1]); - } - - return guid; + return SDL_GUIDFromString(pchGUID); } /* update the power level for this joystick */ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index da3482b1c..327393541 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -85,6 +85,7 @@ add_executable(testgesture testgesture.c) add_executable(testgl2 testgl2.c) add_executable(testgles testgles.c) add_executable(testgles2 testgles2.c) +add_executable(testguid testguid.c) add_executable(testhaptic testhaptic.c) add_executable(testhotplug testhotplug.c) add_executable(testrumble testrumble.c) @@ -166,6 +167,7 @@ SET(ALL_TESTS testgl2 testgles testgles2 + testguid testhaptic testhittesting testhotplug @@ -214,6 +216,7 @@ set(NONINTERACTIVE testatomic testerror testfilesystem + testguid testlocale testplatform testpower @@ -313,35 +316,36 @@ if(PSP) # Build EBOOT files if building for PSP set(BUILD_EBOOT ${NEEDS_RESOURCES} - testbounds - testgl2 - testsem - testdisplayinfo - teststreaming - testgeometry - testfile - testdraw2 - testviewport - testhittesting - testoverlay2 - testver - testdrawchessboard - testsurround - testintersections - testmessage - testaudiocapture - testerror testatomic - testjoystick - testiconv - testfilesystem - testplatform - testthread - testqsort + testaudiocapture testaudioinfo + testbounds + testdisplayinfo + testdraw2 + testdrawchessboard + testerror + testfile + testfilesystem + testgeometry + testgl2 + testguid + testhittesting + testiconv + testintersections + testjoystick testlock - testtimer + testmessage + testoverlay2 + testplatform testpower + testqsort + testsem + teststreaming + testsurround + testthread + testtimer + testver + testviewport testwm2 torturethread ) diff --git a/test/Makefile.in b/test/Makefile.in index e3e6db991..9fc38f230 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -40,6 +40,7 @@ TARGETS = \ testgamecontroller$(EXE) \ testgeometry$(EXE) \ testgesture$(EXE) \ + testguid$(EXE) \ testhaptic$(EXE) \ testhittesting$(EXE) \ testhotplug$(EXE) \ @@ -201,7 +202,7 @@ testgeometry$(EXE): $(srcdir)/testgeometry.c $(srcdir)/testutils.c testgesture$(EXE): $(srcdir)/testgesture.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ - + testgl2$(EXE): $(srcdir)/testgl2.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ @@ -214,6 +215,9 @@ testgles2$(EXE): $(srcdir)/testgles2.c testgles2_sdf$(EXE): $(srcdir)/testgles2_sdf.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ +testguid$(EXE): $(srcdir)/testguid.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + testhaptic$(EXE): $(srcdir)/testhaptic.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) diff --git a/test/testguid.c b/test/testguid.c new file mode 100644 index 000000000..3b2b90f17 --- /dev/null +++ b/test/testguid.c @@ -0,0 +1,169 @@ +/* + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +/** + * Automated tests for GUID processing + */ + +#include + +#include "SDL.h" + +/* Helpers */ + +static int _error_count = 0; + +static int +_require_eq(Uint64 expected, Uint64 actual, int line, char *msg) +{ + if (expected != actual) { + _error_count += 1; + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "[%s, L%d] %s: Actual %ld (0x%lx) != expected %ld (0x%lx)", + __FILE__, line, msg, actual, actual, expected, expected); + return 0; + } + return 1; +} + +#define ASSERT_EQ(MSG, EXPECTED, ACTUAL) _require_eq((EXPECTED), (ACTUAL), __LINE__, (MSG)) + +/* Helpers */ + +#define NUM_TEST_GUIDS 5 + +static struct { + char *str; + Uint64 upper, lower; +} test_guids[NUM_TEST_GUIDS] = { + { "0000000000000000" "ffffffffffffffff", + 0x0000000000000000, 0xfffffffffffffffflu }, + { "0011223344556677" "8091a2b3c4d5e6f0", + 0x0011223344556677lu, 0x8091a2b3c4d5e6f0lu }, + { "a011223344556677" "8091a2b3c4d5e6f0", + 0xa011223344556677lu, 0x8091a2b3c4d5e6f0lu }, + { "a011223344556677" "8091a2b3c4d5e6f1", + 0xa011223344556677lu, 0x8091a2b3c4d5e6f1lu }, + { "a011223344556677" "8191a2b3c4d5e6f0", + 0xa011223344556677lu, 0x8191a2b3c4d5e6f0lu }, +}; + +static void +upper_lower_to_bytestring(Uint8* out, Uint64 upper, Uint64 lower) +{ + Uint64 values[2]; + int i, k; + + values[0] = upper; + values [1] = lower; + + for (i = 0; i < 2; ++i) { + Uint64 v = values[i]; + + for (k = 0; k < 8; ++k) { + *out++ = v >> 56; + v <<= 8; + } + } +} + +/* ================= Test Case Implementation ================== */ + +/** + * @brief Check String-to-GUID conversion + * + * @sa SDL_GUIDFromString + */ +static void +TestGuidFromString(void) +{ + int i; + + for (i = 0; i < NUM_TEST_GUIDS; ++i) { + Uint8 expected[16]; + SDL_GUID guid; + + upper_lower_to_bytestring(expected, + test_guids[i].upper, test_guids[i].lower); + + guid = SDL_GUIDFromString(test_guids[i].str); + if (!ASSERT_EQ("GUID from string", 0, SDL_memcmp(expected, guid.data, 16))) { + SDL_Log(" GUID was: '%s'", test_guids[i].str); + } + } +} + +/** + * @brief Check GUID-to-String conversion + * + * @sa SDL_GUIDToString + */ +static void +TestGuidToString(void) +{ + int i; + + for (i = 0; i < NUM_TEST_GUIDS; ++i) { + const int guid_str_offset = 4; + char guid_str_buf[64]; + char *guid_str = guid_str_buf + guid_str_offset; + SDL_GUID guid; + int size; + + upper_lower_to_bytestring(guid.data, + test_guids[i].upper, test_guids[i].lower); + + /* Serialise to limited-length buffers */ + for (size = 0; size <= 36; ++size) { + const Uint8 fill_char = size + 0xa0; + Uint32 expected_prefix; + Uint32 actual_prefix; + int written_size; + + SDL_memset(guid_str_buf, fill_char, sizeof(guid_str_buf)); + SDL_GUIDToString(guid, guid_str, size); + + /* Check bytes before guid_str_buf */ + expected_prefix = fill_char | (fill_char << 8) | (fill_char << 16) | (fill_char << 24); + SDL_memcpy(&actual_prefix, guid_str_buf, 4); + if (!ASSERT_EQ("String buffer memory before output untouched: ", expected_prefix, actual_prefix)) { + SDL_Log(" at size=%d", size); + } + + /* Check that we did not overwrite too much */ + written_size = 0; + while ((guid_str[written_size] & 0xff) != fill_char && written_size < 256) { + ++written_size; + } + if (!ASSERT_EQ("Output length is within expected bounds", 1, written_size <= size)) { + SDL_Log(" with lenght %d: wrote %d of %d permitted bytes", + size, written_size, size); + } + if (size >= 33) { + if (!ASSERT_EQ("GUID string equality", 0, SDL_strcmp(guid_str, test_guids[i].str))) { + SDL_Log(" from string: %s", test_guids[i].str); + } + } + } + } +} + +int +main(int argc, char *argv[]) +{ + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + TestGuidFromString(); + TestGuidToString(); + + return _error_count > 0; +} diff --git a/test/watcom.mif b/test/watcom.mif index dbeec5ddd..ad759a845 100644 --- a/test/watcom.mif +++ b/test/watcom.mif @@ -11,7 +11,7 @@ TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe & testdrawchessboard.exe testdropfile.exe testerror.exe testfile.exe & testfilesystem.exe testgamecontroller.exe testgeometry.exe testgesture.exe & testhittesting.exe testhotplug.exe testiconv.exe testime.exe testlocale.exe & - testintersections.exe testjoystick.exe testkeys.exe testloadso.exe & + testguid.exe testintersections.exe testjoystick.exe testkeys.exe testloadso.exe & testlock.exe testmessage.exe testoverlay2.exe testplatform.exe & testpower.exe testsensor.exe testrelative.exe testrendercopyex.exe & testrendertarget.exe testrumble.exe testscale.exe testsem.exe &