From 30f41c02aec763d32e62351452da9ef582bc3472 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 6 Mar 2026 13:30:59 -0800 Subject: Move contrib libraries to contrib repo --- .../SDL-3.2.8/build-scripts/SDL_migration.cocci | 3836 -------------------- .../build-scripts/add-source-to-projects.pl | 599 --- .../SDL-3.2.8/build-scripts/androidbuildlibs.sh | 78 - contrib/SDL-3.2.8/build-scripts/build-release.py | 1556 -------- .../SDL-3.2.8/build-scripts/build-web-examples.pl | 420 --- contrib/SDL-3.2.8/build-scripts/casefolding.txt | 1627 --------- .../SDL-3.2.8/build-scripts/check_android_jni.py | 172 - .../SDL-3.2.8/build-scripts/check_stdlib_usage.py | 262 -- .../SDL-3.2.8/build-scripts/clang-format-src.sh | 39 - .../cmake-toolchain-mingw64-i686.cmake | 18 - .../cmake-toolchain-mingw64-x86_64.cmake | 18 - .../cmake-toolchain-qnx-aarch64le.cmake | 14 - .../build-scripts/cmake-toolchain-qnx-x86_64.cmake | 14 - .../build-scripts/codechecker-buildbot.sh | 59 - .../build-scripts/create-android-project.py | 241 -- contrib/SDL-3.2.8/build-scripts/create-release.py | 45 - contrib/SDL-3.2.8/build-scripts/fnsince.pl | 169 - .../build-scripts/gen_audio_channel_conversion.c | 461 --- .../SDL-3.2.8/build-scripts/git-pre-push-hook.pl | 78 - .../build-scripts/makecasefoldhashtable.pl | 322 -- contrib/SDL-3.2.8/build-scripts/mkinstalldirs | 162 - .../pkg-support/android/INSTALL.md.in | 91 - .../pkg-support/android/aar/__main__.py.in | 104 - .../android/aar/cmake/SDL3ConfigVersion.cmake.in | 38 - .../pkg-support/android/aar/description.json.in | 5 - .../build-scripts/pkg-support/mingw/INSTALL.md.in | 53 - .../build-scripts/pkg-support/mingw/Makefile | 39 - .../pkg-support/msvc/Directory.Build.props | 8 - .../build-scripts/pkg-support/msvc/INSTALL.md.in | 45 - .../pkg-support/msvc/arm64/INSTALL.md.in | 13 - .../pkg-support/msvc/cmake/SDL3Config.cmake.in | 135 - .../msvc/cmake/SDL3ConfigVersion.cmake.in | 38 - .../pkg-support/msvc/x64/INSTALL.md.in | 13 - .../pkg-support/msvc/x86/INSTALL.md.in | 13 - .../pkg-support/source/SDL_revision.h.cmake.in | 41 - .../pkg-support/source/SDL_revision.h.in | 56 - contrib/SDL-3.2.8/build-scripts/release-info.json | 210 -- contrib/SDL-3.2.8/build-scripts/rename_api.py | 254 -- contrib/SDL-3.2.8/build-scripts/rename_headers.py | 75 - contrib/SDL-3.2.8/build-scripts/rename_macros.py | 382 -- contrib/SDL-3.2.8/build-scripts/rename_symbols.py | 130 - contrib/SDL-3.2.8/build-scripts/rename_types.py | 80 - .../SDL-3.2.8/build-scripts/setup-gdk-desktop.py | 303 -- contrib/SDL-3.2.8/build-scripts/showrev.sh | 48 - contrib/SDL-3.2.8/build-scripts/strip_fPIC.sh | 21 - contrib/SDL-3.2.8/build-scripts/test-versioning.sh | 170 - .../SDL-3.2.8/build-scripts/update-copyright.sh | 15 - contrib/SDL-3.2.8/build-scripts/update-version.sh | 81 - contrib/SDL-3.2.8/build-scripts/updaterev.sh | 48 - contrib/SDL-3.2.8/build-scripts/wikiheaders.pl | 3360 ----------------- 50 files changed, 16059 deletions(-) delete mode 100644 contrib/SDL-3.2.8/build-scripts/SDL_migration.cocci delete mode 100755 contrib/SDL-3.2.8/build-scripts/add-source-to-projects.pl delete mode 100755 contrib/SDL-3.2.8/build-scripts/androidbuildlibs.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/build-release.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/build-web-examples.pl delete mode 100644 contrib/SDL-3.2.8/build-scripts/casefolding.txt delete mode 100755 contrib/SDL-3.2.8/build-scripts/check_android_jni.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/check_stdlib_usage.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/clang-format-src.sh delete mode 100644 contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-i686.cmake delete mode 100644 contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-x86_64.cmake delete mode 100644 contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-aarch64le.cmake delete mode 100644 contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-x86_64.cmake delete mode 100755 contrib/SDL-3.2.8/build-scripts/codechecker-buildbot.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/create-android-project.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/create-release.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/fnsince.pl delete mode 100644 contrib/SDL-3.2.8/build-scripts/gen_audio_channel_conversion.c delete mode 100755 contrib/SDL-3.2.8/build-scripts/git-pre-push-hook.pl delete mode 100755 contrib/SDL-3.2.8/build-scripts/makecasefoldhashtable.pl delete mode 100755 contrib/SDL-3.2.8/build-scripts/mkinstalldirs delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/android/INSTALL.md.in delete mode 100755 contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/__main__.py.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/description.json.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/INSTALL.md.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/Makefile delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/Directory.Build.props delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/INSTALL.md.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/arm64/INSTALL.md.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3ConfigVersion.cmake.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x64/INSTALL.md.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x86/INSTALL.md.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.cmake.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.in delete mode 100644 contrib/SDL-3.2.8/build-scripts/release-info.json delete mode 100755 contrib/SDL-3.2.8/build-scripts/rename_api.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/rename_headers.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/rename_macros.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/rename_symbols.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/rename_types.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/setup-gdk-desktop.py delete mode 100755 contrib/SDL-3.2.8/build-scripts/showrev.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/strip_fPIC.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/test-versioning.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/update-copyright.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/update-version.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/updaterev.sh delete mode 100755 contrib/SDL-3.2.8/build-scripts/wikiheaders.pl (limited to 'contrib/SDL-3.2.8/build-scripts') diff --git a/contrib/SDL-3.2.8/build-scripts/SDL_migration.cocci b/contrib/SDL-3.2.8/build-scripts/SDL_migration.cocci deleted file mode 100644 index 38655af..0000000 --- a/contrib/SDL-3.2.8/build-scripts/SDL_migration.cocci +++ /dev/null @@ -1,3836 +0,0 @@ -// -// This is a coccinelle semantic patch to ease migration of your project from SDL2 to SDL3. -// -// It generates a patch that you can apply to your project to build for SDL3. It does not -// handle conceptual API changes, but it automates API name changes and function parameter -// transformations. -// -// To install (native Ubuntu or using WSL on Windows): -// sudo apt install coccinelle -// -// Apply the semantic patch to generate a patch file: -// cd path/to/your/code -// spatch --sp-file path/to/SDL_migration.cocci . >patch.txt -// -// A few options: -// --c++=11 to parse cpp file -// --max-width 200 to increase line width of generated source -// -// Apply the patch to your project: -// patch -p1 0 ? 0 : -1 - -@ depends on rule_audio_open @ -@@ -{ -+ /* FIXME MIGRATION: maybe move this to a global scope ? */ -+ SDL_AudioDeviceID g_audio_id = -1; -... -SDL_OpenAudioDevice(...) -... -} - -@@ -@@ -- SDL_LockAudio() -+ SDL_LockAudioDevice(g_audio_id) - -@@ -@@ -- SDL_UnlockAudio() -+ SDL_UnlockAudioDevice(g_audio_id) - -@@ -@@ -- SDL_CloseAudio(void) -+ SDL_CloseAudioDevice(g_audio_id) - -@@ -expression e; -@@ -- SDL_PauseAudio(e) -+ e ? SDL_PauseAudioDevice(g_audio_id) : SDL_PlayAudioDevice(g_audio_id) - -@@ -@@ -- SDL_GetAudioStatus() -+ SDL_GetAudioDeviceStatus(g_audio_id) - -@@ -@@ -- SDL_GetQueuedAudioSize(1) -+ SDL_GetQueuedAudioSize(g_audio_id) - -@@ -expression e1, e2; -@@ -- SDL_QueueAudio(1, e1, e2) -+ SDL_QueueAudio(g_audio_id, e1, e2) - - - - -// SDL_EventState() - replaced with SDL_SetEventEnabled() -@@ -expression e1; -@@ -( -- SDL_EventState(e1, SDL_IGNORE) -+ SDL_SetEventEnabled(e1, false) -| -- SDL_EventState(e1, SDL_DISABLE) -+ SDL_SetEventEnabled(e1, false) -| -- SDL_EventState(e1, SDL_ENABLE) -+ SDL_SetEventEnabled(e1, true) -| -- SDL_EventState(e1, SDL_QUERY) -+ SDL_EventEnabled(e1) -) - -// SDL_GetEventState() - replaced with SDL_EventEnabled() -@@ -expression e1; -@@ -- SDL_GetEventState(e1) -+ SDL_EventEnabled(e1) - -@@ -expression e; -@@ -- SDL_JoystickGetDevicePlayerIndex(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_GetJoystickInstancePlayerIndex(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_JoystickIsVirtual(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_IsJoystickVirtual(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_JoystickPathForIndex(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_GetJoystickInstancePath(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_IsGameController(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_IsGamepad(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_GameControllerMappingForDeviceIndex(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_GetGamepadInstanceMapping(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_GameControllerNameForIndex(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_GetGamepadInstanceName(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_GameControllerPathForIndex(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_GetGamepadInstancePath(GetJoystickInstanceFromIndex(e)) - -@@ -expression e; -@@ -- SDL_GameControllerTypeForIndex(e) -+ /* FIXME MIGRATION: check for valid instance */ -+ SDL_GetGamepadInstanceType(GetJoystickInstanceFromIndex(e)) - - -// SDL_Has3DNow() has been removed; there is no replacement. -@@ -@@ -+ /* FIXME MIGRATION: SDL_Has3DNow() has been removed; there is no replacement. */ 0 -- SDL_Has3DNow() - -// SDL_HasRDTSC() has been removed; there is no replacement. -@@ -@@ -+ /* FIXME MIGRATION: SDL_HasRDTSC() has been removed; there is no replacement. */ 0 -- SDL_HasRDTSC() - -// SDL_HINT_VIDEO_X11_XINERAMA (Xinerama no longer supported by the X11 backend) -@@ -@@ -+ /* FIXME MIGRATION: no longer support by the X11 backend */ NULL -- SDL_HINT_VIDEO_X11_XINERAMA - -// SDL_HINT_VIDEO_X11_XVIDMODE (Xvidmode no longer supported by the X11 backend) -@@ -@@ -+ /* FIXME MIGRATION: no longer support by the X11 backend */ NULL -- SDL_HINT_VIDEO_X11_XVIDMODE - -// SDL_HINT_VIDEO_X11_FORCE_EGL (use SDL_HINT_VIDEO_FORCE_EGL instead) -@@ -@@ -- SDL_HINT_VIDEO_X11_FORCE_EGL -+ SDL_HINT_VIDEO_FORCE_EGL - -@@ -@@ -- SDL_HINT_AUDIODRIVER -+ SDL_HINT_AUDIO_DRIVER - -@@ -@@ -- SDL_HINT_VIDEODRIVER -+ SDL_HINT_VIDEO_DRIVER - -// SDL_GetRevisionNumber() has been removed from the API, it always returned 0 in SDL 2.0. -@@ -@@ -+ /* FIXME MIGRATION: SDL_GetRevisionNumber() removed */ 0 -- SDL_GetRevisionNumber() - -// SDL_RWread -@ rule_rwread @ -expression e1, e2, e3, e4; -identifier i; -@@ -( - i = SDL_RWread(e1, e2, -- e3, e4); -+ e3 * e4); -+ i = (i <= 0) ? 0 : i / e3; -| - SDL_RWread(e1, e2, -- e3, e4); -+ e3 * e4); -| -+ /* FIXME MIGRATION: double-check if you use the returned value of SDL_RWread() */ - SDL_RWread(e1, e2, -- e3, e4) -+ e3 * e4) - -) - -// SDL_RWwrite -@ rule_rwwrite @ -expression e1, e2, e3, e4; -identifier i; -@@ -( - i = SDL_RWwrite(e1, e2, -- e3, e4); -+ e3 * e4); -+ i = (i <= 0) ? 0 : i / e3; -| - SDL_RWwrite(e1, e2, -- e3, e4); -+ e3 * e4); -| -+ /* FIXME MIGRATION: double-check if you use the returned value of SDL_RWwrite() */ - SDL_RWwrite(e1, e2, -- e3, e4) -+ e3 * e4) -) - -@ depends on rule_rwread || rule_rwwrite @ -expression e; -@@ -( -- e * 1 -+ e -| -- e / 1 -+ e -) - -// SDL_SIMDAlloc(), SDL_SIMDFree() have been removed. -@@ -expression e1; -@@ -- SDL_SIMDAlloc(e1) -+ SDL_aligned_alloc(SDL_SIMDGetAlignment(), e1) - -@@ -expression e1; -@@ -- SDL_SIMDFree( -+ SDL_aligned_free( - e1) - -// SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter. -@@ -expression e1, e2, e3; -@@ - SDL_Vulkan_GetInstanceExtensions( -- e1, - e2, e3) - -// SDL_Vulkan_GetVkGetInstanceProcAddr() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to PFN_vkGetInstanceProcAddr. -@@ -typedef PFN_vkGetInstanceProcAddr; -@@ -( - (PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr() -| -+ (PFN_vkGetInstanceProcAddr) - SDL_Vulkan_GetVkGetInstanceProcAddr() -) - -// SDL_PauseAudioDevice / SDL_PlayAudioDevice -@@ -expression e; -@@ -( -- SDL_PauseAudioDevice(e, 1) -+ SDL_PauseAudioDevice(e) -| -- SDL_PauseAudioDevice(e, SDL_TRUE) -+ SDL_PauseAudioDevice(e) -| -- SDL_PauseAudioDevice(e, 0) -+ SDL_ResumeAudioDevice(e) -| -- SDL_PauseAudioDevice(e, SDL_FALSE) -+ SDL_ResumeAudioDevice(e) -) - -@@ -expression e, pause_on; -@@ -- SDL_PauseAudioDevice(e, pause_on); -+ if (pause_on) { -+ SDL_PauseAudioDevice(e); -+ } else { -+ SDL_ResumeAudioDevice(e); -+ } - - -// Remove SDL_WINDOW_SHOWN -@@ -expression e; -@@ -( -- SDL_WINDOW_SHOWN | e -+ e -| -- SDL_WINDOW_SHOWN -+ 0 -) - - -@@ -// Remove parameter from SDL_ConvertSurface -expression e1, e2, e3; -@@ -SDL_ConvertSurface(e1, e2 -- ,e3) -+ ) - - -@@ -// Remove parameter from SDL_ConvertSurfaceFormat -expression e1, e2, e3; -@@ -SDL_ConvertSurfaceFormat(e1, e2 -- ,e3) -+ ) - - -@@ -// SDL_CreateRGBSurfaceWithFormat -// remove 'flags' -// remove 'depth' -// rename to SDL_CreateSurface -expression e1, e2, e3, e4, e5; -@@ -- SDL_CreateRGBSurfaceWithFormat(e1, e2, e3, e4, e5) -+ SDL_CreateSurface(e2, e3, e5) - - -@@ -// SDL_CreateRGBSurfaceWithFormat: -// remove 'depth' -// rename to SDL_CreateSurfaceFrom -expression e1, e2, e3, e4, e5, e6; -@@ -- SDL_CreateRGBSurfaceWithFormatFrom(e1, e2, e3, e4, e5, e6) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e5, e6) - - - -@@ -// SDL_CreateRGBSurface : convert Masks to format -expression e1, e2, e3, e4, e5, e6, e7, e8, e9; - -@@ - -( - -// Generated for all formats: - -- SDL_CreateRGBSurface(e1, e2, e3, 1, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_INDEX1LSB) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 1, e4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_INDEX1LSB) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 1, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_INDEX1MSB) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 1, e4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_INDEX1MSB) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_INDEX4LSB) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 4, e4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_INDEX4LSB) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_INDEX4MSB) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 4, e4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_INDEX4MSB) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 8, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_INDEX8) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 8, e4, 0x00000000, 0x00000000, 0x00000000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_INDEX8) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 8, 0x000000E0, 0x0000001C, 0x00000003, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGB332) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 8, e4, 0x000000E0, 0x0000001C, 0x00000003, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGB332) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 12, 0x00000F00, 0x000000F0, 0x0000000F, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGB444) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 12, e4, 0x00000F00, 0x000000F0, 0x0000000F, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGB444) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 15, 0x00007C00, 0x000003E0, 0x0000001F, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGB555) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 15, e4, 0x00007C00, 0x000003E0, 0x0000001F, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGB555) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 15, 0x0000001F, 0x000003E0, 0x00007C00, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGR555) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 15, e4, 0x0000001F, 0x000003E0, 0x00007C00, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGR555) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x00000F00, 0x000000F0, 0x0000000F, 0x0000F000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ARGB4444) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x00000F00, 0x000000F0, 0x0000000F, 0x0000F000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ARGB4444) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000F000, 0x00000F00, 0x000000F0, 0x0000000F) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGBA4444) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000F000, 0x00000F00, 0x000000F0, 0x0000000F) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGBA4444) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ABGR4444) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ABGR4444) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x000000F0, 0x00000F00, 0x0000F000, 0x0000000F) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGRA4444) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x000000F0, 0x00000F00, 0x0000F000, 0x0000000F) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGRA4444) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x00007C00, 0x000003E0, 0x0000001F, 0x00008000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ARGB1555) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x00007C00, 0x000003E0, 0x0000001F, 0x00008000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ARGB1555) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000F800, 0x000007C0, 0x0000003E, 0x00000001) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGBA5551) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000F800, 0x000007C0, 0x0000003E, 0x00000001) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGBA5551) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000001F, 0x000003E0, 0x00007C00, 0x00008000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ABGR1555) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000001F, 0x000003E0, 0x00007C00, 0x00008000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ABGR1555) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000003E, 0x000007C0, 0x0000F800, 0x00000001) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGRA5551) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000003E, 0x000007C0, 0x0000F800, 0x00000001) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGRA5551) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGB565) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGB565) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 16, 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGR565) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 16, e4, 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGR565) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGB24) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 24, e4, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGB24) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGR24) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 24, e4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGR24) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_XRGB8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_XRGB8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGBX8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGBX8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_XBGR8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_XBGR8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGRX8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGRX8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ARGB8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ARGB8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_RGBA8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_RGBA8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ABGR8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ABGR8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_BGRA8888) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_BGRA8888) - -| - -- SDL_CreateRGBSurface(e1, e2, e3, 32, 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000) -+ SDL_CreateSurface(e2, e3, SDL_PIXELFORMAT_ARGB2101010) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, 32, e4, 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e4, SDL_PIXELFORMAT_ARGB2101010) - -| - -// End Generated - - -- SDL_CreateRGBSurface(e1, e2, e3, e4->BitsPerPixel, e4->Rmask, e4->Gmask, e4->Bmask, e4->Amask) -+ SDL_CreateSurface(e2, e3, e4->format) - -| - -- SDL_CreateRGBSurfaceFrom(e1, e2, e3, e4->BitsPerPixel, e5, e4->Rmask, e4->Gmask, e4->Bmask, e4->Amask) -+ SDL_CreateSurfaceFrom(e1, e2, e3, e5, e4->format) - -| - --SDL_CreateRGBSurface(e1, e2, e3, e4, e5, e6, e7, e8) -+SDL_CreateSurface(e2, e3, SDL_MasksToPixelFormatEnum(e4, e5, e6, e7, e8)) - -| - --SDL_CreateRGBSurfaceFrom(e1, e2, e3, e4, e5, e6, e7, e8, e9) -+SDL_CreateSurfaceFrom(e1, e2, e3, e5, SDL_MasksToPixelFormatEnum(e4, e6, e7, e8, e9)) - -) - -@@ -// SDL_CreateRenderer: -// 2nd argument changed from int (default=-1) to const char* (default=NULL) -expression e1, e3; -int e2; -@@ - -( - --SDL_CreateRenderer(e1, -1, e3) -+SDL_CreateRenderer(e1, NULL, e3) - -| - --SDL_CreateRenderer(e1, e2, e3) -+SDL_CreateRenderer(e1, SDL_GetRenderDriver(e2), e3) - -) - -// Renaming of SDL_oldnames.h - -@@ -@@ -- SDL_AudioStreamAvailable -+ SDL_GetAudioStreamAvailable - (...) -@@ -@@ -- SDL_AudioStreamClear -+ SDL_ClearAudioStream - (...) -@@ -@@ -- SDL_AudioStreamFlush -+ SDL_FlushAudioStream - (...) -@@ -@@ -- SDL_AudioStreamGet -+ SDL_GetAudioStreamData - (...) -@@ -@@ -- SDL_AudioStreamPut -+ SDL_PutAudioStreamData - (...) -@@ -@@ -- SDL_FreeAudioStream -+ SDL_DestroyAudioStream - (...) -@@ -@@ -- SDL_FreeWAV -+ SDL_free - (...) -@@ -@@ -- SDL_NewAudioStream -+ SDL_CreateAudioStream - (...) -@@ -@@ -- SDL_CONTROLLERAXISMOTION -+ SDL_EVENT_GAMEPAD_AXIS_MOTION -@@ -@@ -- SDL_CONTROLLERBUTTONDOWN -+ SDL_EVENT_GAMEPAD_BUTTON_DOWN -@@ -@@ -- SDL_CONTROLLERBUTTONUP -+ SDL_EVENT_GAMEPAD_BUTTON_UP -@@ -@@ -- SDL_CONTROLLERDEVICEADDED -+ SDL_EVENT_GAMEPAD_ADDED -@@ -@@ -- SDL_CONTROLLERDEVICEREMAPPED -+ SDL_EVENT_GAMEPAD_REMAPPED -@@ -@@ -- SDL_CONTROLLERDEVICEREMOVED -+ SDL_EVENT_GAMEPAD_REMOVED -@@ -@@ -- SDL_CONTROLLERSENSORUPDATE -+ SDL_EVENT_GAMEPAD_SENSOR_UPDATE -@@ -@@ -- SDL_CONTROLLERTOUCHPADDOWN -+ SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN -@@ -@@ -- SDL_CONTROLLERTOUCHPADMOTION -+ SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION -@@ -@@ -- SDL_CONTROLLERTOUCHPADUP -+ SDL_EVENT_GAMEPAD_TOUCHPAD_UP -@@ -typedef SDL_ControllerAxisEvent, SDL_GamepadAxisEvent; -@@ -- SDL_ControllerAxisEvent -+ SDL_GamepadAxisEvent -@@ -typedef SDL_ControllerButtonEvent, SDL_GamepadButtonEvent; -@@ -- SDL_ControllerButtonEvent -+ SDL_GamepadButtonEvent -@@ -typedef SDL_ControllerDeviceEvent, SDL_GamepadDeviceEvent; -@@ -- SDL_ControllerDeviceEvent -+ SDL_GamepadDeviceEvent -@@ -typedef SDL_ControllerSensorEvent, SDL_GamepadSensorEvent; -@@ -- SDL_ControllerSensorEvent -+ SDL_GamepadSensorEvent -@@ -typedef SDL_ControllerTouchpadEvent, SDL_GamepadTouchpadEvent; -@@ -- SDL_ControllerTouchpadEvent -+ SDL_GamepadTouchpadEvent -@@ -@@ -- SDL_CONTROLLER_AXIS_INVALID -+ SDL_GAMEPAD_AXIS_INVALID -@@ -@@ -- SDL_CONTROLLER_AXIS_LEFTX -+ SDL_GAMEPAD_AXIS_LEFTX -@@ -@@ -- SDL_CONTROLLER_AXIS_LEFTY -+ SDL_GAMEPAD_AXIS_LEFTY -@@ -@@ -- SDL_CONTROLLER_AXIS_MAX -+ SDL_GAMEPAD_AXIS_COUNT -@@ -@@ -- SDL_CONTROLLER_AXIS_RIGHTX -+ SDL_GAMEPAD_AXIS_RIGHTX -@@ -@@ -- SDL_CONTROLLER_AXIS_RIGHTY -+ SDL_GAMEPAD_AXIS_RIGHTY -@@ -@@ -- SDL_CONTROLLER_AXIS_TRIGGERLEFT -+ SDL_GAMEPAD_AXIS_LEFT_TRIGGER -@@ -@@ -- SDL_CONTROLLER_AXIS_TRIGGERRIGHT -+ SDL_GAMEPAD_AXIS_RIGHT_TRIGGER -@@ -@@ -- SDL_CONTROLLER_BINDTYPE_AXIS -+ SDL_GAMEPAD_BINDTYPE_AXIS -@@ -@@ -- SDL_CONTROLLER_BINDTYPE_BUTTON -+ SDL_GAMEPAD_BINDTYPE_BUTTON -@@ -@@ -- SDL_CONTROLLER_BINDTYPE_HAT -+ SDL_GAMEPAD_BINDTYPE_HAT -@@ -@@ -- SDL_CONTROLLER_BINDTYPE_NONE -+ SDL_GAMEPAD_BINDTYPE_NONE -@@ -@@ -- SDL_CONTROLLER_BUTTON_A -+ SDL_GAMEPAD_BUTTON_SOUTH -@@ -@@ -- SDL_CONTROLLER_BUTTON_B -+ SDL_GAMEPAD_BUTTON_EAST -@@ -@@ -- SDL_CONTROLLER_BUTTON_BACK -+ SDL_GAMEPAD_BUTTON_BACK -@@ -@@ -- SDL_CONTROLLER_BUTTON_DPAD_DOWN -+ SDL_GAMEPAD_BUTTON_DPAD_DOWN -@@ -@@ -- SDL_CONTROLLER_BUTTON_DPAD_LEFT -+ SDL_GAMEPAD_BUTTON_DPAD_LEFT -@@ -@@ -- SDL_CONTROLLER_BUTTON_DPAD_RIGHT -+ SDL_GAMEPAD_BUTTON_DPAD_RIGHT -@@ -@@ -- SDL_CONTROLLER_BUTTON_DPAD_UP -+ SDL_GAMEPAD_BUTTON_DPAD_UP -@@ -@@ -- SDL_CONTROLLER_BUTTON_GUIDE -+ SDL_GAMEPAD_BUTTON_GUIDE -@@ -@@ -- SDL_CONTROLLER_BUTTON_INVALID -+ SDL_GAMEPAD_BUTTON_INVALID -@@ -@@ -- SDL_CONTROLLER_BUTTON_LEFTSHOULDER -+ SDL_GAMEPAD_BUTTON_LEFT_SHOULDER -@@ -@@ -- SDL_CONTROLLER_BUTTON_LEFTSTICK -+ SDL_GAMEPAD_BUTTON_LEFT_STICK -@@ -@@ -- SDL_CONTROLLER_BUTTON_MAX -+ SDL_GAMEPAD_BUTTON_COUNT -@@ -@@ -- SDL_CONTROLLER_BUTTON_MISC1 -+ SDL_GAMEPAD_BUTTON_MISC1 -@@ -@@ -- SDL_CONTROLLER_BUTTON_PADDLE1 -+ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1 -@@ -@@ -- SDL_CONTROLLER_BUTTON_PADDLE2 -+ SDL_GAMEPAD_BUTTON_LEFT_PADDLE1 -@@ -@@ -- SDL_CONTROLLER_BUTTON_PADDLE3 -+ SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2 -@@ -@@ -- SDL_CONTROLLER_BUTTON_PADDLE4 -+ SDL_GAMEPAD_BUTTON_LEFT_PADDLE2 -@@ -@@ -- SDL_CONTROLLER_BUTTON_RIGHTSHOULDER -+ SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER -@@ -@@ -- SDL_CONTROLLER_BUTTON_RIGHTSTICK -+ SDL_GAMEPAD_BUTTON_RIGHT_STICK -@@ -@@ -- SDL_CONTROLLER_BUTTON_START -+ SDL_GAMEPAD_BUTTON_START -@@ -@@ -- SDL_CONTROLLER_BUTTON_TOUCHPAD -+ SDL_GAMEPAD_BUTTON_TOUCHPAD -@@ -@@ -- SDL_CONTROLLER_BUTTON_X -+ SDL_GAMEPAD_BUTTON_WEST -@@ -@@ -- SDL_CONTROLLER_BUTTON_Y -+ SDL_GAMEPAD_BUTTON_NORTH -@@ -@@ -- SDL_CONTROLLER_TYPE_AMAZON_LUNA -+ SDL_GAMEPAD_TYPE_AMAZON_LUNA -@@ -@@ -- SDL_CONTROLLER_TYPE_GOOGLE_STADIA -+ SDL_GAMEPAD_TYPE_GOOGLE_STADIA -@@ -@@ -- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT -+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT -@@ -@@ -- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR -+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR -@@ -@@ -- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT -+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT -@@ -@@ -- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO -+ SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO -@@ -@@ -- SDL_CONTROLLER_TYPE_NVIDIA_SHIELD -+ SDL_GAMEPAD_TYPE_NVIDIA_SHIELD -@@ -@@ -- SDL_CONTROLLER_TYPE_PS3 -+ SDL_GAMEPAD_TYPE_PS3 -@@ -@@ -- SDL_CONTROLLER_TYPE_PS4 -+ SDL_GAMEPAD_TYPE_PS4 -@@ -@@ -- SDL_CONTROLLER_TYPE_PS5 -+ SDL_GAMEPAD_TYPE_PS5 -@@ -@@ -- SDL_CONTROLLER_TYPE_UNKNOWN -+ SDL_GAMEPAD_TYPE_UNKNOWN -@@ -@@ -- SDL_CONTROLLER_TYPE_VIRTUAL -+ SDL_GAMEPAD_TYPE_VIRTUAL -@@ -@@ -- SDL_CONTROLLER_TYPE_XBOX360 -+ SDL_GAMEPAD_TYPE_XBOX360 -@@ -@@ -- SDL_CONTROLLER_TYPE_XBOXONE -+ SDL_GAMEPAD_TYPE_XBOXONE -@@ -typedef SDL_GameController, SDL_Gamepad; -@@ -- SDL_GameController -+ SDL_Gamepad -@@ -@@ -- SDL_GameControllerAddMapping -+ SDL_AddGamepadMapping - (...) -@@ -@@ -- SDL_GameControllerAddMappingsFromFile -+ SDL_AddGamepadMappingsFromFile - (...) -@@ -@@ -- SDL_GameControllerAddMappingsFromRW -+ SDL_AddGamepadMappingsFromIO - (...) -@@ -typedef SDL_GameControllerAxis, SDL_GamepadAxis; -@@ -- SDL_GameControllerAxis -+ SDL_GamepadAxis -@@ -typedef SDL_GameControllerBindType, SDL_GamepadBindingType; -@@ -- SDL_GameControllerBindType -+ SDL_GamepadBindingType -@@ -typedef SDL_GameControllerButton, SDL_GamepadButton; -@@ -- SDL_GameControllerButton -+ SDL_GamepadButton -@@ -@@ -- SDL_GameControllerClose -+ SDL_CloseGamepad - (...) -@@ -@@ -- SDL_GameControllerFromInstanceID -+ SDL_GetGamepadFromID - (...) -@@ -@@ -- SDL_GameControllerFromPlayerIndex -+ SDL_GetGamepadFromPlayerIndex - (...) -@@ -@@ -- SDL_GameControllerGetAppleSFSymbolsNameForAxis -+ SDL_GetGamepadAppleSFSymbolsNameForAxis - (...) -@@ -@@ -- SDL_GameControllerGetAppleSFSymbolsNameForButton -+ SDL_GetGamepadAppleSFSymbolsNameForButton - (...) -@@ -@@ -- SDL_GameControllerGetAttached -+ SDL_GamepadConnected - (...) -@@ -@@ -- SDL_GameControllerGetAxis -+ SDL_GetGamepadAxis - (...) -@@ -@@ -- SDL_GameControllerGetAxisFromString -+ SDL_GetGamepadAxisFromString - (...) -@@ -@@ -- SDL_GameControllerGetButton -+ SDL_GetGamepadButton - (...) -@@ -@@ -- SDL_GameControllerGetButtonFromString -+ SDL_GetGamepadButtonFromString - (...) -@@ -@@ -- SDL_GameControllerGetFirmwareVersion -+ SDL_GetGamepadFirmwareVersion - (...) -@@ -@@ -- SDL_GameControllerGetJoystick -+ SDL_GetGamepadJoystick - (...) -@@ -@@ -- SDL_GameControllerGetNumTouchpadFingers -+ SDL_GetNumGamepadTouchpadFingers - (...) -@@ -@@ -- SDL_GameControllerGetNumTouchpads -+ SDL_GetNumGamepadTouchpads - (...) -@@ -@@ -- SDL_GameControllerGetPlayerIndex -+ SDL_GetGamepadPlayerIndex - (...) -@@ -@@ -- SDL_GameControllerGetProduct -+ SDL_GetGamepadProduct - (...) -@@ -@@ -- SDL_GameControllerGetProductVersion -+ SDL_GetGamepadProductVersion - (...) -@@ -@@ -- SDL_GameControllerGetSensorData -+ SDL_GetGamepadSensorData - (...) -@@ -@@ -- SDL_GameControllerGetSensorDataRate -+ SDL_GetGamepadSensorDataRate - (...) -@@ -@@ -- SDL_GameControllerGetSerial -+ SDL_GetGamepadSerial - (...) -@@ -@@ -- SDL_GameControllerGetStringForAxis -+ SDL_GetGamepadStringForAxis - (...) -@@ -@@ -- SDL_GameControllerGetStringForButton -+ SDL_GetGamepadStringForButton - (...) -@@ -@@ -- SDL_GameControllerGetTouchpadFinger -+ SDL_GetGamepadTouchpadFinger - (...) -@@ -@@ -- SDL_GameControllerGetType -+ SDL_GetGamepadType - (...) -@@ -@@ -- SDL_GameControllerGetVendor -+ SDL_GetGamepadVendor - (...) -@@ -@@ -- SDL_GameControllerHasAxis -+ SDL_GamepadHasAxis - (...) -@@ -@@ -- SDL_GameControllerHasButton -+ SDL_GamepadHasButton - (...) -@@ -@@ -- SDL_GameControllerHasSensor -+ SDL_GamepadHasSensor - (...) -@@ -@@ -- SDL_GameControllerIsSensorEnabled -+ SDL_GamepadSensorEnabled - (...) -@@ -@@ -- SDL_GameControllerMapping -+ SDL_GetGamepadMapping - (...) -@@ -@@ -- SDL_GameControllerMappingForGUID -+ SDL_GetGamepadMappingForGUID - (...) -@@ -@@ -- SDL_GameControllerName -+ SDL_GetGamepadName - (...) -@@ -@@ -- SDL_GameControllerOpen -+ SDL_OpenGamepad - (...) -@@ -@@ -- SDL_GameControllerPath -+ SDL_GetGamepadPath - (...) -@@ -@@ -- SDL_GameControllerRumble -+ SDL_RumbleGamepad - (...) -@@ -@@ -- SDL_GameControllerRumbleTriggers -+ SDL_RumbleGamepadTriggers - (...) -@@ -@@ -- SDL_GameControllerSendEffect -+ SDL_SendGamepadEffect - (...) -@@ -@@ -- SDL_GameControllerSetLED -+ SDL_SetGamepadLED - (...) -@@ -@@ -- SDL_GameControllerSetPlayerIndex -+ SDL_SetGamepadPlayerIndex - (...) -@@ -@@ -- SDL_GameControllerSetSensorEnabled -+ SDL_SetGamepadSensorEnabled - (...) -@@ -@@ -- SDL_GameControllerType -+ SDL_GamepadType - (...) -@@ -@@ -- SDL_GameControllerUpdate -+ SDL_UpdateGamepads - (...) -@@ -@@ -- SDL_INIT_GAMECONTROLLER -+ SDL_INIT_GAMEPAD -@ rule_init_noparachute @ -@@ -- SDL_INIT_NOPARACHUTE -+ 0 -@@ -@@ -- SDL_JOYSTICK_TYPE_GAMECONTROLLER -+ SDL_JOYSTICK_TYPE_GAMEPAD -@@ -@@ -- SDL_JoystickAttachVirtualEx -+ SDL_AttachVirtualJoystick - (...) -@@ -@@ -- SDL_JoystickClose -+ SDL_CloseJoystick - (...) -@@ -@@ -- SDL_JoystickCurrentPowerLevel -+ SDL_GetJoystickPowerLevel - (...) -@@ -@@ -- SDL_JoystickDetachVirtual -+ SDL_DetachVirtualJoystick - (...) -@@ -@@ -- SDL_JoystickFromInstanceID -+ SDL_GetJoystickFromID - (...) -@@ -@@ -- SDL_JoystickFromPlayerIndex -+ SDL_GetJoystickFromPlayerIndex - (...) -@@ -@@ -- SDL_JoystickGetAttached -+ SDL_JoystickConnected - (...) -@@ -@@ -- SDL_JoystickGetAxis -+ SDL_GetJoystickAxis - (...) -@@ -@@ -- SDL_JoystickGetAxisInitialState -+ SDL_GetJoystickAxisInitialState - (...) -@@ -@@ -- SDL_JoystickGetButton -+ SDL_GetJoystickButton - (...) -@@ -@@ -- SDL_JoystickGetFirmwareVersion -+ SDL_GetJoystickFirmwareVersion - (...) -@@ -@@ -- SDL_JoystickGetGUID -+ SDL_GetJoystickGUID - (...) -@@ -@@ -- SDL_JoystickGetGUIDFromString -+ SDL_StringToGUID - (...) -@@ -@@ -- SDL_JoystickGetHat -+ SDL_GetJoystickHat - (...) -@@ -@@ -- SDL_JoystickGetPlayerIndex -+ SDL_GetJoystickPlayerIndex - (...) -@@ -@@ -- SDL_JoystickGetProduct -+ SDL_GetJoystickProduct - (...) -@@ -@@ -- SDL_JoystickGetProductVersion -+ SDL_GetJoystickProductVersion - (...) -@@ -@@ -- SDL_JoystickGetSerial -+ SDL_GetJoystickSerial - (...) -@@ -@@ -- SDL_JoystickGetType -+ SDL_GetJoystickType - (...) -@@ -@@ -- SDL_JoystickGetVendor -+ SDL_GetJoystickVendor - (...) -@@ -@@ -- SDL_JoystickInstanceID -+ SDL_GetJoystickID - (...) -@@ -@@ -- SDL_JoystickName -+ SDL_GetJoystickName - (...) -@@ -@@ -- SDL_JoystickNumAxes -+ SDL_GetNumJoystickAxes - (...) -@@ -@@ -- SDL_JoystickNumButtons -+ SDL_GetNumJoystickButtons - (...) -@@ -@@ -- SDL_JoystickNumHats -+ SDL_GetNumJoystickHats - (...) -@@ -@@ -- SDL_JoystickOpen -+ SDL_OpenJoystick - (...) -@@ -@@ -- SDL_JoystickPath -+ SDL_GetJoystickPath - (...) -@@ -@@ -- SDL_JoystickRumble -+ SDL_RumbleJoystick - (...) -@@ -@@ -- SDL_JoystickRumbleTriggers -+ SDL_RumbleJoystickTriggers - (...) -@@ -@@ -- SDL_JoystickSendEffect -+ SDL_SendJoystickEffect - (...) -@@ -@@ -- SDL_JoystickSetLED -+ SDL_SetJoystickLED - (...) -@@ -@@ -- SDL_JoystickSetPlayerIndex -+ SDL_SetJoystickPlayerIndex - (...) -@@ -@@ -- SDL_JoystickSetVirtualAxis -+ SDL_SetJoystickVirtualAxis - (...) -@@ -@@ -- SDL_JoystickSetVirtualButton -+ SDL_SetJoystickVirtualButton - (...) -@@ -@@ -- SDL_JoystickSetVirtualHat -+ SDL_SetJoystickVirtualHat - (...) -@@ -@@ -- SDL_JoystickUpdate -+ SDL_UpdateJoysticks - (...) -@@ -@@ -- SDL_IsScreenKeyboardShown -+ SDL_ScreenKeyboardShown - (...) -@@ -@@ -- SDL_IsTextInputActive -+ SDL_TextInputActive - (...) -@@ -@@ -- SDL_IsTextInputShown -+ SDL_TextInputShown - (...) -@@ -SDL_Event e1; -@@ -- e1.key.keysym.mod -+ e1.key.mod -@@ -SDL_Event *e1; -@@ -- e1->key.keysym.mod -+ e1->key.mod -@@ -SDL_KeyboardEvent *e1; -@@ -- e1->keysym.mod -+ e1->mod -@@ -SDL_Event e1; -@@ -- e1.key.keysym.sym -+ e1.key.key -@@ -SDL_Event *e1; -@@ -- e1->key.keysym.sym -+ e1->key.key -@@ -SDL_KeyboardEvent *e1; -@@ -- e1->keysym.sym -+ e1->key -@@ -SDL_Event e1; -@@ -- e1.key.keysym.scancode -+ e1.key.scancode -@@ -SDL_Event *e1; -@@ -- e1->key.keysym.scancode -+ e1->key.scancode -@@ -SDL_KeyboardEvent *e1; -@@ -- e1->keysym.scancode -+ e1->scancode -@@ -@@ -- KMOD_ALT -+ SDL_KMOD_ALT -@@ -@@ -- KMOD_CAPS -+ SDL_KMOD_CAPS -@@ -@@ -- KMOD_CTRL -+ SDL_KMOD_CTRL -@@ -@@ -- KMOD_GUI -+ SDL_KMOD_GUI -@@ -@@ -- KMOD_LALT -+ SDL_KMOD_LALT -@@ -@@ -- KMOD_LCTRL -+ SDL_KMOD_LCTRL -@@ -@@ -- KMOD_LGUI -+ SDL_KMOD_LGUI -@@ -@@ -- KMOD_LSHIFT -+ SDL_KMOD_LSHIFT -@@ -@@ -- KMOD_MODE -+ SDL_KMOD_MODE -@@ -@@ -- KMOD_NONE -+ SDL_KMOD_NONE -@@ -@@ -- KMOD_NUM -+ SDL_KMOD_NUM -@@ -@@ -- KMOD_RALT -+ SDL_KMOD_RALT -@@ -@@ -- KMOD_RCTRL -+ SDL_KMOD_RCTRL -@@ -@@ -- KMOD_RGUI -+ SDL_KMOD_RGUI -@@ -@@ -- KMOD_RSHIFT -+ SDL_KMOD_RSHIFT -@@ -@@ -- KMOD_SCROLL -+ SDL_KMOD_SCROLL -@@ -@@ -- KMOD_SHIFT -+ SDL_KMOD_SHIFT -@@ -@@ -- SDL_FreeCursor -+ SDL_DestroyCursor - (...) -@@ -@@ -- SDL_AllocFormat -+ SDL_GetPixelFormatDetails - (...) -@@ -@@ -- SDL_AllocPalette -+ SDL_CreatePalette - (...) -@@ -@@ -- SDL_FreePalette -+ SDL_DestroyPalette - (...) -@@ -@@ -- SDL_MasksToPixelFormatEnum -+ SDL_GetPixelFormatForMasks - (...) -@@ -@@ -- SDL_PixelFormatEnumToMasks -+ SDL_GetMasksForPixelFormat - (...) -@@ -@@ -- SDL_EncloseFPoints -+ SDL_GetRectEnclosingPointsFloat - (...) -@@ -@@ -- SDL_EnclosePoints -+ SDL_GetRectEnclosingPoints - (...) -@@ -@@ -- SDL_FRectEmpty -+ SDL_RectEmptyFloat - (...) -@@ -@@ -- SDL_FRectEquals -+ SDL_RectsEqualFloat - (...) -@@ -@@ -- SDL_FRectEqualsEpsilon -+ SDL_RectsEqualEpsilon - (...) -@@ -@@ -- SDL_HasIntersection -+ SDL_HasRectIntersection - (...) -@@ -@@ -- SDL_HasIntersectionF -+ SDL_HasRectIntersectionFloat - (...) -@@ -@@ -- SDL_IntersectFRect -+ SDL_GetRectIntersectionFloat - (...) -@@ -@@ -- SDL_IntersectFRectAndLine -+ SDL_GetRectAndLineIntersectionFloat - (...) -@@ -@@ -- SDL_IntersectRect -+ SDL_GetRectIntersection - (...) -@@ -@@ -- SDL_IntersectRectAndLine -+ SDL_GetRectAndLineIntersection - (...) -@@ -@@ -- SDL_PointInFRect -+ SDL_PointInRectFloat - (...) -@@ -@@ -- SDL_RectEquals -+ SDL_RectsEqual - (...) -@@ -@@ -- SDL_UnionFRect -+ SDL_GetRectUnionFloat - (...) -@@ -@@ -- SDL_UnionRect -+ SDL_GetRectUnion - (...) -@@ -@@ -- SDL_RenderCopyExF -+ SDL_RenderTextureRotated - (...) -@@ -@@ -- SDL_RenderCopyF -+ SDL_RenderTexture - (...) -@@ -@@ -- SDL_RenderDrawLineF -+ SDL_RenderLine - (...) -@@ -@@ -- SDL_RenderDrawLinesF -+ SDL_RenderLines - (...) -@@ -@@ -- SDL_RenderDrawPointF -+ SDL_RenderPoint - (...) -@@ -@@ -- SDL_RenderDrawPointsF -+ SDL_RenderPoints - (...) -@@ -@@ -- SDL_RenderDrawRectF -+ SDL_RenderRect - (...) -@@ -@@ -- SDL_RenderDrawRectsF -+ SDL_RenderRects - (...) -@@ -@@ -- SDL_RenderFillRectF -+ SDL_RenderFillRect - (...) -@@ -@@ -- SDL_RenderFillRectsF -+ SDL_RenderFillRects - (...) -@@ -@@ -- SDL_RenderGetClipRect -+ SDL_GetRenderClipRect - (...) -@@ -SDL_Renderer *renderer; -int *e1; -int *e2; -@@ -- SDL_RenderGetLogicalSize(renderer, e1, e2) -+ SDL_GetRenderLogicalPresentation(renderer, e1, e2, NULL, NULL) -@@ -@@ -- SDL_RenderGetMetalCommandEncoder -+ SDL_GetRenderMetalCommandEncoder - (...) -@@ -@@ -- SDL_RenderGetMetalLayer -+ SDL_GetRenderMetalLayer - (...) -@@ -@@ -- SDL_RenderGetScale -+ SDL_GetRenderScale - (...) -@@ -@@ -- SDL_RenderGetViewport -+ SDL_GetRenderViewport - (...) -@@ -@@ -- SDL_RenderGetWindow -+ SDL_GetRenderWindow - (...) -@@ -@@ -- SDL_RenderIsClipEnabled -+ SDL_RenderClipEnabled - (...) -@@ -@@ -- SDL_RenderSetClipRect -+ SDL_SetRenderClipRect - (...) -@@ -SDL_Renderer *renderer; -expression e1; -expression e2; -@@ -( -- SDL_RenderSetLogicalSize(renderer, 0, 0) -+ SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED) -| -- SDL_RenderSetLogicalSize(renderer, e1, e2) -+ SDL_SetRenderLogicalPresentation(renderer, e1, e2, SDL_LOGICAL_PRESENTATION_LETTERBOX) -) -@@ -@@ -- SDL_RenderSetScale -+ SDL_SetRenderScale - (...) -@@ -@@ -- SDL_RenderSetVSync -+ SDL_SetRenderVSync - (...) -@@ -@@ -- SDL_RenderSetViewport -+ SDL_SetRenderViewport - (...) -@@ -@@ -- RW_SEEK_CUR -+ SDL_IO_SEEK_CUR -@@ -@@ -- RW_SEEK_END -+ SDL_IO_SEEK_END -@@ -@@ -- RW_SEEK_SET -+ SDL_IO_SEEK_SET -@@ -@@ -- SDL_SensorClose -+ SDL_CloseSensor - (...) -@@ -@@ -- SDL_SensorFromInstanceID -+ SDL_GetSensorFromID - (...) -@@ -@@ -- SDL_SensorGetData -+ SDL_GetSensorData - (...) -@@ -@@ -- SDL_SensorGetInstanceID -+ SDL_GetSensorID - (...) -@@ -@@ -- SDL_SensorGetName -+ SDL_GetSensorName - (...) -@@ -@@ -- SDL_SensorGetNonPortableType -+ SDL_GetSensorNonPortableType - (...) -@@ -@@ -- SDL_SensorGetType -+ SDL_GetSensorType - (...) -@@ -@@ -- SDL_SensorOpen -+ SDL_OpenSensor - (...) -@@ -@@ -- SDL_SensorUpdate -+ SDL_UpdateSensors - (...) -@@ -@@ -- SDL_FillRect -+ SDL_FillSurfaceRect - (...) -@@ -@@ -- SDL_FillRects -+ SDL_FillSurfaceRects - (...) -@@ -@@ -- SDL_FreeSurface -+ SDL_DestroySurface - (...) -@@ -@@ -- SDL_GetClipRect -+ SDL_GetSurfaceClipRect - (...) -@@ -@@ -- SDL_GetColorKey -+ SDL_GetSurfaceColorKey - (...) -@@ -@@ -- SDL_HasColorKey -+ SDL_SurfaceHasColorKey - (...) -@@ -@@ -- SDL_HasSurfaceRLE -+ SDL_SurfaceHasRLE - (...) -@@ -@@ -- SDL_LowerBlit -+ SDL_BlitSurfaceUnchecked - (...) -@@ -expression e1, e2, e3, e4; -@@ -- SDL_LowerBlitScaled(e1, e2, e3, e4) -+ SDL_BlitSurfaceUncheckedScaled(e1, e2, e3, e4, SDL_SCALEMODE_NEAREST) -@@ -@@ -- SDL_SetClipRect -+ SDL_SetSurfaceClipRect - (...) -@@ -@@ -- SDL_SetColorKey -+ SDL_SetSurfaceColorKey - (...) -@@ -@@ -- SDL_UpperBlit -+ SDL_BlitSurface - (...) -@@ -expression e1, e2, e3, e4; -@@ -- SDL_UpperBlitScaled(e1, e2, e3, e4) -+ SDL_BlitSurfaceScaled(e1, e2, e3, e4, SDL_SCALEMODE_NEAREST) -@@ -@@ -- SDL_RenderGetD3D11Device -+ SDL_GetRenderD3D11Device - (...) -@@ -@@ -- SDL_RenderGetD3D9Device -+ SDL_GetRenderD3D9Device - (...) -@@ -@@ -- SDL_GetTicks64 -+ SDL_GetTicks - (...) -@@ -@@ -- SDL_GetPointDisplayIndex -+ SDL_GetDisplayForPoint - (...) -@@ -@@ -- SDL_GetRectDisplayIndex -+ SDL_GetDisplayForRect - (...) -@ depends on rule_init_noparachute @ -expression e; -@@ -- e | 0 -+ e -@@ -@@ -- SDL_FIRSTEVENT -+ SDL_EVENT_FIRST -@@ -@@ -- SDL_QUIT -+ SDL_EVENT_QUIT -@@ -@@ -- SDL_APP_TERMINATING -+ SDL_EVENT_TERMINATING -@@ -@@ -- SDL_APP_LOWMEMORY -+ SDL_EVENT_LOW_MEMORY -@@ -@@ -- SDL_APP_WILLENTERBACKGROUND -+ SDL_EVENT_WILL_ENTER_BACKGROUND -@@ -@@ -- SDL_APP_DIDENTERBACKGROUND -+ SDL_EVENT_DID_ENTER_BACKGROUND -@@ -@@ -- SDL_APP_WILLENTERFOREGROUND -+ SDL_EVENT_WILL_ENTER_FOREGROUND -@@ -@@ -- SDL_APP_DIDENTERFOREGROUND -+ SDL_EVENT_DID_ENTER_FOREGROUND -@@ -@@ -- SDL_LOCALECHANGED -+ SDL_EVENT_LOCALE_CHANGED -@@ -@@ -- SDL_DISPLAYEVENT_ORIENTATION -+ SDL_EVENT_DISPLAY_ORIENTATION -@@ -@@ -- SDL_DISPLAYEVENT_CONNECTED -+ SDL_EVENT_DISPLAY_CONNECTED -@@ -@@ -- SDL_DISPLAYEVENT_DISCONNECTED -+ SDL_EVENT_DISPLAY_DISCONNECTED -@@ -@@ -- SDL_DISPLAYEVENT_MOVED -+ SDL_EVENT_DISPLAY_MOVED -@@ -@@ -- SDL_DISPLAYEVENT_FIRST -+ SDL_EVENT_DISPLAY_FIRST -@@ -@@ -- SDL_DISPLAYEVENT_LAST -+ SDL_EVENT_DISPLAY_LAST -@@ -@@ -- SDL_SYSWMEVENT -+ SDL_EVENT_SYSWM -@@ -@@ -- SDL_WINDOWEVENT_SHOWN -+ SDL_EVENT_WINDOW_SHOWN -@@ -@@ -- SDL_WINDOWEVENT_HIDDEN -+ SDL_EVENT_WINDOW_HIDDEN -@@ -@@ -- SDL_WINDOWEVENT_EXPOSED -+ SDL_EVENT_WINDOW_EXPOSED -@@ -@@ -- SDL_WINDOWEVENT_MOVED -+ SDL_EVENT_WINDOW_MOVED -@@ -@@ -- SDL_WINDOWEVENT_RESIZED -+ SDL_EVENT_WINDOW_RESIZED -@@ -@@ -- SDL_WINDOWEVENT_SIZE_CHANGED -+ SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED -@@ -@@ -- SDL_WINDOWEVENT_MINIMIZED -+ SDL_EVENT_WINDOW_MINIMIZED -@@ -@@ -- SDL_WINDOWEVENT_MAXIMIZED -+ SDL_EVENT_WINDOW_MAXIMIZED -@@ -@@ -- SDL_WINDOWEVENT_RESTORED -+ SDL_EVENT_WINDOW_RESTORED -@@ -@@ -- SDL_WINDOWEVENT_ENTER -+ SDL_EVENT_WINDOW_MOUSE_ENTER -@@ -@@ -- SDL_WINDOWEVENT_LEAVE -+ SDL_EVENT_WINDOW_MOUSE_LEAVE -@@ -@@ -- SDL_WINDOWEVENT_FOCUS_GAINED -+ SDL_EVENT_WINDOW_FOCUS_GAINED -@@ -@@ -- SDL_WINDOWEVENT_FOCUS_LOST -+ SDL_EVENT_WINDOW_FOCUS_LOST -@@ -@@ -- SDL_WINDOWEVENT_CLOSE -+ SDL_EVENT_WINDOW_CLOSE_REQUESTED -@@ -@@ -- SDL_WINDOWEVENT_TAKE_FOCUS -+ /* FIXME MIGRATION: SDL_WINDOWEVENT_TAKE_FOCUS has been removed; there is no replacement. */ 0 -@@ -@@ -- SDL_WINDOWEVENT_HIT_TEST -+ SDL_EVENT_WINDOW_HIT_TEST -@@ -@@ -- SDL_WINDOWEVENT_ICCPROF_CHANGED -+ SDL_EVENT_WINDOW_ICCPROF_CHANGED -@@ -@@ -- SDL_WINDOWEVENT_DISPLAY_CHANGED -+ SDL_EVENT_WINDOW_DISPLAY_CHANGED -@@ -@@ -- SDL_WINDOWEVENT_FIRST -+ SDL_EVENT_WINDOW_FIRST -@@ -@@ -- SDL_WINDOWEVENT_LAST -+ SDL_EVENT_WINDOW_LAST -@@ -@@ -- SDL_KEYDOWN -+ SDL_EVENT_KEY_DOWN -@@ -@@ -- SDL_KEYUP -+ SDL_EVENT_KEY_UP -@@ -@@ -- SDL_TEXTEDITING -+ SDL_EVENT_TEXT_EDITING -@@ -@@ -- SDL_TEXTINPUT -+ SDL_EVENT_TEXT_INPUT -@@ -@@ -- SDL_KEYMAPCHANGED -+ SDL_EVENT_KEYMAP_CHANGED -@@ -@@ -- SDL_TEXTEDITING_EXT -+ SDL_EVENT_TEXT_EDITING_EXT -@@ -@@ -- SDL_MOUSEMOTION -+ SDL_EVENT_MOUSE_MOTION -@@ -@@ -- SDL_MOUSEBUTTONDOWN -+ SDL_EVENT_MOUSE_BUTTON_DOWN -@@ -@@ -- SDL_MOUSEBUTTONUP -+ SDL_EVENT_MOUSE_BUTTON_UP -@@ -@@ -- SDL_MOUSEWHEEL -+ SDL_EVENT_MOUSE_WHEEL -@@ -@@ -- SDL_JOYAXISMOTION -+ SDL_EVENT_JOYSTICK_AXIS_MOTION -@@ -@@ -- SDL_JOYBALLMOTION -+ SDL_EVENT_JOYSTICK_BALL_MOTION -@@ -@@ -- SDL_JOYHATMOTION -+ SDL_EVENT_JOYSTICK_HAT_MOTION -@@ -@@ -- SDL_JOYBUTTONDOWN -+ SDL_EVENT_JOYSTICK_BUTTON_DOWN -@@ -@@ -- SDL_JOYBUTTONUP -+ SDL_EVENT_JOYSTICK_BUTTON_UP -@@ -@@ -- SDL_JOYDEVICEADDED -+ SDL_EVENT_JOYSTICK_ADDED -@@ -@@ -- SDL_JOYDEVICEREMOVED -+ SDL_EVENT_JOYSTICK_REMOVED -@@ -@@ -- SDL_JOYBATTERYUPDATED -+ SDL_EVENT_JOYSTICK_BATTERY_UPDATED -@@ -@@ -- SDL_FINGERDOWN -+ SDL_EVENT_FINGER_DOWN -@@ -@@ -- SDL_FINGERUP -+ SDL_EVENT_FINGER_UP -@@ -@@ -- SDL_FINGERMOTION -+ SDL_EVENT_FINGER_MOTION -@@ -@@ -- SDL_CLIPBOARDUPDATE -+ SDL_EVENT_CLIPBOARD_UPDATE -@@ -@@ -- SDL_DROPFILE -+ SDL_EVENT_DROP_FILE -@@ -@@ -- SDL_DROPTEXT -+ SDL_EVENT_DROP_TEXT -@@ -@@ -- SDL_DROPBEGIN -+ SDL_EVENT_DROP_BEGIN -@@ -@@ -- SDL_DROPCOMPLETE -+ SDL_EVENT_DROP_COMPLETE -@@ -@@ -- SDL_AUDIODEVICEADDED -+ SDL_EVENT_AUDIO_DEVICE_ADDED -@@ -@@ -- SDL_AUDIODEVICEREMOVED -+ SDL_EVENT_AUDIO_DEVICE_REMOVED -@@ -@@ -- SDL_SENSORUPDATE -+ SDL_EVENT_SENSOR_UPDATE -@@ -@@ -- SDL_RENDER_TARGETS_RESET -+ SDL_EVENT_RENDER_TARGETS_RESET -@@ -@@ -- SDL_RENDER_DEVICE_RESET -+ SDL_EVENT_RENDER_DEVICE_RESET -@@ -@@ -- SDL_POLLSENTINEL -+ SDL_EVENT_POLL_SENTINEL -@@ -@@ -- SDL_USEREVENT -+ SDL_EVENT_USER -@@ -@@ -- SDL_LASTEVENT -+ SDL_EVENT_LAST -@@ -@@ -- SDL_WINDOW_INPUT_GRABBED -+ SDL_WINDOW_MOUSE_GRABBED -@@ -@@ -- SDL_GetWindowDisplayIndex -+ SDL_GetDisplayForWindow - (...) -@@ -@@ -- SDL_SetWindowDisplayMode -+ SDL_SetWindowFullscreenMode - (...) -@@ -@@ -- SDL_GetWindowDisplayMode -+ SDL_GetWindowFullscreenMode - (...) -@@ -@@ -- SDL_GetClosestDisplayMode -+ SDL_GetClosestFullscreenDisplayMode - (...) -@@ -@@ -- SDL_GetRendererOutputSize -+ SDL_GetCurrentRenderOutputSize - (...) -@@ -@@ -- SDL_RenderWindowToLogical -+ SDL_RenderCoordinatesFromWindow - (...) -@@ -@@ -- SDL_RenderLogicalToWindow -+ SDL_RenderCoordinatesToWindow - (...) -@@ -symbol SDL_ScaleModeNearest; -@@ -- SDL_ScaleModeNearest -+ SDL_SCALEMODE_NEAREST -@@ -symbol SDL_ScaleModeLinear; -@@ -- SDL_ScaleModeLinear -+ SDL_SCALEMODE_LINEAR -@@ -@@ -- SDL_RenderCopy -+ SDL_RenderTexture - (...) -@@ -@@ -- SDL_RenderCopyEx -+ SDL_RenderTextureRotated - (...) -@@ -SDL_Renderer *renderer; -constant c1; -constant c2; -constant c3; -constant c4; -expression e1; -expression e2; -expression e3; -expression e4; -@@ -- SDL_RenderDrawLine(renderer, -+ SDL_RenderLine(renderer, -( - c1 -| -- e1 -+ (float)e1 -) - , -( - c2 -| -- e2 -+ (float)e2 -) - , -( - c3 -| -- e3 -+ (float)e3 -) - , -( - c4 -| -- e4 -+ (float)e4 -) - ) -@@ -@@ -- SDL_RenderDrawLines -+ SDL_RenderLines - (...) -@@ -SDL_Renderer *renderer; -constant c1; -constant c2; -expression e1; -expression e2; -@@ -- SDL_RenderDrawPoint(renderer, -+ SDL_RenderPoint(renderer, -( - c1 -| -- e1 -+ (float)e1 -) - , -( - c2 -| -- e2 -+ (float)e2 -) - ) -@@ -@@ -- SDL_RenderDrawPoints -+ SDL_RenderPoints - (...) -@@ -@@ -- SDL_RenderDrawRect -+ SDL_RenderRect - (...) -@@ -@@ -- SDL_RenderDrawRects -+ SDL_RenderRects - (...) -@@ -@@ -- SDL_GL_GetDrawableSize -+ SDL_GetWindowSizeInPixels - (...) -@@ -@@ -- SDL_Metal_GetDrawableSize -+ SDL_GetWindowSizeInPixels - (...) -@@ -@@ -- SDL_Vulkan_GetDrawableSize -+ SDL_GetWindowSizeInPixels - (...) -@@ -@@ -- SDL_IsScreenSaverEnabled -+ SDL_ScreenSaverEnabled - (...) -@@ -SDL_Event e1; -@@ -- e1.caxis -+ e1.gaxis -@@ -SDL_Event *e1; -@@ -- e1->caxis -+ e1->gaxis -@@ -SDL_Event e1; -@@ -- e1.cbutton -+ e1.gbutton -@@ -SDL_Event *e1; -@@ -- e1->cbutton -+ e1->gbutton -@@ -SDL_Event e1; -@@ -- e1.cdevice -+ e1.gdevice -@@ -SDL_Event *e1; -@@ -- e1->cdevice -+ e1->gdevice -@@ -SDL_Event e1; -@@ -- e1.ctouchpad -+ e1.gtouchpad -@@ -SDL_Event *e1; -@@ -- e1->ctouchpad -+ e1->gtouchpad -@@ -SDL_Event e1; -@@ -- e1.csensor -+ e1.gsensor -@@ -SDL_Event *e1; -@@ -- e1->csensor -+ e1->gsensor -@@ -SDL_Event e1; -@@ -- e1.wheel.mouseX -+ e1.wheel.mouse_x -@@ -SDL_Event *e1; -@@ -- e1->wheel.mouseX -+ e1->wheel.mouse_x -@@ -SDL_MouseWheelEvent *e1; -@@ -- e1->mouseX -+ e1->mouse_x -@@ -SDL_Event e1; -@@ -- e1.wheel.mouseY -+ e1.wheel.mouse_y -@@ -SDL_Event *e1; -@@ -- e1->wheel.mouseY -+ e1->wheel.mouse_y -@@ -SDL_MouseWheelEvent *e1; -@@ -- e1->mouseY -+ e1->mouse_y -@@ -SDL_Event e1; -@@ -- e1.wheel.preciseX -+ e1.wheel.x -@@ -SDL_Event *e1; -@@ -- e1->wheel.preciseX -+ e1->wheel.x -@@ -SDL_MouseWheelEvent *e1; -@@ -- e1->preciseX -+ e1->x -@@ -SDL_Event e1; -@@ -- e1.wheel.preciseY -+ e1.wheel.y -@@ -SDL_Event *e1; -@@ -- e1->wheel.preciseY -+ e1->wheel.y -@@ -SDL_MouseWheelEvent *e1; -@@ -- e1->preciseY -+ e1->y -@@ -SDL_Event e1; -@@ -- e1.tfinger.touchId -+ e1.tfinger.touchID -@@ -SDL_Event *e1; -@@ -- e1->tfinger.touchId -+ e1->tfinger.touchID -@@ -SDL_TouchFingerEvent *e1; -@@ -- e1->touchId -+ e1->touchID -@@ -SDL_Event e1; -@@ -- e1.tfinger.fingerId -+ e1.tfinger.fingerID -@@ -SDL_Event *e1; -@@ -- e1->tfinger.fingerId -+ e1->tfinger.fingerID -@@ -SDL_TouchFingerEvent *e1; -@@ -- e1->fingerId -+ e1->fingerID -@@ -expression e1, e2, e3, e4; -@@ -- SDL_CreateWindow(e1, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, e2, e3, e4) -+ SDL_CreateWindow(e1, e2, e3, e4) -@@ -expression e1, e2, e3, e4; -constant c1, c2; -@@ -- SDL_CreateShapedWindow(e1, c1, c2, e2, e3, e4) -+ SDL_CreateShapedWindow(e1, e2, e3, e4) -@@ -typedef SDL_atomic_t, SDL_AtomicInt; -@@ -- SDL_atomic_t -+ SDL_AtomicInt -@@ -@@ -- SDL_SemWait -+ SDL_WaitSemaphore - (...) -@@ -@@ -- SDL_SemTryWait -+ SDL_TryWaitSemaphore - (...) -@@ -@@ -- SDL_SemWaitTimeout -+ SDL_WaitSemaphoreTimeout - (...) -@@ -@@ -- SDL_SemPost -+ SDL_SignalSemaphore - (...) -@@ -@@ -- SDL_SemValue -+ SDL_GetSemaphoreValue - (...) -@@ -@@ -- SDL_CreateCond -+ SDL_CreateCondition - (...) -@@ -@@ -- SDL_DestroyCond -+ SDL_DestroyCondition - (...) -@@ -@@ -- SDL_CondSignal -+ SDL_SignalCondition - (...) -@@ -@@ -- SDL_CondBroadcast -+ SDL_BroadcastCondition - (...) -@@ -@@ -- SDL_CondWait -+ SDL_WaitCondition - (...) -@@ -@@ -- SDL_CondWaitTimeout -+ SDL_WaitConditionTimeout - (...) -@@ -typedef SDL_mutex, SDL_Mutex; -@@ -- SDL_mutex -+ SDL_Mutex -@@ -typedef SDL_sem, SDL_Semaphore; -@@ -- SDL_sem -+ SDL_Semaphore -@@ -typedef SDL_cond, SDL_Condition; -@@ -- SDL_cond -+ SDL_Condition -@@ -@@ -- AUDIO_F32 -+ SDL_AUDIO_F32LE -@@ -@@ -- AUDIO_F32LSB -+ SDL_AUDIO_F32LE -@@ -@@ -- AUDIO_F32MSB -+ SDL_AUDIO_F32BE -@@ -@@ -- AUDIO_F32SYS -+ SDL_AUDIO_F32 -@@ -@@ -- AUDIO_S16 -+ SDL_AUDIO_S16LE -@@ -@@ -- AUDIO_S16LSB -+ SDL_AUDIO_S16LE -@@ -@@ -- AUDIO_S16MSB -+ SDL_AUDIO_S16BE -@@ -@@ -- AUDIO_S16SYS -+ SDL_AUDIO_S16 -@@ -@@ -- AUDIO_S32 -+ SDL_AUDIO_S32LE -@@ -@@ -- AUDIO_S32LSB -+ SDL_AUDIO_S32LE -@@ -@@ -- AUDIO_S32MSB -+ SDL_AUDIO_S32BE -@@ -@@ -- AUDIO_S32SYS -+ SDL_AUDIO_S32 -@@ -@@ -- AUDIO_S8 -+ SDL_AUDIO_S8 -@@ -@@ -- AUDIO_U8 -+ SDL_AUDIO_U8 -@@ -@@ -- SDL_WINDOW_ALLOW_HIGHDPI -+ SDL_WINDOW_HIGH_PIXEL_DENSITY -@@ -@@ -- SDL_TLSGet -+ SDL_GetTLS - (...) -@@ -@@ -- SDL_TLSSet -+ SDL_SetTLS - (...) -@@ -@@ -- SDL_TLSCleanup -+ SDL_CleanupTLS - (...) -@@ -@@ -- SDL_GetDisplayOrientation -+ SDL_GetDisplayCurrentOrientation - (...) -@@ -@@ -- SDL_WINDOW_SKIP_TASKBAR -+ SDL_WINDOW_UTILITY -@@ -@@ -- SDL_PIXELFORMAT_BGR444 -+ SDL_PIXELFORMAT_XBGR4444 -@@ -@@ -- SDL_PIXELFORMAT_BGR555 -+ SDL_PIXELFORMAT_XBGR1555 -@@ -@@ -- SDL_PIXELFORMAT_BGR888 -+ SDL_PIXELFORMAT_XBGR8888 -@@ -@@ -- SDL_PIXELFORMAT_RGB444 -+ SDL_PIXELFORMAT_XRGB4444 -@@ -@@ -- SDL_PIXELFORMAT_RGB555 -+ SDL_PIXELFORMAT_XRGB1555 -@@ -@@ -- SDL_PIXELFORMAT_RGB888 -+ SDL_PIXELFORMAT_XRGB8888 -@@ -@@ -- SDL_strtokr -+ SDL_strtok_r - (...) -@@ -@@ -- SDL_ReadLE16 -+ SDL_ReadU16LE - (...) -@@ -@@ -- SDL_ReadLE32 -+ SDL_ReadU32LE - (...) -@@ -@@ -- SDL_ReadBE32 -+ SDL_ReadU32BE - (...) -@@ -@@ -- SDL_ReadBE16 -+ SDL_ReadU16BE - (...) -@@ -@@ -- SDL_ReadLE64 -+ SDL_ReadU64LE - (...) -@@ -@@ -- SDL_ReadBE64 -+ SDL_ReadU64BE - (...) -@@ -@@ -- SDL_WriteLE16 -+ SDL_WriteU16LE - (...) -@@ -@@ -- SDL_WriteBE16 -+ SDL_WriteU16BE - (...) -@@ -@@ -- SDL_WriteLE32 -+ SDL_WriteU32LE - (...) -@@ -@@ -- SDL_WriteBE32 -+ SDL_WriteU32BE - (...) -@@ -@@ -- SDL_WriteLE64 -+ SDL_WriteU64LE - (...) -@@ -@@ -- SDL_WriteBE64 -+ SDL_WriteU64BE - (...) -@@ -expression e, n; -@@ -- SDL_GetWindowData(e, n) -+ SDL_GetProperty(SDL_GetWindowProperties(e), n) -@@ -expression e, n, v; -@@ -- SDL_SetWindowData(e, n, v) -+ SDL_SetProperty(SDL_GetWindowProperties(e), n, v, NULL, NULL) -@@ -expression w, i, s; -@@ -- SDL_Vulkan_CreateSurface(w, i, s) -+ SDL_Vulkan_CreateSurface(w, i, NULL, s) -@@ -@@ -- SDL_RenderFlush -+ SDL_FlushRenderer - (...) -@@ -@@ -- SDL_CONTROLLERSTEAMHANDLEUPDATED -+ SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED -@@ -@@ -- SDL_GameControllerGetSteamHandle -+ SDL_GetGamepadSteamHandle - (...) -@@ -expression e1, e2, e3, e4; -@@ -- SDL_SoftStretch(e1, e2, e3, e4) -+ SDL_SoftStretch(e1, e2, e3, e4, SDL_SCALEMODE_NEAREST) -@@ -expression e1, e2, e3, e4; -@@ -- SDL_SoftStretchLinear(e1, e2, e3, e4) -+ SDL_SoftStretch(e1, e2, e3, e4, SDL_SCALEMODE_LINEAR) -@@ -@@ -- SDL_HapticClose -+ SDL_CloseHaptic - (...) -@@ -@@ -- SDL_HapticOpen -+ SDL_OpenHaptic - (...) -@@ -@@ -- SDL_HapticOpenFromMouse -+ SDL_OpenHapticFromMouse - (...) -@@ -@@ -- SDL_HapticOpenFromJoystick -+ SDL_OpenHapticFromJoystick - (...) -@@ -@@ -- SDL_MouseIsHaptic -+ SDL_IsMouseHaptic - (...) -@@ -@@ -- SDL_JoystickIsHaptic -+ SDL_IsJoystickHaptic - (...) -@@ -@@ -- SDL_HapticNumEffects -+ SDL_GetMaxHapticEffects - (...) -@@ -@@ -- SDL_HapticNumEffectsPlaying -+ SDL_GetMaxHapticEffectsPlaying - (...) -@@ -@@ -- SDL_HapticQuery -+ SDL_GetHapticFeatures - (...) -@@ -@@ -- SDL_HapticNumAxes -+ SDL_GetNumHapticAxes - (...) -@@ -@@ -- SDL_HapticNewEffect -+ SDL_CreateHapticEffect - (...) -@@ -@@ -- SDL_HapticUpdateEffect -+ SDL_UpdateHapticEffect - (...) -@@ -@@ -- SDL_HapticRunEffect -+ SDL_RunHapticEffect - (...) -@@ -@@ -- SDL_HapticStopEffect -+ SDL_StopHapticEffect - (...) -@@ -@@ -- SDL_HapticDestroyEffect -+ SDL_DestroyHapticEffect - (...) -@@ -@@ -- SDL_HapticGetEffectStatus -+ SDL_GetHapticEffectStatus - (...) -@@ -@@ -- SDL_HapticSetGain -+ SDL_SetHapticGain - (...) -@@ -@@ -- SDL_HapticSetAutocenter -+ SDL_SetHapticAutocenter - (...) -@@ -@@ -- SDL_HapticPause -+ SDL_PauseHaptic - (...) -@@ -@@ -- SDL_HapticUnpause -+ SDL_ResumeHaptic - (...) -@@ -@@ -- SDL_HapticStopAll -+ SDL_StopHapticEffects - (...) -@@ -@@ -- SDL_HapticRumbleInit -+ SDL_InitHapticRumble - (...) -@@ -@@ -- SDL_HapticRumblePlay -+ SDL_PlayHapticRumble - (...) -@@ -@@ -- SDL_HapticRumbleStop -+ SDL_StopHapticRumble - (...) -@@ -@@ -- SDL_AtomicTryLock -+ SDL_TryLockSpinlock - (...) -@@ -@@ -- SDL_AtomicLock -+ SDL_LockSpinlock - (...) -@@ -@@ -- SDL_AtomicUnlock -+ SDL_UnlockSpinlock - (...) -@@ -@@ -- SDL_AtomicCAS -+ SDL_CompareAndSwapAtomicInt - (...) -@@ -@@ -- SDL_AtomicSet -+ SDL_SetAtomicInt - (...) -@@ -@@ -- SDL_AtomicGet -+ SDL_GetAtomicInt - (...) -@@ -@@ -- SDL_AtomicAdd -+ SDL_AddAtomicInt - (...) -@@ -@@ -- SDL_AtomicCASPtr -+ SDL_CompareAndSwapAtomicPointer - (...) -@@ -@@ -- SDL_AtomicSetPtr -+ SDL_SetAtomicPointer - (...) -@@ -@@ -- SDL_AtomicGetPtr -+ SDL_GetAtomicPointer - (...) -@@ -@@ -- SDL_ThreadID -+ SDL_GetCurrentThreadID - (...) -@@ -@@ -- SDL_threadID -+ SDL_ThreadID - (...) -@@ -@@ -- SDL_HasWindowSurface -+ SDL_WindowHasSurface - (...) -@@ -SDL_PixelFormat e1; -@@ -- e1.BitsPerPixel -+ e1.bits_per_pixel -@@ -SDL_PixelFormat *e1; -@@ -- e1->BitsPerPixel -+ e1->bits_per_pixel -@@ -SDL_PixelFormat e1; -@@ -- e1.BytesPerPixel -+ e1.bytes_per_pixel -@@ -SDL_PixelFormat *e1; -@@ -- e1->BytesPerPixel -+ e1->bytes_per_pixel -@@ -SDL_MessageBoxButtonData e1; -@@ -- e1.buttonid -+ e1.buttonID -@@ -SDL_MessageBoxButtonData *e1; -@@ -- e1->buttonid -+ e1->buttonID -@@ -SDL_GamepadBinding e1; -@@ -- e1.inputType -+ e1.input_type -@@ -SDL_GamepadBinding *e1; -@@ -- e1->inputType -+ e1->input_type -@@ -SDL_GamepadBinding e1; -@@ -- e1.outputType -+ e1.output_type -@@ -SDL_GamepadBinding *e1; -@@ -- e1->outputType -+ e1->output_type -@@ -@@ -- SDL_HINT_ALLOW_TOPMOST -+ SDL_HINT_WINDOW_ALLOW_TOPMOST -@@ -@@ -- SDL_HINT_DIRECTINPUT_ENABLED -+ SDL_HINT_JOYSTICK_DIRECTINPUT -@@ -@@ -- SDL_HINT_GDK_TEXTINPUT_DEFAULT -+ SDL_HINT_GDK_TEXTINPUT_DEFAULT_TEXT -@@ -@@ -- SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE -+ SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE -@@ -@@ -- SDL_HINT_LINUX_DIGITAL_HATS -+ SDL_HINT_JOYSTICK_LINUX_DIGITAL_HATS -@@ -@@ -- SDL_HINT_LINUX_HAT_DEADZONES -+ SDL_HINT_JOYSTICK_LINUX_HAT_DEADZONES -@@ -@@ -- SDL_HINT_LINUX_JOYSTICK_CLASSIC -+ SDL_HINT_JOYSTICK_LINUX_CLASSIC -@@ -@@ -- SDL_HINT_LINUX_JOYSTICK_DEADZONES -+ SDL_HINT_JOYSTICK_LINUX_DEADZONES -@@ -@@ -- SDL_HINT_PS2_DYNAMIC_VSYNC -+ SDL_HINT_RENDER_PS2_DYNAMIC_VSYNC -@@ -@@ -- SDL_JoystickNumBalls -+ SDL_GetNumJoystickBalls - (...) -@@ -@@ -- SDL_JoystickGetBall -+ SDL_GetJoystickBall - (...) -@@ -@@ -- SDL_RWclose -+ SDL_CloseIO - (...) -@@ -@@ -- SDL_RWread -+ SDL_ReadIO - (...) -@@ -@@ -- SDL_RWwrite -+ SDL_WriteIO - (...) -@@ -@@ -- SDL_RWtell -+ SDL_TellIO - (...) -@@ -@@ -- SDL_RWsize -+ SDL_SizeIO - (...) -@@ -@@ -- SDL_RWseek -+ SDL_SeekIO - (...) -@@ -@@ -- SDL_LoadBMP_RW -+ SDL_LoadBMP_IO - (...) -@@ -@@ -- SDL_LoadWAV_RW -+ SDL_LoadWAV_IO - (...) -@@ -@@ -- SDL_SaveBMP_RW -+ SDL_SaveBMP_IO - (...) -@@ -@@ -- SDL_RWFromFile -+ SDL_IOFromFile - (...) -@@ -@@ -- SDL_RWFromMem -+ SDL_IOFromMem - (...) -@@ -@@ -- SDL_RWFromConstMem -+ SDL_IOFromConstMem - (...) -@@ -typedef SDL_RWops, SDL_IOStream; -@@ -- SDL_RWops -+ SDL_IOStream -@@ -@@ -- SDL_LogGetOutputFunction -+ SDL_GetLogOutputFunction - (...) -@@ -@@ -- SDL_LogSetOutputFunction -+ SDL_SetLogOutputFunction - (...) -@@ -typedef SDL_eventaction, SDL_EventAction; -@@ -- SDL_eventaction -+ SDL_EventAction -@@ -typedef SDL_RendererFlip, SDL_FlipMode; -@@ -- SDL_RendererFlip -+ SDL_FlipMode -@@ -typedef SDL_Colour, SDL_Color; -@@ -- SDL_Colour -+ SDL_Color -@@ -@@ -- SDL_iPhoneSetAnimationCallback -+ SDL_SetiOSAnimationCallback - (...) -@@ -@@ -- SDL_iPhoneSetEventPump -+ SDL_SetiOSEventPump - (...) -@@ -@@ -- SDL_COMPILEDVERSION -+ SDL_VERSION -@@ -@@ -- SDL_PATCHLEVEL -+ SDL_MICRO_VERSION -@@ -@@ -- SDL_TABLESIZE -+ SDL_arraysize -@@ -@@ -- SDLK_QUOTE -+ SDLK_APOSTROPHE -@@ -@@ -- SDLK_BACKQUOTE -+ SDLK_GRAVE -@@ -@@ -- SDLK_QUOTEDBL -+ SDLK_DBLAPOSTROPHE -@@ -@@ -- SDL_LogSetAllPriority -+ SDL_SetLogPriorities - (...) -@@ -@@ -- SDL_LogSetPriority -+ SDL_SetLogPriority - (...) -@@ -@@ -- SDL_LogGetPriority -+ SDL_GetLogPriority - (...) -@@ -@@ -- SDL_LogResetPriorities -+ SDL_ResetLogPriorities - (...) -@@ -@@ -- SDL_SIMDGetAlignment -+ SDL_GetSIMDAlignment - (...) -@@ -@@ -- SDL_MixAudioFormat -+ SDL_MixAudio - (...) -@@ -@@ -- SDL_BlitScaled -+ SDL_BlitSurfaceScaled - (...) -@@ -@@ -- SDL_SYSTEM_CURSOR_ARROW -+ SDL_SYSTEM_CURSOR_DEFAULT -@@ -@@ -- SDL_SYSTEM_CURSOR_IBEAM -+ SDL_SYSTEM_CURSOR_TEXT -@@ -@@ -- SDL_SYSTEM_CURSOR_WAITARROW -+ SDL_SYSTEM_CURSOR_PROGRESS -@@ -@@ -- SDL_SYSTEM_CURSOR_SIZENWSE -+ SDL_SYSTEM_CURSOR_NWSE_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_SIZENESW -+ SDL_SYSTEM_CURSOR_NESW_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_SIZEWE -+ SDL_SYSTEM_CURSOR_EW_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_SIZENS -+ SDL_SYSTEM_CURSOR_NS_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_SIZEALL -+ SDL_SYSTEM_CURSOR_MOVE -@@ -@@ -- SDL_SYSTEM_CURSOR_NO -+ SDL_SYSTEM_CURSOR_NOT_ALLOWED -@@ -@@ -- SDL_SYSTEM_CURSOR_HAND -+ SDL_SYSTEM_CURSOR_POINTER -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT -+ SDL_SYSTEM_CURSOR_NW_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_TOP -+ SDL_SYSTEM_CURSOR_N_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT -+ SDL_SYSTEM_CURSOR_NE_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_RIGHT -+ SDL_SYSTEM_CURSOR_E_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT -+ SDL_SYSTEM_CURSOR_SE_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_BOTTOM -+ SDL_SYSTEM_CURSOR_S_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT -+ SDL_SYSTEM_CURSOR_SW_RESIZE -@@ -@@ -- SDL_SYSTEM_CURSOR_WINDOW_LEFT -+ SDL_SYSTEM_CURSOR_W_RESIZE -@@ -@@ -- SDL_SwapLE16 -+ SDL_Swap16LE - (...) -@@ -@@ -- SDL_SwapLE32 -+ SDL_Swap32LE - (...) -@@ -@@ -- SDL_SwapBE16 -+ SDL_Swap16BE - (...) -@@ -@@ -- SDL_SwapBE32 -+ SDL_Swap32BE - (...) -@@ -@@ -- SDL_SwapLE64 -+ SDL_Swap64LE - (...) -@@ -@@ -- SDL_SwapBE64 -+ SDL_Swap64BE - (...) -@@ -@@ -- SDL_SCANCODE_AUDIOMUTE -+ SDL_SCANCODE_MUTE -@@ -@@ -- SDLK_AUDIOMUTE -+ SDLK_MUTE -@@ -@@ -- SDL_SCANCODE_EJECT -+ SDL_SCANCODE_MEDIA_EJECT -@@ -@@ -- SDLK_EJECT -+ SDLK_MEDIA_EJECT -@@ -@@ -- SDL_SCANCODE_AUDIONEXT -+ SDL_SCANCODE_MEDIA_NEXT_TRACK -@@ -@@ -- SDLK_AUDIONEXT -+ SDLK_MEDIA_NEXT_TRACK -@@ -@@ -- SDL_SCANCODE_AUDIOPREV -+ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK -@@ -@@ -- SDLK_AUDIOPREV -+ SDLK_MEDIA_PREVIOUS_TRACK -@@ -@@ -- SDL_SCANCODE_AUDIOSTOP -+ SDL_SCANCODE_MEDIA_STOP -@@ -@@ -- SDLK_AUDIOSTOP -+ SDLK_MEDIA_STOP -@@ -@@ -- SDL_SCANCODE_AUDIOPLAY -+ SDL_SCANCODE_MEDIA_PLAY -@@ -@@ -- SDLK_AUDIOPLAY -+ SDLK_MEDIA_PLAY -@@ -@@ -- SDL_SCANCODE_AUDIOREWIND -+ SDL_SCANCODE_MEDIA_REWIND -@@ -@@ -- SDLK_AUDIOREWIND -+ SDLK_MEDIA_REWIND -@@ -@@ -- SDL_SCANCODE_AUDIOFASTFORWARD -+ SDL_SCANCODE_MEDIA_FAST_FORWARD -@@ -@@ -- SDLK_AUDIOFASTFORWARD -+ SDLK_MEDIA_FAST_FORWARD -@@ -@@ -- SDL_SCANCODE_MEDIASELECT -+ SDL_SCANCODE_MEDIA_SELECT -@@ -@@ -- SDLK_MEDIASELECT -+ SDLK_MEDIA_SELECT -@@ -@@ -- SDLK_a -+ SDLK_A -@@ -@@ -- SDLK_b -+ SDLK_B -@@ -@@ -- SDLK_c -+ SDLK_C -@@ -@@ -- SDLK_d -+ SDLK_D -@@ -@@ -- SDLK_e -+ SDLK_E -@@ -@@ -- SDLK_f -+ SDLK_F -@@ -@@ -- SDLK_g -+ SDLK_G -@@ -@@ -- SDLK_h -+ SDLK_H -@@ -@@ -- SDLK_i -+ SDLK_I -@@ -@@ -- SDLK_j -+ SDLK_J -@@ -@@ -- SDLK_k -+ SDLK_K -@@ -@@ -- SDLK_l -+ SDLK_L -@@ -@@ -- SDLK_m -+ SDLK_M -@@ -@@ -- SDLK_n -+ SDLK_N -@@ -@@ -- SDLK_o -+ SDLK_O -@@ -@@ -- SDLK_p -+ SDLK_P -@@ -@@ -- SDLK_q -+ SDLK_Q -@@ -@@ -- SDLK_r -+ SDLK_R -@@ -@@ -- SDLK_s -+ SDLK_S -@@ -@@ -- SDLK_t -+ SDLK_T -@@ -@@ -- SDLK_u -+ SDLK_U -@@ -@@ -- SDLK_v -+ SDLK_V -@@ -@@ -- SDLK_w -+ SDLK_W -@@ -@@ -- SDLK_x -+ SDLK_X -@@ -@@ -- SDLK_y -+ SDLK_Y -@@ -@@ -- SDLK_z -+ SDLK_Z -@@ -@@ -- SDL_ConvertSurfaceFormat -+ SDL_ConvertSurface - (...) -@@ -@@ -- SDL_PREALLOC -+ SDL_SURFACE_PREALLOCATED -@@ -@@ -- SDL_SIMD_ALIGNED -+ SDL_SURFACE_SIMD_ALIGNED -@@ -@@ -- SDL_GL_DeleteContext -+ SDL_GL_DestroyContext - (...) -@@ -@@ -- SDL_AndroidGetActivity -+ SDL_GetAndroidActivity - (...) -@@ -@@ -- SDL_AndroidGetExternalStoragePath -+ SDL_GetAndroidExternalStoragePath - (...) -@@ -@@ -- SDL_AndroidGetExternalStorageState -+ SDL_GetAndroidExternalStorageState - (...) -@@ -@@ -- SDL_AndroidGetInternalStoragePath -+ SDL_GetAndroidInternalStoragePath - (...) -@@ -@@ -- SDL_AndroidGetJNIEnv -+ SDL_GetAndroidJNIEnv - (...) -@@ -@@ -- SDL_Direct3D9GetAdapterIndex -+ SDL_GetDirect3D9AdapterIndex - (...) -@@ -@@ -- SDL_GDKGetDefaultUser -+ SDL_GetGDKDefaultUser - (...) -@@ -@@ -- SDL_GDKGetTaskQueue -+ SDL_GetGDKTaskQueue - (...) -@@ -@@ -- SDL_LinuxSetThreadPriority -+ SDL_SetLinuxThreadPriority - (...) -@@ -@@ -- SDL_LinuxSetThreadPriorityAndPolicy -+ SDL_SetLinuxThreadPriorityAndPolicy - (...) -@@ -@@ -- SDL_DXGIGetOutputInfo -+ SDL_GetDXGIOutputInfo - (...) -@@ -@@ -- SDL_AndroidBackButton -+ SDL_TriggerAndroidBackButton - (...) -@@ -@@ -- SDL_AndroidRequestPermission -+ SDL_RequestAndroidPermission - (...) -@@ -@@ -- SDL_AndroidRequestPermissionCallback -+ SDL_RequestAndroidPermissionCallback - (...) -@@ -@@ -- SDL_AndroidShowToast -+ SDL_ShowAndroidToast - (...) -@@ -@@ -- SDL_AndroidSendMessage -+ SDL_SendAndroidMessage - (...) -@@ -typedef SDL_JoystickGUID, SDL_GUID; -@@ -- SDL_JoystickGUID -+ SDL_GUID -@@ -@@ -- SDL_GUIDFromString -+ SDL_StringToGUID - (...) -@@ -@@ -- SDL_OnApplicationWillResignActive -+ SDL_OnApplicationWillEnterBackground - (...) -@@ -@@ -- SDL_OnApplicationDidBecomeActive -+ SDL_OnApplicationDidEnterForeground - (...) -@@ -@@ -- SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP -+ SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE -@@ -@@ -- SDL_DelEventWatch -+ SDL_RemoveEventWatch - (...) -@@ -@@ -- SDL_DelHintCallback -+ SDL_RemoveHintCallback - (...) -@@ -@@ -- SDL_size_mul_overflow -+ SDL_size_mul_check_overflow - (...) -@@ -@@ -- SDL_size_add_overflow -+ SDL_size_add_check_overflow - (...) -@@ -@@ -- SDL_PRESSED -+ true -@@ -@@ -- SDL_RELEASED -+ false - -// This should be the last rule in the file, since it works on SDL3 functions and previous rules may have renamed old functions. -@ bool_return_type @ -identifier func =~ "^(SDL_AddEventWatch|SDL_AddHintCallback|SDL_AddSurfaceAlternateImage|SDL_AddVulkanRenderSemaphores|SDL_BindAudioStream|SDL_BindAudioStreams|SDL_BlitSurface|SDL_BlitSurface9Grid|SDL_BlitSurfaceScaled|SDL_BlitSurfaceTiled|SDL_BlitSurfaceTiledWithScale|SDL_BlitSurfaceUnchecked|SDL_BlitSurfaceUncheckedScaled|SDL_CaptureMouse|SDL_ClearAudioStream|SDL_ClearClipboardData|SDL_ClearComposition|SDL_ClearError|SDL_ClearProperty|SDL_ClearSurface|SDL_CloseIO|SDL_CloseStorage|SDL_ConvertAudioSamples|SDL_ConvertEventToRenderCoordinates|SDL_ConvertPixels|SDL_ConvertPixelsAndColorspace|SDL_CopyFile|SDL_CopyProperties|SDL_CopyStorageFile|SDL_CreateDirectory|SDL_CreateStorageDirectory|SDL_CreateWindowAndRenderer|SDL_DateTimeToTime|SDL_DestroyWindowSurface|SDL_DetachVirtualJoystick|SDL_DisableScreenSaver|SDL_EnableScreenSaver|SDL_EnumerateDirectory|SDL_EnumerateProperties|SDL_EnumerateStorageDirectory|SDL_FillSurfaceRect|SDL_FillSurfaceRects|SDL_FlashWindow|SDL_FlipSurface|SDL_FlushAudioStream|SDL_FlushRenderer|SDL_GL_DestroyContext|SDL_GL_GetAttribute|SDL_GL_GetSwapInterval|SDL_GL_LoadLibrary|SDL_GL_MakeCurrent|SDL_GL_SetAttribute|SDL_GL_SetSwapInterval|SDL_GL_SwapWindow|SDL_GetAudioDeviceFormat|SDL_GetAudioStreamFormat|SDL_GetCameraFormat|SDL_GetClosestFullscreenDisplayMode|SDL_GetCurrentRenderOutputSize|SDL_GetCurrentTime|SDL_GetDXGIOutputInfo|SDL_GetDateTimeLocalePreferences|SDL_GetDisplayBounds|SDL_GetDisplayUsableBounds|SDL_GetGDKDefaultUser|SDL_GetGDKTaskQueue|SDL_GetGamepadSensorData|SDL_GetGamepadTouchpadFinger|SDL_GetHapticEffectStatus|SDL_GetJoystickBall|SDL_GetMasksForPixelFormat|SDL_GetPathInfo|SDL_GetRectUnion|SDL_GetRectUnionFloat|SDL_GetRenderClipRect|SDL_GetRenderColorScale|SDL_GetRenderDrawBlendMode|SDL_GetRenderDrawColor|SDL_GetRenderDrawColorFloat|SDL_GetRenderLogicalPresentation|SDL_GetRenderLogicalPresentationRect|SDL_GetRenderOutputSize|SDL_GetRenderSafeArea|SDL_GetRenderScale|SDL_GetRenderVSync|SDL_GetRenderViewport|SDL_GetSensorData|SDL_GetStorageFileSize|SDL_GetStoragePathInfo|SDL_GetSurfaceAlphaMod|SDL_GetSurfaceBlendMode|SDL_GetSurfaceClipRect|SDL_GetSurfaceColorKey|SDL_GetSurfaceColorMod|SDL_GetTextInputArea|SDL_GetTextureAlphaMod|SDL_GetTextureAlphaModFloat|SDL_GetTextureBlendMode|SDL_GetTextureColorMod|SDL_GetTextureColorModFloat|SDL_GetTextureScaleMode|SDL_GetTextureSize|SDL_GetWindowAspectRatio|SDL_GetWindowBordersSize|SDL_GetWindowMaximumSize|SDL_GetWindowMinimumSize|SDL_GetWindowPosition|SDL_GetWindowRelativeMouseMode|SDL_GetWindowSafeArea|SDL_GetWindowSize|SDL_GetWindowSizeInPixels|SDL_GetWindowSurfaceVSync|SDL_HideCursor|SDL_HideWindow|SDL_Init|SDL_InitHapticRumble|SDL_InitSubSystem|SDL_LoadWAV|SDL_LoadWAV_IO|SDL_LockAudioStream|SDL_LockProperties|SDL_LockSurface|SDL_LockTexture|SDL_LockTextureToSurface|SDL_MaximizeWindow|SDL_MinimizeWindow|SDL_MixAudio|SDL_OpenURL|SDL_OutOfMemory|SDL_PauseAudioDevice|SDL_PauseAudioStreamDevice|SDL_PauseHaptic|SDL_PlayHapticRumble|SDL_PremultiplyAlpha|SDL_PremultiplySurfaceAlpha|SDL_PushEvent|SDL_PutAudioStreamData|SDL_RaiseWindow|SDL_ReadStorageFile|SDL_ReadSurfacePixel|SDL_ReadSurfacePixelFloat|SDL_RegisterApp|SDL_ReloadGamepadMappings|SDL_RemovePath|SDL_RemoveStoragePath|SDL_RemoveTimer|SDL_RenamePath|SDL_RenameStoragePath|SDL_RenderClear|SDL_RenderCoordinatesFromWindow|SDL_RenderCoordinatesToWindow|SDL_RenderFillRect|SDL_RenderFillRects|SDL_RenderGeometry|SDL_RenderGeometryRaw|SDL_RenderLine|SDL_RenderLines|SDL_RenderPoint|SDL_RenderPoints|SDL_RenderPresent|SDL_RenderRect|SDL_RenderRects|SDL_RenderTexture|SDL_RenderTexture9Grid|SDL_RenderTextureRotated|SDL_RenderTextureTiled|SDL_RequestAndroidPermission|SDL_RestoreWindow|SDL_ResumeAudioDevice|SDL_ResumeAudioStreamDevice|SDL_ResumeHaptic|SDL_RumbleGamepad|SDL_RumbleGamepadTriggers|SDL_RumbleJoystick|SDL_RumbleJoystickTriggers|SDL_RunHapticEffect|SDL_SaveBMP|SDL_SaveBMP_IO|SDL_SendAndroidMessage|SDL_SendGamepadEffect|SDL_SendJoystickEffect|SDL_SendJoystickVirtualSensorData|SDL_SetAppMetadata|SDL_SetAppMetadataProperty|SDL_SetAudioDeviceGain|SDL_SetAudioPostmixCallback|SDL_SetAudioStreamFormat|SDL_SetAudioStreamFrequencyRatio|SDL_SetAudioStreamGain|SDL_SetAudioStreamGetCallback|SDL_SetAudioStreamInputChannelMap|SDL_SetAudioStreamOutputChannelMap|SDL_SetAudioStreamPutCallback|SDL_SetBooleanProperty|SDL_SetClipboardData|SDL_SetClipboardText|SDL_SetCursor|SDL_SetFloatProperty|SDL_SetGamepadLED|SDL_SetGamepadMapping|SDL_SetGamepadPlayerIndex|SDL_SetGamepadSensorEnabled|SDL_SetHapticAutocenter|SDL_SetHapticGain|SDL_SetJoystickLED|SDL_SetJoystickPlayerIndex|SDL_SetJoystickVirtualAxis|SDL_SetJoystickVirtualBall|SDL_SetJoystickVirtualButton|SDL_SetJoystickVirtualHat|SDL_SetJoystickVirtualTouchpad|SDL_SetLinuxThreadPriority|SDL_SetLinuxThreadPriorityAndPolicy|SDL_SetLogPriorityPrefix|SDL_SetMemoryFunctions|SDL_SetNumberProperty|SDL_SetPaletteColors|SDL_SetPointerProperty|SDL_SetPointerPropertyWithCleanup|SDL_SetPrimarySelectionText|SDL_SetRenderClipRect|SDL_SetRenderColorScale|SDL_SetRenderDrawBlendMode|SDL_SetRenderDrawColor|SDL_SetRenderDrawColorFloat|SDL_SetRenderLogicalPresentation|SDL_SetRenderScale|SDL_SetRenderTarget|SDL_SetRenderVSync|SDL_SetRenderViewport|SDL_SetScancodeName|SDL_SetStringProperty|SDL_SetSurfaceAlphaMod|SDL_SetSurfaceBlendMode|SDL_SetSurfaceColorKey|SDL_SetSurfaceColorMod|SDL_SetSurfaceColorspace|SDL_SetSurfacePalette|SDL_SetSurfaceRLE|SDL_SetTLS|SDL_SetTextInputArea|SDL_SetTextureAlphaMod|SDL_SetTextureAlphaModFloat|SDL_SetTextureBlendMode|SDL_SetTextureColorMod|SDL_SetTextureColorModFloat|SDL_SetTextureScaleMode|SDL_SetThreadPriority|SDL_SetWindowAlwaysOnTop|SDL_SetWindowAspectRatio|SDL_SetWindowBordered|SDL_SetWindowFocusable|SDL_SetWindowFullscreen|SDL_SetWindowFullscreenMode|SDL_SetWindowHitTest|SDL_SetWindowIcon|SDL_SetWindowKeyboardGrab|SDL_SetWindowMaximumSize|SDL_SetWindowMinimumSize|SDL_SetWindowModalFor|SDL_SetWindowMouseGrab|SDL_SetWindowMouseRect|SDL_SetWindowOpacity|SDL_SetWindowPosition|SDL_SetWindowRelativeMouseMode|SDL_SetWindowResizable|SDL_SetWindowShape|SDL_SetWindowSize|SDL_SetWindowSurfaceVSync|SDL_SetWindowTitle|SDL_SetiOSAnimationCallback|SDL_ShowAndroidToast|SDL_ShowCursor|SDL_ShowMessageBox|SDL_ShowSimpleMessageBox|SDL_ShowWindow|SDL_ShowWindowSystemMenu|SDL_StartTextInput|SDL_StartTextInputWithProperties|SDL_StopHapticEffect|SDL_StopHapticEffects|SDL_StopHapticRumble|SDL_StopTextInput|SDL_SyncWindow|SDL_TimeToDateTime|SDL_TryLockMutex|SDL_TryLockRWLockForReading|SDL_TryLockRWLockForWriting|SDL_TryWaitSemaphore|SDL_UnlockAudioStream|SDL_UpdateHapticEffect|SDL_UpdateNVTexture|SDL_UpdateTexture|SDL_UpdateWindowSurface|SDL_UpdateWindowSurfaceRects|SDL_UpdateYUVTexture|SDL_Vulkan_CreateSurface|SDL_Vulkan_LoadLibrary|SDL_WaitConditionTimeout|SDL_WaitSemaphoreTimeout|SDL_WarpMouseGlobal|SDL_WriteStorageFile|SDL_WriteSurfacePixel|SDL_WriteSurfacePixelFloat|SDL_size_mul_check_overflow|SDL_size_add_check_overflow|TTF_GlyphMetrics|TTF_GlyphMetrics32|TTF_Init|TTF_MeasureText|TTF_MeasureUNICODE|TTF_MeasureUTF8|TTF_SetFontDirection|TTF_SetFontLanguage|TTF_SetFontScriptName|TTF_SetFontSDF|TTF_SetFontSize|TTF_SetFontSizeDPI|TTF_SizeText|TTF_SizeUNICODE|TTF_SizeUTF8|IMG_SaveAVIF|IMG_SaveAVIF_IO|IMG_SaveJPG|IMG_SaveJPG_IO|IMG_SavePNG|IMG_SavePNG_IO|Mix_FadeInMusic|Mix_FadeInMusicPos|Mix_GroupChannels|Mix_ModMusicJumpToOrder|Mix_OpenAudio|Mix_PlayMusic|Mix_SetMusicCMD|Mix_SetMusicPosition|Mix_SetSoundFonts|Mix_StartTrack)$"; -@@ -( - func( - ... - ) -- == 0 -| -- func( -+ !func( - ... - ) -- < 0 -| -- func( -+ !func( - ... - ) -- != 0 -| -- func( -+ !func( - ... - ) -- == -1 -) -@@ -@@ -- SDL_NUM_LOG_PRIORITIES -+ SDL_LOG_PRIORITY_COUNT -@@ -@@ -- SDL_MESSAGEBOX_COLOR_MAX -+ SDL_MESSAGEBOX_COLOR_COUNT -@@ -@@ -- SDL_NUM_SYSTEM_CURSORS -+ SDL_SYSTEM_CURSOR_COUNT -@@ -@@ -- SDL_NUM_SCANCODES -+ SDL_SCANCODE_COUNT -@@ -@@ -- SDL_GetCPUCount -+ SDL_GetNumLogicalCPUCores - (...) -@@ -typedef SDL_bool, bool; -@@ -- SDL_bool -+ bool -@@ -@@ -- SDL_TRUE -+ true -@@ -@@ -- SDL_FALSE -+ false -@@ -@@ -- SDL_IsAndroidTV -+ SDL_IsTV - (...) -@@ -@@ -- SDL_SetThreadPriority -+ SDL_SetCurrentThreadPriority - (...) -@@ -@@ -- SDL_BUTTON -+ SDL_BUTTON_MASK -@@ -@@ -- SDL_GLprofile -+ SDL_GLProfile -@@ -@@ -- SDL_GLcontextFlag -+ SDL_GLContextFlag -@@ -@@ -- SDL_GLcontextReleaseFlag -+ SDL_GLContextReleaseFlag -@@ -@@ -- SDL_GLattr -+ SDL_GLAttr -@@ -@@ -- SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE -+ SDL_HINT_JOYSTICK_ENHANCED_REPORTS -@@ -@@ -- SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE -+ SDL_HINT_JOYSTICK_ENHANCED_REPORTS diff --git a/contrib/SDL-3.2.8/build-scripts/add-source-to-projects.pl b/contrib/SDL-3.2.8/build-scripts/add-source-to-projects.pl deleted file mode 100755 index 5ba0a69..0000000 --- a/contrib/SDL-3.2.8/build-scripts/add-source-to-projects.pl +++ /dev/null @@ -1,599 +0,0 @@ -#!/usr/bin/perl -w - -# Add source files and headers to Xcode and Visual Studio projects. -# THIS IS NOT ROBUST, THIS IS JUST RYAN AVOIDING RUNNING BETWEEN -# THREE COMPUTERS AND A BUNCH OF DEVELOPMENT ENVIRONMENTS TO ADD -# A STUPID FILE TO THE BUILD. - - -use warnings; -use strict; -use File::Basename; - - -my %xcode_references = (); -sub generate_xcode_id { - my @chars = ('0'..'9', 'A'..'F'); - my $str; - - do { - my $len = 16; - $str = '0000'; # start and end with '0000' so we know we added it. - while ($len--) { - $str .= $chars[rand @chars] - }; - $str .= '0000'; # start and end with '0000' so we know we added it. - } while (defined($xcode_references{$str})); - - $xcode_references{$str} = 1; # so future calls can't generate this one. - - return $str; -} - -sub process_xcode { - my $addpath = shift; - my $pbxprojfname = shift; - my $lineno; - - %xcode_references = (); - - my $addfname = basename($addpath); - my $addext = ''; - if ($addfname =~ /\.(.*?)\Z/) { - $addext = $1; - } - - my $is_public_header = ($addpath =~ /\Ainclude\/SDL3\//) ? 1 : 0; - my $filerefpath = $is_public_header ? "SDL3/$addfname" : $addfname; - - my $srcs_or_headers = ''; - my $addfiletype = ''; - - if ($addext eq 'c') { - $srcs_or_headers = 'Sources'; - $addfiletype = 'sourcecode.c.c'; - } elsif ($addext eq 'm') { - $srcs_or_headers = 'Sources'; - $addfiletype = 'sourcecode.c.objc'; - } elsif ($addext eq 'h') { - $srcs_or_headers = 'Headers'; - $addfiletype = 'sourcecode.c.h'; - } else { - die("Unexpected file extension '$addext'\n"); - } - - my $fh; - - open $fh, '<', $pbxprojfname or die("Failed to open '$pbxprojfname': $!\n"); - chomp(my @pbxproj = <$fh>); - close($fh); - - # build a table of all ids, in case we duplicate one by some miracle. - $lineno = 0; - foreach (@pbxproj) { - $lineno++; - - # like "F3676F582A7885080091160D /* SDL3.dmg */ = {" - if (/\A\t\t([A-F0-9]{24}) \/\* (.*?) \*\/ \= \{\Z/) { - $xcode_references{$1} = $2; - } - } - - # build out of a tree of PBXGroup items. - my %pbxgroups = (); - my $thispbxgroup; - my $pbxgroup_children; - my $pbxgroup_state = 0; - my $pubheaders_group_hash = ''; - my $libsrc_group_hash = ''; - $lineno = 0; - foreach (@pbxproj) { - $lineno++; - if ($pbxgroup_state == 0) { - $pbxgroup_state++ if /\A\/\* Begin PBXGroup section \*\/\Z/; - } elsif ($pbxgroup_state == 1) { - # like "F3676F582A7885080091160D /* SDL3.dmg */ = {" - if (/\A\t\t([A-F0-9]{24}) \/\* (.*?) \*\/ \= \{\Z/) { - my %newhash = (); - $pbxgroups{$1} = \%newhash; - $thispbxgroup = \%newhash; - $pubheaders_group_hash = $1 if $2 eq 'Public Headers'; - $libsrc_group_hash = $1 if $2 eq 'Library Source'; - $pbxgroup_state++; - } elsif (/\A\/\* End PBXGroup section \*\/\Z/) { - last; - } else { - die("Expected pbxgroup obj on '$pbxprojfname' line $lineno\n"); - } - } elsif ($pbxgroup_state == 2) { - if (/\A\t\t\tisa \= PBXGroup;\Z/) { - $pbxgroup_state++; - } else { - die("Expected pbxgroup obj's isa field on '$pbxprojfname' line $lineno\n"); - } - } elsif ($pbxgroup_state == 3) { - if (/\A\t\t\tchildren \= \(\Z/) { - my %newhash = (); - $$thispbxgroup{'children'} = \%newhash; - $pbxgroup_children = \%newhash; - $pbxgroup_state++; - } else { - die("Expected pbxgroup obj's children field on '$pbxprojfname' line $lineno\n"); - } - } elsif ($pbxgroup_state == 4) { - if (/\A\t\t\t\t([A-F0-9]{24}) \/\* (.*?) \*\/,\Z/) { - $$pbxgroup_children{$1} = $2; - } elsif (/\A\t\t\t\);\Z/) { - $pbxgroup_state++; - } else { - die("Expected pbxgroup obj's children element on '$pbxprojfname' line $lineno\n"); - } - } elsif ($pbxgroup_state == 5) { - if (/\A\t\t\t(.*?) \= (.*?);\Z/) { - $$thispbxgroup{$1} = $2; - } elsif (/\A\t\t\};\Z/) { - $pbxgroup_state = 1; - } else { - die("Expected pbxgroup obj field on '$pbxprojfname' line $lineno\n"); - } - } else { - die("bug in this script."); - } - } - - die("Didn't see PBXGroup section in '$pbxprojfname'. Bug?\n") if $pbxgroup_state == 0; - die("Didn't see Public Headers PBXGroup in '$pbxprojfname'. Bug?\n") if $pubheaders_group_hash eq ''; - die("Didn't see Library Source PBXGroup in '$pbxprojfname'. Bug?\n") if $libsrc_group_hash eq ''; - - # Some debug log dumping... - if (0) { - foreach (keys %pbxgroups) { - my $k = $_; - my $g = $pbxgroups{$k}; - print("$_:\n"); - foreach (keys %$g) { - print(" $_:\n"); - if ($_ eq 'children') { - my $kids = $$g{$_}; - foreach (keys %$kids) { - print(" $_ -> " . $$kids{$_} . "\n"); - } - } else { - print(' ' . $$g{$_} . "\n"); - } - } - print("\n"); - } - } - - # Get some unique IDs for our new thing. - my $fileref = generate_xcode_id(); - my $buildfileref = generate_xcode_id(); - - - # Figure out what group to insert this into (or what groups to make) - my $add_to_group_fileref = $fileref; - my $add_to_group_addfname = $addfname; - my $newgrptext = ''; - my $grphash = ''; - if ($is_public_header) { - $grphash = $pubheaders_group_hash; # done! - } else { - $grphash = $libsrc_group_hash; - my @splitpath = split(/\//, dirname($addpath)); - if ($splitpath[0] eq 'src') { - shift @splitpath; - } - while (my $elem = shift(@splitpath)) { - my $g = $pbxgroups{$grphash}; - my $kids = $$g{'children'}; - my $found = 0; - foreach (keys %$kids) { - my $hash = $_; - my $fname = $$kids{$hash}; - if (uc($fname) eq uc($elem)) { - $grphash = $hash; - $found = 1; - last; - } - } - unshift(@splitpath, $elem), last if (not $found); - } - - if (@splitpath) { # still elements? We need to build groups. - my $newgroupref = generate_xcode_id(); - - $add_to_group_fileref = $newgroupref; - $add_to_group_addfname = $splitpath[0]; - - while (my $elem = shift(@splitpath)) { - my $lastelem = @splitpath ? 0 : 1; - my $childhash = $lastelem ? $fileref : generate_xcode_id(); - my $childpath = $lastelem ? $addfname : $splitpath[0]; - $newgrptext .= "\t\t$newgroupref /* $elem */ = {\n"; - $newgrptext .= "\t\t\tisa = PBXGroup;\n"; - $newgrptext .= "\t\t\tchildren = (\n"; - $newgrptext .= "\t\t\t\t$childhash /* $childpath */,\n"; - $newgrptext .= "\t\t\t);\n"; - $newgrptext .= "\t\t\tpath = $elem;\n"; - $newgrptext .= "\t\t\tsourceTree = \"\";\n"; - $newgrptext .= "\t\t};\n"; - $newgroupref = $childhash; - } - } - } - - my $tmpfname = "$pbxprojfname.tmp"; - open $fh, '>', $tmpfname or die("Failed to open '$tmpfname': $!\n"); - - my $add_to_this_group = 0; - $pbxgroup_state = 0; - $lineno = 0; - foreach (@pbxproj) { - $lineno++; - if ($pbxgroup_state == 0) { - # Drop in new references at the end of their sections... - if (/\A\/\* End PBXBuildFile section \*\/\Z/) { - print $fh "\t\t$buildfileref /* $addfname in $srcs_or_headers */ = {isa = PBXBuildFile; fileRef = $fileref /* $addfname */;"; - if ($is_public_header) { - print $fh " settings = {ATTRIBUTES = (Public, ); };"; - } - print $fh " };\n"; - } elsif (/\A\/\* End PBXFileReference section \*\/\Z/) { - print $fh "\t\t$fileref /* $addfname */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = $addfiletype; name = $addfname; path = $filerefpath; sourceTree = \"\"; };\n"; - } elsif (/\A\/\* Begin PBXGroup section \*\/\Z/) { - $pbxgroup_state = 1; - } elsif (/\A\/\* Begin PBXSourcesBuildPhase section \*\/\Z/) { - $pbxgroup_state = 5; - } - } elsif ($pbxgroup_state == 1) { - if (/\A\t\t([A-F0-9]{24}) \/\* (.*?) \*\/ \= \{\Z/) { - $pbxgroup_state++; - $add_to_this_group = $1 eq $grphash; - } elsif (/\A\/\* End PBXGroup section \*\/\Z/) { - print $fh $newgrptext; - $pbxgroup_state = 0; - } - } elsif ($pbxgroup_state == 2) { - if (/\A\t\t\tchildren \= \(\Z/) { - $pbxgroup_state++; - } - } elsif ($pbxgroup_state == 3) { - if (/\A\t\t\t\);\Z/) { - if ($add_to_this_group) { - print $fh "\t\t\t\t$add_to_group_fileref /* $add_to_group_addfname */,\n"; - } - $pbxgroup_state++; - } - } elsif ($pbxgroup_state == 4) { - if (/\A\t\t\};\Z/) { - $add_to_this_group = 0; - } - $pbxgroup_state = 1; - } elsif ($pbxgroup_state == 5) { - if (/\A\t\t\t\);\Z/) { - if ($srcs_or_headers eq 'Sources') { - print $fh "\t\t\t\t$buildfileref /* $addfname in $srcs_or_headers */,\n"; - } - $pbxgroup_state = 0; - } - } - - print $fh "$_\n"; - } - - close($fh); - rename($tmpfname, $pbxprojfname); -} - -my %visualc_references = (); -sub generate_visualc_id { # these are just standard Windows GUIDs. - my @chars = ('0'..'9', 'a'..'f'); - my $str; - - do { - my $len = 24; - $str = '0000'; # start and end with '0000' so we know we added it. - while ($len--) { - $str .= $chars[rand @chars] - }; - $str .= '0000'; # start and end with '0000' so we know we added it. - $str =~ s/\A(........)(....)(....)(............)\Z/$1-$2-$3-$4/; # add dashes in the appropriate places. - } while (defined($visualc_references{$str})); - - $visualc_references{$str} = 1; # so future calls can't generate this one. - - return $str; -} - - -sub process_visualstudio { - my $addpath = shift; - my $vcxprojfname = shift; - my $lineno; - - %visualc_references = (); - - my $is_public_header = ($addpath =~ /\Ainclude\/SDL3\//) ? 1 : 0; - - my $addfname = basename($addpath); - my $addext = ''; - if ($addfname =~ /\.(.*?)\Z/) { - $addext = $1; - } - - my $isheader = 0; - if ($addext eq 'c') { - $isheader = 0; - } elsif ($addext eq 'm') { - return; # don't add Objective-C files to Visual Studio projects! - } elsif ($addext eq 'h') { - $isheader = 1; - } else { - die("Unexpected file extension '$addext'\n"); - } - - my $fh; - - open $fh, '<', $vcxprojfname or die("Failed to open '$vcxprojfname': $!\n"); - chomp(my @vcxproj = <$fh>); - close($fh); - - my $vcxgroup_state; - - my $rawaddvcxpath = "$addpath"; - $rawaddvcxpath =~ s/\//\\/g; - - # Figure out relative path from vcxproj file... - my $addvcxpath = ''; - my @subdirs = split(/\//, $vcxprojfname); - pop @subdirs; - foreach (@subdirs) { - $addvcxpath .= "..\\"; - } - $addvcxpath .= $rawaddvcxpath; - - my $prevname = undef; - - my $tmpfname; - - $tmpfname = "$vcxprojfname.tmp"; - open $fh, '>', $tmpfname or die("Failed to open '$tmpfname': $!\n"); - - my $added = 0; - - $added = 0; - $vcxgroup_state = 0; - $prevname = undef; - $lineno = 0; - foreach (@vcxproj) { - $lineno++; - if ($vcxgroup_state == 0) { - if (/\A \\Z/) { - $vcxgroup_state = 1; - $prevname = undef; - } - } elsif ($vcxgroup_state == 1) { - if (/\A \\Z/) { - $vcxgroup_state = 0; - $prevname = undef; - } - } - - # Don't do elsif, we need to check this line again. - if ($vcxgroup_state == 2) { - if (/\A \Z/) { - my $nextname = $1; - if ((not $added) && (((not defined $prevname) || (uc($prevname) lt uc($addvcxpath))) && (uc($nextname) gt uc($addvcxpath)))) { - print $fh " \n"; - $vcxgroup_state = 0; - $added = 1; - } - $prevname = $nextname; - } elsif (/\A \<\/ItemGroup\>\Z/) { - if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { - print $fh " \n"; - $vcxgroup_state = 0; - $added = 1; - } - } - } elsif ($vcxgroup_state == 3) { - if (/\A \Z/) { - my $nextname = $1; - if ((not $added) && (((not defined $prevname) || (uc($prevname) lt uc($addvcxpath))) && (uc($nextname) gt uc($addvcxpath)))) { - print $fh " \n"; - $vcxgroup_state = 0; - $added = 1; - } - $prevname = $nextname; - } elsif (/\A \<\/ItemGroup\>\Z/) { - if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { - print $fh " \n"; - $vcxgroup_state = 0; - $added = 1; - } - } - } - - print $fh "$_\n"; - } - - close($fh); - rename($tmpfname, $vcxprojfname); - - my $vcxfiltersfname = "$vcxprojfname.filters"; - open $fh, '<', $vcxfiltersfname or die("Failed to open '$vcxfiltersfname': $!\n"); - chomp(my @vcxfilters = <$fh>); - close($fh); - - my $newgrptext = ''; - my $filter = ''; - if ($is_public_header) { - $filter = 'API Headers'; - } else { - $filter = lc(dirname($addpath)); - $filter =~ s/\Asrc\///; # there's no filter for the base "src/" dir, where SDL.c and friends live. - $filter =~ s/\//\\/g; - $filter = '' if $filter eq 'src'; - - if ($filter ne '') { - # see if the filter already exists, otherwise add it. - my %existing_filters = (); - my $current_filter = ''; - my $found = 0; - foreach (@vcxfilters) { - # These lines happen to be unique, so we don't have to parse down to find this section. - if (/\A \\Z/) { - $current_filter = lc($1); - if ($current_filter eq $filter) { - $found = 1; - } - } elsif (/\A \\{(.*?)\}\<\/UniqueIdentifier\>\Z/) { - $visualc_references{$1} = $current_filter; # gather up existing GUIDs to avoid duplicates. - $existing_filters{$current_filter} = $1; - } - } - - if (not $found) { # didn't find it? We need to build filters. - my $subpath = ''; - my @splitpath = split(/\\/, $filter); - while (my $elem = shift(@splitpath)) { - $subpath .= "\\" if ($subpath ne ''); - $subpath .= $elem; - if (not $existing_filters{$subpath}) { - my $newgroupref = generate_visualc_id(); - $newgrptext .= " \n"; - $newgrptext .= " {$newgroupref}\n"; - $newgrptext .= " \n" - } - } - } - } - } - - $tmpfname = "$vcxfiltersfname.tmp"; - open $fh, '>', $tmpfname or die("Failed to open '$tmpfname': $!\n"); - - $added = 0; - $vcxgroup_state = 0; - $prevname = undef; - $lineno = 0; - foreach (@vcxfilters) { - $lineno++; - - # We cheat here, because these lines are unique, we don't have to fully parse this file. - if ($vcxgroup_state == 0) { - if (/\A \\Z/) { - if ($newgrptext ne '') { - $vcxgroup_state = 1; - $prevname = undef; - } - } elsif (/\A \\Z/) { - print $fh $newgrptext; - $newgrptext = ''; - $vcxgroup_state = 0; - } - } elsif ($vcxgroup_state == 2) { - if (/\A \n"; - print $fh " $filter\n"; - print $fh " \n"; - } else { - print $fh " />\n"; - } - $added = 1; - } - $prevname = $nextname; - } elsif (/\A \<\/ItemGroup\>\Z/) { - if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { - print $fh " \n"; - print $fh " $filter\n"; - print $fh " \n"; - } else { - print $fh " />\n"; - } - $added = 1; - } - $vcxgroup_state = 0; - } - } elsif ($vcxgroup_state == 3) { - if (/\A \n"; - print $fh " $filter\n"; - print $fh " \n"; - } else { - print $fh " />\n"; - } - $added = 1; - } - $prevname = $nextname; - } elsif (/\A \<\/ItemGroup\>\Z/) { - if ((not $added) && ((not defined $prevname) || (uc($prevname) lt uc($addvcxpath)))) { - print $fh " \n"; - print $fh " $filter\n"; - print $fh " \n"; - } else { - print $fh " />\n"; - } - $added = 1; - } - $vcxgroup_state = 0; - } - } - - print $fh "$_\n"; - } - - close($fh); - rename($tmpfname, $vcxfiltersfname); -} - - -# Mainline! - -chdir(dirname($0)); # assumed to be in build-scripts -chdir('..'); # head to root of source tree. - -foreach (@ARGV) { - s/\A\.\///; # Turn "./path/to/file.txt" into "path/to/file.txt" - my $arg = $_; - process_xcode($arg, 'Xcode/SDL/SDL.xcodeproj/project.pbxproj'); - process_visualstudio($arg, 'VisualC/SDL/SDL.vcxproj'); - process_visualstudio($arg, 'VisualC-GDK/SDL/SDL.vcxproj'); -} - -print("Done. Please run `git diff` and make sure this looks okay!\n"); - -exit(0); - diff --git a/contrib/SDL-3.2.8/build-scripts/androidbuildlibs.sh b/contrib/SDL-3.2.8/build-scripts/androidbuildlibs.sh deleted file mode 100755 index a903f36..0000000 --- a/contrib/SDL-3.2.8/build-scripts/androidbuildlibs.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -# -# Build the Android libraries without needing a project -# (AndroidManifest.xml, jni/{Application,Android}.mk, etc.) -# -# Usage: androidbuildlibs.sh [arg for ndk-build ...]" -# -# Useful NDK arguments: -# -# NDK_DEBUG=1 - build debug version -# NDK_LIBS_OUT= - specify alternate destination for installable -# modules. -# - - -# Android.mk is in srcdir -srcdir=`dirname $0`/.. -srcdir=`cd $srcdir && pwd` -cd $srcdir - - -# -# Create the build directories -# - -build=build -buildandroid=$build/android -platform=android-21 -abi="arm64-v8a" # "armeabi-v7a arm64-v8a x86 x86_64" -obj= -lib= -ndk_args= - -# Allow an external caller to specify locations and platform. -while [ $# -gt 0 ]; do - arg=$1 - if [ "${arg:0:8}" == "NDK_OUT=" ]; then - obj=${arg#NDK_OUT=} - elif [ "${arg:0:13}" == "NDK_LIBS_OUT=" ]; then - lib=${arg#NDK_LIBS_OUT=} - elif [ "${arg:0:13}" == "APP_PLATFORM=" ]; then - platform=${arg#APP_PLATFORM=} - elif [ "${arg:0:8}" == "APP_ABI=" ]; then - abi=${arg#APP_ABI=} - else - ndk_args="$ndk_args $arg" - fi - shift -done - -if [ -z $obj ]; then - obj=$buildandroid/obj -fi -if [ -z $lib ]; then - lib=$buildandroid/lib -fi - -for dir in $build $buildandroid $obj $lib; do - if test -d $dir; then - : - else - mkdir $dir || exit 1 - fi -done - - -# APP_* variables set in the environment here will not be seen by the -# ndk-build makefile segments that use them, e.g., default-application.mk. -# For consistency, pass all values on the command line. -ndk-build \ - NDK_PROJECT_PATH=null \ - NDK_OUT=$obj \ - NDK_LIBS_OUT=$lib \ - APP_BUILD_SCRIPT=Android.mk \ - APP_ABI="$abi" \ - APP_PLATFORM="$platform" \ - APP_MODULES="SDL3" \ - $ndk_args diff --git a/contrib/SDL-3.2.8/build-scripts/build-release.py b/contrib/SDL-3.2.8/build-scripts/build-release.py deleted file mode 100755 index f3faa06..0000000 --- a/contrib/SDL-3.2.8/build-scripts/build-release.py +++ /dev/null @@ -1,1556 +0,0 @@ -#!/usr/bin/env python3 - -""" -This script is shared between SDL2, SDL3, and all satellite libraries. -Don't specialize this script for doing project-specific modifications. -Rather, modify release-info.json. -""" - -import argparse -import collections -import dataclasses -from collections.abc import Callable -import contextlib -import datetime -import fnmatch -import glob -import io -import json -import logging -import multiprocessing -import os -from pathlib import Path -import platform -import re -import shlex -import shutil -import subprocess -import sys -import tarfile -import tempfile -import textwrap -import typing -import zipfile - - -logger = logging.getLogger(__name__) -GIT_HASH_FILENAME = ".git-hash" -REVISION_TXT = "REVISION.txt" - -RE_ILLEGAL_MINGW_LIBRARIES = re.compile(r"(?:lib)?(?:gcc|(?:std)?c[+][+]|(?:win)?pthread).*", flags=re.I) - - -def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime: - try: - return datetime.datetime.fromisoformat(str_isotime) - except ValueError: - pass - logger.warning("Invalid iso time: %s", str_isotime) - if str_isotime[-6:-5] in ("+", "-"): - # Commits can have isotime with invalid timezone offset (e.g. "2021-07-04T20:01:40+32:00") - modified_str_isotime = str_isotime[:-6] + "+00:00" - try: - return datetime.datetime.fromisoformat(modified_str_isotime) - except ValueError: - pass - raise ValueError(f"Invalid isotime: {str_isotime}") - - -def arc_join(*parts: list[str]) -> str: - assert all(p[:1] != "/" and p[-1:] != "/" for p in parts), f"None of {parts} may start or end with '/'" - return "/".join(p for p in parts if p) - - -@dataclasses.dataclass(frozen=True) -class VsArchPlatformConfig: - arch: str - configuration: str - platform: str - - def extra_context(self): - return { - "ARCH": self.arch, - "CONFIGURATION": self.configuration, - "PLATFORM": self.platform, - } - - -@contextlib.contextmanager -def chdir(path): - original_cwd = os.getcwd() - try: - os.chdir(path) - yield - finally: - os.chdir(original_cwd) - - -class Executer: - def __init__(self, root: Path, dry: bool=False): - self.root = root - self.dry = dry - - def run(self, cmd, cwd=None, env=None): - logger.info("Executing args=%r", cmd) - sys.stdout.flush() - if not self.dry: - subprocess.check_call(cmd, cwd=cwd or self.root, env=env, text=True) - - def check_output(self, cmd, cwd=None, dry_out=None, env=None, text=True): - logger.info("Executing args=%r", cmd) - sys.stdout.flush() - if self.dry: - return dry_out - return subprocess.check_output(cmd, cwd=cwd or self.root, env=env, text=text) - - -class SectionPrinter: - @contextlib.contextmanager - def group(self, title: str): - print(f"{title}:") - yield - - -class GitHubSectionPrinter(SectionPrinter): - def __init__(self): - super().__init__() - self.in_group = False - - @contextlib.contextmanager - def group(self, title: str): - print(f"::group::{title}") - assert not self.in_group, "Can enter a group only once" - self.in_group = True - yield - self.in_group = False - print("::endgroup::") - - -class VisualStudio: - def __init__(self, executer: Executer, year: typing.Optional[str]=None): - self.executer = executer - self.vsdevcmd = self.find_vsdevcmd(year) - self.msbuild = self.find_msbuild() - - @property - def dry(self) -> bool: - return self.executer.dry - - VS_YEAR_TO_VERSION = { - "2022": 17, - "2019": 16, - "2017": 15, - "2015": 14, - "2013": 12, - } - - def find_vsdevcmd(self, year: typing.Optional[str]=None) -> typing.Optional[Path]: - vswhere_spec = ["-latest"] - if year is not None: - try: - version = self.VS_YEAR_TO_VERSION[year] - except KeyError: - logger.error("Invalid Visual Studio year") - return None - vswhere_spec.extend(["-version", f"[{version},{version+1})"]) - vswhere_cmd = ["vswhere"] + vswhere_spec + ["-property", "installationPath"] - vs_install_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp").strip()) - logger.info("VS install_path = %s", vs_install_path) - assert vs_install_path.is_dir(), "VS installation path does not exist" - vsdevcmd_path = vs_install_path / "Common7/Tools/vsdevcmd.bat" - logger.info("vsdevcmd path = %s", vsdevcmd_path) - if self.dry: - vsdevcmd_path.parent.mkdir(parents=True, exist_ok=True) - vsdevcmd_path.touch(exist_ok=True) - assert vsdevcmd_path.is_file(), "vsdevcmd.bat batch file does not exist" - return vsdevcmd_path - - def find_msbuild(self) -> typing.Optional[Path]: - vswhere_cmd = ["vswhere", "-latest", "-requires", "Microsoft.Component.MSBuild", "-find", r"MSBuild\**\Bin\MSBuild.exe"] - msbuild_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp/MSBuild.exe").strip()) - logger.info("MSBuild path = %s", msbuild_path) - if self.dry: - msbuild_path.parent.mkdir(parents=True, exist_ok=True) - msbuild_path.touch(exist_ok=True) - assert msbuild_path.is_file(), "MSBuild.exe does not exist" - return msbuild_path - - def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path]): - assert projects, "Need at least one project to build" - - vsdev_cmd_str = f"\"{self.vsdevcmd}\" -arch={arch_platform.arch}" - msbuild_cmd_str = " && ".join([f"\"{self.msbuild}\" \"{project}\" /m /p:BuildInParallel=true /p:Platform={arch_platform.platform} /p:Configuration={arch_platform.configuration}" for project in projects]) - bat_contents = f"{vsdev_cmd_str} && {msbuild_cmd_str}\n" - bat_path = Path(tempfile.gettempdir()) / "cmd.bat" - with bat_path.open("w") as f: - f.write(bat_contents) - - logger.info("Running cmd.exe script (%s): %s", bat_path, bat_contents) - cmd = ["cmd.exe", "/D", "/E:ON", "/V:OFF", "/S", "/C", f"CALL {str(bat_path)}"] - self.executer.run(cmd) - - -class Archiver: - def __init__(self, zip_path: typing.Optional[Path]=None, tgz_path: typing.Optional[Path]=None, txz_path: typing.Optional[Path]=None): - self._zip_files = [] - self._tar_files = [] - self._added_files = set() - if zip_path: - self._zip_files.append(zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED)) - if tgz_path: - self._tar_files.append(tarfile.open(tgz_path, "w:gz")) - if txz_path: - self._tar_files.append(tarfile.open(txz_path, "w:xz")) - - @property - def added_files(self) -> set[str]: - return self._added_files - - def add_file_data(self, arcpath: str, data: bytes, mode: int, time: datetime.datetime): - for zf in self._zip_files: - file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second) - zip_info = zipfile.ZipInfo(filename=arcpath, date_time=file_data_time) - zip_info.external_attr = mode << 16 - zip_info.compress_type = zipfile.ZIP_DEFLATED - zf.writestr(zip_info, data=data) - for tf in self._tar_files: - tar_info = tarfile.TarInfo(arcpath) - tar_info.type = tarfile.REGTYPE - tar_info.mode = mode - tar_info.size = len(data) - tar_info.mtime = int(time.timestamp()) - tf.addfile(tar_info, fileobj=io.BytesIO(data)) - - self._added_files.add(arcpath) - - def add_symlink(self, arcpath: str, target: str, time: datetime.datetime, files_for_zip): - logger.debug("Adding symlink (target=%r) -> %s", target, arcpath) - for zf in self._zip_files: - file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second) - for f in files_for_zip: - zip_info = zipfile.ZipInfo(filename=f["arcpath"], date_time=file_data_time) - zip_info.external_attr = f["mode"] << 16 - zip_info.compress_type = zipfile.ZIP_DEFLATED - zf.writestr(zip_info, data=f["data"]) - for tf in self._tar_files: - tar_info = tarfile.TarInfo(arcpath) - tar_info.type = tarfile.SYMTYPE - tar_info.mode = 0o777 - tar_info.mtime = int(time.timestamp()) - tar_info.linkname = target - tf.addfile(tar_info) - - self._added_files.update(f["arcpath"] for f in files_for_zip) - - def add_git_hash(self, arcdir: str, commit: str, time: datetime.datetime): - arcpath = arc_join(arcdir, GIT_HASH_FILENAME) - data = f"{commit}\n".encode() - self.add_file_data(arcpath=arcpath, data=data, mode=0o100644, time=time) - - def add_file_path(self, arcpath: str, path: Path): - assert path.is_file(), f"{path} should be a file" - logger.debug("Adding %s -> %s", path, arcpath) - for zf in self._zip_files: - zf.write(path, arcname=arcpath) - for tf in self._tar_files: - tf.add(path, arcname=arcpath) - - def add_file_directory(self, arcdirpath: str, dirpath: Path): - assert dirpath.is_dir() - if arcdirpath and arcdirpath[-1:] != "/": - arcdirpath += "/" - for f in dirpath.iterdir(): - if f.is_file(): - arcpath = f"{arcdirpath}{f.name}" - logger.debug("Adding %s to %s", f, arcpath) - self.add_file_path(arcpath=arcpath, path=f) - - def close(self): - # Archiver is intentionally made invalid after this function - del self._zip_files - self._zip_files = None - del self._tar_files - self._tar_files = None - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - -class NodeInArchive: - def __init__(self, arcpath: str, path: typing.Optional[Path]=None, data: typing.Optional[bytes]=None, mode: typing.Optional[int]=None, symtarget: typing.Optional[str]=None, time: typing.Optional[datetime.datetime]=None, directory: bool=False): - self.arcpath = arcpath - self.path = path - self.data = data - self.mode = mode - self.symtarget = symtarget - self.time = time - self.directory = directory - - @classmethod - def from_fs(cls, arcpath: str, path: Path, mode: int=0o100644, time: typing.Optional[datetime.datetime]=None) -> "NodeInArchive": - if time is None: - time = datetime.datetime.fromtimestamp(os.stat(path).st_mtime) - return cls(arcpath=arcpath, path=path, mode=mode) - - @classmethod - def from_data(cls, arcpath: str, data: bytes, time: datetime.datetime) -> "NodeInArchive": - return cls(arcpath=arcpath, data=data, time=time, mode=0o100644) - - @classmethod - def from_text(cls, arcpath: str, text: str, time: datetime.datetime) -> "NodeInArchive": - return cls.from_data(arcpath=arcpath, data=text.encode(), time=time) - - @classmethod - def from_symlink(cls, arcpath: str, symtarget: str) -> "NodeInArchive": - return cls(arcpath=arcpath, symtarget=symtarget) - - @classmethod - def from_directory(cls, arcpath: str) -> "NodeInArchive": - return cls(arcpath=arcpath, directory=True) - - def __repr__(self) -> str: - return f"<{type(self).__name__}:arcpath={self.arcpath},path='{str(self.path)}',len(data)={len(self.data) if self.data else 'n/a'},directory={self.directory},symtarget={self.symtarget}>" - - -def configure_file(path: Path, context: dict[str, str]) -> bytes: - text = path.read_text() - return configure_text(text, context=context).encode() - - -def configure_text(text: str, context: dict[str, str]) -> str: - original_text = text - for txt, repl in context.items(): - text = text.replace(f"@<@{txt}@>@", repl) - success = all(thing not in text for thing in ("@<@", "@>@")) - if not success: - raise ValueError(f"Failed to configure {repr(original_text)}") - return text - - -def configure_text_list(text_list: list[str], context: dict[str, str]) -> list[str]: - return [configure_text(text=e, context=context) for e in text_list] - - -class ArchiveFileTree: - def __init__(self): - self._tree: dict[str, NodeInArchive] = {} - - def add_file(self, file: NodeInArchive): - self._tree[file.arcpath] = file - - def __iter__(self) -> typing.Iterable[NodeInArchive]: - yield from self._tree.values() - - def __contains__(self, value: str) -> bool: - return value in self._tree - - def get_latest_mod_time(self) -> datetime.datetime: - return max(item.time for item in self._tree.values() if item.time) - - def add_to_archiver(self, archive_base: str, archiver: Archiver): - remaining_symlinks = set() - added_files = dict() - - def calculate_symlink_target(s: NodeInArchive) -> str: - dest_dir = os.path.dirname(s.arcpath) - if dest_dir: - dest_dir += "/" - target = dest_dir + s.symtarget - while True: - new_target, n = re.subn(r"([^/]+/+[.]{2}/)", "", target) - target = new_target - if not n: - break - return target - - # Add files in first pass - for arcpath, node in self._tree.items(): - assert node is not None, f"{arcpath} -> node" - if node.data is not None: - archiver.add_file_data(arcpath=arc_join(archive_base, arcpath), data=node.data, time=node.time, mode=node.mode) - assert node.arcpath is not None, f"{node=}" - added_files[node.arcpath] = node - elif node.path is not None: - archiver.add_file_path(arcpath=arc_join(archive_base, arcpath), path=node.path) - assert node.arcpath is not None, f"{node=}" - added_files[node.arcpath] = node - elif node.symtarget is not None: - remaining_symlinks.add(node) - elif node.directory: - pass - else: - raise ValueError(f"Invalid Archive Node: {repr(node)}") - - assert None not in added_files - - # Resolve symlinks in second pass: zipfile does not support symlinks, so add files to zip archive - while True: - if not remaining_symlinks: - break - symlinks_this_time = set() - extra_added_files = {} - for symlink in remaining_symlinks: - symlink_files_for_zip = {} - symlink_target_path = calculate_symlink_target(symlink) - if symlink_target_path in added_files: - symlink_files_for_zip[symlink.arcpath] = added_files[symlink_target_path] - else: - symlink_target_path_slash = symlink_target_path + "/" - for added_file in added_files: - if added_file.startswith(symlink_target_path_slash): - path_in_symlink = symlink.arcpath + "/" + added_file.removeprefix(symlink_target_path_slash) - symlink_files_for_zip[path_in_symlink] = added_files[added_file] - if symlink_files_for_zip: - symlinks_this_time.add(symlink) - extra_added_files.update(symlink_files_for_zip) - files_for_zip = [{"arcpath": f"{archive_base}/{sym_path}", "data": sym_info.data, "mode": sym_info.mode} for sym_path, sym_info in symlink_files_for_zip.items()] - archiver.add_symlink(arcpath=f"{archive_base}/{symlink.arcpath}", target=symlink.symtarget, time=symlink.time, files_for_zip=files_for_zip) - # if not symlinks_this_time: - # logger.info("files added: %r", set(path for path in added_files.keys())) - assert symlinks_this_time, f"No targets found for symlinks: {remaining_symlinks}" - remaining_symlinks.difference_update(symlinks_this_time) - added_files.update(extra_added_files) - - def add_directory_tree(self, arc_dir: str, path: Path, time: datetime.datetime): - assert path.is_dir() - for files_dir, _, filenames in os.walk(path): - files_dir_path = Path(files_dir) - rel_files_path = files_dir_path.relative_to(path) - for filename in filenames: - self.add_file(NodeInArchive.from_fs(arcpath=arc_join(arc_dir, str(rel_files_path), filename), path=files_dir_path / filename, time=time)) - - def _add_files_recursively(self, arc_dir: str, paths: list[Path], time: datetime.datetime): - logger.debug(f"_add_files_recursively({arc_dir=} {paths=})") - for path in paths: - arcpath = arc_join(arc_dir, path.name) - if path.is_file(): - logger.debug("Adding %s as %s", path, arcpath) - self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time)) - elif path.is_dir(): - self._add_files_recursively(arc_dir=arc_join(arc_dir, path.name), paths=list(path.iterdir()), time=time) - else: - raise ValueError(f"Unsupported file type to add recursively: {path}") - - def add_file_mapping(self, arc_dir: str, file_mapping: dict[str, list[str]], file_mapping_root: Path, context: dict[str, str], time: datetime.datetime): - for meta_rel_destdir, meta_file_globs in file_mapping.items(): - rel_destdir = configure_text(meta_rel_destdir, context=context) - assert "@" not in rel_destdir, f"archive destination should not contain an @ after configuration ({repr(meta_rel_destdir)}->{repr(rel_destdir)})" - for meta_file_glob in meta_file_globs: - file_glob = configure_text(meta_file_glob, context=context) - assert "@" not in rel_destdir, f"archive glob should not contain an @ after configuration ({repr(meta_file_glob)}->{repr(file_glob)})" - if ":" in file_glob: - original_path, new_filename = file_glob.rsplit(":", 1) - assert ":" not in original_path, f"Too many ':' in {repr(file_glob)}" - assert "/" not in new_filename, f"New filename cannot contain a '/' in {repr(file_glob)}" - path = file_mapping_root / original_path - arcpath = arc_join(arc_dir, rel_destdir, new_filename) - if path.suffix == ".in": - data = configure_file(path, context=context) - logger.debug("Adding processed %s -> %s", path, arcpath) - self.add_file(NodeInArchive.from_data(arcpath=arcpath, data=data, time=time)) - else: - logger.debug("Adding %s -> %s", path, arcpath) - self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time)) - else: - relative_file_paths = glob.glob(file_glob, root_dir=file_mapping_root) - assert relative_file_paths, f"Glob '{file_glob}' does not match any file" - self._add_files_recursively(arc_dir=arc_join(arc_dir, rel_destdir), paths=[file_mapping_root / p for p in relative_file_paths], time=time) - - -class SourceCollector: - # TreeItem = collections.namedtuple("TreeItem", ("path", "mode", "data", "symtarget", "directory", "time")) - def __init__(self, root: Path, commit: str, filter: typing.Optional[Callable[[str], bool]], executer: Executer): - self.root = root - self.commit = commit - self.filter = filter - self.executer = executer - - def get_archive_file_tree(self) -> ArchiveFileTree: - git_archive_args = ["git", "archive", "--format=tar.gz", self.commit, "-o", "/dev/stdout"] - logger.info("Executing args=%r", git_archive_args) - contents_tgz = subprocess.check_output(git_archive_args, cwd=self.root, text=False) - tar_archive = tarfile.open(fileobj=io.BytesIO(contents_tgz), mode="r:gz") - filenames = tuple(m.name for m in tar_archive if (m.isfile() or m.issym())) - - file_times = self._get_file_times(paths=filenames) - git_contents = ArchiveFileTree() - for ti in tar_archive: - if self.filter and not self.filter(ti.name): - continue - data = None - symtarget = None - directory = False - file_time = None - if ti.isfile(): - contents_file = tar_archive.extractfile(ti.name) - data = contents_file.read() - file_time = file_times[ti.name] - elif ti.issym(): - symtarget = ti.linkname - file_time = file_times[ti.name] - elif ti.isdir(): - directory = True - else: - raise ValueError(f"{ti.name}: unknown type") - node = NodeInArchive(arcpath=ti.name, data=data, mode=ti.mode, symtarget=symtarget, time=file_time, directory=directory) - git_contents.add_file(node) - return git_contents - - def _get_file_times(self, paths: tuple[str, ...]) -> dict[str, datetime.datetime]: - dry_out = textwrap.dedent("""\ - time=2024-03-14T15:40:25-07:00 - - M\tCMakeLists.txt - """) - git_log_out = self.executer.check_output(["git", "log", "--name-status", '--pretty=time=%cI', self.commit], dry_out=dry_out, cwd=self.root).splitlines(keepends=False) - current_time = None - set_paths = set(paths) - path_times: dict[str, datetime.datetime] = {} - for line in git_log_out: - if not line: - continue - if line.startswith("time="): - current_time = safe_isotime_to_datetime(line.removeprefix("time=")) - continue - mod_type, file_paths = line.split(maxsplit=1) - assert current_time is not None - for file_path in file_paths.split("\t"): - if file_path in set_paths and file_path not in path_times: - path_times[file_path] = current_time - - # FIXME: find out why some files are not shown in "git log" - # assert set(path_times.keys()) == set_paths - if set(path_times.keys()) != set_paths: - found_times = set(path_times.keys()) - paths_without_times = set_paths.difference(found_times) - logger.warning("No times found for these paths: %s", paths_without_times) - max_time = max(time for time in path_times.values()) - for path in paths_without_times: - path_times[path] = max_time - - return path_times - - -class AndroidApiVersion: - def __init__(self, name: str, ints: tuple[int, ...]): - self.name = name - self.ints = ints - - def __repr__(self) -> str: - return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>" - - -class Releaser: - def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool): - self.release_info = release_info - self.project = release_info["name"] - self.version = self.extract_sdl_version(root=root, release_info=release_info) - self.root = root - self.commit = commit - self.revision = revision - self.dist_path = dist_path - self.section_printer = section_printer - self.executer = executer - self.cmake_generator = cmake_generator - self.cpu_count = multiprocessing.cpu_count() - self.deps_path = deps_path - self.overwrite = overwrite - self.github = github - self.fast = fast - self.arc_time = datetime.datetime.now() - - self.artifacts: dict[str, Path] = {} - - def get_context(self, extra_context: typing.Optional[dict[str, str]]=None) -> dict[str, str]: - ctx = { - "PROJECT_NAME": self.project, - "PROJECT_VERSION": self.version, - "PROJECT_COMMIT": self.commit, - "PROJECT_REVISION": self.revision, - "PROJECT_ROOT": str(self.root), - } - if extra_context: - ctx.update(extra_context) - return ctx - - @property - def dry(self) -> bool: - return self.executer.dry - - def prepare(self): - logger.debug("Creating dist folder") - self.dist_path.mkdir(parents=True, exist_ok=True) - - @classmethod - def _path_filter(cls, path: str) -> bool: - if ".gitmodules" in path: - return True - if path.startswith(".git"): - return False - return True - - @classmethod - def _external_repo_path_filter(cls, path: str) -> bool: - if not cls._path_filter(path): - return False - if path.startswith("test/") or path.startswith("tests/"): - return False - return True - - def create_source_archives(self) -> None: - source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter) - print(f"Collecting sources of {self.project}...") - archive_tree: ArchiveFileTree = source_collector.get_archive_file_tree() - latest_mod_time = archive_tree.get_latest_mod_time() - archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time)) - archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time)) - archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time) - - if "Makefile.am" in archive_tree: - patched_time = latest_mod_time + datetime.timedelta(minutes=1) - print(f"Makefile.am detected -> touching aclocal.m4, */Makefile.in, configure") - for node_data in archive_tree: - arc_name = os.path.basename(node_data.arcpath) - arc_name_we, arc_name_ext = os.path.splitext(arc_name) - if arc_name in ("aclocal.m4", "configure", "Makefile.in"): - print(f"Bumping time of {node_data.arcpath}") - node_data.time = patched_time - - archive_base = f"{self.project}-{self.version}" - zip_path = self.dist_path / f"{archive_base}.zip" - tgz_path = self.dist_path / f"{archive_base}.tar.gz" - txz_path = self.dist_path / f"{archive_base}.tar.xz" - - logger.info("Creating zip/tgz/txz source archives ...") - if self.dry: - zip_path.touch() - tgz_path.touch() - txz_path.touch() - else: - with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver: - print(f"Adding source files of {self.project}...") - archive_tree.add_to_archiver(archive_base=archive_base, archiver=archiver) - - for extra_repo in self.release_info["source"].get("extra-repos", []): - extra_repo_root = self.root / extra_repo - assert (extra_repo_root / ".git").exists(), f"{extra_repo_root} must be a git repo" - extra_repo_commit = self.executer.check_output(["git", "rev-parse", "HEAD"], dry_out=f"gitsha-extra-repo-{extra_repo}", cwd=extra_repo_root).strip() - extra_repo_source_collector = SourceCollector(root=extra_repo_root, commit=extra_repo_commit, executer=self.executer, filter=self._external_repo_path_filter) - print(f"Collecting sources of {extra_repo} ...") - extra_repo_archive_tree = extra_repo_source_collector.get_archive_file_tree() - print(f"Adding source files of {extra_repo} ...") - extra_repo_archive_tree.add_to_archiver(archive_base=f"{archive_base}/{extra_repo}", archiver=archiver) - - for file in self.release_info["source"]["checks"]: - assert f"{archive_base}/{file}" in archiver.added_files, f"'{archive_base}/{file}' must exist" - - logger.info("... done") - - self.artifacts["src-zip"] = zip_path - self.artifacts["src-tar-gz"] = tgz_path - self.artifacts["src-tar-xz"] = txz_path - - if not self.dry: - with tgz_path.open("r+b") as f: - # Zero the embedded timestamp in the gzip'ed tarball - f.seek(4, 0) - f.write(b"\x00\x00\x00\x00") - - def create_dmg(self, configuration: str="Release") -> None: - dmg_in = self.root / self.release_info["dmg"]["path"] - xcode_project = self.root / self.release_info["dmg"]["project"] - assert xcode_project.is_dir(), f"{xcode_project} must be a directory" - assert (xcode_project / "project.pbxproj").is_file, f"{xcode_project} must contain project.pbxproj" - if not self.fast: - dmg_in.unlink(missing_ok=True) - build_xcconfig = self.release_info["dmg"].get("build-xcconfig") - if build_xcconfig: - shutil.copy(self.root / build_xcconfig, xcode_project.parent / "build.xcconfig") - - xcode_scheme = self.release_info["dmg"].get("scheme") - xcode_target = self.release_info["dmg"].get("target") - assert xcode_scheme or xcode_target, "dmg needs scheme or target" - assert not (xcode_scheme and xcode_target), "dmg cannot have both scheme and target set" - if xcode_scheme: - scheme_or_target = "-scheme" - target_like = xcode_scheme - else: - scheme_or_target = "-target" - target_like = xcode_target - self.executer.run(["xcodebuild", "ONLY_ACTIVE_ARCH=NO", "-project", xcode_project, scheme_or_target, target_like, "-configuration", configuration]) - if self.dry: - dmg_in.parent.mkdir(parents=True, exist_ok=True) - dmg_in.touch() - - assert dmg_in.is_file(), f"{self.project}.dmg was not created by xcodebuild" - - dmg_out = self.dist_path / f"{self.project}-{self.version}.dmg" - shutil.copy(dmg_in, dmg_out) - self.artifacts["dmg"] = dmg_out - - @property - def git_hash_data(self) -> bytes: - return f"{self.commit}\n".encode() - - def verify_mingw_library(self, triplet: str, path: Path): - objdump_output = self.executer.check_output([f"{triplet}-objdump", "-p", str(path)]) - libraries = re.findall(r"DLL Name: ([^\n]+)", objdump_output) - logger.info("%s (%s) libraries: %r", path, triplet, libraries) - illegal_libraries = list(filter(RE_ILLEGAL_MINGW_LIBRARIES.match, libraries)) - logger.error("Detected 'illegal' libraries: %r", illegal_libraries) - if illegal_libraries: - raise Exception(f"{path} links to illegal libraries: {illegal_libraries}") - - def create_mingw_archives(self) -> None: - build_type = "Release" - build_parent_dir = self.root / "build-mingw" - ARCH_TO_GNU_ARCH = { - # "arm64": "aarch64", - "x86": "i686", - "x64": "x86_64", - } - ARCH_TO_TRIPLET = { - # "arm64": "aarch64-w64-mingw32", - "x86": "i686-w64-mingw32", - "x64": "x86_64-w64-mingw32", - } - - new_env = dict(os.environ) - - cmake_prefix_paths = [] - mingw_deps_path = self.deps_path / "mingw-deps" - - if "dependencies" in self.release_info["mingw"]: - shutil.rmtree(mingw_deps_path, ignore_errors=True) - mingw_deps_path.mkdir() - - for triplet in ARCH_TO_TRIPLET.values(): - (mingw_deps_path / triplet).mkdir() - - def extract_filter(member: tarfile.TarInfo, path: str, /): - if member.name.startswith("SDL"): - member.name = "/".join(Path(member.name).parts[1:]) - return member - for dep in self.release_info.get("dependencies", {}): - extract_path = mingw_deps_path / f"extract-{dep}" - extract_path.mkdir() - with chdir(extract_path): - tar_path = self.deps_path / glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)[0] - logger.info("Extracting %s to %s", tar_path, mingw_deps_path) - assert tar_path.suffix in (".gz", ".xz") - with tarfile.open(tar_path, mode=f"r:{tar_path.suffix.strip('.')}") as tarf: - tarf.extractall(filter=extract_filter) - for arch, triplet in ARCH_TO_TRIPLET.items(): - install_cmd = self.release_info["mingw"]["dependencies"][dep]["install-command"] - extra_configure_data = { - "ARCH": ARCH_TO_GNU_ARCH[arch], - "TRIPLET": triplet, - "PREFIX": str(mingw_deps_path / triplet), - } - install_cmd = configure_text(install_cmd, context=self.get_context(extra_configure_data)) - self.executer.run(shlex.split(install_cmd), cwd=str(extract_path)) - - dep_binpath = mingw_deps_path / triplet / "bin" - assert dep_binpath.is_dir(), f"{dep_binpath} for PATH should exist" - dep_pkgconfig = mingw_deps_path / triplet / "lib/pkgconfig" - assert dep_pkgconfig.is_dir(), f"{dep_pkgconfig} for PKG_CONFIG_PATH should exist" - - new_env["PATH"] = os.pathsep.join([str(dep_binpath), new_env["PATH"]]) - new_env["PKG_CONFIG_PATH"] = str(dep_pkgconfig) - cmake_prefix_paths.append(mingw_deps_path) - - new_env["CFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}" - new_env["CXXFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}" - - assert any(system in self.release_info["mingw"] for system in ("autotools", "cmake")) - assert not all(system in self.release_info["mingw"] for system in ("autotools", "cmake")) - - mingw_archs = set() - arc_root = f"{self.project}-{self.version}" - archive_file_tree = ArchiveFileTree() - - if "autotools" in self.release_info["mingw"]: - for arch in self.release_info["mingw"]["autotools"]["archs"]: - triplet = ARCH_TO_TRIPLET[arch] - new_env["CC"] = f"{triplet}-gcc" - new_env["CXX"] = f"{triplet}-g++" - new_env["RC"] = f"{triplet}-windres" - - assert arch not in mingw_archs - mingw_archs.add(arch) - - build_path = build_parent_dir / f"build-{triplet}" - install_path = build_parent_dir / f"install-{triplet}" - shutil.rmtree(install_path, ignore_errors=True) - build_path.mkdir(parents=True, exist_ok=True) - context = self.get_context({ - "ARCH": arch, - "DEP_PREFIX": str(mingw_deps_path / triplet), - }) - extra_args = configure_text_list(text_list=self.release_info["mingw"]["autotools"]["args"], context=context) - - with self.section_printer.group(f"Configuring MinGW {triplet} (autotools)"): - assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})" - self.executer.run([ - self.root / "configure", - f"--prefix={install_path}", - f"--includedir=${{prefix}}/include", - f"--libdir=${{prefix}}/lib", - f"--bindir=${{prefix}}/bin", - f"--host={triplet}", - f"--build=x86_64-none-linux-gnu", - "CFLAGS=-O2", - "CXXFLAGS=-O2", - "LDFLAGS=-Wl,-s", - ] + extra_args, cwd=build_path, env=new_env) - with self.section_printer.group(f"Build MinGW {triplet} (autotools)"): - self.executer.run(["make", f"-j{self.cpu_count}"], cwd=build_path, env=new_env) - with self.section_printer.group(f"Install MinGW {triplet} (autotools)"): - self.executer.run(["make", "install"], cwd=build_path, env=new_env) - self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll") - archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time) - - print("Recording arch-dependent extra files for MinGW development archive ...") - extra_context = { - "TRIPLET": ARCH_TO_TRIPLET[arch], - } - archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["autotools"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) - - if "cmake" in self.release_info["mingw"]: - assert self.release_info["mingw"]["cmake"]["shared-static"] in ("args", "both") - for arch in self.release_info["mingw"]["cmake"]["archs"]: - triplet = ARCH_TO_TRIPLET[arch] - new_env["CC"] = f"{triplet}-gcc" - new_env["CXX"] = f"{triplet}-g++" - new_env["RC"] = f"{triplet}-windres" - - assert arch not in mingw_archs - mingw_archs.add(arch) - - context = self.get_context({ - "ARCH": arch, - "DEP_PREFIX": str(mingw_deps_path / triplet), - }) - extra_args = configure_text_list(text_list=self.release_info["mingw"]["cmake"]["args"], context=context) - - build_path = build_parent_dir / f"build-{triplet}" - install_path = build_parent_dir / f"install-{triplet}" - shutil.rmtree(install_path, ignore_errors=True) - build_path.mkdir(parents=True, exist_ok=True) - if self.release_info["mingw"]["cmake"]["shared-static"] == "args": - args_for_shared_static = ([], ) - elif self.release_info["mingw"]["cmake"]["shared-static"] == "both": - args_for_shared_static = (["-DBUILD_SHARED_LIBS=ON"], ["-DBUILD_SHARED_LIBS=OFF"]) - for arg_for_shared_static in args_for_shared_static: - with self.section_printer.group(f"Configuring MinGW {triplet} (CMake)"): - assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})" - self.executer.run([ - f"cmake", - f"-S", str(self.root), "-B", str(build_path), - f"-DCMAKE_BUILD_TYPE={build_type}", - f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', - f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', - f"-DCMAKE_PREFIX_PATH={mingw_deps_path / triplet}", - f"-DCMAKE_INSTALL_PREFIX={install_path}", - f"-DCMAKE_INSTALL_INCLUDEDIR=include", - f"-DCMAKE_INSTALL_LIBDIR=lib", - f"-DCMAKE_INSTALL_BINDIR=bin", - f"-DCMAKE_INSTALL_DATAROOTDIR=share", - f"-DCMAKE_TOOLCHAIN_FILE={self.root}/build-scripts/cmake-toolchain-mingw64-{ARCH_TO_GNU_ARCH[arch]}.cmake", - f"-G{self.cmake_generator}", - ] + extra_args + ([] if self.fast else ["--fresh"]) + arg_for_shared_static, cwd=build_path, env=new_env) - with self.section_printer.group(f"Build MinGW {triplet} (CMake)"): - self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env) - with self.section_printer.group(f"Install MinGW {triplet} (CMake)"): - self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env) - self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll") - archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time) - - print("Recording arch-dependent extra files for MinGW development archive ...") - extra_context = { - "TRIPLET": ARCH_TO_TRIPLET[arch], - } - archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["cmake"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) - print("... done") - - print("Recording extra files for MinGW development archive ...") - archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) - print("... done") - - print("Creating zip/tgz/txz development archives ...") - zip_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.zip" - tgz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.gz" - txz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.xz" - - with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver: - archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) - archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) - print("... done") - - self.artifacts["mingw-devel-zip"] = zip_path - self.artifacts["mingw-devel-tar-gz"] = tgz_path - self.artifacts["mingw-devel-tar-xz"] = txz_path - - def _detect_android_api(self, android_home: str) -> typing.Optional[AndroidApiVersion]: - platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*")) - re_platform = re.compile("^android-([0-9]+)(?:-ext([0-9]+))?$") - platform_versions: list[AndroidApiVersion] = [] - for platform_dir in platform_dirs: - logger.debug("Found Android Platform SDK: %s", platform_dir) - if not (platform_dir / "android.jar").is_file(): - logger.debug("Skipping SDK, missing android.jar") - continue - if m:= re_platform.match(platform_dir.name): - platform_versions.append(AndroidApiVersion(name=platform_dir.name, ints=(int(m.group(1)), int(m.group(2) or 0)))) - platform_versions.sort(key=lambda v: v.ints) - logger.info("Available platform versions: %s", platform_versions) - platform_versions = list(filter(lambda v: v.ints >= self._android_api_minimum.ints, platform_versions)) - logger.info("Valid platform versions (>=%s): %s", self._android_api_minimum.ints, platform_versions) - if not platform_versions: - return None - android_api = platform_versions[0] - logger.info("Selected API version %s", android_api) - return android_api - - def _get_prefab_json_text(self) -> str: - return textwrap.dedent(f"""\ - {{ - "schema_version": 2, - "name": "{self.project}", - "version": "{self.version}", - "dependencies": [] - }} - """) - - def _get_prefab_module_json_text(self, library_name: typing.Optional[str], export_libraries: list[str]) -> str: - for lib in export_libraries: - assert isinstance(lib, str), f"{lib} must be a string" - module_json_dict = { - "export_libraries": export_libraries, - } - if library_name: - module_json_dict["library_name"] = f"lib{library_name}" - return json.dumps(module_json_dict, indent=4) - - @property - def _android_api_minimum(self) -> AndroidApiVersion: - value = self.release_info["android"]["api-minimum"] - if isinstance(value, int): - ints = (value, ) - elif isinstance(value, str): - ints = tuple(split(".")) - else: - raise ValueError("Invalid android.api-minimum: must be X or X.Y") - match len(ints): - case 1: name = f"android-{ints[0]}" - case 2: name = f"android-{ints[0]}-ext-{ints[1]}" - case _: raise ValueError("Invalid android.api-minimum: must be X or X.Y") - return AndroidApiVersion(name=name, ints=ints) - - @property - def _android_api_target(self): - return self.release_info["android"]["api-target"] - - @property - def _android_ndk_minimum(self): - return self.release_info["android"]["ndk-minimum"] - - def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str: - abi_json_dict = { - "abi": abi, - "api": self._android_api_minimum.ints[0], - "ndk": self._android_ndk_minimum, - "stl": "c++_shared" if cpp else "none", - "static": not shared, - } - return json.dumps(abi_json_dict, indent=4) - - def _get_android_manifest_text(self) -> str: - return textwrap.dedent(f"""\ - - - - """) - - def create_android_archives(self, android_api: int, android_home: Path, android_ndk_home: Path) -> None: - cmake_toolchain_file = Path(android_ndk_home) / "build/cmake/android.toolchain.cmake" - if not cmake_toolchain_file.exists(): - logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file) - raise SystemExit(1) - aar_path = self.root / "build-android" / f"{self.project}-{self.version}.aar" - android_dist_path = self.dist_path / f"{self.project}-devel-{self.version}-android.zip" - android_abis = self.release_info["android"]["abis"] - java_jars_added = False - module_data_added = False - android_deps_path = self.deps_path / "android-deps" - shutil.rmtree(android_deps_path, ignore_errors=True) - - for dep, depinfo in self.release_info["android"].get("dependencies", {}).items(): - dep_devel_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] - - dep_extract_path = self.deps_path / f"extract/android/{dep}" - shutil.rmtree(dep_extract_path, ignore_errors=True) - dep_extract_path.mkdir(parents=True, exist_ok=True) - - with self.section_printer.group(f"Extracting Android dependency {dep} ({dep_devel_zip})"): - with zipfile.ZipFile(dep_devel_zip, "r") as zf: - zf.extractall(dep_extract_path) - - dep_devel_aar = dep_extract_path / glob.glob("*.aar", root_dir=dep_extract_path)[0] - self.executer.run([sys.executable, str(dep_devel_aar), "-o", str(android_deps_path)]) - - for module_name, module_info in self.release_info["android"]["modules"].items(): - assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type" - - aar_file_tree = ArchiveFileTree() - android_devel_file_tree = ArchiveFileTree() - - for android_abi in android_abis: - with self.section_printer.group(f"Building for Android {android_api} {android_abi}"): - build_dir = self.root / "build-android" / f"{android_abi}-build" - install_dir = self.root / "install-android" / f"{android_abi}-install" - shutil.rmtree(install_dir, ignore_errors=True) - assert not install_dir.is_dir(), f"{install_dir} should not exist prior to build" - build_type = "Release" - cmake_args = [ - "cmake", - "-S", str(self.root), - "-B", str(build_dir), - f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', - f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', - f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}", - f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}", - f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH", - f"-DANDROID_HOME={android_home}", - f"-DANDROID_PLATFORM={android_api}", - f"-DANDROID_ABI={android_abi}", - "-DCMAKE_POSITION_INDEPENDENT_CODE=ON", - f"-DCMAKE_INSTALL_PREFIX={install_dir}", - "-DCMAKE_INSTALL_INCLUDEDIR=include ", - "-DCMAKE_INSTALL_LIBDIR=lib", - "-DCMAKE_INSTALL_DATAROOTDIR=share", - f"-DCMAKE_BUILD_TYPE={build_type}", - f"-G{self.cmake_generator}", - ] + self.release_info["android"]["cmake"]["args"] + ([] if self.fast else ["--fresh"]) - build_args = [ - "cmake", - "--build", str(build_dir), - "--verbose", - "--config", build_type, - ] - install_args = [ - "cmake", - "--install", str(build_dir), - "--config", build_type, - ] - self.executer.run(cmake_args) - self.executer.run(build_args) - self.executer.run(install_args) - - for module_name, module_info in self.release_info["android"]["modules"].items(): - arcdir_prefab_module = f"prefab/modules/{module_name}" - if module_info["type"] == "library": - library = install_dir / module_info["library"] - assert library.suffix in (".so", ".a") - assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}" - arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}" - aar_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time)) - aar_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time)) - - if not module_data_added: - library_name = None - if module_info["type"] == "library": - library_name = Path(module_info["library"]).stem.removeprefix("lib") - export_libraries = module_info.get("export-libraries", []) - aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time)) - arcdir_prefab_include = f"prefab/modules/{module_name}/include" - if "includes" in module_info: - aar_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time) - else: - aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time)) - module_data_added = True - - if not java_jars_added: - java_jars_added = True - if "jars" in self.release_info["android"]: - classes_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["classes"], context=self.get_context()) - sources_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["sources"], context=self.get_context()) - doc_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["doc"], context=self.get_context()) - assert classes_jar_path.is_file(), f"CMake should have compiled the java sources and archived them into a JAR ({classes_jar_path})" - assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})" - assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})" - - aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time)) - aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time)) - aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time)) - - assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives" - - aar_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["aar-files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) - - aar_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time)) - aar_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time)) - - with Archiver(zip_path=aar_path) as archiver: - aar_file_tree.add_to_archiver(archive_base="", archiver=archiver) - archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) - - android_devel_file_tree.add_file(NodeInArchive.from_fs(arcpath=aar_path.name, path=aar_path)) - android_devel_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) - with Archiver(zip_path=android_dist_path) as archiver: - android_devel_file_tree.add_to_archiver(archive_base="", archiver=archiver) - archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) - - self.artifacts[f"android-aar"] = android_dist_path - - def download_dependencies(self): - shutil.rmtree(self.deps_path, ignore_errors=True) - self.deps_path.mkdir(parents=True) - - if self.github: - with open(os.environ["GITHUB_OUTPUT"], "a") as f: - f.write(f"dep-path={self.deps_path.absolute()}\n") - - for dep, depinfo in self.release_info.get("dependencies", {}).items(): - startswith = depinfo["startswith"] - dep_repo = depinfo["repo"] - # FIXME: dropped "--exclude-pre-releases" - dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip() - dep_data = json.loads(dep_string_data) - dep_tag = dep_data["tagName"] - dep_version = dep_data["name"] - logger.info("Download dependency %s version %s (tag=%s) ", dep, dep_version, dep_tag) - self.executer.run(["gh", "-R", dep_repo, "release", "download", dep_tag], cwd=self.deps_path) - if self.github: - with open(os.environ["GITHUB_OUTPUT"], "a") as f: - f.write(f"dep-{dep.lower()}-version={dep_version}\n") - - def verify_dependencies(self): - for dep, depinfo in self.release_info.get("dependencies", {}).items(): - if "mingw" in self.release_info: - mingw_matches = glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) - assert len(mingw_matches) == 1, f"Exactly one archive matches mingw {dep} dependency: {mingw_matches}" - if "dmg" in self.release_info: - dmg_matches = glob.glob(self.release_info["dmg"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) - assert len(dmg_matches) == 1, f"Exactly one archive matches dmg {dep} dependency: {dmg_matches}" - if "msvc" in self.release_info: - msvc_matches = glob.glob(self.release_info["msvc"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) - assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}" - if "android" in self.release_info: - android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) - assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {android_matches}" - - @staticmethod - def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig: - ARCH_TO_VS_PLATFORM = { - "x86": VsArchPlatformConfig(arch="x86", platform="Win32", configuration=configuration), - "x64": VsArchPlatformConfig(arch="x64", platform="x64", configuration=configuration), - "arm64": VsArchPlatformConfig(arch="arm64", platform="ARM64", configuration=configuration), - } - return ARCH_TO_VS_PLATFORM[arch] - - def build_msvc(self): - with self.section_printer.group("Find Visual Studio"): - vs = VisualStudio(executer=self.executer) - for arch in self.release_info["msvc"].get("msbuild", {}).get("archs", []): - self._build_msvc_msbuild(arch_platform=self._arch_to_vs_platform(arch=arch), vs=vs) - if "cmake" in self.release_info["msvc"]: - deps_path = self.root / "msvc-deps" - shutil.rmtree(deps_path, ignore_errors=True) - dep_roots = [] - for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): - dep_extract_path = deps_path / f"extract-{dep}" - msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] - with zipfile.ZipFile(msvc_zip, "r") as zf: - zf.extractall(dep_extract_path) - contents_msvc_zip = glob.glob(str(dep_extract_path / "*")) - assert len(contents_msvc_zip) == 1, f"There must be exactly one root item in the root directory of {dep}" - dep_roots.append(contents_msvc_zip[0]) - - for arch in self.release_info["msvc"].get("cmake", {}).get("archs", []): - self._build_msvc_cmake(arch_platform=self._arch_to_vs_platform(arch=arch), dep_roots=dep_roots) - with self.section_printer.group("Create SDL VC development zip"): - self._build_msvc_devel() - - def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio): - platform_context = self.get_context(arch_platform.extra_context()) - for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): - msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] - - src_globs = [configure_text(instr["src"], context=platform_context) for instr in depinfo["copy"]] - with zipfile.ZipFile(msvc_zip, "r") as zf: - for member in zf.namelist(): - member_path = "/".join(Path(member).parts[1:]) - for src_i, src_glob in enumerate(src_globs): - if fnmatch.fnmatch(member_path, src_glob): - dst = (self.root / configure_text(depinfo["copy"][src_i]["dst"], context=platform_context)).resolve() / Path(member_path).name - zip_data = zf.read(member) - if dst.exists(): - identical = False - if dst.is_file(): - orig_bytes = dst.read_bytes() - if orig_bytes == zip_data: - identical = True - if not identical: - logger.warning("Extracting dependency %s, will cause %s to be overwritten", dep, dst) - if not self.overwrite: - raise RuntimeError("Run with --overwrite to allow overwriting") - logger.debug("Extracting %s -> %s", member, dst) - - dst.parent.mkdir(exist_ok=True, parents=True) - dst.write_bytes(zip_data) - - prebuilt_paths = set(self.root / full_prebuilt_path for prebuilt_path in self.release_info["msvc"]["msbuild"].get("prebuilt", []) for full_prebuilt_path in glob.glob(configure_text(prebuilt_path, context=platform_context), root_dir=self.root)) - msbuild_paths = set(self.root / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["msbuild"]["files-lib"], self.release_info["msvc"]["msbuild"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) - assert prebuilt_paths.issubset(msbuild_paths), f"msvc.msbuild.prebuilt must be a subset of (msvc.msbuild.files-lib, msvc.msbuild.files-devel)" - built_paths = msbuild_paths.difference(prebuilt_paths) - logger.info("MSbuild builds these files, to be included in the package: %s", built_paths) - if not self.fast: - for b in built_paths: - b.unlink(missing_ok=True) - - rel_projects: list[str] = self.release_info["msvc"]["msbuild"]["projects"] - projects = list(self.root / p for p in rel_projects) - - directory_build_props_src_relpath = self.release_info["msvc"]["msbuild"].get("directory-build-props") - for project in projects: - dir_b_props = project.parent / "Directory.Build.props" - dir_b_props.unlink(missing_ok = True) - if directory_build_props_src_relpath: - src = self.root / directory_build_props_src_relpath - logger.debug("Copying %s -> %s", src, dir_b_props) - shutil.copy(src=src, dst=dir_b_props) - - with self.section_printer.group(f"Build {arch_platform.arch} VS binary"): - vs.build(arch_platform=arch_platform, projects=projects) - - if self.dry: - for b in built_paths: - b.parent.mkdir(parents=True, exist_ok=True) - b.touch() - - for b in built_paths: - assert b.is_file(), f"{b} has not been created" - b.parent.mkdir(parents=True, exist_ok=True) - b.touch() - - zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip" - zip_path.unlink(missing_ok=True) - - logger.info("Collecting files...") - archive_file_tree = ArchiveFileTree() - archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["msbuild"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) - archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) - - logger.info("Writing to %s", zip_path) - with Archiver(zip_path=zip_path) as archiver: - arc_root = f"" - archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver) - archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) - self.artifacts[f"VC-{arch_platform.arch}"] = zip_path - - for p in built_paths: - assert p.is_file(), f"{p} should exist" - - def _arch_platform_to_build_path(self, arch_platform: VsArchPlatformConfig) -> Path: - return self.root / f"build-vs-{arch_platform.arch}" - - def _arch_platform_to_install_path(self, arch_platform: VsArchPlatformConfig) -> Path: - return self._arch_platform_to_build_path(arch_platform) / "prefix" - - def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list[Path]): - build_path = self._arch_platform_to_build_path(arch_platform) - install_path = self._arch_platform_to_install_path(arch_platform) - platform_context = self.get_context(extra_context=arch_platform.extra_context()) - - build_type = "Release" - extra_context = { - "ARCH": arch_platform.arch, - "PLATFORM": arch_platform.platform, - } - - built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) - logger.info("CMake builds these files, to be included in the package: %s", built_paths) - if not self.fast: - for b in built_paths: - b.unlink(missing_ok=True) - - shutil.rmtree(install_path, ignore_errors=True) - build_path.mkdir(parents=True, exist_ok=True) - with self.section_printer.group(f"Configure VC CMake project for {arch_platform.arch}"): - self.executer.run([ - "cmake", "-S", str(self.root), "-B", str(build_path), - "-A", arch_platform.platform, - "-DCMAKE_INSTALL_BINDIR=bin", - "-DCMAKE_INSTALL_DATAROOTDIR=share", - "-DCMAKE_INSTALL_INCLUDEDIR=include", - "-DCMAKE_INSTALL_LIBDIR=lib", - f"-DCMAKE_BUILD_TYPE={build_type}", - f"-DCMAKE_INSTALL_PREFIX={install_path}", - # MSVC debug information format flags are selected by an abstraction - "-DCMAKE_POLICY_DEFAULT_CMP0141=NEW", - # MSVC debug information format - "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase", - # Linker flags for executables - "-DCMAKE_EXE_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF", - # Linker flag for shared libraries - "-DCMAKE_SHARED_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF", - # MSVC runtime library flags are selected by an abstraction - "-DCMAKE_POLICY_DEFAULT_CMP0091=NEW", - # Use statically linked runtime (-MT) (ideally, should be "MultiThreaded$<$:Debug>") - "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded", - f"-DCMAKE_PREFIX_PATH={';'.join(str(s) for s in dep_roots)}", - ] + self.release_info["msvc"]["cmake"]["args"] + ([] if self.fast else ["--fresh"])) - - with self.section_printer.group(f"Build VC CMake project for {arch_platform.arch}"): - self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type]) - with self.section_printer.group(f"Install VC CMake project for {arch_platform.arch}"): - self.executer.run(["cmake", "--install", str(build_path), "--config", build_type]) - - if self.dry: - for b in built_paths: - b.parent.mkdir(parents=True, exist_ok=True) - b.touch() - - zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip" - zip_path.unlink(missing_ok=True) - - logger.info("Collecting files...") - archive_file_tree = ArchiveFileTree() - archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time) - archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) - - logger.info("Creating %s", zip_path) - with Archiver(zip_path=zip_path) as archiver: - arc_root = f"" - archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver) - archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) - - for p in built_paths: - assert p.is_file(), f"{p} should exist" - - def _build_msvc_devel(self) -> None: - zip_path = self.dist_path / f"{self.project}-devel-{self.version}-VC.zip" - arc_root = f"{self.project}-{self.version}" - - def copy_files_devel(ctx): - archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["files-devel"], file_mapping_root=self.root, context=ctx, time=self.arc_time) - - - logger.info("Collecting files...") - archive_file_tree = ArchiveFileTree() - if "msbuild" in self.release_info["msvc"]: - for arch in self.release_info["msvc"]["msbuild"]["archs"]: - arch_platform = self._arch_to_vs_platform(arch=arch) - platform_context = self.get_context(arch_platform.extra_context()) - archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["msbuild"]["files-devel"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) - copy_files_devel(ctx=platform_context) - if "cmake" in self.release_info["msvc"]: - for arch in self.release_info["msvc"]["cmake"]["archs"]: - arch_platform = self._arch_to_vs_platform(arch=arch) - platform_context = self.get_context(arch_platform.extra_context()) - archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["cmake"]["files-devel"], file_mapping_root=self._arch_platform_to_install_path(arch_platform), context=platform_context, time=self.arc_time) - copy_files_devel(ctx=platform_context) - - with Archiver(zip_path=zip_path) as archiver: - archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) - archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) - self.artifacts["VC-devel"] = zip_path - - @classmethod - def extract_sdl_version(cls, root: Path, release_info: dict) -> str: - with open(root / release_info["version"]["file"], "r") as f: - text = f.read() - major = next(re.finditer(release_info["version"]["re_major"], text, flags=re.M)).group(1) - minor = next(re.finditer(release_info["version"]["re_minor"], text, flags=re.M)).group(1) - micro = next(re.finditer(release_info["version"]["re_micro"], text, flags=re.M)).group(1) - return f"{major}.{minor}.{micro}" - - -def main(argv=None) -> int: - if sys.version_info < (3, 11): - logger.error("This script needs at least python 3.11") - return 1 - - parser = argparse.ArgumentParser(allow_abbrev=False, description="Create SDL release artifacts") - parser.add_argument("--root", metavar="DIR", type=Path, default=Path(__file__).absolute().parents[1], help="Root of project") - parser.add_argument("--release-info", metavar="JSON", dest="path_release_info", type=Path, default=Path(__file__).absolute().parent / "release-info.json", help="Path of release-info.json") - parser.add_argument("--dependency-folder", metavar="FOLDER", dest="deps_path", type=Path, default="deps", help="Directory containing pre-built archives of dependencies (will be removed when downloading archives)") - parser.add_argument("--out", "-o", metavar="DIR", dest="dist_path", type=Path, default="dist", help="Output directory") - parser.add_argument("--github", action="store_true", help="Script is running on a GitHub runner") - parser.add_argument("--commit", default="HEAD", help="Git commit/tag of which a release should be created") - parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?") - parser.set_defaults(loglevel=logging.INFO) - parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year") - parser.add_argument('--android-api', dest="android_api", help="Android API version") - parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder") - parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder") - parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator") - parser.add_argument('--debug', action='store_const', const=logging.DEBUG, dest="loglevel", help="Print script debug information") - parser.add_argument('--dry-run', action='store_true', dest="dry", help="Don't execute anything") - parser.add_argument('--force', action='store_true', dest="force", help="Ignore a non-clean git tree") - parser.add_argument('--overwrite', action='store_true', dest="overwrite", help="Allow potentially overwriting other projects") - parser.add_argument('--fast', action='store_true', dest="fast", help="Don't do a rebuild") - - args = parser.parse_args(argv) - logging.basicConfig(level=args.loglevel, format='[%(levelname)s] %(message)s') - args.deps_path = args.deps_path.absolute() - args.dist_path = args.dist_path.absolute() - args.root = args.root.absolute() - args.dist_path = args.dist_path.absolute() - if args.dry: - args.dist_path = args.dist_path / "dry" - - if args.github: - section_printer: SectionPrinter = GitHubSectionPrinter() - else: - section_printer = SectionPrinter() - - if args.github and "GITHUB_OUTPUT" not in os.environ: - os.environ["GITHUB_OUTPUT"] = "/tmp/github_output.txt" - - executer = Executer(root=args.root, dry=args.dry) - - root_git_hash_path = args.root / GIT_HASH_FILENAME - root_is_maybe_archive = root_git_hash_path.is_file() - if root_is_maybe_archive: - logger.warning("%s detected: Building from archive", GIT_HASH_FILENAME) - archive_commit = root_git_hash_path.read_text().strip() - if args.commit != archive_commit: - logger.warning("Commit argument is %s, but archive commit is %s. Using %s.", args.commit, archive_commit, archive_commit) - args.commit = archive_commit - revision = (args.root / REVISION_TXT).read_text().strip() - else: - args.commit = executer.check_output(["git", "rev-parse", args.commit], dry_out="e5812a9fd2cda317b503325a702ba3c1c37861d9").strip() - revision = executer.check_output(["git", "describe", "--always", "--tags", "--long", args.commit], dry_out="preview-3.1.3-96-g9512f2144").strip() - logger.info("Using commit %s", args.commit) - - try: - with args.path_release_info.open() as f: - release_info = json.load(f) - except FileNotFoundError: - logger.error(f"Could not find {args.path_release_info}") - - releaser = Releaser( - release_info=release_info, - commit=args.commit, - revision=revision, - root=args.root, - dist_path=args.dist_path, - executer=executer, - section_printer=section_printer, - cmake_generator=args.cmake_generator, - deps_path=args.deps_path, - overwrite=args.overwrite, - github=args.github, - fast=args.fast, - ) - - if root_is_maybe_archive: - logger.warning("Building from archive. Skipping clean git tree check.") - else: - porcelain_status = executer.check_output(["git", "status", "--ignored", "--porcelain"], dry_out="\n").strip() - if porcelain_status: - print(porcelain_status) - logger.warning("The tree is dirty! Do not publish any generated artifacts!") - if not args.force: - raise Exception("The git repo contains modified and/or non-committed files. Run with --force to ignore.") - - if args.fast: - logger.warning("Doing fast build! Do not publish generated artifacts!") - - with section_printer.group("Arguments"): - print(f"project = {releaser.project}") - print(f"version = {releaser.version}") - print(f"revision = {revision}") - print(f"commit = {args.commit}") - print(f"out = {args.dist_path}") - print(f"actions = {args.actions}") - print(f"dry = {args.dry}") - print(f"force = {args.force}") - print(f"overwrite = {args.overwrite}") - print(f"cmake_generator = {args.cmake_generator}") - - releaser.prepare() - - if "download" in args.actions: - releaser.download_dependencies() - - if set(args.actions).intersection({"msvc", "mingw", "android"}): - print("Verifying presence of dependencies (run 'download' action to download) ...") - releaser.verify_dependencies() - print("... done") - - if "source" in args.actions: - if root_is_maybe_archive: - raise Exception("Cannot build source archive from source archive") - with section_printer.group("Create source archives"): - releaser.create_source_archives() - - if "dmg" in args.actions: - if platform.system() != "Darwin" and not args.dry: - parser.error("framework artifact(s) can only be built on Darwin") - - releaser.create_dmg() - - if "msvc" in args.actions: - if platform.system() != "Windows" and not args.dry: - parser.error("msvc artifact(s) can only be built on Windows") - releaser.build_msvc() - - if "mingw" in args.actions: - releaser.create_mingw_archives() - - if "android" in args.actions: - if args.android_home is None or not Path(args.android_home).is_dir(): - parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK") - if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir(): - parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK") - if args.android_api is None: - with section_printer.group("Detect Android APIS"): - args.android_api = releaser._detect_android_api(android_home=args.android_home) - else: - try: - android_api_ints = tuple(int(v) for v in args.android_api.split(".")) - match len(android_api_ints): - case 1: android_api_name = f"android-{android_api_ints[0]}" - case 2: android_api_name = f"android-{android_api_ints[0]}-ext-{android_api_ints[1]}" - case _: raise ValueError - except ValueError: - logger.error("Invalid --android-api, must be a 'X' or 'X.Y' version") - args.android_api = AndroidApiVersion(ints=android_api_ints, name=android_api_name) - if args.android_api is None: - parser.error("Invalid --android-api, and/or could not be detected") - android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}" - if not android_api_path.is_dir(): - parser.error(f"Android API directory does not exist ({android_api_path})") - with section_printer.group("Android arguments"): - print(f"android_home = {args.android_home}") - print(f"android_ndk_home = {args.android_ndk_home}") - print(f"android_api = {args.android_api}") - releaser.create_android_archives( - android_api=args.android_api.ints[0], - android_home=args.android_home, - android_ndk_home=args.android_ndk_home, - ) - with section_printer.group("Summary"): - print(f"artifacts = {releaser.artifacts}") - - if args.github: - with open(os.environ["GITHUB_OUTPUT"], "a") as f: - f.write(f"project={releaser.project}\n") - f.write(f"version={releaser.version}\n") - for k, v in releaser.artifacts.items(): - f.write(f"{k}={v.name}\n") - return 0 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/build-web-examples.pl b/contrib/SDL-3.2.8/build-scripts/build-web-examples.pl deleted file mode 100755 index c255ea3..0000000 --- a/contrib/SDL-3.2.8/build-scripts/build-web-examples.pl +++ /dev/null @@ -1,420 +0,0 @@ -#!/usr/bin/perl -w - -# Simple DirectMedia Layer -# Copyright (C) 1997-2025 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. - -use warnings; -use strict; -use File::Basename; -use File::Copy; -use Cwd qw(abs_path); -use IPC::Open2; - -my $examples_dir = abs_path(dirname(__FILE__) . "/../examples"); -my $project = undef; -my $emsdk_dir = undef; -my $compile_dir = undef; -my $cmake_flags = undef; -my $output_dir = undef; - -sub usage { - die("USAGE: $0 \n\n"); -} - -sub do_system { - my $cmd = shift; - $cmd = "exec /bin/bash -c \"$cmd\""; - print("$cmd\n"); - return system($cmd); -} - -sub do_mkdir { - my $d = shift; - if ( ! -d $d ) { - print("mkdir '$d'\n"); - mkdir($d) or die("Couldn't mkdir('$d'): $!\n"); - } -} - -sub do_copy { - my $src = shift; - my $dst = shift; - print("cp '$src' '$dst'\n"); - copy($src, $dst) or die("Failed to copy '$src' to '$dst': $!\n"); -} - -sub build_latest { - # Try to build just the latest without re-running cmake, since that is SLOW. - print("Building latest version of $project ...\n"); - if (do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && cd '$compile_dir' && ninja") != 0) { - # Build failed? Try nuking the build dir and running CMake from scratch. - print("\n\nBuilding latest version of $project FROM SCRATCH ...\n"); - if (do_system("EMSDK_QUIET=1 source '$emsdk_dir/emsdk_env.sh' && rm -rf '$compile_dir' && mkdir '$compile_dir' && cd '$compile_dir' && emcmake cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel $cmake_flags '$examples_dir/..' && ninja") != 0) { - die("Failed to build latest version of $project!\n"); # oh well. - } - } -} - -sub get_category_description { - my $category = shift; - my $retval = ucfirst($category); - - if (open(my $fh, '<', "$examples_dir/$category/description.txt")) { - $retval = <$fh>; - chomp($retval); - close($fh); - } - - return $retval; -} - -sub get_categories { - my @categories = (); - - if (open(my $fh, '<', "$examples_dir/categories.txt")) { - while (<$fh>) { - chomp; - s/\A\s+//; - s/\s+\Z//; - next if $_ eq ''; - next if /\A\#/; - push @categories, $_; - } - close($fh); - } else { - opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n"); - foreach my $dir (sort readdir $dh) { - next if ($dir eq '.') || ($dir eq '..'); # obviously skip current and parent entries. - next if not -d "$examples_dir/$dir"; # only care about subdirectories. - push @categories, $dir; - } - closedir($dh); - } - - return @categories; -} - -sub get_examples_for_category { - my $category = shift; - - my @examples = (); - - opendir(my $dh, "$examples_dir/$category") or die("Couldn't opendir '$examples_dir/$category': $!\n"); - foreach my $dir (sort readdir $dh) { - next if ($dir eq '.') || ($dir eq '..'); # obviously skip current and parent entries. - next if not -d "$examples_dir/$category/$dir"; # only care about subdirectories. - - push @examples, $dir; - } - closedir($dh); - - return @examples; -} - -sub handle_example_dir { - my $category = shift; - my $example = shift; - - my @files = (); - my $files_str = ''; - opendir(my $dh, "$examples_dir/$category/$example") or die("Couldn't opendir '$examples_dir/$category/$example': $!\n"); - my $spc = ''; - while (readdir($dh)) { - my $path = "$examples_dir/$category/$example/$_"; - next if not -f $path; # only care about files. - push @files, $path if /\.[ch]\Z/; # add .c and .h files to source code. - if (/\.c\Z/) { # only care about .c files for compiling. - $files_str .= "$spc$path"; - $spc = ' '; - } - } - closedir($dh); - - my $dst = "$output_dir/$category/$example"; - - print("Building $category/$example ...\n"); - - my $basefname = "$example"; - $basefname =~ s/\A\d+\-//; - $basefname = "$category-$basefname"; - my $jsfname = "$basefname.js"; - my $wasmfname = "$basefname.wasm"; - my $thumbnailfname = 'thumbnail.png'; - my $onmouseoverfname = 'onmouseover.webp'; - my $jssrc = "$compile_dir/examples/$jsfname"; - my $wasmsrc = "$compile_dir/examples/$wasmfname"; - my $thumbnailsrc = "$examples_dir/$category/$example/$thumbnailfname"; - my $onmouseoversrc = "$examples_dir/$category/$example/$onmouseoverfname"; - my $jsdst = "$dst/$jsfname"; - my $wasmdst = "$dst/$wasmfname"; - my $thumbnaildst = "$dst/$thumbnailfname"; - my $onmouseoverdst = "$dst/$onmouseoverfname"; - - my $description = ''; - my $has_paragraph = 0; - if (open(my $readmetxth, '<', "$examples_dir/$category/$example/README.txt")) { - while (<$readmetxth>) { - chomp; - s/\A\s+//; - s/\s+\Z//; - if (($_ eq '') && ($description ne '')) { - $has_paragraph = 1; - } else { - if ($has_paragraph) { - $description .= "\n
\n
\n"; - $has_paragraph = 0; - } - $description .= "$_ "; - } - } - close($readmetxth); - $description =~ s/\s+\Z//; - } - - do_mkdir($dst); - do_copy($jssrc, $jsdst); - do_copy($wasmsrc, $wasmdst); - do_copy($thumbnailsrc, $thumbnaildst) if ( -f $thumbnailsrc ); - do_copy($onmouseoversrc, $onmouseoverdst) if ( -f $onmouseoversrc ); - - my $highlight_cmd = "highlight '--outdir=$dst' --style-outfile=highlight.css --fragment --enclose-pre --stdout --syntax=c '--plug-in=$examples_dir/highlight-plugin.lua'"; - print("$highlight_cmd\n"); - my $pid = open2(my $child_out, my $child_in, $highlight_cmd); - - my $htmlified_source_code = ''; - foreach (sort(@files)) { - my $path = $_; - open my $srccode, '<', $path or die("Couldn't open '$path': $!\n"); - my $fname = "$path"; - $fname =~ s/\A.*\///; - print $child_in "/* $fname ... */\n\n"; - while (<$srccode>) { - print $child_in $_; - } - print $child_in "\n\n\n"; - close($srccode); - } - - close($child_in); - - while (<$child_out>) { - $htmlified_source_code .= $_; - } - close($child_out); - - waitpid($pid, 0); - - my $other_examples_html = "
    "; - foreach my $example (get_examples_for_category($category)) { - $other_examples_html .= "
  • $category/$example
  • "; - } - $other_examples_html .= "
"; - - my $category_description = get_category_description($category); - my $preview_image = get_example_thumbnail($project, $category, $example); - - my $html = ''; - open my $htmltemplate, '<', "$examples_dir/template.html" or die("Couldn't open '$examples_dir/template.html': $!\n"); - while (<$htmltemplate>) { - s/\@project_name\@/$project/g; - s/\@category_name\@/$category/g; - s/\@category_description\@/$category_description/g; - s/\@example_name\@/$example/g; - s/\@javascript_file\@/$jsfname/g; - s/\@htmlified_source_code\@/$htmlified_source_code/g; - s/\@description\@/$description/g; - s/\@preview_image\@/$preview_image/g; - s/\@other_examples_html\@/$other_examples_html/g; - $html .= $_; - } - close($htmltemplate); - - open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n"); - print $htmloutput $html; - close($htmloutput); -} - -sub get_example_thumbnail { - my $project = shift; - my $category = shift; - my $example = shift; - - if ( -f "$examples_dir/$category/$example/thumbnail.png" ) { - return "/$project/$category/$example/thumbnail.png"; - } elsif ( -f "$examples_dir/$category/thumbnail.png" ) { - return "/$project/$category/thumbnail.png"; - } - - return "/$project/thumbnail.png"; -} - -sub generate_example_thumbnail { - my $project = shift; - my $category = shift; - my $example = shift; - - my $example_no_num = "$example"; - $example_no_num =~ s/\A\d+\-//; - - my $example_image_url = get_example_thumbnail($project, $category, $example); - - my $example_mouseover_html = ''; - if ( -f "$examples_dir/$category/$example/onmouseover.webp" ) { - $example_mouseover_html = "onmouseover=\"this.src='/$project/$category/$example/onmouseover.webp'\" onmouseout=\"this.src='$example_image_url';\""; - } elsif ( -f "$examples_dir/$category/onmouseover.webp" ) { - $example_mouseover_html = "onmouseover=\"this.src='/$project/$category/onmouseover.webp'\" onmouseout=\"this.src='$example_image_url';\""; - } - - return " - -
- -
$example_no_num
-
-
" - ; -} - -sub generate_example_thumbnails_for_category { - my $project = shift; - my $category = shift; - my @examples = get_examples_for_category($category); - my $retval = ''; - foreach my $example (@examples) { - $retval .= generate_example_thumbnail($project, $category, $example); - } - return $retval; -} - -sub handle_category_dir { - my $category = shift; - - print("Category $category ...\n"); - - do_mkdir("$output_dir/$category"); - - opendir(my $dh, "$examples_dir/$category") or die("Couldn't opendir '$examples_dir/$category': $!\n"); - - while (readdir($dh)) { - next if ($_ eq '.') || ($_ eq '..'); # obviously skip current and parent entries. - next if not -d "$examples_dir/$category/$_"; # only care about subdirectories. - handle_example_dir($category, $_); - } - - closedir($dh); - - my $examples_list_html = generate_example_thumbnails_for_category($project, $category); - - my $dst = "$output_dir/$category"; - - do_copy("$examples_dir/$category/thumbnail.png", "$dst/thumbnail.png") if ( -f "$examples_dir/$category/thumbnail.png" ); - do_copy("$examples_dir/$category/onmouseover.webp", "$dst/onmouseover.webp") if ( -f "$examples_dir/$category/onmouseover.webp" ); - - my $category_description = get_category_description($category); - my $preview_image = "/$project/thumbnail.png"; - if ( -f "$examples_dir/$category/thumbnail.png" ) { - $preview_image = "/$project/$category/thumbnail.png"; - } - - # write category page - my $html = ''; - open my $htmltemplate, '<', "$examples_dir/template-category.html" or die("Couldn't open '$examples_dir/template-category.html': $!\n"); - while (<$htmltemplate>) { - s/\@project_name\@/$project/g; - s/\@category_name\@/$category/g; - s/\@category_description\@/$category_description/g; - s/\@examples_list_html\@/$examples_list_html/g; - s/\@preview_image\@/$preview_image/g; - $html .= $_; - } - close($htmltemplate); - - open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n"); - print $htmloutput $html; - close($htmloutput); -} - - -# Mainline! - -foreach (@ARGV) { - $project = $_, next if not defined $project; - $emsdk_dir = $_, next if not defined $emsdk_dir; - $compile_dir = $_, next if not defined $compile_dir; - $cmake_flags = $_, next if not defined $cmake_flags; - $output_dir = $_, next if not defined $output_dir; - usage(); # too many arguments. -} - -usage() if not defined $output_dir; - -print("Examples dir: $examples_dir\n"); -print("emsdk dir: $emsdk_dir\n"); -print("Compile dir: $compile_dir\n"); -print("CMake flags: $cmake_flags\n"); -print("Output dir: $output_dir\n"); - -do_system("rm -rf '$output_dir'"); -do_mkdir($output_dir); - -build_latest(); - -do_copy("$examples_dir/template.css", "$output_dir/examples.css"); -do_copy("$examples_dir/template-placeholder.png", "$output_dir/thumbnail.png"); - -opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n"); - -while (readdir($dh)) { - next if ($_ eq '.') || ($_ eq '..'); # obviously skip current and parent entries. - next if not -d "$examples_dir/$_"; # only care about subdirectories. - # !!! FIXME: this needs to generate a preview page for all the categories. - handle_category_dir($_); -} - -closedir($dh); - -# write homepage -my $homepage_list_html = ""; -foreach my $category (get_categories()) { - my $category_description = get_category_description($category); - $homepage_list_html .= "

$category_description

"; - $homepage_list_html .= "
"; - $homepage_list_html .= generate_example_thumbnails_for_category($project, $category); - $homepage_list_html .= "
"; -} - -my $preview_image = "/$project/thumbnail.png"; - -my $dst = "$output_dir/"; -my $html = ''; -open my $htmltemplate, '<', "$examples_dir/template-homepage.html" or die("Couldn't open '$examples_dir/template-category.html': $!\n"); -while (<$htmltemplate>) { - s/\@project_name\@/$project/g; - s/\@homepage_list_html\@/$homepage_list_html/g; - s/\@preview_image\@/$preview_image/g; - $html .= $_; -} -close($htmltemplate); - -open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n"); -print $htmloutput $html; -close($htmloutput); - -print("All examples built successfully!\n"); -exit(0); # success! diff --git a/contrib/SDL-3.2.8/build-scripts/casefolding.txt b/contrib/SDL-3.2.8/build-scripts/casefolding.txt deleted file mode 100644 index 69c5c64..0000000 --- a/contrib/SDL-3.2.8/build-scripts/casefolding.txt +++ /dev/null @@ -1,1627 +0,0 @@ -# CaseFolding-15.1.0.txt -# Date: 2023-05-12, 21:53:10 GMT -# © 2023 Unicode®, Inc. -# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html -# -# Unicode Character Database -# For documentation, see https://www.unicode.org/reports/tr44/ -# -# Case Folding Properties -# -# This file is a supplement to the UnicodeData file. -# It provides a case folding mapping generated from the Unicode Character Database. -# If all characters are mapped according to the full mapping below, then -# case differences (according to UnicodeData.txt and SpecialCasing.txt) -# are eliminated. -# -# The data supports both implementations that require simple case foldings -# (where string lengths don't change), and implementations that allow full case folding -# (where string lengths may grow). Note that where they can be supported, the -# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match. -# -# All code points not listed in this file map to themselves. -# -# NOTE: case folding does not preserve normalization formats! -# -# For information on case folding, including how to have case folding -# preserve normalization formats, see Section 3.13 Default Case Algorithms in -# The Unicode Standard. -# -# ================================================================================ -# Format -# ================================================================================ -# The entries in this file are in the following machine-readable format: -# -# ; ; ; # -# -# The status field is: -# C: common case folding, common mappings shared by both simple and full mappings. -# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces. -# S: simple case folding, mappings to single characters where different from F. -# T: special case for uppercase I and dotted uppercase I -# - For non-Turkic languages, this mapping is normally not used. -# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters. -# Note that the Turkic mappings do not maintain canonical equivalence without additional processing. -# See the discussions of case mapping in the Unicode Standard for more information. -# -# Usage: -# A. To do a simple case folding, use the mappings with status C + S. -# B. To do a full case folding, use the mappings with status C + F. -# -# The mappings with status T can be used or omitted depending on the desired case-folding -# behavior. (The default option is to exclude them.) -# -# ================================================================= - -# Property: Case_Folding - -# All code points not explicitly listed for Case_Folding -# have the value C for the status field, and the code point itself for the mapping field. - -# ================================================================= -0041; C; 0061; # LATIN CAPITAL LETTER A -0042; C; 0062; # LATIN CAPITAL LETTER B -0043; C; 0063; # LATIN CAPITAL LETTER C -0044; C; 0064; # LATIN CAPITAL LETTER D -0045; C; 0065; # LATIN CAPITAL LETTER E -0046; C; 0066; # LATIN CAPITAL LETTER F -0047; C; 0067; # LATIN CAPITAL LETTER G -0048; C; 0068; # LATIN CAPITAL LETTER H -0049; C; 0069; # LATIN CAPITAL LETTER I -0049; T; 0131; # LATIN CAPITAL LETTER I -004A; C; 006A; # LATIN CAPITAL LETTER J -004B; C; 006B; # LATIN CAPITAL LETTER K -004C; C; 006C; # LATIN CAPITAL LETTER L -004D; C; 006D; # LATIN CAPITAL LETTER M -004E; C; 006E; # LATIN CAPITAL LETTER N -004F; C; 006F; # LATIN CAPITAL LETTER O -0050; C; 0070; # LATIN CAPITAL LETTER P -0051; C; 0071; # LATIN CAPITAL LETTER Q -0052; C; 0072; # LATIN CAPITAL LETTER R -0053; C; 0073; # LATIN CAPITAL LETTER S -0054; C; 0074; # LATIN CAPITAL LETTER T -0055; C; 0075; # LATIN CAPITAL LETTER U -0056; C; 0076; # LATIN CAPITAL LETTER V -0057; C; 0077; # LATIN CAPITAL LETTER W -0058; C; 0078; # LATIN CAPITAL LETTER X -0059; C; 0079; # LATIN CAPITAL LETTER Y -005A; C; 007A; # LATIN CAPITAL LETTER Z -00B5; C; 03BC; # MICRO SIGN -00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE -00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE -00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX -00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE -00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS -00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE -00C6; C; 00E6; # LATIN CAPITAL LETTER AE -00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA -00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE -00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE -00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX -00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS -00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE -00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE -00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX -00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS -00D0; C; 00F0; # LATIN CAPITAL LETTER ETH -00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE -00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE -00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE -00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX -00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE -00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS -00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE -00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE -00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE -00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX -00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS -00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE -00DE; C; 00FE; # LATIN CAPITAL LETTER THORN -00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S -0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON -0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE -0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK -0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE -0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX -010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE -010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON -010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON -0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE -0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON -0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE -0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE -0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK -011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON -011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX -011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE -0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE -0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA -0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX -0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE -0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE -012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON -012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE -012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK -0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE -0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE -0132; C; 0133; # LATIN CAPITAL LIGATURE IJ -0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX -0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA -0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE -013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA -013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON -013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT -0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE -0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE -0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA -0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON -0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -014A; C; 014B; # LATIN CAPITAL LETTER ENG -014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON -014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE -0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -0152; C; 0153; # LATIN CAPITAL LIGATURE OE -0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE -0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA -0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON -015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE -015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX -015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA -0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON -0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA -0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON -0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE -0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE -016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON -016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE -016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE -0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK -0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX -0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS -0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE -017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE -017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON -017F; C; 0073; # LATIN SMALL LETTER LONG S -0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK -0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR -0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX -0186; C; 0254; # LATIN CAPITAL LETTER OPEN O -0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK -0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D -018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK -018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR -018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E -018F; C; 0259; # LATIN CAPITAL LETTER SCHWA -0190; C; 025B; # LATIN CAPITAL LETTER OPEN E -0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK -0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK -0194; C; 0263; # LATIN CAPITAL LETTER GAMMA -0196; C; 0269; # LATIN CAPITAL LETTER IOTA -0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE -0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK -019C; C; 026F; # LATIN CAPITAL LETTER TURNED M -019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK -019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE -01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN -01A2; C; 01A3; # LATIN CAPITAL LETTER OI -01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK -01A6; C; 0280; # LATIN LETTER YR -01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO -01A9; C; 0283; # LATIN CAPITAL LETTER ESH -01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK -01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK -01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN -01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON -01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK -01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK -01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE -01B7; C; 0292; # LATIN CAPITAL LETTER EZH -01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED -01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE -01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON -01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON -01C7; C; 01C9; # LATIN CAPITAL LETTER LJ -01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J -01CA; C; 01CC; # LATIN CAPITAL LETTER NJ -01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J -01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON -01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON -01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON -01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON -01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON -01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE -01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON -01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE -01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON -01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON -01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON -01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE -01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON -01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON -01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK -01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON -01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON -01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON -01F1; C; 01F3; # LATIN CAPITAL LETTER DZ -01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z -01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE -01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR -01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN -01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE -01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE -01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE -01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE -0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE -0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE -0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE -0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE -0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE -020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE -020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE -020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE -0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE -0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE -0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE -0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE -0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW -021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW -021C; C; 021D; # LATIN CAPITAL LETTER YOGH -021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON -0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG -0222; C; 0223; # LATIN CAPITAL LETTER OU -0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK -0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE -0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA -022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON -022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON -022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE -0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON -0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON -023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE -023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE -023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR -023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE -0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP -0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE -0244; C; 0289; # LATIN CAPITAL LETTER U BAR -0245; C; 028C; # LATIN CAPITAL LETTER TURNED V -0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE -0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE -024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL -024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE -024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE -0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI -0370; C; 0371; # GREEK CAPITAL LETTER HETA -0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI -0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA -037F; C; 03F3; # GREEK CAPITAL LETTER YOT -0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS -0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS -0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS -038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS -038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS -038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS -038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS -0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA -0392; C; 03B2; # GREEK CAPITAL LETTER BETA -0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA -0394; C; 03B4; # GREEK CAPITAL LETTER DELTA -0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON -0396; C; 03B6; # GREEK CAPITAL LETTER ZETA -0397; C; 03B7; # GREEK CAPITAL LETTER ETA -0398; C; 03B8; # GREEK CAPITAL LETTER THETA -0399; C; 03B9; # GREEK CAPITAL LETTER IOTA -039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA -039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA -039C; C; 03BC; # GREEK CAPITAL LETTER MU -039D; C; 03BD; # GREEK CAPITAL LETTER NU -039E; C; 03BE; # GREEK CAPITAL LETTER XI -039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON -03A0; C; 03C0; # GREEK CAPITAL LETTER PI -03A1; C; 03C1; # GREEK CAPITAL LETTER RHO -03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA -03A4; C; 03C4; # GREEK CAPITAL LETTER TAU -03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON -03A6; C; 03C6; # GREEK CAPITAL LETTER PHI -03A7; C; 03C7; # GREEK CAPITAL LETTER CHI -03A8; C; 03C8; # GREEK CAPITAL LETTER PSI -03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA -03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA -03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL -03D0; C; 03B2; # GREEK BETA SYMBOL -03D1; C; 03B8; # GREEK THETA SYMBOL -03D5; C; 03C6; # GREEK PHI SYMBOL -03D6; C; 03C0; # GREEK PI SYMBOL -03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA -03DA; C; 03DB; # GREEK LETTER STIGMA -03DC; C; 03DD; # GREEK LETTER DIGAMMA -03DE; C; 03DF; # GREEK LETTER KOPPA -03E0; C; 03E1; # GREEK LETTER SAMPI -03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI -03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI -03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI -03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI -03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA -03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA -03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI -03F0; C; 03BA; # GREEK KAPPA SYMBOL -03F1; C; 03C1; # GREEK RHO SYMBOL -03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL -03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL -03F7; C; 03F8; # GREEK CAPITAL LETTER SHO -03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL -03FA; C; 03FB; # GREEK CAPITAL LETTER SAN -03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL -03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL -03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL -0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE -0401; C; 0451; # CYRILLIC CAPITAL LETTER IO -0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE -0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE -0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE -0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE -0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -0407; C; 0457; # CYRILLIC CAPITAL LETTER YI -0408; C; 0458; # CYRILLIC CAPITAL LETTER JE -0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE -040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE -040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE -040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE -040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE -040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U -040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE -0410; C; 0430; # CYRILLIC CAPITAL LETTER A -0411; C; 0431; # CYRILLIC CAPITAL LETTER BE -0412; C; 0432; # CYRILLIC CAPITAL LETTER VE -0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE -0414; C; 0434; # CYRILLIC CAPITAL LETTER DE -0415; C; 0435; # CYRILLIC CAPITAL LETTER IE -0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE -0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE -0418; C; 0438; # CYRILLIC CAPITAL LETTER I -0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I -041A; C; 043A; # CYRILLIC CAPITAL LETTER KA -041B; C; 043B; # CYRILLIC CAPITAL LETTER EL -041C; C; 043C; # CYRILLIC CAPITAL LETTER EM -041D; C; 043D; # CYRILLIC CAPITAL LETTER EN -041E; C; 043E; # CYRILLIC CAPITAL LETTER O -041F; C; 043F; # CYRILLIC CAPITAL LETTER PE -0420; C; 0440; # CYRILLIC CAPITAL LETTER ER -0421; C; 0441; # CYRILLIC CAPITAL LETTER ES -0422; C; 0442; # CYRILLIC CAPITAL LETTER TE -0423; C; 0443; # CYRILLIC CAPITAL LETTER U -0424; C; 0444; # CYRILLIC CAPITAL LETTER EF -0425; C; 0445; # CYRILLIC CAPITAL LETTER HA -0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE -0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE -0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA -0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA -042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN -042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU -042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN -042D; C; 044D; # CYRILLIC CAPITAL LETTER E -042E; C; 044E; # CYRILLIC CAPITAL LETTER YU -042F; C; 044F; # CYRILLIC CAPITAL LETTER YA -0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA -0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT -0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E -0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS -0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS -046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS -046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS -046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI -0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI -0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA -0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA -0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT -0478; C; 0479; # CYRILLIC CAPITAL LETTER UK -047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA -047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO -047E; C; 047F; # CYRILLIC CAPITAL LETTER OT -0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA -048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL -048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN -048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK -0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN -0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE -0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK -0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER -0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER -049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER -049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE -049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE -04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA -04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER -04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE -04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK -04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA -04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER -04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER -04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U -04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE -04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER -04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE -04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER -04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE -04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA -04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE -04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER -04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA -04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE -04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK -04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL -04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK -04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL -04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE -04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL -04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE -04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS -04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE -04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE -04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA -04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS -04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS -04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS -04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE -04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON -04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS -04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS -04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O -04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS -04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS -04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON -04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS -04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE -04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS -04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER -04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS -04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK -04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK -04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE -0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE -0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE -0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE -0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE -0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE -050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE -050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE -050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE -0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE -0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK -0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA -0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA -0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE -051A; C; 051B; # CYRILLIC CAPITAL LETTER QA -051C; C; 051D; # CYRILLIC CAPITAL LETTER WE -051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA -0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK -0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK -0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER -0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER -0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK -052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE -052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE -052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER -0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB -0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN -0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM -0534; C; 0564; # ARMENIAN CAPITAL LETTER DA -0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH -0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA -0537; C; 0567; # ARMENIAN CAPITAL LETTER EH -0538; C; 0568; # ARMENIAN CAPITAL LETTER ET -0539; C; 0569; # ARMENIAN CAPITAL LETTER TO -053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE -053B; C; 056B; # ARMENIAN CAPITAL LETTER INI -053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN -053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH -053E; C; 056E; # ARMENIAN CAPITAL LETTER CA -053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN -0540; C; 0570; # ARMENIAN CAPITAL LETTER HO -0541; C; 0571; # ARMENIAN CAPITAL LETTER JA -0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD -0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH -0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN -0545; C; 0575; # ARMENIAN CAPITAL LETTER YI -0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW -0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA -0548; C; 0578; # ARMENIAN CAPITAL LETTER VO -0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA -054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH -054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH -054C; C; 057C; # ARMENIAN CAPITAL LETTER RA -054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH -054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW -054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN -0550; C; 0580; # ARMENIAN CAPITAL LETTER REH -0551; C; 0581; # ARMENIAN CAPITAL LETTER CO -0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN -0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR -0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH -0555; C; 0585; # ARMENIAN CAPITAL LETTER OH -0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH -0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN -10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN -10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN -10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN -10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON -10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN -10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN -10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN -10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN -10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN -10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN -10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS -10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN -10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR -10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON -10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR -10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR -10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE -10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN -10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR -10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN -10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR -10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR -10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN -10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR -10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN -10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN -10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN -10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL -10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL -10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR -10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN -10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN -10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE -10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE -10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE -10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE -10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR -10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE -10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN -10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN -13F8; C; 13F0; # CHEROKEE SMALL LETTER YE -13F9; C; 13F1; # CHEROKEE SMALL LETTER YI -13FA; C; 13F2; # CHEROKEE SMALL LETTER YO -13FB; C; 13F3; # CHEROKEE SMALL LETTER YU -13FC; C; 13F4; # CHEROKEE SMALL LETTER YV -13FD; C; 13F5; # CHEROKEE SMALL LETTER MV -1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE -1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE -1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O -1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES -1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE -1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE -1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN -1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT -1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK -1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN -1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN -1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN -1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON -1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN -1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN -1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN -1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN -1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN -1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN -1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS -1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN -1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR -1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON -1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR -1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR -1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE -1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN -1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR -1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN -1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR -1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR -1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN -1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR -1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN -1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN -1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN -1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL -1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL -1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR -1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN -1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN -1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE -1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE -1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE -1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE -1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR -1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE -1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI -1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN -1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI -1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN -1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN -1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN -1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN -1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN -1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW -1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE -1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW -1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW -1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE -1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE -1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW -1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW -1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA -1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW -1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE -1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE -1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW -1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW -1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE -1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE -1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON -1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE -1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW -1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS -1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA -1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW -1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW -1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE -1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE -1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW -1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW -1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW -1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON -1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW -1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW -1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE -1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE -1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW -1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE -1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW -1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW -1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW -1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE -1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS -1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE -1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE -1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE -1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE -1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE -1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW -1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON -1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW -1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE -1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW -1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE -1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE -1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE -1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE -1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW -1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW -1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW -1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW -1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW -1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW -1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE -1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS -1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE -1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW -1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE -1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE -1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS -1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE -1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW -1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE -1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS -1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE -1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX -1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW -1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW -1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW -1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS -1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE -1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE -1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING -1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE -1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S -1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S -1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW -1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE -1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE -1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE -1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE -1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE -1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW -1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE -1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE -1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE -1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE -1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW -1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW -1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE -1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE -1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE -1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE -1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE -1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE -1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW -1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE -1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW -1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW -1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE -1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE -1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE -1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE -1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE -1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW -1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE -1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE -1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE -1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE -1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW -1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW -1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE -1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE -1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE -1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE -1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE -1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW -1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE -1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW -1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE -1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE -1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL -1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V -1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP -1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI -1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA -1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA -1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA -1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA -1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA -1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI -1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI -1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI -1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA -1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA -1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA -1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA -1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA -1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI -1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA -1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA -1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA -1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA -1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA -1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI -1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI -1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI -1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA -1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA -1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA -1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA -1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA -1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI -1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI -1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI -1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA -1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA -1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA -1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA -1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA -1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI -1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA -1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA -1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI -1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA -1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA -1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA -1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI -1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI -1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA -1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA -1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA -1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA -1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA -1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI -1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI -1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI -1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI -1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI -1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI -1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI -1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI -1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI -1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI -1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI -1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI -1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI -1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI -1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI -1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI -1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI -1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI -1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI -1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI -1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI -1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI -1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI -1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI -1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI -1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI -1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI -1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI -1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI -1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI -1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI -1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI -1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI -1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI -1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI -1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI -1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI -1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI -1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI -1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI -1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI -1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI -1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI -1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY -1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON -1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA -1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA -1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI -1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI -1FBE; C; 03B9; # GREEK PROSGEGRAMMENI -1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI -1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI -1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI -1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI -1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI -1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA -1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA -1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA -1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA -1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI -1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI -1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA -1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA -1FD3; S; 0390; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA -1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI -1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI -1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY -1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON -1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA -1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA -1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA -1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA -1FE3; S; 03B0; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA -1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI -1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI -1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI -1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY -1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON -1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA -1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA -1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA -1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI -1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI -1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI -1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI -1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI -1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA -1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA -1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA -1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA -1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI -1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI -2126; C; 03C9; # OHM SIGN -212A; C; 006B; # KELVIN SIGN -212B; C; 00E5; # ANGSTROM SIGN -2132; C; 214E; # TURNED CAPITAL F -2160; C; 2170; # ROMAN NUMERAL ONE -2161; C; 2171; # ROMAN NUMERAL TWO -2162; C; 2172; # ROMAN NUMERAL THREE -2163; C; 2173; # ROMAN NUMERAL FOUR -2164; C; 2174; # ROMAN NUMERAL FIVE -2165; C; 2175; # ROMAN NUMERAL SIX -2166; C; 2176; # ROMAN NUMERAL SEVEN -2167; C; 2177; # ROMAN NUMERAL EIGHT -2168; C; 2178; # ROMAN NUMERAL NINE -2169; C; 2179; # ROMAN NUMERAL TEN -216A; C; 217A; # ROMAN NUMERAL ELEVEN -216B; C; 217B; # ROMAN NUMERAL TWELVE -216C; C; 217C; # ROMAN NUMERAL FIFTY -216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED -216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED -216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND -2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED -24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A -24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B -24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C -24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D -24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E -24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F -24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G -24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H -24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I -24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J -24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K -24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L -24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M -24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N -24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O -24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P -24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q -24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R -24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S -24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T -24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U -24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V -24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W -24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X -24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y -24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z -2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU -2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY -2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE -2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI -2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO -2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU -2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE -2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO -2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA -2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE -2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE -2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I -2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI -2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO -2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE -2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE -2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI -2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU -2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI -2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI -2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO -2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO -2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU -2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU -2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU -2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU -2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE -2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA -2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI -2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI -2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA -2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU -2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI -2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI -2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA -2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU -2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS -2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL -2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO -2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS -2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS -2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS -2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA -2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA -2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC -2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A -2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE -2C2F; C; 2C5F; # GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI -2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR -2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE -2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE -2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL -2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER -2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER -2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER -2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA -2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK -2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A -2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA -2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK -2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H -2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL -2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL -2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA -2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA -2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA -2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA -2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE -2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU -2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA -2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE -2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE -2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA -2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA -2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA -2C98; C; 2C99; # COPTIC CAPITAL LETTER MI -2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI -2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI -2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O -2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI -2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO -2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA -2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU -2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA -2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI -2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI -2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI -2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU -2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF -2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN -2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE -2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA -2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI -2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI -2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU -2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI -2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI -2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI -2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH -2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI -2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI -2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI -2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA -2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA -2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI -2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT -2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA -2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA -2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA -2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA -2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI -2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI -2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU -2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI -2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA -2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI -A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA -A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO -A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE -A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA -A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV -A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK -A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA -A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER -A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER -A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT -A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU -A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A -A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS -A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS -A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS -A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN -A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE -A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE -A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL -A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM -A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O -A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O -A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O -A680; C; A681; # CYRILLIC CAPITAL LETTER DWE -A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE -A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE -A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE -A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE -A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK -A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE -A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE -A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE -A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE -A694; C; A695; # CYRILLIC CAPITAL LETTER HWE -A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE -A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O -A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O -A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF -A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN -A726; C; A727; # LATIN CAPITAL LETTER HENG -A728; C; A729; # LATIN CAPITAL LETTER TZ -A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO -A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO -A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA -A732; C; A733; # LATIN CAPITAL LETTER AA -A734; C; A735; # LATIN CAPITAL LETTER AO -A736; C; A737; # LATIN CAPITAL LETTER AU -A738; C; A739; # LATIN CAPITAL LETTER AV -A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR -A73C; C; A73D; # LATIN CAPITAL LETTER AY -A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT -A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE -A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE -A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE -A746; C; A747; # LATIN CAPITAL LETTER BROKEN L -A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE -A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY -A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP -A74E; C; A74F; # LATIN CAPITAL LETTER OO -A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER -A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH -A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL -A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER -A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE -A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA -A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA -A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE -A760; C; A761; # LATIN CAPITAL LETTER VY -A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z -A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE -A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER -A768; C; A769; # LATIN CAPITAL LETTER VEND -A76A; C; A76B; # LATIN CAPITAL LETTER ET -A76C; C; A76D; # LATIN CAPITAL LETTER IS -A76E; C; A76F; # LATIN CAPITAL LETTER CON -A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D -A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F -A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G -A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G -A780; C; A781; # LATIN CAPITAL LETTER TURNED L -A782; C; A783; # LATIN CAPITAL LETTER INSULAR R -A784; C; A785; # LATIN CAPITAL LETTER INSULAR S -A786; C; A787; # LATIN CAPITAL LETTER INSULAR T -A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO -A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H -A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER -A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR -A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH -A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE -A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE -A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE -A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE -A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE -A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE -A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE -A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE -A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE -A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK -A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E -A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G -A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT -A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I -A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K -A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T -A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL -A7B3; C; AB53; # LATIN CAPITAL LETTER CHI -A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA -A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA -A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE -A7BA; C; A7BB; # LATIN CAPITAL LETTER GLOTTAL A -A7BC; C; A7BD; # LATIN CAPITAL LETTER GLOTTAL I -A7BE; C; A7BF; # LATIN CAPITAL LETTER GLOTTAL U -A7C0; C; A7C1; # LATIN CAPITAL LETTER OLD POLISH O -A7C2; C; A7C3; # LATIN CAPITAL LETTER ANGLICANA W -A7C4; C; A794; # LATIN CAPITAL LETTER C WITH PALATAL HOOK -A7C5; C; 0282; # LATIN CAPITAL LETTER S WITH HOOK -A7C6; C; 1D8E; # LATIN CAPITAL LETTER Z WITH PALATAL HOOK -A7C7; C; A7C8; # LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY -A7C9; C; A7CA; # LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY -A7D0; C; A7D1; # LATIN CAPITAL LETTER CLOSED INSULAR G -A7D6; C; A7D7; # LATIN CAPITAL LETTER MIDDLE SCOTS S -A7D8; C; A7D9; # LATIN CAPITAL LETTER SIGMOID S -A7F5; C; A7F6; # LATIN CAPITAL LETTER REVERSED HALF H -AB70; C; 13A0; # CHEROKEE SMALL LETTER A -AB71; C; 13A1; # CHEROKEE SMALL LETTER E -AB72; C; 13A2; # CHEROKEE SMALL LETTER I -AB73; C; 13A3; # CHEROKEE SMALL LETTER O -AB74; C; 13A4; # CHEROKEE SMALL LETTER U -AB75; C; 13A5; # CHEROKEE SMALL LETTER V -AB76; C; 13A6; # CHEROKEE SMALL LETTER GA -AB77; C; 13A7; # CHEROKEE SMALL LETTER KA -AB78; C; 13A8; # CHEROKEE SMALL LETTER GE -AB79; C; 13A9; # CHEROKEE SMALL LETTER GI -AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO -AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU -AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV -AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA -AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE -AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI -AB80; C; 13B0; # CHEROKEE SMALL LETTER HO -AB81; C; 13B1; # CHEROKEE SMALL LETTER HU -AB82; C; 13B2; # CHEROKEE SMALL LETTER HV -AB83; C; 13B3; # CHEROKEE SMALL LETTER LA -AB84; C; 13B4; # CHEROKEE SMALL LETTER LE -AB85; C; 13B5; # CHEROKEE SMALL LETTER LI -AB86; C; 13B6; # CHEROKEE SMALL LETTER LO -AB87; C; 13B7; # CHEROKEE SMALL LETTER LU -AB88; C; 13B8; # CHEROKEE SMALL LETTER LV -AB89; C; 13B9; # CHEROKEE SMALL LETTER MA -AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME -AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI -AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO -AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU -AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA -AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA -AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH -AB91; C; 13C1; # CHEROKEE SMALL LETTER NE -AB92; C; 13C2; # CHEROKEE SMALL LETTER NI -AB93; C; 13C3; # CHEROKEE SMALL LETTER NO -AB94; C; 13C4; # CHEROKEE SMALL LETTER NU -AB95; C; 13C5; # CHEROKEE SMALL LETTER NV -AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA -AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE -AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI -AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO -AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU -AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV -AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA -AB9D; C; 13CD; # CHEROKEE SMALL LETTER S -AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE -AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI -ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO -ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU -ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV -ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA -ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA -ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE -ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE -ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI -ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI -ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO -ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU -ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV -ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA -ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA -ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE -ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI -ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO -ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU -ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV -ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA -ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE -ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI -ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO -ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU -ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV -ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA -ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE -ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI -ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO -ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU -ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV -ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA -FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF -FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI -FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL -FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI -FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL -FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T -FB05; S; FB06; # LATIN SMALL LIGATURE LONG S T -FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST -FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW -FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH -FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI -FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW -FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH -FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A -FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B -FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C -FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D -FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E -FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F -FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G -FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H -FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I -FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J -FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K -FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L -FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M -FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N -FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O -FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P -FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q -FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R -FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S -FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T -FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U -FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V -FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W -FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X -FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y -FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z -10400; C; 10428; # DESERET CAPITAL LETTER LONG I -10401; C; 10429; # DESERET CAPITAL LETTER LONG E -10402; C; 1042A; # DESERET CAPITAL LETTER LONG A -10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH -10404; C; 1042C; # DESERET CAPITAL LETTER LONG O -10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO -10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I -10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E -10408; C; 10430; # DESERET CAPITAL LETTER SHORT A -10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH -1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O -1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO -1040C; C; 10434; # DESERET CAPITAL LETTER AY -1040D; C; 10435; # DESERET CAPITAL LETTER OW -1040E; C; 10436; # DESERET CAPITAL LETTER WU -1040F; C; 10437; # DESERET CAPITAL LETTER YEE -10410; C; 10438; # DESERET CAPITAL LETTER H -10411; C; 10439; # DESERET CAPITAL LETTER PEE -10412; C; 1043A; # DESERET CAPITAL LETTER BEE -10413; C; 1043B; # DESERET CAPITAL LETTER TEE -10414; C; 1043C; # DESERET CAPITAL LETTER DEE -10415; C; 1043D; # DESERET CAPITAL LETTER CHEE -10416; C; 1043E; # DESERET CAPITAL LETTER JEE -10417; C; 1043F; # DESERET CAPITAL LETTER KAY -10418; C; 10440; # DESERET CAPITAL LETTER GAY -10419; C; 10441; # DESERET CAPITAL LETTER EF -1041A; C; 10442; # DESERET CAPITAL LETTER VEE -1041B; C; 10443; # DESERET CAPITAL LETTER ETH -1041C; C; 10444; # DESERET CAPITAL LETTER THEE -1041D; C; 10445; # DESERET CAPITAL LETTER ES -1041E; C; 10446; # DESERET CAPITAL LETTER ZEE -1041F; C; 10447; # DESERET CAPITAL LETTER ESH -10420; C; 10448; # DESERET CAPITAL LETTER ZHEE -10421; C; 10449; # DESERET CAPITAL LETTER ER -10422; C; 1044A; # DESERET CAPITAL LETTER EL -10423; C; 1044B; # DESERET CAPITAL LETTER EM -10424; C; 1044C; # DESERET CAPITAL LETTER EN -10425; C; 1044D; # DESERET CAPITAL LETTER ENG -10426; C; 1044E; # DESERET CAPITAL LETTER OI -10427; C; 1044F; # DESERET CAPITAL LETTER EW -104B0; C; 104D8; # OSAGE CAPITAL LETTER A -104B1; C; 104D9; # OSAGE CAPITAL LETTER AI -104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN -104B3; C; 104DB; # OSAGE CAPITAL LETTER AH -104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA -104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA -104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA -104B7; C; 104DF; # OSAGE CAPITAL LETTER E -104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN -104B9; C; 104E1; # OSAGE CAPITAL LETTER HA -104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA -104BB; C; 104E3; # OSAGE CAPITAL LETTER I -104BC; C; 104E4; # OSAGE CAPITAL LETTER KA -104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA -104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA -104BF; C; 104E7; # OSAGE CAPITAL LETTER LA -104C0; C; 104E8; # OSAGE CAPITAL LETTER MA -104C1; C; 104E9; # OSAGE CAPITAL LETTER NA -104C2; C; 104EA; # OSAGE CAPITAL LETTER O -104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN -104C4; C; 104EC; # OSAGE CAPITAL LETTER PA -104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA -104C6; C; 104EE; # OSAGE CAPITAL LETTER SA -104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA -104C8; C; 104F0; # OSAGE CAPITAL LETTER TA -104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA -104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA -104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA -104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA -104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA -104CE; C; 104F6; # OSAGE CAPITAL LETTER U -104CF; C; 104F7; # OSAGE CAPITAL LETTER WA -104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA -104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA -104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA -104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA -10570; C; 10597; # VITHKUQI CAPITAL LETTER A -10571; C; 10598; # VITHKUQI CAPITAL LETTER BBE -10572; C; 10599; # VITHKUQI CAPITAL LETTER BE -10573; C; 1059A; # VITHKUQI CAPITAL LETTER CE -10574; C; 1059B; # VITHKUQI CAPITAL LETTER CHE -10575; C; 1059C; # VITHKUQI CAPITAL LETTER DE -10576; C; 1059D; # VITHKUQI CAPITAL LETTER DHE -10577; C; 1059E; # VITHKUQI CAPITAL LETTER EI -10578; C; 1059F; # VITHKUQI CAPITAL LETTER E -10579; C; 105A0; # VITHKUQI CAPITAL LETTER FE -1057A; C; 105A1; # VITHKUQI CAPITAL LETTER GA -1057C; C; 105A3; # VITHKUQI CAPITAL LETTER HA -1057D; C; 105A4; # VITHKUQI CAPITAL LETTER HHA -1057E; C; 105A5; # VITHKUQI CAPITAL LETTER I -1057F; C; 105A6; # VITHKUQI CAPITAL LETTER IJE -10580; C; 105A7; # VITHKUQI CAPITAL LETTER JE -10581; C; 105A8; # VITHKUQI CAPITAL LETTER KA -10582; C; 105A9; # VITHKUQI CAPITAL LETTER LA -10583; C; 105AA; # VITHKUQI CAPITAL LETTER LLA -10584; C; 105AB; # VITHKUQI CAPITAL LETTER ME -10585; C; 105AC; # VITHKUQI CAPITAL LETTER NE -10586; C; 105AD; # VITHKUQI CAPITAL LETTER NJE -10587; C; 105AE; # VITHKUQI CAPITAL LETTER O -10588; C; 105AF; # VITHKUQI CAPITAL LETTER PE -10589; C; 105B0; # VITHKUQI CAPITAL LETTER QA -1058A; C; 105B1; # VITHKUQI CAPITAL LETTER RE -1058C; C; 105B3; # VITHKUQI CAPITAL LETTER SE -1058D; C; 105B4; # VITHKUQI CAPITAL LETTER SHE -1058E; C; 105B5; # VITHKUQI CAPITAL LETTER TE -1058F; C; 105B6; # VITHKUQI CAPITAL LETTER THE -10590; C; 105B7; # VITHKUQI CAPITAL LETTER U -10591; C; 105B8; # VITHKUQI CAPITAL LETTER VE -10592; C; 105B9; # VITHKUQI CAPITAL LETTER XE -10594; C; 105BB; # VITHKUQI CAPITAL LETTER Y -10595; C; 105BC; # VITHKUQI CAPITAL LETTER ZE -10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A -10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA -10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB -10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB -10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC -10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC -10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS -10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED -10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND -10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E -10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E -10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE -10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF -10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG -10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY -10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH -10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I -10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II -10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ -10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK -10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK -10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK -10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL -10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY -10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM -10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN -10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY -10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O -10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO -10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE -10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE -10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE -10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP -10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP -10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER -10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER -10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES -10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ -10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET -10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT -10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY -10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH -10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U -10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU -10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE -10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE -10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV -10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ -10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS -10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN -10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US -118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA -118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A -118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI -118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU -118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA -118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO -118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II -118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU -118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E -118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O -118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG -118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA -118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO -118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY -118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ -118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC -118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN -118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD -118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE -118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG -118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA -118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT -118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM -118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU -118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU -118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO -118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO -118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR -118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR -118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU -118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII -118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO -16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M -16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S -16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V -16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W -16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU -16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z -16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP -16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P -16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T -16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G -16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F -16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I -16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K -16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A -16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J -16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E -16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B -16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C -16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U -16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU -16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L -16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q -16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP -16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY -16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X -16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D -16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE -16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N -16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R -16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O -16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI -16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y -1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF -1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI -1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM -1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM -1E904; C; 1E926; # ADLAM CAPITAL LETTER BA -1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE -1E906; C; 1E928; # ADLAM CAPITAL LETTER PE -1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE -1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA -1E909; C; 1E92B; # ADLAM CAPITAL LETTER E -1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA -1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I -1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O -1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA -1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE -1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW -1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN -1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF -1E912; C; 1E934; # ADLAM CAPITAL LETTER YA -1E913; C; 1E935; # ADLAM CAPITAL LETTER U -1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM -1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI -1E916; C; 1E938; # ADLAM CAPITAL LETTER HA -1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF -1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA -1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA -1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU -1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA -1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA -1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA -1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE -1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL -1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO -1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA -# -# EOF diff --git a/contrib/SDL-3.2.8/build-scripts/check_android_jni.py b/contrib/SDL-3.2.8/build-scripts/check_android_jni.py deleted file mode 100755 index 9e519fb..0000000 --- a/contrib/SDL-3.2.8/build-scripts/check_android_jni.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env python - -import argparse -import dataclasses -import os -import pathlib -import re - -ROOT = pathlib.Path(__file__).resolve().parents[1] -SDL_ANDROID_C = ROOT / "src/core/android/SDL_android.c" -METHOD_SOURCE_PATHS = ( - SDL_ANDROID_C, - ROOT / "src/hidapi/android/hid.cpp", -) -JAVA_ROOT = ROOT / "android-project/app/src/main/java" - - -BASIC_TYPE_SPEC_LUT = { - "char": "C", - "byte": "B", - "short": "S", - "int": "I", - "long": "J", - "float": "F", - "double": "D", - "void": "V", - "boolean": "Z", - "Object": "Ljava/lang/Object;", - "String": "Ljava/lang/String;", -} - - -@dataclasses.dataclass(frozen=True) -class JniType: - typ: str - array: int - - -def java_type_to_jni_spec_internal(type_str: str) -> tuple[int, str]: - for basic_type_str, basic_type_spec in BASIC_TYPE_SPEC_LUT.items(): - if type_str.startswith(basic_type_str): - return len(basic_type_str), basic_type_spec - raise ValueError(f"Don't know how to convert {repr(type_str)} to its equivalent jni spec") - - -def java_type_to_jni_spec(type_str: str) -> str: - end, type_spec = java_type_to_jni_spec_internal(type_str) - suffix_str = type_str[end:] - assert(all(c in "[] \t" for c in suffix_str)) - suffix_str = "".join(filter(lambda v: v in "[]", suffix_str)) - assert len(suffix_str) % 2 == 0 - array_spec = "[" * (len(suffix_str) // 2) - return array_spec + type_spec - - -def java_method_to_jni_spec(ret: str, args: list[str]) -> str: - return "(" + "".join(java_type_to_jni_spec(a) for a in args) +")" + java_type_to_jni_spec(ret) - - -@dataclasses.dataclass(frozen=True) -class JniMethodBinding: - name: str - spec: str - - -def collect_jni_bindings_from_c() -> dict[str, set[JniMethodBinding]]: - bindings = {} - - sdl_android_text = SDL_ANDROID_C.read_text() - for m in re.finditer(r"""register_methods\((?:[A-Za-z0-9]+),\s*"(?P[a-zA-Z0-9_/]+)",\s*(?P[a-zA-Z0-9_]+),\s*SDL_arraysize\((?P=table)\)\)""", sdl_android_text): - kls = m["class"] - table = m["table"] - methods = set() - in_struct = False - for method_source_path in METHOD_SOURCE_PATHS: - method_source = method_source_path.read_text() - for line in method_source.splitlines(keepends=False): - if re.match(f"(static )?JNINativeMethod {table}" + r"\[([0-9]+)?\] = \{", line): - in_struct = True - continue - if in_struct: - if re.match(r"\};", line): - in_struct = False - break - n = re.match(r"""\s*\{\s*"(?P[a-zA-Z0-9_]+)"\s*,\s*"(?P[()A-Za-z0-9_/;[]+)"\s*,\s*(\(void\*\))?(HID|SDL)[_A-Z]*_JAVA_[_A-Z]*INTERFACE[_A-Z]*\((?P=method)\)\s*\},?""", line) - assert n, f"'{line}' does not match regex" - methods.add(JniMethodBinding(name=n["method"], spec=n["spec"])) - continue - if methods: - break - if methods: - break - assert methods, f"Could not find methods for {kls} (table={table})" - - assert not in_struct - - assert kls not in bindings, f"{kls} must be unique in C sources" - bindings[kls] = methods - return bindings - -def collect_jni_bindings_from_java() -> dict[str, set[JniMethodBinding]]: - bindings = {} - - for root, _, files in os.walk(JAVA_ROOT): - for file in files: - file_path = pathlib.Path(root) / file - java_text = file_path.read_text() - methods = set() - for m in re.finditer(r"(?:(?:public|private)\s+)?(?:static\s+)?native\s+(?P[A-Za-z0-9_]+)\s+(?P[a-zA-Z0-9_]+)\s*\(\s*(?P[^)]*)\);", java_text): - name = m["method"] - ret = m["ret"] - args = [] - args_str = m["args"].strip() - if args_str: - for a_s in args_str.split(","): - atype_str, _ = a_s.strip().rsplit(" ") - args.append(atype_str.strip()) - - spec = java_method_to_jni_spec(ret=ret, args=args) - methods.add(JniMethodBinding(name=name, spec=spec)) - if methods: - relative_java_path = file_path.relative_to(JAVA_ROOT) - relative_java_path_without_suffix = relative_java_path.with_suffix("") - kls = "/".join(relative_java_path_without_suffix.parts) - assert kls not in bindings, f"{kls} must be unique in JAVA sources" - bindings[kls] = methods - return bindings - - -def print_error(*args): - print("ERROR:", *args) - - -def main(): - parser = argparse.ArgumentParser(allow_abbrev=False, description="Verify Android JNI bindings") - args = parser.parse_args() - - bindings_from_c = collect_jni_bindings_from_c() - bindings_from_java = collect_jni_bindings_from_java() - - all_ok = bindings_from_c == bindings_from_java - if all_ok: - print("OK") - else: - print("NOT OK") - kls_c = set(bindings_from_c.keys()) - kls_java = set(bindings_from_java.keys()) - if kls_c != kls_java: - only_c = kls_c - kls_java - for c in only_c: - print_error(f"Missing class in JAVA sources: {c}") - only_java = kls_java - kls_c - for c in only_java: - print_error(f"Missing class in C sources: {c}") - - klasses = kls_c.union(kls_java) - for kls in klasses: - m_c = bindings_from_c.get(kls) - m_j = bindings_from_java.get(kls) - if m_c and m_j and m_c != m_j: - m_only_c = m_c - m_j - for c in m_only_c: - print_error(f"{kls}: Binding only in C source: {c.name} {c.spec}") - m_only_j = m_j - m_c - for c in m_only_j: - print_error(f"{kls}: Binding only in JAVA source: {c.name} {c.spec}") - - return 0 if all_ok else 1 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/check_stdlib_usage.py b/contrib/SDL-3.2.8/build-scripts/check_stdlib_usage.py deleted file mode 100755 index 0994130..0000000 --- a/contrib/SDL-3.2.8/build-scripts/check_stdlib_usage.py +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python3 -# -# Simple DirectMedia Layer -# Copyright (C) 1997-2025 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. -# -# This script detects use of stdlib function in SDL code - -import argparse -import os -import pathlib -import re -import sys - -SDL_ROOT = pathlib.Path(__file__).resolve().parents[1] - -STDLIB_SYMBOLS = [ - 'abs', - 'acos', - 'acosf', - 'asin', - 'asinf', - 'asprintf', - 'atan', - 'atan2', - 'atan2f', - 'atanf', - 'atof', - 'atoi', - 'bsearch', - 'calloc', - 'ceil', - 'ceilf', - 'copysign', - 'copysignf', - 'cos', - 'cosf', - 'crc32', - 'exp', - 'expf', - 'fabs', - 'fabsf', - 'floor', - 'floorf', - 'fmod', - 'fmodf', - 'free', - 'getenv', - 'isalnum', - 'isalpha', - 'isblank', - 'iscntrl', - 'isdigit', - 'isgraph', - 'islower', - 'isprint', - 'ispunct', - 'isspace', - 'isupper', - 'isxdigit', - 'itoa', - 'lltoa', - 'log10', - 'log10f', - 'logf', - 'lround', - 'lroundf', - 'ltoa', - 'malloc', - 'memalign', - 'memcmp', - 'memcpy', - 'memcpy4', - 'memmove', - 'memset', - 'pow', - 'powf', - 'qsort', - 'qsort_r', - 'qsort_s', - 'realloc', - 'round', - 'roundf', - 'scalbn', - 'scalbnf', - 'setenv', - 'sin', - 'sinf', - 'snprintf', - 'sqrt', - 'sqrtf', - 'sscanf', - 'strcasecmp', - 'strchr', - 'strcmp', - 'strdup', - 'strlcat', - 'strlcpy', - 'strlen', - 'strlwr', - 'strncasecmp', - 'strncmp', - 'strrchr', - 'strrev', - 'strstr', - 'strtod', - 'strtokr', - 'strtol', - 'strtoll', - 'strtoul', - 'strupr', - 'tan', - 'tanf', - 'tolower', - 'toupper', - 'trunc', - 'truncf', - 'uitoa', - 'ulltoa', - 'ultoa', - 'utf8strlcpy', - 'utf8strlen', - 'vasprintf', - 'vsnprintf', - 'vsscanf', - 'wcscasecmp', - 'wcscmp', - 'wcsdup', - 'wcslcat', - 'wcslcpy', - 'wcslen', - 'wcsncasecmp', - 'wcsncmp', - 'wcsstr', -] -RE_STDLIB_SYMBOL = re.compile(rf"\b(?P{'|'.join(STDLIB_SYMBOLS)})\b\(") - - -def find_symbols_in_file(file: pathlib.Path) -> int: - match_count = 0 - - allowed_extensions = [ ".c", ".cpp", ".m", ".h", ".hpp", ".cc" ] - - excluded_paths = [ - "src/stdlib", - "src/libm", - "src/hidapi", - "src/video/khronos", - "src/video/stb_image.h", - "include/SDL3", - "build-scripts/gen_audio_resampler_filter.c", - "build-scripts/gen_audio_channel_conversion.c", - "test/win32/sdlprocdump.c", - ] - - filename = pathlib.Path(file) - - for ep in excluded_paths: - if ep in filename.as_posix(): - # skip - return 0 - - if filename.suffix not in allowed_extensions: - # skip - return 0 - - # print("Parse %s" % file) - - try: - with file.open("r", encoding="UTF-8", newline="") as rfp: - parsing_comment = False - for line_i, original_line in enumerate(rfp, start=1): - line = original_line.strip() - - line_comment = "" - - # Get the comment block /* ... */ across several lines - while True: - if parsing_comment: - pos_end_comment = line.find("*/") - if pos_end_comment >= 0: - line = line[pos_end_comment+2:] - parsing_comment = False - else: - break - else: - pos_start_comment = line.find("/*") - if pos_start_comment >= 0: - pos_end_comment = line.find("*/", pos_start_comment+2) - if pos_end_comment >= 0: - line_comment += line[pos_start_comment:pos_end_comment+2] - line = line[:pos_start_comment] + line[pos_end_comment+2:] - else: - line_comment += line[pos_start_comment:] - line = line[:pos_start_comment] - parsing_comment = True - break - else: - break - if parsing_comment: - continue - pos_line_comment = line.find("//") - if pos_line_comment >= 0: - line_comment += line[pos_line_comment:] - line = line[:pos_line_comment] - - if m := RE_STDLIB_SYMBOL.match(line): - override_string = f"This should NOT be SDL_{m['symbol']}()" - if override_string not in line_comment: - print(f"{filename}:{line_i}") - print(f" {line}") - print(f"") - match_count += 1 - - except UnicodeDecodeError: - print(f"{file} is not text, skipping", file=sys.stderr) - - return match_count - -def find_symbols_in_dir(path: pathlib.Path) -> int: - match_count = 0 - for entry in path.glob("*"): - if entry.is_dir(): - match_count += find_symbols_in_dir(entry) - else: - match_count += find_symbols_in_file(entry) - return match_count - -def main(): - parser = argparse.ArgumentParser(fromfile_prefix_chars="@") - parser.add_argument("path", default=SDL_ROOT, nargs="?", type=pathlib.Path, help="Path to look for stdlib symbols") - args = parser.parse_args() - - print(f"Looking for stdlib usage in {args.path}...") - - match_count = find_symbols_in_dir(args.path) - - if match_count: - print("If the stdlib usage is intentional, add a '// This should NOT be SDL_()' line comment.") - print("") - print("NOT OK") - else: - print("OK") - return 1 if match_count else 0 - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/clang-format-src.sh b/contrib/SDL-3.2.8/build-scripts/clang-format-src.sh deleted file mode 100755 index bc0defc..0000000 --- a/contrib/SDL-3.2.8/build-scripts/clang-format-src.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -cd "$(dirname $0)/../src" - -echo "Running clang-format in $(pwd)" - -find . -regex '.*\.[chm]p*' -exec clang-format -i {} \; - -# Revert third-party code -git checkout \ - events/imKStoUCS.* \ - hidapi \ - joystick/controller_type.c \ - joystick/controller_type.h \ - joystick/hidapi/steam/controller_constants.h \ - joystick/hidapi/steam/controller_structs.h \ - libm \ - stdlib/SDL_malloc.c \ - stdlib/SDL_qsort.c \ - stdlib/SDL_strtokr.c \ - video/khronos \ - video/x11/edid.h \ - video/x11/edid-parse.c \ - video/x11/xsettings-client.* \ - video/yuv2rgb -clang-format -i hidapi/SDL_hidapi.c - -# Revert generated code -git checkout \ - dynapi/SDL_dynapi_overrides.h \ - dynapi/SDL_dynapi_procs.h \ - render/*/*Shader*.h \ - render/metal/SDL_shaders_metal_*.h \ - render/vitagxm/SDL_render_vita_gxm_shaders.h \ - video/directx/SDL_d3d12_xbox_cmacros.h \ - video/directx/d3d12.h \ - video/directx/d3d12sdklayers.h \ - -echo "clang-format complete!" diff --git a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-i686.cmake b/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-i686.cmake deleted file mode 100644 index 8be7b3a..0000000 --- a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-i686.cmake +++ /dev/null @@ -1,18 +0,0 @@ -set(CMAKE_SYSTEM_NAME Windows) -set(CMAKE_SYSTEM_PROCESSOR x86) - -find_program(CMAKE_C_COMPILER NAMES i686-w64-mingw32-gcc) -find_program(CMAKE_CXX_COMPILER NAMES i686-w64-mingw32-g++) -find_program(CMAKE_RC_COMPILER NAMES i686-w64-mingw32-windres windres) - -if(NOT CMAKE_C_COMPILER) - message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.") -endif() - -if(NOT CMAKE_CXX_COMPILER) - message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.") -endif() - -if(NOT CMAKE_RC_COMPILER) - message(FATAL_ERROR "Failed to find CMAKE_RC_COMPILER.") -endif() diff --git a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-x86_64.cmake b/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-x86_64.cmake deleted file mode 100644 index 8bf4366..0000000 --- a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-mingw64-x86_64.cmake +++ /dev/null @@ -1,18 +0,0 @@ -set(CMAKE_SYSTEM_NAME Windows) -set(CMAKE_SYSTEM_PROCESSOR x86_64) - -find_program(CMAKE_C_COMPILER NAMES x86_64-w64-mingw32-gcc) -find_program(CMAKE_CXX_COMPILER NAMES x86_64-w64-mingw32-g++) -find_program(CMAKE_RC_COMPILER NAMES x86_64-w64-mingw32-windres windres) - -if(NOT CMAKE_C_COMPILER) - message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.") -endif() - -if(NOT CMAKE_CXX_COMPILER) - message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.") -endif() - -if(NOT CMAKE_RC_COMPILER) - message(FATAL_ERROR "Failed to find CMAKE_RC_COMPILER.") -endif() diff --git a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-aarch64le.cmake b/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-aarch64le.cmake deleted file mode 100644 index 26f5da4..0000000 --- a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-aarch64le.cmake +++ /dev/null @@ -1,14 +0,0 @@ -set(CMAKE_SYSTEM_NAME QNX) - -set(arch gcc_ntoaarch64le) - -set(CMAKE_C_COMPILER qcc) -set(CMAKE_C_COMPILER_TARGET ${arch}) -set(CMAKE_CXX_COMPILER q++) -set(CMAKE_CXX_COMPILER_TARGET ${arch}) - -set(CMAKE_SYSROOT $ENV{QNX_TARGET}) - -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-x86_64.cmake b/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-x86_64.cmake deleted file mode 100644 index 29f795a..0000000 --- a/contrib/SDL-3.2.8/build-scripts/cmake-toolchain-qnx-x86_64.cmake +++ /dev/null @@ -1,14 +0,0 @@ -set(CMAKE_SYSTEM_NAME QNX) - -set(arch gcc_ntox86_64) - -set(CMAKE_C_COMPILER qcc) -set(CMAKE_C_COMPILER_TARGET ${arch}) -set(CMAKE_CXX_COMPILER q++) -set(CMAKE_CXX_COMPILER_TARGET ${arch}) - -set(CMAKE_SYSROOT $ENV{QNX_TARGET}) - -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/contrib/SDL-3.2.8/build-scripts/codechecker-buildbot.sh b/contrib/SDL-3.2.8/build-scripts/codechecker-buildbot.sh deleted file mode 100755 index 76b7853..0000000 --- a/contrib/SDL-3.2.8/build-scripts/codechecker-buildbot.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -# This is a script used by some Buildbot build workers to push the project -# through Clang's static analyzer and prepare the output to be uploaded -# back to the buildmaster. You might find it useful too. - -# Install Clang (you already have it on macOS, apt-get install clang -# on Ubuntu, etc), install CMake, and pip3 install codechecker. - -FINALDIR="$1" - -set -x -set -e - -cd `dirname "$0"` -cd .. - -rm -rf codechecker-buildbot -if [ ! -z "$FINALDIR" ]; then - rm -rf "$FINALDIR" -fi - -mkdir codechecker-buildbot -cd codechecker-buildbot - -# We turn off deprecated declarations, because we don't care about these warnings during static analysis. -cmake -Wno-dev -DSDL_STATIC=OFF -DCMAKE_BUILD_TYPE=Debug -DSDL_ASSERTIONS=enabled -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. - -# CMake on macOS adds "-arch arm64" or whatever is appropriate, but this confuses CodeChecker, so strip it out. -perl -w -pi -e 's/\-arch\s+.*?\s+//g;' compile_commands.json - -rm -rf ../analysis -CodeChecker analyze compile_commands.json -o ./reports - -# "parse" returns 2 if there was a static analysis issue to report, but this -# does not signify an error in the parsing (that would be error code 1). Turn -# off the abort-on-error flag. -set +e -CodeChecker parse ./reports -e html -o ../analysis -set -e - -cd .. -chmod -R a+r analysis -chmod -R go-w analysis -find analysis -type d -exec chmod a+x {} \; -if [ -x /usr/bin/xattr ]; then find analysis -exec /usr/bin/xattr -d com.apple.quarantine {} \; 2>/dev/null ; fi - -if [ ! -z "$FINALDIR" ]; then - mv analysis "$FINALDIR" -else - FINALDIR=analysis -fi - -rm -rf codechecker-buildbot - -echo "Done. Final output is in '$FINALDIR' ..." - -# end of codechecker-buildbot.sh ... - diff --git a/contrib/SDL-3.2.8/build-scripts/create-android-project.py b/contrib/SDL-3.2.8/build-scripts/create-android-project.py deleted file mode 100755 index 0b8994f..0000000 --- a/contrib/SDL-3.2.8/build-scripts/create-android-project.py +++ /dev/null @@ -1,241 +0,0 @@ -#!/usr/bin/env python3 -import os -from argparse import ArgumentParser -from pathlib import Path -import re -import shutil -import sys -import textwrap - - -SDL_ROOT = Path(__file__).resolve().parents[1] - -def extract_sdl_version() -> str: - """ - Extract SDL version from SDL3/SDL_version.h - """ - - with open(SDL_ROOT / "include/SDL3/SDL_version.h") as f: - data = f.read() - - major = int(next(re.finditer(r"#define\s+SDL_MAJOR_VERSION\s+([0-9]+)", data)).group(1)) - minor = int(next(re.finditer(r"#define\s+SDL_MINOR_VERSION\s+([0-9]+)", data)).group(1)) - micro = int(next(re.finditer(r"#define\s+SDL_MICRO_VERSION\s+([0-9]+)", data)).group(1)) - return f"{major}.{minor}.{micro}" - -def replace_in_file(path: Path, regex_what: str, replace_with: str) -> None: - with path.open("r") as f: - data = f.read() - - new_data, count = re.subn(regex_what, replace_with, data) - - assert count > 0, f"\"{regex_what}\" did not match anything in \"{path}\"" - - with open(path, "w") as f: - f.write(new_data) - - -def android_mk_use_prefab(path: Path) -> None: - """ - Replace relative SDL inclusion with dependency on prefab package - """ - - with path.open() as f: - data = "".join(line for line in f.readlines() if "# SDL" not in line) - - data, _ = re.subn("[\n]{3,}", "\n\n", data) - - data, count = re.subn(r"(LOCAL_SHARED_LIBRARIES\s*:=\s*SDL3)", "LOCAL_SHARED_LIBRARIES := SDL3 SDL3-Headers", data) - assert count == 1, f"Must have injected SDL3-Headers in {path} exactly once" - - newdata = data + textwrap.dedent(""" - # https://google.github.io/prefab/build-systems.html - - # Add the prefab modules to the import path. - $(call import-add-path,/out) - - # Import SDL3 so we can depend on it. - $(call import-module,prefab/SDL3) - """) - - with path.open("w") as f: - f.write(newdata) - - -def cmake_mk_no_sdl(path: Path) -> None: - """ - Don't add the source directories of SDL/SDL_image/SDL_mixer/... - """ - - with path.open() as f: - lines = f.readlines() - - newlines: list[str] = [] - for line in lines: - if "add_subdirectory(SDL" in line: - while newlines[-1].startswith("#"): - newlines = newlines[:-1] - continue - newlines.append(line) - - newdata, _ = re.subn("[\n]{3,}", "\n\n", "".join(newlines)) - - with path.open("w") as f: - f.write(newdata) - - -def gradle_add_prefab_and_aar(path: Path, aar: str) -> None: - with path.open() as f: - data = f.read() - - data, count = re.subn("android {", textwrap.dedent(""" - android { - buildFeatures { - prefab true - }"""), data) - assert count == 1 - - data, count = re.subn("dependencies {", textwrap.dedent(f""" - dependencies {{ - implementation files('libs/{aar}')"""), data) - assert count == 1 - - with path.open("w") as f: - f.write(data) - - -def gradle_add_package_name(path: Path, package_name: str) -> None: - with path.open() as f: - data = f.read() - - data, count = re.subn("org.libsdl.app", package_name, data) - assert count >= 1 - - with path.open("w") as f: - f.write(data) - - -def main() -> int: - description = "Create a simple Android gradle project from input sources." - epilog = textwrap.dedent("""\ - You need to manually copy a prebuilt SDL3 Android archive into the project tree when using the aar variant. - - Any changes you have done to the sources in the Android project will be lost - """) - parser = ArgumentParser(description=description, epilog=epilog, allow_abbrev=False) - parser.add_argument("package_name", metavar="PACKAGENAME", help="Android package name (e.g. com.yourcompany.yourapp)") - parser.add_argument("sources", metavar="SOURCE", nargs="*", help="Source code of your application. The files are copied to the output directory.") - parser.add_argument("--variant", choices=["copy", "symlink", "aar"], default="copy", help="Choose variant of SDL project (copy: copy SDL sources, symlink: symlink SDL sources, aar: use Android aar archive)") - parser.add_argument("--output", "-o", default=SDL_ROOT / "build", type=Path, help="Location where to store the Android project") - parser.add_argument("--version", default=None, help="SDL3 version to use as aar dependency (only used for aar variant)") - - args = parser.parse_args() - if not args.sources: - print("Reading source file paths from stdin (press CTRL+D to stop)") - args.sources = [path for path in sys.stdin.read().strip().split() if path] - if not args.sources: - parser.error("No sources passed") - - if not os.getenv("ANDROID_HOME"): - print("WARNING: ANDROID_HOME environment variable not set", file=sys.stderr) - if not os.getenv("ANDROID_NDK_HOME"): - print("WARNING: ANDROID_NDK_HOME environment variable not set", file=sys.stderr) - - args.sources = [Path(src) for src in args.sources] - - build_path = args.output / args.package_name - - # Remove the destination folder - shutil.rmtree(build_path, ignore_errors=True) - - # Copy the Android project - shutil.copytree(SDL_ROOT / "android-project", build_path) - - # Add the source files to the ndk-build and cmake projects - replace_in_file(build_path / "app/jni/src/Android.mk", r"YourSourceHere\.c", " \\\n ".join(src.name for src in args.sources)) - replace_in_file(build_path / "app/jni/src/CMakeLists.txt", r"YourSourceHere\.c", "\n ".join(src.name for src in args.sources)) - - # Remove placeholder source "YourSourceHere.c" - (build_path / "app/jni/src/YourSourceHere.c").unlink() - - # Copy sources to output folder - for src in args.sources: - if not src.is_file(): - parser.error(f"\"{src}\" is not a file") - shutil.copyfile(src, build_path / "app/jni/src" / src.name) - - sdl_project_files = ( - SDL_ROOT / "src", - SDL_ROOT / "include", - SDL_ROOT / "LICENSE.txt", - SDL_ROOT / "README.md", - SDL_ROOT / "Android.mk", - SDL_ROOT / "CMakeLists.txt", - SDL_ROOT / "cmake", - ) - if args.variant == "copy": - (build_path / "app/jni/SDL").mkdir(exist_ok=True, parents=True) - for sdl_project_file in sdl_project_files: - # Copy SDL project files and directories - if sdl_project_file.is_dir(): - shutil.copytree(sdl_project_file, build_path / "app/jni/SDL" / sdl_project_file.name) - elif sdl_project_file.is_file(): - shutil.copyfile(sdl_project_file, build_path / "app/jni/SDL" / sdl_project_file.name) - elif args.variant == "symlink": - (build_path / "app/jni/SDL").mkdir(exist_ok=True, parents=True) - # Create symbolic links for all SDL project files - for sdl_project_file in sdl_project_files: - os.symlink(sdl_project_file, build_path / "app/jni/SDL" / sdl_project_file.name) - elif args.variant == "aar": - if not args.version: - args.version = extract_sdl_version() - - major = args.version.split(".")[0] - aar = f"SDL{ major }-{ args.version }.aar" - - # Remove all SDL java classes - shutil.rmtree(build_path / "app/src/main/java") - - # Use prefab to generate include-able files - gradle_add_prefab_and_aar(build_path / "app/build.gradle", aar=aar) - - # Make sure to use the prefab-generated files and not SDL sources - android_mk_use_prefab(build_path / "app/jni/src/Android.mk") - cmake_mk_no_sdl(build_path / "app/jni/CMakeLists.txt") - - aar_libs_folder = build_path / "app/libs" - aar_libs_folder.mkdir(parents=True) - with (aar_libs_folder / "copy-sdl-aars-here.txt").open("w") as f: - f.write(f"Copy {aar} to this folder.\n") - - print(f"WARNING: copy { aar } to { aar_libs_folder }", file=sys.stderr) - - # Add the package name to build.gradle - gradle_add_package_name(build_path / "app/build.gradle", args.package_name) - - # Create entry activity, subclassing SDLActivity - activity = args.package_name[args.package_name.rfind(".") + 1:].capitalize() + "Activity" - activity_path = build_path / "app/src/main/java" / args.package_name.replace(".", "/") / f"{activity}.java" - activity_path.parent.mkdir(parents=True) - with activity_path.open("w") as f: - f.write(textwrap.dedent(f""" - package {args.package_name}; - - import org.libsdl.app.SDLActivity; - - public class {activity} extends SDLActivity - {{ - }} - """)) - - # Add the just-generated activity to the Android manifest - replace_in_file(build_path / "app/src/main/AndroidManifest.xml", 'name="SDLActivity"', f'name="{activity}"') - - # Update project and build - print("To build and install to a device for testing, run the following:") - print(f"cd {build_path}") - print("./gradlew installDebug") - return 0 - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/create-release.py b/contrib/SDL-3.2.8/build-scripts/create-release.py deleted file mode 100755 index 14916fa..0000000 --- a/contrib/SDL-3.2.8/build-scripts/create-release.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -from pathlib import Path -import json -import logging -import re -import subprocess - -ROOT = Path(__file__).resolve().parents[1] - - -def determine_remote() -> str: - text = (ROOT / "build-scripts/release-info.json").read_text() - release_info = json.loads(text) - if "remote" in release_info: - return release_info["remote"] - project_with_version = release_info["name"] - project, _ = re.subn("([^a-zA-Z_])", "", project_with_version) - return f"libsdl-org/{project}" - - -def main(): - default_remote = determine_remote() - - parser = argparse.ArgumentParser(allow_abbrev=False) - parser.add_argument("--ref", required=True, help=f"Name of branch or tag containing release.yml") - parser.add_argument("--remote", "-R", default=default_remote, help=f"Remote repo (default={default_remote})") - parser.add_argument("--commit", help=f"Input 'commit' of release.yml (default is the hash of the ref)") - args = parser.parse_args() - - if args.commit is None: - args.commit = subprocess.check_output(["git", "rev-parse", args.ref], cwd=ROOT, text=True).strip() - - - print(f"Running release.yml workflow:") - print(f" remote = {args.remote}") - print(f" ref = {args.ref}") - print(f" commit = {args.commit}") - - subprocess.check_call(["gh", "-R", args.remote, "workflow", "run", "release.yml", "--ref", args.ref, "-f", f"commit={args.commit}"], cwd=ROOT) - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/fnsince.pl b/contrib/SDL-3.2.8/build-scripts/fnsince.pl deleted file mode 100755 index 9d987fc..0000000 --- a/contrib/SDL-3.2.8/build-scripts/fnsince.pl +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/perl -w - -use warnings; -use strict; -use File::Basename; -use Cwd qw(abs_path); - -my $wikipath = undef; -foreach (@ARGV) { - $wikipath = abs_path($_), next if not defined $wikipath; -} - -chdir(dirname(__FILE__)); -chdir('..'); - -my %fulltags = (); -my @unsorted_releases = (); -open(PIPEFH, '-|', 'git tag -l') or die "Failed to read git release tags: $!\n"; - -while () { - chomp; - my $fulltag = $_; - if ($fulltag =~ /\A(prerelease|preview|release)\-(\d+)\.(\d+)\.(\d+)\Z/) { - # Ignore anything that isn't a x.y.0 release. - # Make sure new APIs are assigned to the next minor version and ignore the patch versions, but we'll make an except for the prereleases. - my $release_type = $1; - my $major = int($2); - my $minor = int($3); - my $patch = int($4); - next if ($major != 3); # Ignore anything that isn't an SDL3 release. - next if ($patch != 0) && ($minor >= 2); # Ignore anything that is a patch release (unless it was between the preview release and the official release). - - # Consider this release version. - my $ver = "${major}.${minor}.${patch}"; - push @unsorted_releases, $ver; - $fulltags{$ver} = $fulltag; - } -} -close(PIPEFH); - -#print("\n\nUNSORTED\n"); -#foreach (@unsorted_releases) { -# print "$_\n"; -#} - -my @releases = sort { - my @asplit = split /\./, $a; - my @bsplit = split /\./, $b; - my $rc; - for (my $i = 0; $i < scalar(@asplit); $i++) { - return 1 if (scalar(@bsplit) <= $i); # a is "2.0.1" and b is "2.0", or whatever. - my $aseg = $asplit[$i]; - my $bseg = $bsplit[$i]; - $rc = int($aseg) <=> int($bseg); - return $rc if ($rc != 0); # found the difference. - } - return 0; # still here? They matched completely?! -} @unsorted_releases; - -my $current_release = $releases[-1]; -my $next_release; - -if (scalar(@releases) > 0) { - # this happens to work for how SDL versions things at the moment. - $current_release = $releases[-1]; - - my @current_release_segments = split /\./, $current_release; - # if we're still in the 3.1.x prereleases, call the "next release" 3.2.0 even if we do more prereleases. - if (($current_release_segments[0] == '3') && ($current_release_segments[1] == '1')) { - $next_release = '3.2.0'; - } else { - @current_release_segments[1] = '' . (int($current_release_segments[1]) + 2); - $next_release = join('.', @current_release_segments); - } -} - -#print("\n\nSORTED\n"); -#foreach (@releases) { -# print "$_\n"; -#} -#print("\nCURRENT RELEASE: $current_release\n"); -#print("NEXT RELEASE: $next_release\n\n"); - -push @releases, 'HEAD'; -$fulltags{'HEAD'} = 'HEAD'; - -my %funcs = (); -foreach my $release (@releases) { - #print("Checking $release...\n"); - my $tag = $fulltags{$release}; - my $blobname = "$tag:src/dynapi/SDL_dynapi_overrides.h"; - - if ($release =~ /\A3\.[01]\.\d+\Z/) { # make everything up to the first SDL3 official release look like 3.2.0. - $release = '3.2.0'; - } - - open(PIPEFH, '-|', "git show '$blobname'") or die "Failed to read git blob '$blobname': $!\n"; - while () { - chomp; - if (/\A\#define\s+(SDL_.*?)\s+SDL_.*?_REAL\Z/) { - my $fn = $1; - $funcs{$fn} = $release if not defined $funcs{$fn}; - } - } - close(PIPEFH); -} - -if (not defined $wikipath) { - foreach my $release (@releases) { - foreach my $fn (sort keys %funcs) { - print("$fn: $funcs{$fn}\n") if $funcs{$fn} eq $release; - } - } -} else { - if (defined $wikipath) { - chdir($wikipath); - foreach my $fn (keys %funcs) { - next if $fn eq 'SDL_ThreadID'; # this was a function early on (it's now called SDL_GetThreadID), but now it's a datatype (which originally had a different capitalization). - my $revision = $funcs{$fn}; - $revision = $next_release if $revision eq 'HEAD'; - my $fname = "$fn.md"; - if ( ! -f $fname ) { - #print STDERR "No such file: $fname\n"; - next; - } - - my @lines = (); - open(FH, '<', $fname) or die("Can't open $fname for read: $!\n"); - my $added = 0; - while () { - chomp; - if ((/\A\-\-\-\-/) && (!$added)) { - push @lines, "## Version"; - push @lines, ""; - push @lines, "This function is available since SDL $revision."; - push @lines, ""; - $added = 1; - } - push @lines, $_; - next if not /\A\#\#\s+Version/; - $added = 1; - push @lines, ""; - push @lines, "This function is available since SDL $revision."; - push @lines, ""; - while () { - chomp; - next if not (/\A\#\#\s+/ || /\A\-\-\-\-/); - push @lines, $_; - last; - } - } - close(FH); - - if (!$added) { - push @lines, "## Version"; - push @lines, ""; - push @lines, "This function is available since SDL $revision."; - push @lines, ""; - } - - open(FH, '>', $fname) or die("Can't open $fname for write: $!\n"); - foreach (@lines) { - print FH "$_\n"; - } - close(FH); - } - } -} - diff --git a/contrib/SDL-3.2.8/build-scripts/gen_audio_channel_conversion.c b/contrib/SDL-3.2.8/build-scripts/gen_audio_channel_conversion.c deleted file mode 100644 index 85a856e..0000000 --- a/contrib/SDL-3.2.8/build-scripts/gen_audio_channel_conversion.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 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 - -/* - -Built with: - -gcc -o genchancvt build-scripts/gen_audio_channel_conversion.c -lm && ./genchancvt > src/audio/SDL_audio_channel_converters.h - -*/ - -#define NUM_CHANNELS 8 - -static const char *layout_names[NUM_CHANNELS] = { - "Mono", "Stereo", "2.1", "Quad", "4.1", "5.1", "6.1", "7.1" -}; - -static const char *channel_names[NUM_CHANNELS][NUM_CHANNELS] = { - /* mono */ { "FC" }, - /* stereo */ { "FL", "FR" }, - /* 2.1 */ { "FL", "FR", "LFE" }, - /* quad */ { "FL", "FR", "BL", "BR" }, - /* 4.1 */ { "FL", "FR", "LFE", "BL", "BR" }, - /* 5.1 */ { "FL", "FR", "FC", "LFE", "BL", "BR" }, - /* 6.1 */ { "FL", "FR", "FC", "LFE", "BC", "SL", "SR" }, - /* 7.1 */ { "FL", "FR", "FC", "LFE", "BL", "BR", "SL", "SR" }, -}; - - -/* - * This table is from FAudio: - * - * https://raw.githubusercontent.com/FNA-XNA/FAudio/master/src/matrix_defaults.inl - */ -static const float channel_conversion_matrix[8][8][64] = { -{ - /* 1 x 1 */ - { 1.000000000f }, - /* 1 x 2 */ - { 1.000000000f, 1.000000000f }, - /* 1 x 3 */ - { 1.000000000f, 1.000000000f, 0.000000000f }, - /* 1 x 4 */ - { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, - /* 1 x 5 */ - { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 1 x 6 */ - { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 1 x 7 */ - { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 1 x 8 */ - { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } -}, -{ - /* 2 x 1 */ - { 0.500000000f, 0.500000000f }, - /* 2 x 2 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 2 x 3 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, - /* 2 x 4 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 2 x 5 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 2 x 6 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 2 x 7 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 2 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } -}, -{ - /* 3 x 1 */ - { 0.333333343f, 0.333333343f, 0.333333343f }, - /* 3 x 2 */ - { 0.800000012f, 0.000000000f, 0.200000003f, 0.000000000f, 0.800000012f, 0.200000003f }, - /* 3 x 3 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 3 x 4 */ - { 0.888888896f, 0.000000000f, 0.111111112f, 0.000000000f, 0.888888896f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f }, - /* 3 x 5 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 3 x 6 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 3 x 7 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 3 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } -}, -{ - /* 4 x 1 */ - { 0.250000000f, 0.250000000f, 0.250000000f, 0.250000000f }, - /* 4 x 2 */ - { 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f }, - /* 4 x 3 */ - { 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 4 x 4 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 4 x 5 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 4 x 6 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 4 x 7 */ - { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, - /* 4 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } -}, -{ - /* 5 x 1 */ - { 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f }, - /* 5 x 2 */ - { 0.374222219f, 0.000000000f, 0.111111112f, 0.319111109f, 0.195555553f, 0.000000000f, 0.374222219f, 0.111111112f, 0.195555553f, 0.319111109f }, - /* 5 x 3 */ - { 0.421000004f, 0.000000000f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.000000000f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, - /* 5 x 4 */ - { 0.941176474f, 0.000000000f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.941176474f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.941176474f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.000000000f, 0.941176474f }, - /* 5 x 5 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 5 x 6 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 5 x 7 */ - { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, - /* 5 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } -}, -{ - /* 6 x 1 */ - { 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f }, - /* 6 x 2 */ - { 0.294545442f, 0.000000000f, 0.208181813f, 0.090909094f, 0.251818180f, 0.154545456f, 0.000000000f, 0.294545442f, 0.208181813f, 0.090909094f, 0.154545456f, 0.251818180f }, - /* 6 x 3 */ - { 0.324000001f, 0.000000000f, 0.229000002f, 0.000000000f, 0.277000010f, 0.170000002f, 0.000000000f, 0.324000001f, 0.229000002f, 0.000000000f, 0.170000002f, 0.277000010f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, - /* 6 x 4 */ - { 0.558095276f, 0.000000000f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.558095276f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.558095276f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.000000000f, 0.558095276f }, - /* 6 x 5 */ - { 0.586000025f, 0.000000000f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f }, - /* 6 x 6 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 6 x 7 */ - { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, - /* 6 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } -}, -{ - /* 7 x 1 */ - { 0.143142849f, 0.143142849f, 0.143142849f, 0.142857149f, 0.143142849f, 0.143142849f, 0.143142849f }, - /* 7 x 2 */ - { 0.247384623f, 0.000000000f, 0.174461529f, 0.076923080f, 0.174461529f, 0.226153851f, 0.100615382f, 0.000000000f, 0.247384623f, 0.174461529f, 0.076923080f, 0.174461529f, 0.100615382f, 0.226153851f }, - /* 7 x 3 */ - { 0.268000007f, 0.000000000f, 0.188999996f, 0.000000000f, 0.188999996f, 0.245000005f, 0.108999997f, 0.000000000f, 0.268000007f, 0.188999996f, 0.000000000f, 0.188999996f, 0.108999997f, 0.245000005f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 7 x 4 */ - { 0.463679999f, 0.000000000f, 0.327360004f, 0.040000003f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.463679999f, 0.327360004f, 0.040000003f, 0.000000000f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.431039989f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.000000000f, 0.431039989f }, - /* 7 x 5 */ - { 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.000000000f, 0.449000001f }, - /* 7 x 6 */ - { 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.568000019f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.000000000f, 0.568000019f }, - /* 7 x 7 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, - /* 7 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f } -}, -{ - /* 8 x 1 */ - { 0.125125006f, 0.125125006f, 0.125125006f, 0.125000000f, 0.125125006f, 0.125125006f, 0.125125006f, 0.125125006f }, - /* 8 x 2 */ - { 0.211866662f, 0.000000000f, 0.150266662f, 0.066666670f, 0.181066677f, 0.111066669f, 0.194133341f, 0.085866667f, 0.000000000f, 0.211866662f, 0.150266662f, 0.066666670f, 0.111066669f, 0.181066677f, 0.085866667f, 0.194133341f }, - /* 8 x 3 */ - { 0.226999998f, 0.000000000f, 0.160999998f, 0.000000000f, 0.194000006f, 0.119000003f, 0.208000004f, 0.092000000f, 0.000000000f, 0.226999998f, 0.160999998f, 0.000000000f, 0.119000003f, 0.194000006f, 0.092000000f, 0.208000004f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, - /* 8 x 4 */ - { 0.466344833f, 0.000000000f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.466344833f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.466344833f, 0.000000000f, 0.433517247f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.000000000f, 0.466344833f, 0.000000000f, 0.433517247f }, - /* 8 x 5 */ - { 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f }, - /* 8 x 6 */ - { 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f }, - /* 8 x 7 */ - { 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.287999988f, 0.287999988f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f }, - /* 8 x 8 */ - { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f } -} -}; - -static char *remove_dots(const char *str) /* this is NOT robust. */ -{ - static char retval1[32]; - static char retval2[32]; - static int idx = 0; - char *retval = (idx++ & 1) ? retval1 : retval2; - char *ptr = retval; - while (*str) { - if (*str != '.') { - *(ptr++) = *str; - } - str++; - } - *ptr = '\0'; - return retval; -} - -static char *lowercase(const char *str) /* this is NOT robust. */ -{ - static char retval1[32]; - static char retval2[32]; - static int idx = 0; - char *retval = (idx++ & 1) ? retval1 : retval2; - char *ptr = retval; - while (*str) { - const char ch = *(str++); - *(ptr++) = ((ch >= 'A') && (ch <= 'Z')) ? (ch - ('A' - 'a')) : ch; - } - *ptr = '\0'; - return retval; -} - -static void write_converter(const int fromchans, const int tochans) -{ - const char *fromstr = layout_names[fromchans-1]; - const char *tostr = layout_names[tochans-1]; - const float *cvtmatrix = channel_conversion_matrix[fromchans-1][tochans-1]; - const float *fptr; - const int convert_backwards = (tochans > fromchans); - int input_channel_used[NUM_CHANNELS]; - int i, j; - - if (tochans == fromchans) { - return; /* nothing to convert, don't generate a converter. */ - } - - for (i = 0; i < fromchans; i++) { - input_channel_used[i] = 0; - } - - fptr = cvtmatrix; - for (j = 0; j < tochans; j++) { - for (i = 0; i < fromchans; i++) { - #if 0 - printf("to=%d, from=%d, coeff=%f\n", j, i, *fptr); - #endif - if (*(fptr++) != 0.0f) { - input_channel_used[i]++; - } - } - } - - printf("static void SDL_Convert%sTo%s(float *dst, const float *src, int num_frames)\n{\n", remove_dots(fromstr), remove_dots(tostr)); - - printf(" int i;\n" - "\n" - " LOG_DEBUG_AUDIO_CONVERT(\"%s\", \"%s\");\n" - "\n", lowercase(fromstr), lowercase(tostr)); - - if (convert_backwards) { /* must convert backwards when growing the output in-place. */ - printf(" // convert backwards, since output is growing in-place.\n"); - printf(" src += (num_frames-1)"); - if (fromchans != 1) { - printf(" * %d", fromchans); - } - printf(";\n"); - - printf(" dst += (num_frames-1)"); - if (tochans != 1) { - printf(" * %d", tochans); - } - printf(";\n"); - printf(" for (i = num_frames; i; i--, "); - if (fromchans == 1) { - printf("src--"); - } else { - printf("src -= %d", fromchans); - } - printf(", "); - if (tochans == 1) { - printf("dst--"); - } else { - printf("dst -= %d", tochans); - } - printf(") {\n"); - fptr = cvtmatrix; - for (i = 0; i < fromchans; i++) { - if (input_channel_used[i] > 1) { /* don't read it from src more than once. */ - printf(" const float src%s = src[%d];\n", channel_names[fromchans-1][i], i); - } - } - - for (j = tochans - 1; j >= 0; j--) { - int has_input = 0; - fptr = cvtmatrix + (fromchans * j); - printf(" dst[%d] /* %s */ =", j, channel_names[tochans-1][j]); - for (i = fromchans - 1; i >= 0; i--) { - const float coefficient = fptr[i]; - char srcname[32]; - if (coefficient == 0.0f) { - continue; - } else if (input_channel_used[i] > 1) { - snprintf(srcname, sizeof (srcname), "src%s", channel_names[fromchans-1][i]); - } else { - snprintf(srcname, sizeof (srcname), "src[%d]", i); - } - - if (has_input) { - printf(" +"); - } - - has_input = 1; - - if (coefficient == 1.0f) { - printf(" %s", srcname); - } else { - printf(" (%s * %.9ff)", srcname, coefficient); - } - } - - if (!has_input) { - printf(" 0.0f"); - } - - printf(";\n"); - } - - printf(" }\n"); - } else { - printf(" for (i = num_frames; i; i--, "); - if (fromchans == 1) { - printf("src++"); - } else { - printf("src += %d", fromchans); - } - printf(", "); - if (tochans == 1) { - printf("dst++"); - } else { - printf("dst += %d", tochans); - } - printf(") {\n"); - - fptr = cvtmatrix; - for (i = 0; i < fromchans; i++) { - if (input_channel_used[i] > 1) { /* don't read it from src more than once. */ - printf(" const float src%s = src[%d];\n", channel_names[fromchans-1][i], i); - } - } - - for (j = 0; j < tochans; j++) { - int has_input = 0; - fptr = cvtmatrix + (fromchans * j); - printf(" dst[%d] /* %s */ =", j, channel_names[tochans-1][j]); - for (i = 0; i < fromchans; i++) { - const float coefficient = fptr[i]; - char srcname[32]; - if (coefficient == 0.0f) { - continue; - } else if (input_channel_used[i] > 1) { - snprintf(srcname, sizeof (srcname), "src%s", channel_names[fromchans-1][i]); - } else { - snprintf(srcname, sizeof (srcname), "src[%d]", i); - } - - if (has_input) { - printf(" +"); - } - - has_input = 1; - - if (coefficient == 1.0f) { - printf(" %s", srcname); - } else { - printf(" (%s * %.9ff)", srcname, coefficient); - } - } - - if (!has_input) { - printf(" 0.0f"); - } - - printf(";\n"); - } - printf(" }\n"); - } - - printf("\n}\n\n"); -} - -int main(void) -{ - int ini, outi; - - printf( - "/*\n" - " Simple DirectMedia Layer\n" - " Copyright (C) 1997-2025 Sam Lantinga \n" - "\n" - " This software is provided 'as-is', without any express or implied\n" - " warranty. In no event will the authors be held liable for any damages\n" - " arising from the use of this software.\n" - "\n" - " Permission is granted to anyone to use this software for any purpose,\n" - " including commercial applications, and to alter it and redistribute it\n" - " freely, subject to the following restrictions:\n" - "\n" - " 1. The origin of this software must not be misrepresented; you must not\n" - " claim that you wrote the original software. If you use this software\n" - " in a product, an acknowledgment in the product documentation would be\n" - " appreciated but is not required.\n" - " 2. Altered source versions must be plainly marked as such, and must not be\n" - " misrepresented as being the original software.\n" - " 3. This notice may not be removed or altered from any source distribution.\n" - "*/\n" - "\n" - "// DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_channel_conversion.c\n" - "\n" - "\n" - "typedef void (*SDL_AudioChannelConverter)(float *dst, const float *src, int num_frames);\n" - "\n" - ); - - for (ini = 1; ini <= NUM_CHANNELS; ini++) { - for (outi = 1; outi <= NUM_CHANNELS; outi++) { - write_converter(ini, outi); - } - } - - printf("static const SDL_AudioChannelConverter channel_converters[%d][%d] = { /* [from][to] */\n", NUM_CHANNELS, NUM_CHANNELS); - for (ini = 1; ini <= NUM_CHANNELS; ini++) { - const char *comma = ""; - printf(" {"); - for (outi = 1; outi <= NUM_CHANNELS; outi++) { - const char *fromstr = layout_names[ini-1]; - const char *tostr = layout_names[outi-1]; - if (ini == outi) { - printf("%s NULL", comma); - } else { - printf("%s SDL_Convert%sTo%s", comma, remove_dots(fromstr), remove_dots(tostr)); - } - comma = ","; - } - printf(" }%s\n", (ini == NUM_CHANNELS) ? "" : ","); - } - - printf("};\n\n"); - - return 0; -} diff --git a/contrib/SDL-3.2.8/build-scripts/git-pre-push-hook.pl b/contrib/SDL-3.2.8/build-scripts/git-pre-push-hook.pl deleted file mode 100755 index 63596b6..0000000 --- a/contrib/SDL-3.2.8/build-scripts/git-pre-push-hook.pl +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/perl -w - -# To use this script: symlink it to .git/hooks/pre-push, then "git push" -# -# This script is called by "git push" after it has checked the remote status, -# but before anything has been pushed. If this script exits with a non-zero -# status nothing will be pushed. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# - -use warnings; -use strict; - -my $remote = $ARGV[0]; -my $url = $ARGV[1]; - -#print("remote: $remote\n"); -#print("url: $url\n"); - -$url =~ s/\.git$//; # change myorg/myproject.git to myorg/myproject -$url =~ s#^git\@github\.com\:#https://github.com/#i; -my $commiturl = $url =~ /\Ahttps?:\/\/github.com\// ? "$url/commit/" : ''; - -my $z40 = '0000000000000000000000000000000000000000'; -my $reported = 0; - -while () { - chomp; - my ($local_ref, $local_sha, $remote_ref, $remote_sha) = split / /; - #print("local_ref: $local_ref\n"); - #print("local_sha: $local_sha\n"); - #print("remote_ref: $remote_ref\n"); - #print("remote_sha: $remote_sha\n"); - - my $range = ''; - if ($remote_sha eq $z40) { # New branch, examine all commits - $range = $local_sha; - } else { # Update to existing branch, examine new commits - $range = "$remote_sha..$local_sha"; - } - - my $gitcmd = "git log --reverse --oneline --no-abbrev-commit '$range'"; - open(GITPIPE, '-|', $gitcmd) or die("\n\n$0: Failed to run '$gitcmd': $!\n\nAbort push!\n\n"); - while () { - chomp; - if (/\A([a-fA-F0-9]+)\s+(.*?)\Z/) { - my $hash = $1; - my $msg = $2; - - if (!$reported) { - print("\nCommits expected to be pushed:\n"); - $reported = 1; - } - - #print("hash: $hash\n"); - #print("msg: $msg\n"); - - print("$commiturl$hash -- $msg\n"); - } else { - die("$0: Unexpected output from '$gitcmd'!\n\nAbort push!\n\n"); - } - } - die("\n\n$0: Failing exit code from running '$gitcmd'!\n\nAbort push!\n\n") if !close(GITPIPE); -} - -print("\n") if $reported; - -exit(0); # Let the push go forward. diff --git a/contrib/SDL-3.2.8/build-scripts/makecasefoldhashtable.pl b/contrib/SDL-3.2.8/build-scripts/makecasefoldhashtable.pl deleted file mode 100755 index efe3534..0000000 --- a/contrib/SDL-3.2.8/build-scripts/makecasefoldhashtable.pl +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/perl -w - -# Simple DirectMedia Layer -# Copyright (C) 1997-2025 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. - -# This script was originally written by Ryan C. Gordon for PhysicsFS -# ( https://icculus.org/physfs/ ), under the zlib license: the same license -# that SDL itself uses). - -use warnings; -use strict; - -my $HASHBUCKETS1_16 = 256; -my $HASHBUCKETS1_32 = 16; -my $HASHBUCKETS2_16 = 16; -my $HASHBUCKETS3_16 = 4; - -my $mem_used = 0; - -print <<__EOF__; -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 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. -*/ - -/* - * This data was generated by SDL/build-scripts/makecasefoldhashtable.pl - * - * Do not manually edit this file! - */ - -#ifndef SDL_casefolding_h_ -#define SDL_casefolding_h_ - -/* We build three simple hashmaps here: one that maps Unicode codepoints to -a one, two, or three lowercase codepoints. To retrieve this info: look at -case_fold_hashX, where X is 1, 2, or 3. Most foldable codepoints fold to one, -a few dozen fold to two, and a handful fold to three. If the codepoint isn't -in any of these hashes, it doesn't fold (no separate upper and lowercase). - -Almost all these codepoints fit into 16 bits, so we hash them as such to save -memory. If a codepoint is > 0xFFFF, we have separate hashes for them, -since there are (currently) only about 120 of them and (currently) all of them -map to a single lowercase codepoint. */ - -typedef struct CaseFoldMapping1_32 -{ - Uint32 from; - Uint32 to0; -} CaseFoldMapping1_32; - -typedef struct CaseFoldMapping1_16 -{ - Uint16 from; - Uint16 to0; -} CaseFoldMapping1_16; - -typedef struct CaseFoldMapping2_16 -{ - Uint16 from; - Uint16 to0; - Uint16 to1; -} CaseFoldMapping2_16; - -typedef struct CaseFoldMapping3_16 -{ - Uint16 from; - Uint16 to0; - Uint16 to1; - Uint16 to2; -} CaseFoldMapping3_16; - -typedef struct CaseFoldHashBucket1_16 -{ - const CaseFoldMapping1_16 *list; - const Uint8 count; -} CaseFoldHashBucket1_16; - -typedef struct CaseFoldHashBucket1_32 -{ - const CaseFoldMapping1_32 *list; - const Uint8 count; -} CaseFoldHashBucket1_32; - -typedef struct CaseFoldHashBucket2_16 -{ - const CaseFoldMapping2_16 *list; - const Uint8 count; -} CaseFoldHashBucket2_16; - -typedef struct CaseFoldHashBucket3_16 -{ - const CaseFoldMapping3_16 *list; - const Uint8 count; -} CaseFoldHashBucket3_16; - -__EOF__ - - -my @foldPairs1_16; -my @foldPairs2_16; -my @foldPairs3_16; -my @foldPairs1_32; - -for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) { - $foldPairs1_16[$i] = ''; -} - -for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) { - $foldPairs1_32[$i] = ''; -} - -for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) { - $foldPairs2_16[$i] = ''; -} - -for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) { - $foldPairs3_16[$i] = ''; -} - -open(FH,'<','casefolding.txt') or die("failed to open casefolding.txt: $!\n"); -while () { - chomp; - # strip comments from textfile... - s/\#.*\Z//; - - # strip whitespace... - s/\A\s+//; - s/\s+\Z//; - - next if not /\A([a-fA-F0-9]+)\;\s*(.)\;\s*(.+)\;/; - my ($code, $status, $mapping) = ($1, $2, $3); - - my $hexxed = hex($code); - #print("// code '$code' status '$status' mapping '$mapping'\n"); - - if (($status eq 'C') or ($status eq 'F')) { - my ($map1, $map2, $map3) = (undef, undef, undef); - $map1 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//; - $map2 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//; - $map3 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//; - die("mapping space too small for '$code'\n") if ($mapping ne ''); - die("problem parsing mapping for '$code'\n") if (not defined($map1)); - - if ($hexxed < 128) { - # Just ignore these, we'll handle the low-ASCII ones ourselves. - } elsif ($hexxed > 0xFFFF) { - # We just need to add the 32-bit 2 and/or 3 codepoint maps if this die()'s here. - die("Uhoh, a codepoint > 0xFFFF that folds to multiple codepoints! Fixme.") if defined($map2); - my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS1_32-1)); - #print("// hexxed '$hexxed' hashed1 '$hashed'\n"); - $foldPairs1_32[$hashed] .= " { 0x$code, 0x$map1 },\n"; - $mem_used += 8; - } elsif (not defined($map2)) { - my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS1_16-1)); - #print("// hexxed '$hexxed' hashed1 '$hashed'\n"); - $foldPairs1_16[$hashed] .= " { 0x$code, 0x$map1 },\n"; - $mem_used += 4; - } elsif (not defined($map3)) { - my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS2_16-1)); - #print("// hexxed '$hexxed' hashed2 '$hashed'\n"); - $foldPairs2_16[$hashed] .= " { 0x$code, 0x$map1, 0x$map2 },\n"; - $mem_used += 6; - } else { - my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS3_16-1)); - #print("// hexxed '$hexxed' hashed3 '$hashed'\n"); - $foldPairs3_16[$hashed] .= " { 0x$code, 0x$map1, 0x$map2, 0x$map3 },\n"; - $mem_used += 8; - } - } -} -close(FH); - -for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) { - $foldPairs1_16[$i] =~ s/,\n\Z//; - my $str = $foldPairs1_16[$i]; - next if $str eq ''; - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold1_16_${num}"; - print("static const CaseFoldMapping1_16 ${sym}[] = {\n$str\n};\n\n"); -} - -for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) { - $foldPairs1_32[$i] =~ s/,\n\Z//; - my $str = $foldPairs1_32[$i]; - next if $str eq ''; - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold1_32_${num}"; - print("static const CaseFoldMapping1_32 ${sym}[] = {\n$str\n};\n\n"); -} - -for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) { - $foldPairs2_16[$i] =~ s/,\n\Z//; - my $str = $foldPairs2_16[$i]; - next if $str eq ''; - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold2_16_${num}"; - print("static const CaseFoldMapping2_16 ${sym}[] = {\n$str\n};\n\n"); -} - -for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) { - $foldPairs3_16[$i] =~ s/,\n\Z//; - my $str = $foldPairs3_16[$i]; - next if $str eq ''; - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold3_16_${num}"; - print("static const CaseFoldMapping3_16 ${sym}[] = {\n$str\n};\n\n"); -} - -print("static const CaseFoldHashBucket1_16 case_fold_hash1_16[] = {\n"); - -for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) { - my $str = $foldPairs1_16[$i]; - if ($str eq '') { - print(" { NULL, 0 },\n"); - } else { - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold1_16_${num}"; - print(" { $sym, SDL_arraysize($sym) },\n"); - } - $mem_used += 12; -} -print("};\n\n"); - - -print("static const CaseFoldHashBucket1_32 case_fold_hash1_32[] = {\n"); - -for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) { - my $str = $foldPairs1_32[$i]; - if ($str eq '') { - print(" { NULL, 0 },\n"); - } else { - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold1_32_${num}"; - print(" { $sym, SDL_arraysize($sym) },\n"); - } - $mem_used += 12; -} -print("};\n\n"); - - -print("static const CaseFoldHashBucket2_16 case_fold_hash2_16[] = {\n"); - -for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) { - my $str = $foldPairs2_16[$i]; - if ($str eq '') { - print(" { NULL, 0 },\n"); - } else { - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold2_16_${num}"; - print(" { $sym, SDL_arraysize($sym) },\n"); - } - $mem_used += 12; -} -print("};\n\n"); - -print("static const CaseFoldHashBucket3_16 case_fold_hash3_16[] = {\n"); - -for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) { - my $str = $foldPairs3_16[$i]; - if ($str eq '') { - print(" { NULL, 0 },\n"); - } else { - my $num = '000' . $i; - $num =~ s/\A.*?(\d\d\d)\Z/$1/; - my $sym = "case_fold3_16_${num}"; - print(" { $sym, SDL_arraysize($sym) },\n"); - } - $mem_used += 12; -} -print("};\n\n"); - -print <<__EOF__; -#endif /* SDL_casefolding_h_ */ - -__EOF__ - -print STDERR "Memory required for case-folding hashtable: $mem_used bytes\n"; - -exit 0; - -# end of makecashfoldhashtable.pl ... - diff --git a/contrib/SDL-3.2.8/build-scripts/mkinstalldirs b/contrib/SDL-3.2.8/build-scripts/mkinstalldirs deleted file mode 100755 index c364f3d..0000000 --- a/contrib/SDL-3.2.8/build-scripts/mkinstalldirs +++ /dev/null @@ -1,162 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2020-07-26.22; # UTC - -# Original author: Noah Friedman -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the 'mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because '.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "umask 22" - umask 22 - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -echo "umask 22" -umask 22 - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp=$pathcomp/ - done - - if test ! -z "$dirmode"; then - echo "chmod $dirmode $file" - chmod "$dirmode" "$file" || errstatus=$? - fi -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/INSTALL.md.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/android/INSTALL.md.in deleted file mode 100644 index 80321c2..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/INSTALL.md.in +++ /dev/null @@ -1,91 +0,0 @@ - -# Using this package - -This package contains @<@PROJECT_NAME@>@ built for the Android platform. - -## Gradle integration - -For integration with CMake/ndk-build, it uses [prefab](https://google.github.io/prefab/). - -Copy the aar archive (@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar) to a `app/libs` directory of your project. - -In `app/build.gradle` of your Android project, add: -``` -android { - /* ... */ - buildFeatures { - prefab true - } -} -dependencies { - implementation files('libs/@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar') - /* ... */ -} -``` - -If you're using CMake, add the following to your CMakeLists.txt: -``` -find_package(@<@PROJECT_NAME@>@ REQUIRED CONFIG) -target_link_libraries(yourgame PRIVATE @<@PROJECT_NAME@>@::@<@PROJECT_NAME@>@) -``` - -If you use ndk-build, add the following before `include $(BUILD_SHARED_LIBRARY)` to your `Android.mk`: -``` -LOCAL_SHARED_LIBARARIES := SDL3 SDL3-Headers -``` -And add the following at the bottom: -``` -# https://google.github.io/prefab/build-systems.html - -# Add the prefab modules to the import path. -$(call import-add-path,/out) - -# Import @<@PROJECT_NAME@>@ so we can depend on it. -$(call import-module,prefab/@<@PROJECT_NAME@>@) -``` - ---- - -## Other build systems (advanced) - -If you want to build a project without Gradle, -running the following command will extract the Android archive into a more common directory structure. -``` -python @<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar -o android_prefix -``` -Add `--help` for a list of all available options. - -# Documentation - -An API reference, tutorials, and additional documentation is available at: - -https://wiki.libsdl.org/@<@PROJECT_NAME@>@ - -# Example code - -There are simple example programs available at: - -https://examples.libsdl.org/SDL3 - -# Discussions - -## Discord - -You can join the official Discord server at: - -https://discord.com/invite/BwpFGBWsv8 - -## Forums/mailing lists - -You can join SDL development discussions at: - -https://discourse.libsdl.org/ - -Once you sign up, you can use the forum through the website or as a mailing list from your email client. - -## Announcement list - -You can sign up for the low traffic announcement list at: - -https://www.libsdl.org/mailing-list.php - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/__main__.py.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/__main__.py.in deleted file mode 100755 index 344cf71..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/__main__.py.in +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python - -""" -Create a @<@PROJECT_NAME@>@ SDK prefix from an Android archive -This file is meant to be placed in a the root of an android .aar archive - -Example usage: -```sh -python @<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.aar -o /usr/opt/android-sdks -cmake -S my-project \ - -DCMAKE_PREFIX_PATH=/usr/opt/android-sdks \ - -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \ - -B build-arm64 -DANDROID_ABI=arm64-v8a \ - -DCMAKE_BUILD_TYPE=Releaase -cmake --build build-arm64 -``` -""" -import argparse -import io -import json -import os -import pathlib -import re -import stat -import zipfile - - -AAR_PATH = pathlib.Path(__file__).resolve().parent -ANDROID_ARCHS = { "armeabi-v7a", "arm64-v8a", "x86", "x86_64" } - - -def main(): - parser = argparse.ArgumentParser( - description="Convert a @<@PROJECT_NAME@>@ Android .aar archive into a SDK", - allow_abbrev=False, - ) - parser.add_argument("--version", action="version", version="@<@PROJECT_NAME@>@ @<@PROJECT_VERSION@>@") - parser.add_argument("-o", dest="output", type=pathlib.Path, required=True, help="Folder where to store the SDK") - args = parser.parse_args() - - print(f"Creating a @<@PROJECT_NAME@>@ SDK at {args.output}...") - - prefix = args.output - incdir = prefix / "include" - libdir = prefix / "lib" - - RE_LIB_MODULE_ARCH = re.compile(r"prefab/modules/(?P[A-Za-z0-9_-]+)/libs/android\.(?P[a-zA-Z0-9_-]+)/(?Plib[A-Za-z0-9_]+\.(?:so|a))") - RE_INC_MODULE_ARCH = re.compile(r"prefab/modules/(?P[A-Za-z0-9_-]+)/include/(?P
[a-zA-Z0-9_./-]+)") - RE_LICENSE = re.compile(r"(?:.*/)?(?P(?:license|copying)(?:\.md|\.txt)?)", flags=re.I) - RE_PROGUARD = re.compile(r"(?:.*/)?(?Pproguard.*\.(?:pro|txt))", flags=re.I) - RE_CMAKE = re.compile(r"(?:.*/)?(?P.*\.cmake)", flags=re.I) - - with zipfile.ZipFile(AAR_PATH) as zf: - project_description = json.loads(zf.read("description.json")) - project_name = project_description["name"] - project_version = project_description["version"] - licensedir = prefix / "share/licenses" / project_name - cmakedir = libdir / "cmake" / project_name - javadir = prefix / "share/java" / project_name - javadocdir = prefix / "share/javadoc" / project_name - - def read_zipfile_and_write(path: pathlib.Path, zippath: str): - data = zf.read(zippath) - path.parent.mkdir(parents=True, exist_ok=True) - path.write_bytes(data) - - for zip_info in zf.infolist(): - zippath = zip_info.filename - if m := RE_LIB_MODULE_ARCH.match(zippath): - lib_path = libdir / m["arch"] / m["filename"] - read_zipfile_and_write(lib_path, zippath) - if m["filename"].endswith(".so"): - os.chmod(lib_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) - - elif m := RE_INC_MODULE_ARCH.match(zippath): - header_path = incdir / m["header"] - read_zipfile_and_write(header_path, zippath) - elif m:= RE_LICENSE.match(zippath): - license_path = licensedir / m["filename"] - read_zipfile_and_write(license_path, zippath) - elif m:= RE_PROGUARD.match(zippath): - proguard_path = javadir / m["filename"] - read_zipfile_and_write(proguard_path, zippath) - elif m:= RE_CMAKE.match(zippath): - cmake_path = cmakedir / m["filename"] - read_zipfile_and_write(cmake_path, zippath) - elif zippath == "classes.jar": - versioned_jar_path = javadir / f"{project_name}-{project_version}.jar" - unversioned_jar_path = javadir / f"{project_name}.jar" - read_zipfile_and_write(versioned_jar_path, zippath) - os.symlink(src=versioned_jar_path.name, dst=unversioned_jar_path) - elif zippath == "classes-sources.jar": - jarpath = javadir / f"{project_name}-{project_version}-sources.jar" - read_zipfile_and_write(jarpath, zippath) - elif zippath == "classes-doc.jar": - jarpath = javadocdir / f"{project_name}-{project_version}-javadoc.jar" - read_zipfile_and_write(jarpath, zippath) - - print("... done") - return 0 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in deleted file mode 100644 index 3268da7..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in +++ /dev/null @@ -1,38 +0,0 @@ -# @<@PROJECT_NAME@>@ CMake version configuration file: -# This file is meant to be placed in a lib/cmake/@<@PROJECT_NAME@>@ subfolder of a reconstructed Android SDL3 SDK - -set(PACKAGE_VERSION "@<@PROJECT_VERSION@>@") - -if(PACKAGE_FIND_VERSION_RANGE) - # Package version must be in the requested version range - if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN) - OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX) - OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX))) - set(PACKAGE_VERSION_COMPATIBLE FALSE) - else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - endif() -else() - if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) - set(PACKAGE_VERSION_COMPATIBLE FALSE) - else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) - set(PACKAGE_VERSION_EXACT TRUE) - endif() - endif() -endif() - -# if the using project doesn't have CMAKE_SIZEOF_VOID_P set, fail. -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() - -include("${CMAKE_CURRENT_LIST_DIR}/sdlcpu.cmake") -SDL_DetectTargetCPUArchitectures(_detected_archs) - -# check that the installed version has a compatible architecture as the one which is currently searching: -if(NOT(SDL_CPU_X86 OR SDL_CPU_X64 OR SDL_CPU_ARM32 OR SDL_CPU_ARM64)) - set(PACKAGE_VERSION "${PACKAGE_VERSION} (X86,X64,ARM32,ARM64)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/description.json.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/description.json.in deleted file mode 100644 index e75ef38..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/android/aar/description.json.in +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@<@PROJECT_NAME@>@", - "version": "@<@PROJECT_VERSION@>@", - "git-hash": "@<@PROJECT_COMMIT@>@" -} diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/INSTALL.md.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/INSTALL.md.in deleted file mode 100644 index f1a6a78..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/INSTALL.md.in +++ /dev/null @@ -1,53 +0,0 @@ - -# Using this package - -This package contains @<@PROJECT_NAME@>@ built for the mingw-w64 toolchain. - -The files for 32-bit architecture are in i686-w64-mingw32 -The files for 64-bit architecture are in x86_64-w64-mingw32 - -You can install them to another location, just type `make` for help. - -To use this package, point your include path at _arch_/include and your library path at _arch_/lib, link with the @<@PROJECT_NAME@>@ library and copy _arch_/bin/@<@PROJECT_NAME@>@.dll next to your executable. - -e.g. -```sh -gcc -o hello.exe hello.c -Ix86_64-w64-mingw32/include -Lx86_64-w64-mingw32/lib -l@<@PROJECT_NAME@>@ -cp x86_64-w64-mingw32/bin/@<@PROJECT_NAME@>@.dll . -./hello.exe -``` - -# Documentation - -An API reference, tutorials, and additional documentation is available at: - -https://wiki.libsdl.org/@<@PROJECT_NAME@>@ - -# Example code - -There are simple example programs available at: - -https://examples.libsdl.org/SDL3 - -# Discussions - -## Discord - -You can join the official Discord server at: - -https://discord.com/invite/BwpFGBWsv8 - -## Forums/mailing lists - -You can join SDL development discussions at: - -https://discourse.libsdl.org/ - -Once you sign up, you can use the forum through the website or as a mailing list from your email client. - -## Announcement list - -You can sign up for the low traffic announcement list at: - -https://www.libsdl.org/mailing-list.php - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/Makefile b/contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/Makefile deleted file mode 100644 index 9b6cd55..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/mingw/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Makefile for installing the mingw32 version of the SDL library - -DESTDIR = /usr/local -ARCHITECTURES := i686-w64-mingw32 x86_64-w64-mingw32 - -default: - @echo "Run \"make install-i686\" to install 32-bit" - @echo "Run \"make install-x86_64\" to install 64-bit" - @echo "Run \"make install-all\" to install both" - @echo "Add DESTDIR=/custom/path to change the destination folder" - -install: - @if test -d $(ARCH) && test -d $(DESTDIR); then \ - (cd $(ARCH) && cp -rv bin include lib share $(DESTDIR)/); \ - else \ - echo "*** ERROR: $(ARCH) or $(DESTDIR) does not exist!"; \ - exit 1; \ - fi - -install-i686: - $(MAKE) install ARCH=i686-w64-mingw32 - -install-x86_64: - $(MAKE) install ARCH=x86_64-w64-mingw32 - -install-all: - @if test -d $(DESTDIR); then \ - mkdir -p $(DESTDIR)/cmake; \ - cp -rv cmake/* $(DESTDIR)/cmake; \ - for arch in $(ARCHITECTURES); do \ - $(MAKE) install ARCH=$$arch DESTDIR=$(DESTDIR)/$$arch; \ - done \ - else \ - echo "*** ERROR: $(DESTDIR) does not exist!"; \ - exit 1; \ - fi - -.PHONY: default install install-i686 install-x86_64 install-all diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/Directory.Build.props b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/Directory.Build.props deleted file mode 100644 index 24033f4..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - SDL_VENDOR_INFO="libsdl.org";%(PreprocessorDefinitions) - - - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/INSTALL.md.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/INSTALL.md.in deleted file mode 100644 index 671f524..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/INSTALL.md.in +++ /dev/null @@ -1,45 +0,0 @@ - -# Using this package - -This package contains @<@PROJECT_NAME@>@ built for Visual Studio. - -To use this package, edit your project properties: -- Add the include directory to "VC++ Directories" -> "Include Directories" -- Add the lib/_arch_ directory to "VC++ Directories" -> "Library Directories" -- Add @<@PROJECT_NAME@>@.lib to Linker -> Input -> "Additional Dependencies" -- Copy lib/_arch_/@<@PROJECT_NAME@>@.dll to your project directory. - -# Documentation - -An API reference, tutorials, and additional documentation is available at: - -https://wiki.libsdl.org/@<@PROJECT_NAME@>@ - -# Example code - -There are simple example programs available at: - -https://examples.libsdl.org/SDL3 - -# Discussions - -## Discord - -You can join the official Discord server at: - -https://discord.com/invite/BwpFGBWsv8 - -## Forums/mailing lists - -You can join SDL development discussions at: - -https://discourse.libsdl.org/ - -Once you sign up, you can use the forum through the website or as a mailing list from your email client. - -## Announcement list - -You can sign up for the low traffic announcement list at: - -https://www.libsdl.org/mailing-list.php - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/arm64/INSTALL.md.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/arm64/INSTALL.md.in deleted file mode 100644 index c185171..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/arm64/INSTALL.md.in +++ /dev/null @@ -1,13 +0,0 @@ - -# Using this package - -This package contains @<@PROJECT_NAME@>@ built for arm64 Windows. - -To use this package, simply replace an existing 64-bit ARM @<@PROJECT_NAME@>@.dll with the one included here. - -# Development packages - -If you're looking for packages with headers and libraries, you can download one of these: -- @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-VC.zip, for development using Visual Studio -- @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-mingw.zip, for development using mingw-w64 - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in deleted file mode 100644 index 6387376..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in +++ /dev/null @@ -1,135 +0,0 @@ -# @<@PROJECT_NAME@>@ CMake configuration file: -# This file is meant to be placed in a cmake subfolder of @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-VC.zip - -cmake_minimum_required(VERSION 3.0...3.28) - -include(FeatureSummary) -set_package_properties(SDL3 PROPERTIES - URL "https://www.libsdl.org/" - DESCRIPTION "low level access to audio, keyboard, mouse, joystick, and graphics hardware" -) - -# Copied from `configure_package_config_file` -macro(set_and_check _var _file) - set(${_var} "${_file}") - if(NOT EXISTS "${_file}") - message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") - endif() -endmacro() - -# Copied from `configure_package_config_file` -macro(check_required_components _NAME) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(NOT ${_NAME}_${comp}_FOUND) - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - endif() - endif() - endforeach() -endmacro() - -set(SDL3_FOUND TRUE) - -if(SDL_CPU_X86) - set(_sdl_arch_subdir "x86") -elseif(SDL_CPU_X64 OR SDL_CPU_ARM64EC) - set(_sdl_arch_subdir "x64") -elseif(SDL_CPU_ARM64) - set(_sdl_arch_subdir "arm64") -else() - set(SDL3_FOUND FALSE) - return() -endif() - -get_filename_component(_sdl3_prefix "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set_and_check(_sdl3_prefix "${_sdl3_prefix}") -set(_sdl3_include_dirs "${_sdl3_prefix}/include") - -set(_sdl3_implib "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3.lib") -set(_sdl3_dll "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3.dll") -set(_sdl3test_lib "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3_test.lib") - -unset(_sdl_arch_subdir) -unset(_sdl3_prefix) - -# All targets are created, even when some might not be requested though COMPONENTS. -# This is done for compatibility with CMake generated SDL3-target.cmake files. - -if(NOT TARGET SDL3::Headers) - add_library(SDL3::Headers INTERFACE IMPORTED) - set_target_properties(SDL3::Headers - PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${_sdl3_include_dirs}" - ) -endif() -set(SDL3_Headers_FOUND TRUE) -unset(_sdl3_include_dirs) - -if(EXISTS "${_sdl3_implib}" AND EXISTS "${_sdl3_dll}") - if(NOT TARGET SDL3::SDL3-shared) - add_library(SDL3::SDL3-shared SHARED IMPORTED) - set_target_properties(SDL3::SDL3-shared - PROPERTIES - INTERFACE_LINK_LIBRARIES "SDL3::Headers" - IMPORTED_IMPLIB "${_sdl3_implib}" - IMPORTED_LOCATION "${_sdl3_dll}" - COMPATIBLE_INTERFACE_BOOL "SDL3_SHARED" - INTERFACE_SDL3_SHARED "ON" - COMPATIBLE_INTERFACE_STRING "SDL_VERSION" - INTERFACE_SDL_VERSION "SDL3" - ) - endif() - set(SDL3_SDL3-shared_FOUND TRUE) -else() - set(SDL3_SDL3-shared_FOUND FALSE) -endif() -unset(_sdl3_implib) -unset(_sdl3_dll) - -set(SDL3_SDL3-static_FOUND FALSE) - -if(EXISTS "${_sdl3test_lib}") - if(NOT TARGET SDL3::SDL3_test) - add_library(SDL3::SDL3_test STATIC IMPORTED) - set_target_properties(SDL3::SDL3_test - PROPERTIES - INTERFACE_LINK_LIBRARIES "SDL3::Headers" - IMPORTED_LOCATION "${_sdl3test_lib}" - COMPATIBLE_INTERFACE_STRING "SDL_VERSION" - INTERFACE_SDL_VERSION "SDL3" - ) - endif() - set(SDL3_SDL3_test_FOUND TRUE) -else() - set(SDL3_SDL3_test_FOUND FALSE) -endif() -unset(_sdl3test_lib) - -if(SDL3_SDL3-shared_FOUND OR SDL3_SDL3-static_FOUND) - set(SDL3_SDL3_FOUND TRUE) -endif() - -function(_sdl_create_target_alias_compat NEW_TARGET TARGET) - if(CMAKE_VERSION VERSION_LESS "3.18") - # Aliasing local targets is not supported on CMake < 3.18, so make it global. - add_library(${NEW_TARGET} INTERFACE IMPORTED) - set_target_properties(${NEW_TARGET} PROPERTIES INTERFACE_LINK_LIBRARIES "${TARGET}") - else() - add_library(${NEW_TARGET} ALIAS ${TARGET}) - endif() -endfunction() - -# Make sure SDL3::SDL3 always exists -if(NOT TARGET SDL3::SDL3) - if(TARGET SDL3::SDL3-shared) - _sdl_create_target_alias_compat(SDL3::SDL3 SDL3::SDL3-shared) - endif() -endif() - -check_required_components(SDL3) - -set(SDL3_LIBRARIES SDL3::SDL3) -set(SDL3_STATIC_LIBRARIES SDL3::SDL3-static) -set(SDL3_STATIC_PRIVATE_LIBS) - -set(SDL3TEST_LIBRARY SDL3::SDL3_test) diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3ConfigVersion.cmake.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3ConfigVersion.cmake.in deleted file mode 100644 index 82b6af0..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/cmake/SDL3ConfigVersion.cmake.in +++ /dev/null @@ -1,38 +0,0 @@ -# @<@PROJECT_NAME@>@ CMake version configuration file: -# This file is meant to be placed in a cmake subfolder of @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-VC.zip - -set(PACKAGE_VERSION "@<@PROJECT_VERSION@>@") - -if(PACKAGE_FIND_VERSION_RANGE) - # Package version must be in the requested version range - if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN) - OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX) - OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX))) - set(PACKAGE_VERSION_COMPATIBLE FALSE) - else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - endif() -else() - if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) - set(PACKAGE_VERSION_COMPATIBLE FALSE) - else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) - set(PACKAGE_VERSION_EXACT TRUE) - endif() - endif() -endif() - -# if the using project doesn't have CMAKE_SIZEOF_VOID_P set, fail. -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() - -include("${CMAKE_CURRENT_LIST_DIR}/sdlcpu.cmake") -SDL_DetectTargetCPUArchitectures(_detected_archs) - -# check that the installed version has a compatible architecture as the one which is currently searching: -if(NOT(SDL_CPU_X86 OR SDL_CPU_X64 OR SDL_CPU_ARM64 OR SDL_CPU_ARM64EC)) - set(PACKAGE_VERSION "${PACKAGE_VERSION} (X86,X64,ARM64)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x64/INSTALL.md.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x64/INSTALL.md.in deleted file mode 100644 index 74cd678..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x64/INSTALL.md.in +++ /dev/null @@ -1,13 +0,0 @@ - -# Using this package - -This package contains @<@PROJECT_NAME@>@ built for x64 Windows. - -To use this package, simply replace an existing 64-bit @<@PROJECT_NAME@>@.dll with the one included here. - -# Development packages - -If you're looking for packages with headers and libraries, you can download one of these: -- @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-VC.zip, for development using Visual Studio -- @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-mingw.zip, for development using mingw-w64 - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x86/INSTALL.md.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x86/INSTALL.md.in deleted file mode 100644 index 041c116..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/msvc/x86/INSTALL.md.in +++ /dev/null @@ -1,13 +0,0 @@ - -# Using this package - -This package contains @<@PROJECT_NAME@>@ built for x86 Windows. - -To use this package, simply replace an existing 32-bit @<@PROJECT_NAME@>@.dll with the one included here. - -# Development packages - -If you're looking for packages with headers and libraries, you can download one of these: -- @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-VC.zip, for development using Visual Studio -- @<@PROJECT_NAME@>@-devel-@<@PROJECT_VERSION@>@-mingw.zip, for development using mingw-w64 - diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.cmake.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.cmake.in deleted file mode 100644 index 99e9f80..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.cmake.in +++ /dev/null @@ -1,41 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 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. -*/ - -/* WIKI CATEGORY: Version */ - -/* - * SDL_revision.h contains the SDL revision, which might be defined on the - * compiler command line, or generated right into the header itself by the - * build system. - */ - -#ifndef SDL_revision_h_ -#define SDL_revision_h_ - -#cmakedefine SDL_VENDOR_INFO "@SDL_VENDOR_INFO@" - -#if defined(SDL_VENDOR_INFO) -#define SDL_REVISION "@<@PROJECT_REVISION@>@ (" SDL_VENDOR_INFO ")" -#else -#define SDL_REVISION "@<@PROJECT_REVISION@>@" -#endif - -#endif /* SDL_revision_h_ */ diff --git a/contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.in b/contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.in deleted file mode 100644 index 7dd6bc1..0000000 --- a/contrib/SDL-3.2.8/build-scripts/pkg-support/source/SDL_revision.h.in +++ /dev/null @@ -1,56 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 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. -*/ - -/* WIKI CATEGORY: Version */ - -/* - * SDL_revision.h contains the SDL revision, which might be defined on the - * compiler command line, or generated right into the header itself by the - * build system. - */ - -#ifndef SDL_revision_h_ -#define SDL_revision_h_ - -#ifdef SDL_WIKI_DOCUMENTATION_SECTION - -/** - * This macro is a string describing the source at a particular point in - * development. - * - * This string is often generated from revision control's state at build time. - * - * This string can be quite complex and does not follow any standard. For - * example, it might be something like "SDL-prerelease-3.1.1-47-gf687e0732". - * It might also be user-defined at build time, so it's best to treat it as a - * clue in debugging forensics and not something the app will parse in any - * way. - * - * \since This macro is available since SDL 3.0.0. - */ -#define SDL_REVISION "Some arbitrary string decided at SDL build time" -#elif defined(SDL_VENDOR_INFO) -#define SDL_REVISION "@<@PROJECT_REVISION@>@ (" SDL_VENDOR_INFO ")" -#else -#define SDL_REVISION "@<@PROJECT_REVISION@>@" -#endif - -#endif /* SDL_revision_h_ */ diff --git a/contrib/SDL-3.2.8/build-scripts/release-info.json b/contrib/SDL-3.2.8/build-scripts/release-info.json deleted file mode 100644 index 8ba213a..0000000 --- a/contrib/SDL-3.2.8/build-scripts/release-info.json +++ /dev/null @@ -1,210 +0,0 @@ -{ - "name": "SDL3", - "remote": "libsdl-org/SDL", - "version": { - "file": "include/SDL3/SDL_version.h", - "re_major": "^#define SDL_MAJOR_VERSION\\s+([0-9]+)$", - "re_minor": "^#define SDL_MINOR_VERSION\\s+([0-9]+)$", - "re_micro": "^#define SDL_MICRO_VERSION\\s+([0-9]+)$" - }, - "source": { - "checks": [ - "src/SDL.c", - "include/SDL3/SDL.h", - "test/testsprite.c", - "android-project/app/src/main/java/org/libsdl/app/SDLActivity.java" - ], - "files": { - "include/SDL3": [ - "build-scripts/pkg-support/source/SDL_revision.h.in:SDL_revision.h" - ], - "include/build_config": [ - "build-scripts/pkg-support/source/SDL_revision.h.cmake.in:SDL_revision.h.cmake" - ] - } - }, - "dmg": { - "project": "Xcode/SDL/SDL.xcodeproj", - "path": "Xcode/SDL/build/SDL3.dmg", - "target": "SDL3.dmg", - "build-xcconfig": "Xcode/SDL/pkg-support/build.xcconfig" - }, - "mingw": { - "cmake": { - "archs": ["x86", "x64"], - "args": [ - "-DSDL_SHARED=ON", - "-DSDL_STATIC=OFF", - "-DSDL_DISABLE_INSTALL_DOCS=ON", - "-DSDL_RELOCATABLE=ON", - "-DSDL_TEST_LIBRARY=ON", - "-DSDL_TESTS=OFF", - "-DSDL_VENDOR_INFO=libsdl.org" - ], - "shared-static": "args" - }, - "files": { - "": [ - "build-scripts/pkg-support/mingw/INSTALL.md.in:INSTALL.md", - "build-scripts/pkg-support/mingw/Makefile", - "LICENSE.txt", - "README.md" - ], - "cmake": [ - "build-scripts/pkg-support/mingw/cmake/SDL3Config.cmake", - "build-scripts/pkg-support/mingw/cmake/SDL3ConfigVersion.cmake" - ] - } - }, - "msvc": { - "msbuild": { - "archs": [ - "x86", - "x64" - ], - "directory-build-props": "build-scripts/pkg-support/msvc/Directory.Build.props", - "projects": [ - "VisualC/SDL/SDL.vcxproj", - "VisualC/SDL_test/SDL_test.vcxproj" - ], - "files-lib": { - "": [ - "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL3.dll" - ] - }, - "files-devel": { - "lib/@<@ARCH@>@": [ - "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL3.dll", - "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL3.lib", - "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL3.pdb", - "VisualC/SDL_test/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL3_test.lib" - ] - } - }, - "cmake": { - "archs": [ - "arm64" - ], - "args": [ - "-DSDL_SHARED=ON", - "-DSDL_STATIC=OFF", - "-DSDL_TEST_LIBRARY=ON", - "-DSDL_TESTS=OFF", - "-DSDL_DISABLE_INSTALL_DOCS=ON", - "-DSDL_RELOCATABLE=ON", - "-DSDL_VENDOR_INFO=libsdl.org" - ], - "files-lib": { - "": [ - "bin/SDL3.dll" - ] - }, - "files-devel": { - "lib/@<@ARCH@>@": [ - "bin/SDL3.dll", - "bin/SDL3.pdb", - "lib/SDL3.lib", - "lib/SDL3_test.lib" - ] - } - }, - "files-lib": { - "": [ - "build-scripts/pkg-support/msvc/@<@ARCH@>@/INSTALL.md.in:INSTALL.md", - "LICENSE.txt", - "README.md" - ] - }, - "files-devel": { - "": [ - "build-scripts/pkg-support/msvc/INSTALL.md.in:INSTALL.md", - "LICENSE.txt", - "README.md" - ], - "cmake": [ - "build-scripts/pkg-support/msvc/cmake/SDL3Config.cmake.in:SDL3Config.cmake", - "build-scripts/pkg-support/msvc/cmake/SDL3ConfigVersion.cmake.in:SDL3ConfigVersion.cmake", - "cmake/sdlcpu.cmake" - ], - "include/SDL3": [ - "include/SDL3/*.h" - ] - } - }, - "android": { - "cmake": { - "args": [ - "-DSDL_SHARED=ON", - "-DSDL_STATIC=OFF", - "-DSDL_TEST_LIBRARY=ON", - "-DSDL_TESTS=OFF", - "-DSDL_ANDROID_JAR=ON", - "-DSDL_INSTALL=ON", - "-DSDL_INSTALL_DOCS=ON", - "-DSDL_VENDOR_INFO=libsdl.org" - ] - }, - "modules": { - "SDL3-Headers": { - "type": "interface", - "includes": { - "SDL3": ["include/SDL3/*.h"] - } - }, - "Headers": { - "type": "interface", - "export-libraries": [":SDL3-Headers"] - }, - "SDL3_test": { - "type": "library", - "library": "lib/libSDL3_test.a", - "export-libraries": [":Headers"] - }, - "SDL3-shared": { - "type": "library", - "library": "lib/libSDL3.so", - "export-libraries": [":Headers"] - }, - "SDL3": { - "type": "interface", - "export-libraries": [":SDL3-shared"] - } - }, - "jars": { - "classes": "share/java/@<@PROJECT_NAME@>@/@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@.jar", - "sources": "share/java/@<@PROJECT_NAME@>@/@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@-sources.jar", - "doc": "share/javadoc/@<@PROJECT_NAME@>@/@<@PROJECT_NAME@>@-@<@PROJECT_VERSION@>@-javadoc.jar" - }, - "abis": [ - "armeabi-v7a", - "arm64-v8a", - "x86", - "x86_64" - ], - "api-minimum": 21, - "api-target": 35, - "ndk-minimum": 21, - "aar-files": { - "": [ - "android-project/app/proguard-rules.pro:proguard.txt", - "build-scripts/pkg-support/android/aar/__main__.py.in:__main__.py", - "build-scripts/pkg-support/android/aar/description.json.in:description.json" - ], - "META-INF": [ - "LICENSE.txt" - ], - "cmake": [ - "cmake/sdlcpu.cmake", - "build-scripts/pkg-support/android/aar/cmake/SDL3Config.cmake", - "build-scripts/pkg-support/android/aar/cmake/SDL3ConfigVersion.cmake.in:SDL3ConfigVersion.cmake" - ] - }, - "files": { - "": [ - "build-scripts/pkg-support/android/INSTALL.md.in:INSTALL.md", - "LICENSE.txt", - "README.md" - ] - } - } -} diff --git a/contrib/SDL-3.2.8/build-scripts/rename_api.py b/contrib/SDL-3.2.8/build-scripts/rename_api.py deleted file mode 100755 index 605ffa0..0000000 --- a/contrib/SDL-3.2.8/build-scripts/rename_api.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python3 -# -# This script renames symbols in the API, updating SDL_oldnames.h and -# adding documentation for the change. - -import argparse -import os -import pathlib -import pprint -import re -import sys -from rename_symbols import create_regex_from_replacements, replace_symbols_in_path - -SDL_ROOT = pathlib.Path(__file__).resolve().parents[1] - -SDL_INCLUDE_DIR = SDL_ROOT / "include/SDL3" -SDL_BUILD_SCRIPTS = SDL_ROOT / "build-scripts" - - -def main(): - if len(args.args) == 0 or (len(args.args) % 2) != 0: - print("Usage: %s [-h] [--skip-header-check] header {enum,function,hint,structure,symbol} [old new ...]" % sys.argv[0]) - exit(1) - - # Check whether we can still modify the ABI - version_header = pathlib.Path( SDL_INCLUDE_DIR / "SDL_version.h" ).read_text() - if not re.search(r"SDL_MINOR_VERSION\s+[01]\s", version_header): - raise Exception("ABI is frozen, symbols cannot be renamed") - - # Find the symbol in the headers - if pathlib.Path(args.header).is_file(): - header = pathlib.Path(args.header) - else: - header = pathlib.Path(SDL_INCLUDE_DIR / args.header) - - if not header.exists(): - raise Exception("Couldn't find header %s" % header) - - header_name = header.name - if (header.name == "SDL_gamepad.h"): - header_name = "SDL_gamecontroller.h" - - header_text = header.read_text() - - # Replace the symbols in source code - replacements = {} - i = 0 - while i < len(args.args): - oldname = args.args[i + 0] - newname = args.args[i + 1] - - if not args.skip_header_check and not re.search((r"\b%s\b" % oldname), header_text): - raise Exception("Couldn't find %s in %s" % (oldname, header)) - - replacements[ oldname ] = newname - replacements[ oldname + "_REAL" ] = newname + "_REAL" - i += 2 - - regex = create_regex_from_replacements(replacements) - for dir in ["src", "test", "examples", "include", "docs", "cmake/test"]: - replace_symbols_in_path(SDL_ROOT / dir, regex, replacements) - - # Replace the symbols in documentation - i = 0 - while i < len(args.args): - oldname = args.args[i + 0] - newname = args.args[i + 1] - - add_symbol_to_oldnames(header_name, oldname, newname) - add_symbol_to_migration(header_name, args.type, oldname, newname) - add_symbol_to_coccinelle(args.type, oldname, newname) - i += 2 - - -def add_line(lines, i, section): - lines.insert(i, section) - i += 1 - return i - - -def add_content(lines, i, content, add_trailing_line): - if lines[i - 1] == "": - lines[i - 1] = content - else: - i = add_line(lines, i, content) - - if add_trailing_line: - i = add_line(lines, i, "") - return i - - -def add_symbol_to_coccinelle(symbol_type, oldname, newname): - file = open(SDL_BUILD_SCRIPTS / "SDL_migration.cocci", "a") - # Append-adds at last - - if symbol_type == "function": - file.write("@@\n") - file.write("@@\n") - file.write("- %s\n" % oldname) - file.write("+ %s\n" % newname) - file.write(" (...)\n") - - if symbol_type == "symbol": - file.write("@@\n") - file.write("@@\n") - file.write("- %s\n" % oldname) - file.write("+ %s\n" % newname) - - # double check ? - if symbol_type == "hint": - file.write("@@\n") - file.write("@@\n") - file.write("- %s\n" % oldname) - file.write("+ %s\n" % newname) - - if symbol_type == "enum" or symbol_type == "structure": - file.write("@@\n") - file.write("typedef %s, %s;\n" % (oldname, newname)) - file.write("@@\n") - file.write("- %s\n" % oldname) - file.write("+ %s\n" % newname) - - file.close() - - -def add_symbol_to_oldnames(header, oldname, newname): - file = (SDL_INCLUDE_DIR / "SDL_oldnames.h") - lines = file.read_text().splitlines() - mode = 0 - i = 0 - while i < len(lines): - line = lines[i] - if line == "#ifdef SDL_ENABLE_OLD_NAMES": - if mode == 0: - mode = 1 - section = ("/* ##%s */" % header) - section_added = False - content = ("#define %s %s" % (oldname, newname)) - content_added = False - else: - raise Exception("add_symbol_to_oldnames(): expected mode 0") - elif line == "#elif !defined(SDL_DISABLE_OLD_NAMES)": - if mode == 1: - if not section_added: - i = add_line(lines, i, section) - - if not content_added: - i = add_content(lines, i, content, True) - - mode = 2 - section = ("/* ##%s */" % header) - section_added = False - content = ("#define %s %s_renamed_%s" % (oldname, oldname, newname)) - content_added = False - else: - raise Exception("add_symbol_to_oldnames(): expected mode 1") - elif line == "#endif /* SDL_ENABLE_OLD_NAMES */": - if mode == 2: - if not section_added: - i = add_line(lines, i, section) - - if not content_added: - i = add_content(lines, i, content, True) - - mode = 3 - else: - raise Exception("add_symbol_to_oldnames(): expected mode 2") - elif line != "" and (mode == 1 or mode == 2): - if line.startswith("/* ##"): - if section_added: - if not content_added: - i = add_content(lines, i, content, True) - content_added = True - elif line == section: - section_added = True - elif section < line: - i = add_line(lines, i, section) - section_added = True - i = add_content(lines, i, content, True) - content_added = True - elif line != "" and section_added and not content_added: - if content == line: - content_added = True - elif content < line: - i = add_content(lines, i, content, False) - content_added = True - i += 1 - - file.write_text("\n".join(lines) + "\n") - - -def add_symbol_to_migration(header, symbol_type, oldname, newname): - file = (SDL_ROOT / "docs/README-migration.md") - lines = file.read_text().splitlines() - section = ("## %s" % header) - section_added = False - note = ("The following %ss have been renamed:" % symbol_type) - note_added = False - if symbol_type == "function": - content = ("* %s() => %s()" % (oldname, newname)) - else: - content = ("* %s => %s" % (oldname, newname)) - content_added = False - mode = 0 - i = 0 - while i < len(lines): - line = lines[i] - if line.startswith("##") and line.endswith(".h"): - if line == section: - section_added = True - elif section < line: - break - - elif section_added and not note_added: - if note == line: - note_added = True - elif note_added and not content_added: - if content == line: - content_added = True - elif line == "" or content < line: - i = add_line(lines, i, content) - content_added = True - i += 1 - - if not section_added: - i = add_line(lines, i, section) - i = add_line(lines, i, "") - - if not note_added: - i = add_line(lines, i, note) - - if not content_added: - i = add_content(lines, i, content, True) - - file.write_text("\n".join(lines) + "\n") - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser(fromfile_prefix_chars='@') - parser.add_argument("--skip-header-check", action="store_true") - parser.add_argument("header") - parser.add_argument("type", choices=["enum", "function", "hint", "structure", "symbol"]) - parser.add_argument("args", nargs="*") - args = parser.parse_args() - - try: - main() - except Exception as e: - print(e) - exit(-1) - - exit(0) - diff --git a/contrib/SDL-3.2.8/build-scripts/rename_headers.py b/contrib/SDL-3.2.8/build-scripts/rename_headers.py deleted file mode 100755 index b61e477..0000000 --- a/contrib/SDL-3.2.8/build-scripts/rename_headers.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python3 -# -# This script renames SDL headers in the specified paths - -import argparse -import pathlib -import re - - -def do_include_replacements(paths): - replacements = [ - ( re.compile(r"(?:[\"<])(?:SDL2/)?SDL_image.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?SDL_mixer.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?SDL_net.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?SDL_rtf.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?SDL_ttf.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?SDL_gamecontroller.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?begin_code.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?close_code.h(?:[\">])"), r"" ), - ( re.compile(r"(?:[\"<])(?:SDL2/)?(SDL[_a-z0-9]*\.h)(?:[\">])"), r"" ) - ] - for entry in paths: - path = pathlib.Path(entry) - if not path.exists(): - print("{} does not exist, skipping".format(entry)) - continue - - replace_headers_in_path(path, replacements) - - -def replace_headers_in_file(file, replacements): - try: - with file.open("r", encoding="UTF-8", newline="") as rfp: - original = rfp.read() - contents = original - for regex, replacement in replacements: - contents = regex.sub(replacement, contents) - if contents != original: - with file.open("w", encoding="UTF-8", newline="") as wfp: - wfp.write(contents) - except UnicodeDecodeError: - print("%s is not text, skipping" % file) - except Exception as err: - print("%s" % err) - - -def replace_headers_in_dir(path, replacements): - for entry in path.glob("*"): - if entry.is_dir(): - replace_headers_in_dir(entry, replacements) - else: - print("Processing %s" % entry) - replace_headers_in_file(entry, replacements) - - -def replace_headers_in_path(path, replacements): - if path.is_dir(): - replace_headers_in_dir(path, replacements) - else: - replace_headers_in_file(path, replacements) - - -def main(): - parser = argparse.ArgumentParser(fromfile_prefix_chars='@', description="Rename #include's for SDL3.") - parser.add_argument("args", metavar="PATH", nargs="*", help="Input source file") - args = parser.parse_args() - - try: - do_include_replacements(args.args) - except Exception as e: - print(e) - return 1 - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/rename_macros.py b/contrib/SDL-3.2.8/build-scripts/rename_macros.py deleted file mode 100755 index 978120c..0000000 --- a/contrib/SDL-3.2.8/build-scripts/rename_macros.py +++ /dev/null @@ -1,382 +0,0 @@ -#!/usr/bin/env python3 -# -# This script renames SDL macros in the specified paths - -import argparse -import pathlib -import re - - -class TextReplacer: - def __init__(self, macros, repl_format): - if isinstance(macros, dict): - macros_keys = macros.keys() - else: - macros_keys = macros - self.macros = macros - self.re_macros = re.compile(r"\W(" + "|".join(macros_keys) + r")(?:\W|$)") - self.repl_format = repl_format - - def apply(self, contents): - def cb(m): - macro = m.group(1) - original = m.group(0) - match_start, _ = m.span(0) - platform_start, platform_end = m.span(1) - if isinstance(self.macros, dict): - repl_args = (macro, self.macros[macro]) - else: - repl_args = macro, - new_text = self.repl_format.format(*repl_args) - r = original[:(platform_start-match_start)] + new_text + original[platform_end-match_start:] - return r - contents, _ = self.re_macros.subn(cb, contents) - - return contents - - -class MacrosCheck: - def __init__(self): - self.renamed_platform_macros = TextReplacer(RENAMED_MACROS, "{1}") - self.deprecated_platform_macros = TextReplacer(DEPRECATED_PLATFORM_MACROS, "{0} /* {0} has been removed in SDL3 */") - - def run(self, contents): - contents = self.renamed_platform_macros.apply(contents) - contents = self.deprecated_platform_macros.apply(contents) - return contents - - -def apply_checks(paths): - checks = ( - MacrosCheck(), - ) - - for entry in paths: - path = pathlib.Path(entry) - if not path.exists(): - print("{} does not exist, skipping".format(entry)) - continue - apply_checks_in_path(path, checks) - - -def apply_checks_in_file(file, checks): - try: - with file.open("r", encoding="UTF-8", newline="") as rfp: - original = rfp.read() - contents = original - for check in checks: - contents = check.run(contents) - if contents != original: - with file.open("w", encoding="UTF-8", newline="") as wfp: - wfp.write(contents) - except UnicodeDecodeError: - print("%s is not text, skipping" % file) - except Exception as err: - print("%s" % err) - - -def apply_checks_in_dir(path, checks): - for entry in path.glob("*"): - if entry.is_dir(): - apply_checks_in_dir(entry, checks) - else: - print("Processing %s" % entry) - apply_checks_in_file(entry, checks) - - -def apply_checks_in_path(path, checks): - if path.is_dir(): - apply_checks_in_dir(path, checks) - else: - apply_checks_in_file(path, checks) - - -def main(): - parser = argparse.ArgumentParser(fromfile_prefix_chars='@', description="Rename macros for SDL3") - parser.add_argument("args", nargs="*", help="Input source files") - args = parser.parse_args() - - try: - apply_checks(args.args) - except Exception as e: - print(e) - return 1 - - -RENAMED_MACROS = { - "__AIX__": "SDL_PLATFORM_AIX", - "__HAIKU__": "SDL_PLATFORM_HAIKU", - "__BSDI__": "SDL_PLATFORM_BSDI", - "__FREEBSD__": "SDL_PLATFORM_FREEBSD", - "__HPUX__": "SDL_PLATFORM_HPUX", - "__IRIX__": "SDL_PLATFORM_IRIX", - "__LINUX__": "SDL_PLATFORM_LINUX", - "__OS2__": "SDL_PLATFORM_OS2", - # "__ANDROID__": "SDL_PLATFORM_ANDROID, - "__APPLE__": "SDL_PLATFORM_APPLE", - "__TVOS__": "SDL_PLATFORM_TVOS", - "__IPHONEOS__": "SDL_PLATFORM_IOS", - "__MACOSX__": "SDL_PLATFORM_MACOS", - "__NETBSD__": "SDL_PLATFORM_NETBSD", - "__OPENBSD__": "SDL_PLATFORM_OPENBSD", - "__OSF__": "SDL_PLATFORM_OSF", - "__QNXNTO__": "SDL_PLATFORM_QNXNTO", - "__RISCOS__": "SDL_PLATFORM_RISCOS", - "__SOLARIS__": "SDL_PLATFORM_SOLARIS", - "__PSP__": "SDL_PLATFORM_PSP", - "__PS2__": "SDL_PLATFORM_PS2", - "__VITA__": "SDL_PLATFORM_VITA", - "__3DS__": "SDL_PLATFORM_3DS", - # "__unix__": "SDL_PLATFORM_UNIX, - "__XBOXSERIES__": "SDL_PLATFORM_XBOXSERIES", - "__XBOXONE__": "SDL_PLATFORM_XBOXONE", - "__WINDOWS__": "SDL_PLATFORM_WINDOWS", - "__WIN32__": "SDL_PLATFORM_WIN32", - # "__CYGWIN_": "SDL_PLATFORM_CYGWIN", - "__WINGDK__": "SDL_PLATFORM_WINGDK", - "__GDK__": "SDL_PLATFORM_GDK", - # "__EMSCRIPTEN__": "SDL_PLATFORM_EMSCRIPTEN", -} - -DEPRECATED_PLATFORM_MACROS = { - "__DREAMCAST__", - "__NACL__", - "__PNACL__", - "__WINDOWS__", - "__WINRT__", - "SDL_ALTIVEC_BLITTERS", - "SDL_ARM_NEON_BLITTERS", - "SDL_ARM_SIMD_BLITTERS", - "SDL_ATOMIC_DISABLED", - "SDL_AUDIO_DISABLED", - "SDL_AUDIO_DRIVER_AAUDIO", - "SDL_AUDIO_DRIVER_ALSA", - "SDL_AUDIO_DRIVER_ALSA_DYNAMIC", - "SDL_AUDIO_DRIVER_ANDROID", - "SDL_AUDIO_DRIVER_ARTS", - "SDL_AUDIO_DRIVER_ARTS_DYNAMIC", - "SDL_AUDIO_DRIVER_COREAUDIO", - "SDL_AUDIO_DRIVER_DISK", - "SDL_AUDIO_DRIVER_DSOUND", - "SDL_AUDIO_DRIVER_DUMMY", - "SDL_AUDIO_DRIVER_EMSCRIPTEN", - "SDL_AUDIO_DRIVER_ESD", - "SDL_AUDIO_DRIVER_ESD_DYNAMIC", - "SDL_AUDIO_DRIVER_FUSIONSOUND", - "SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC", - "SDL_AUDIO_DRIVER_HAIKU", - "SDL_AUDIO_DRIVER_JACK", - "SDL_AUDIO_DRIVER_JACK_DYNAMIC", - "SDL_AUDIO_DRIVER_N3DS", - "SDL_AUDIO_DRIVER_NAS", - "SDL_AUDIO_DRIVER_NAS_DYNAMIC", - "SDL_AUDIO_DRIVER_NETBSD", - "SDL_AUDIO_DRIVER_OPENSLES", - "SDL_AUDIO_DRIVER_OS2", - "SDL_AUDIO_DRIVER_OSS", - "SDL_AUDIO_DRIVER_PAUDIO", - "SDL_AUDIO_DRIVER_PIPEWIRE", - "SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC", - "SDL_AUDIO_DRIVER_PS2", - "SDL_AUDIO_DRIVER_PSP", - "SDL_AUDIO_DRIVER_PULSEAUDIO", - "SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC", - "SDL_AUDIO_DRIVER_QSA", - "SDL_AUDIO_DRIVER_SNDIO", - "SDL_AUDIO_DRIVER_SNDIO_DYNAMIC", - "SDL_AUDIO_DRIVER_SUNAUDIO", - "SDL_AUDIO_DRIVER_VITA", - "SDL_AUDIO_DRIVER_WASAPI", - "SDL_AUDIO_DRIVER_WINMM", - "SDL_CPUINFO_DISABLED", - "SDL_DEFAULT_ASSERT_LEVEL", - "SDL_EVENTS_DISABLED", - "SDL_FILESYSTEM_ANDROID", - "SDL_FILESYSTEM_COCOA", - "SDL_FILESYSTEM_DISABLED", - "SDL_FILESYSTEM_DUMMY", - "SDL_FILESYSTEM_EMSCRIPTEN", - "SDL_FILESYSTEM_HAIKU", - "SDL_FILESYSTEM_N3DS", - "SDL_FILESYSTEM_OS2", - "SDL_FILESYSTEM_PS2", - "SDL_FILESYSTEM_PSP", - "SDL_FILESYSTEM_RISCOS", - "SDL_FILESYSTEM_UNIX", - "SDL_FILESYSTEM_VITA", - "SDL_FILESYSTEM_WINDOWS", - "SDL_FILE_DISABLED", - "SDL_HAPTIC_ANDROID", - "SDL_HAPTIC_DINPUT", - "SDL_HAPTIC_DISABLED", - "SDL_HAPTIC_DUMMY", - "SDL_HAPTIC_IOKIT", - "SDL_HAPTIC_LINUX", - "SDL_HAPTIC_XINPUT", - "SDL_HAVE_LIBDECOR_GET_MIN_MAX", - "SDL_HAVE_MACHINE_JOYSTICK_H", - "SDL_HIDAPI_DISABLED", - "SDL_INPUT_FBSDKBIO", - "SDL_INPUT_LINUXEV", - "SDL_INPUT_LINUXKD", - "SDL_INPUT_WSCONS", - "SDL_IPHONE_KEYBOARD", - "SDL_IPHONE_LAUNCHSCREEN", - "SDL_JOYSTICK_ANDROID", - "SDL_JOYSTICK_DINPUT", - "SDL_JOYSTICK_DISABLED", - "SDL_JOYSTICK_DUMMY", - "SDL_JOYSTICK_EMSCRIPTEN", - "SDL_JOYSTICK_HAIKU", - "SDL_JOYSTICK_HIDAPI", - "SDL_JOYSTICK_IOKIT", - "SDL_JOYSTICK_LINUX", - "SDL_JOYSTICK_MFI", - "SDL_JOYSTICK_N3DS", - "SDL_JOYSTICK_OS2", - "SDL_JOYSTICK_PS2", - "SDL_JOYSTICK_PSP", - "SDL_JOYSTICK_RAWINPUT", - "SDL_JOYSTICK_USBHID", - "SDL_JOYSTICK_VIRTUAL", - "SDL_JOYSTICK_VITA", - "SDL_JOYSTICK_WGI", - "SDL_JOYSTICK_XINPUT", - "SDL_LIBSAMPLERATE_DYNAMIC", - "SDL_LIBUSB_DYNAMIC", - "SDL_LOADSO_DISABLED", - "SDL_LOADSO_DLOPEN", - "SDL_LOADSO_DUMMY", - "SDL_LOADSO_LDG", - "SDL_LOADSO_OS2", - "SDL_LOADSO_WINDOWS", - "SDL_LOCALE_DISABLED", - "SDL_LOCALE_DUMMY", - "SDL_MISC_DISABLED", - "SDL_MISC_DUMMY", - "SDL_POWER_ANDROID", - "SDL_POWER_DISABLED", - "SDL_POWER_EMSCRIPTEN", - "SDL_POWER_HAIKU", - "SDL_POWER_HARDWIRED", - "SDL_POWER_LINUX", - "SDL_POWER_MACOSX", - "SDL_POWER_N3DS", - "SDL_POWER_PSP", - "SDL_POWER_UIKIT", - "SDL_POWER_VITA", - "SDL_POWER_WINDOWS", - "SDL_POWER_WINRT", - "SDL_RENDER_DISABLED", - "SDL_SENSOR_ANDROID", - "SDL_SENSOR_COREMOTION", - "SDL_SENSOR_DISABLED", - "SDL_SENSOR_DUMMY", - "SDL_SENSOR_N3DS", - "SDL_SENSOR_VITA", - "SDL_SENSOR_WINDOWS", - "SDL_THREADS_DISABLED", - "SDL_THREAD_GENERIC_COND_SUFFIX", - "SDL_THREAD_N3DS", - "SDL_THREAD_OS2", - "SDL_THREAD_PS2", - "SDL_THREAD_PSP", - "SDL_THREAD_PTHREAD", - "SDL_THREAD_PTHREAD_RECURSIVE_MUTEX", - "SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP", - "SDL_THREAD_VITA", - "SDL_THREAD_WINDOWS", - "SDL_TIMERS_DISABLED", - "SDL_TIMER_DUMMY", - "SDL_TIMER_HAIKU", - "SDL_TIMER_N3DS", - "SDL_TIMER_OS2", - "SDL_TIMER_PS2", - "SDL_TIMER_PSP", - "SDL_TIMER_UNIX", - "SDL_TIMER_VITA", - "SDL_TIMER_WINDOWS", - "SDL_UDEV_DYNAMIC", - "SDL_USE_IME", - "SDL_USE_LIBICONV", - "SDL_VIDEO_DISABLED", - "SDL_VIDEO_DRIVER_ANDROID", - "SDL_VIDEO_DRIVER_COCOA", - "SDL_VIDEO_DRIVER_DIRECTFB", - "SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC", - "SDL_VIDEO_DRIVER_DUMMY", - "SDL_VIDEO_DRIVER_EMSCRIPTEN", - "SDL_VIDEO_DRIVER_HAIKU", - "SDL_VIDEO_DRIVER_KMSDRM", - "SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC", - "SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM", - "SDL_VIDEO_DRIVER_N3DS", - "SDL_VIDEO_DRIVER_OFFSCREEN", - "SDL_VIDEO_DRIVER_OS2", - "SDL_VIDEO_DRIVER_PS2", - "SDL_VIDEO_DRIVER_PSP", - "SDL_VIDEO_DRIVER_QNX", - "SDL_VIDEO_DRIVER_RISCOS", - "SDL_VIDEO_DRIVER_RPI", - "SDL_VIDEO_DRIVER_UIKIT", - "SDL_VIDEO_DRIVER_VITA", - "SDL_VIDEO_DRIVER_VIVANTE", - "SDL_VIDEO_DRIVER_VIVANTE_VDK", - "SDL_VIDEO_DRIVER_WAYLAND", - "SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC", - "SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR", - "SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL", - "SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR", - "SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON", - "SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH", - "SDL_VIDEO_DRIVER_WINDOWS", - "SDL_VIDEO_DRIVER_WINRT", - "SDL_VIDEO_DRIVER_X11", - "SDL_VIDEO_DRIVER_X11_DYNAMIC", - "SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR", - "SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT", - "SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES", - "SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2", - "SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR", - "SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS", - "SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM", - "SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS", - "SDL_VIDEO_DRIVER_X11_XCURSOR", - "SDL_VIDEO_DRIVER_X11_XDBE", - "SDL_VIDEO_DRIVER_X11_XFIXES", - "SDL_VIDEO_DRIVER_X11_XINPUT2", - "SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH", - "SDL_VIDEO_DRIVER_X11_XRANDR", - "SDL_VIDEO_DRIVER_X11_XSCRNSAVER", - "SDL_VIDEO_DRIVER_X11_XSHAPE", - "SDL_VIDEO_METAL", - "SDL_VIDEO_OPENGL", - "SDL_VIDEO_OPENGL_BGL", - "SDL_VIDEO_OPENGL_CGL", - "SDL_VIDEO_OPENGL_EGL", - "SDL_VIDEO_OPENGL_ES", - "SDL_VIDEO_OPENGL_ES2", - "SDL_VIDEO_OPENGL_GLX", - "SDL_VIDEO_OPENGL_OSMESA", - "SDL_VIDEO_OPENGL_OSMESA_DYNAMIC", - "SDL_VIDEO_OPENGL_WGL", - "SDL_VIDEO_RENDER_D3D", - "SDL_VIDEO_RENDER_D3D11", - "SDL_VIDEO_RENDER_D3D12", - "SDL_VIDEO_RENDER_DIRECTFB", - "SDL_VIDEO_RENDER_METAL", - "SDL_VIDEO_RENDER_OGL", - "SDL_VIDEO_RENDER_OGL_ES", - "SDL_VIDEO_RENDER_OGL_ES2", - "SDL_VIDEO_RENDER_PS2", - "SDL_VIDEO_RENDER_PSP", - "SDL_VIDEO_RENDER_VITA_GXM", - "SDL_VIDEO_VITA_PIB", - "SDL_VIDEO_VITA_PVR", - "SDL_VIDEO_VITA_PVR_OGL", - "SDL_VIDEO_VULKAN", -} - -if __name__ == "__main__": - raise SystemExit(main()) - diff --git a/contrib/SDL-3.2.8/build-scripts/rename_symbols.py b/contrib/SDL-3.2.8/build-scripts/rename_symbols.py deleted file mode 100755 index 33a92dd..0000000 --- a/contrib/SDL-3.2.8/build-scripts/rename_symbols.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -# -# This script renames symbols in the specified paths - -import argparse -import os -import pathlib -import re -import sys - - -SDL_ROOT = pathlib.Path(__file__).resolve().parents[1] - -SDL_INCLUDE_DIR = SDL_ROOT / "include/SDL3" - - -def main(): - if args.all_symbols: - if len(args.args) < 1: - print("Usage: %s --all-symbols files_or_directories ..." % sys.argv[0]) - exit(1) - - replacements = get_all_replacements() - entries = args.args - - else: - if len(args.args) < 3: - print("Usage: %s [--substring] oldname newname files_or_directories ..." % sys.argv[0]) - exit(1) - - replacements = { args.args[0]: args.args[1] } - entries = args.args[2:] - - if args.substring: - regex = create_substring_regex_from_replacements(replacements) - else: - regex = create_regex_from_replacements(replacements) - - for entry in entries: - path = pathlib.Path(entry) - if not path.exists(): - print("%s doesn't exist, skipping" % entry) - continue - - replace_symbols_in_path(path, regex, replacements) - - -def get_all_replacements(): - replacements = {} - file = (SDL_INCLUDE_DIR / "SDL_oldnames.h") - mode = 0 - for line in file.read_text().splitlines(): - if line == "#ifdef SDL_ENABLE_OLD_NAMES": - if mode == 0: - mode = 1 - else: - raise Exception("get_all_replacements(): expected mode 0") - elif line == "#elif !defined(SDL_DISABLE_OLD_NAMES)": - if mode == 1: - mode = 2 - else: - raise Exception("get_all_replacements(): expected mode 1") - elif line == "#endif /* SDL_ENABLE_OLD_NAMES */": - if mode == 2: - mode = 3 - else: - raise Exception("add_symbol_to_oldnames(): expected mode 2") - elif mode == 1 and line.startswith("#define "): - words = line.split() - replacements[words[1]] = words[2] - # In case things are accidentally renamed to the "X_renamed_Y" symbol - #replacements[words[1] + "_renamed_" + words[2]] = words[2] - - return replacements - - -def create_regex_from_replacements(replacements): - return re.compile(r"\b(%s)\b" % "|".join(map(re.escape, replacements.keys()))) - - -def create_substring_regex_from_replacements(replacements): - return re.compile(r"(%s)" % "|".join(map(re.escape, replacements.keys()))) - - -def replace_symbols_in_file(file, regex, replacements): - try: - with file.open("r", encoding="UTF-8", newline="") as rfp: - original = rfp.read() - contents = regex.sub(lambda mo: replacements[mo.string[mo.start():mo.end()]], original) - if contents != original: - with file.open("w", encoding="UTF-8", newline="") as wfp: - wfp.write(contents) - except UnicodeDecodeError: - print("%s is not text, skipping" % file) - except Exception as err: - print("%s" % err) - - -def replace_symbols_in_dir(path, regex, replacements): - for entry in path.glob("*"): - if entry.is_dir(): - replace_symbols_in_dir(entry, regex, replacements) - else: - print("Processing %s" % entry) - replace_symbols_in_file(entry, regex, replacements) - - -def replace_symbols_in_path(path, regex, replacements): - if path.is_dir(): - replace_symbols_in_dir(path, regex, replacements) - else: - replace_symbols_in_file(path, regex, replacements) - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser(fromfile_prefix_chars='@') - parser.add_argument("--all-symbols", action="store_true") - parser.add_argument("--substring", action="store_true") - parser.add_argument("args", nargs="*") - args = parser.parse_args() - - try: - main() - except Exception as e: - print(e) - exit(-1) - - exit(0) - diff --git a/contrib/SDL-3.2.8/build-scripts/rename_types.py b/contrib/SDL-3.2.8/build-scripts/rename_types.py deleted file mode 100755 index 137b409..0000000 --- a/contrib/SDL-3.2.8/build-scripts/rename_types.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# -# This script renames symbols in the specified paths - -import argparse -import os -import pathlib -import re -import sys - - -def main(): - if len(args.args) < 1: - print("Usage: %s files_or_directories ..." % sys.argv[0]) - exit(1) - - replacements = { - "SDL_bool": "bool", - "SDL_TRUE": "true", - "SDL_FALSE": "false", - } - entries = args.args[0:] - - regex = create_regex_from_replacements(replacements) - - for entry in entries: - path = pathlib.Path(entry) - if not path.exists(): - print("%s doesn't exist, skipping" % entry) - continue - - replace_symbols_in_path(path, regex, replacements) - -def create_regex_from_replacements(replacements): - return re.compile(r"\b(%s)\b" % "|".join(map(re.escape, replacements.keys()))) - -def replace_symbols_in_file(file, regex, replacements): - try: - with file.open("r", encoding="UTF-8", newline="") as rfp: - original = rfp.read() - contents = regex.sub(lambda mo: replacements[mo.string[mo.start():mo.end()]], original) - if contents != original: - with file.open("w", encoding="UTF-8", newline="") as wfp: - wfp.write(contents) - except UnicodeDecodeError: - print("%s is not text, skipping" % file) - except Exception as err: - print("%s" % err) - - -def replace_symbols_in_dir(path, regex, replacements): - for entry in path.glob("*"): - if entry.is_dir(): - replace_symbols_in_dir(entry, regex, replacements) - else: - print("Processing %s" % entry) - replace_symbols_in_file(entry, regex, replacements) - - -def replace_symbols_in_path(path, regex, replacements): - if path.is_dir(): - replace_symbols_in_dir(path, regex, replacements) - else: - replace_symbols_in_file(path, regex, replacements) - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser(fromfile_prefix_chars='@') - parser.add_argument("args", nargs="*") - args = parser.parse_args() - - try: - main() - except Exception as e: - print(e) - exit(-1) - - exit(0) - diff --git a/contrib/SDL-3.2.8/build-scripts/setup-gdk-desktop.py b/contrib/SDL-3.2.8/build-scripts/setup-gdk-desktop.py deleted file mode 100755 index d2309a0..0000000 --- a/contrib/SDL-3.2.8/build-scripts/setup-gdk-desktop.py +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env python - -import argparse -import functools -import logging -import os -from pathlib import Path -import re -import shutil -import subprocess -import tempfile -import textwrap -import urllib.request -import zipfile - -# Update both variables when updating the GDK -GIT_REF = "June_2024_Update_1" -GDK_EDITION = "240601" # YYMMUU - -logger = logging.getLogger(__name__) - -class GdDesktopConfigurator: - def __init__(self, gdk_path, arch, vs_folder, vs_version=None, vs_toolset=None, temp_folder=None, git_ref=None, gdk_edition=None): - self.git_ref = git_ref or GIT_REF - self.gdk_edition = gdk_edition or GDK_EDITION - self.gdk_path = gdk_path - self.temp_folder = temp_folder or Path(tempfile.gettempdir()) - self.dl_archive_path = Path(self.temp_folder) / f"{ self.git_ref }.zip" - self.gdk_extract_path = Path(self.temp_folder) / f"GDK-{ self.git_ref }" - self.arch = arch - self.vs_folder = vs_folder - self._vs_version = vs_version - self._vs_toolset = vs_toolset - - def download_archive(self) -> None: - gdk_url = f"https://github.com/microsoft/GDK/archive/refs/tags/{ GIT_REF }.zip" - logger.info("Downloading %s to %s", gdk_url, self.dl_archive_path) - urllib.request.urlretrieve(gdk_url, self.dl_archive_path) - assert self.dl_archive_path.is_file() - - def extract_zip_archive(self) -> None: - extract_path = self.gdk_extract_path.parent - assert self.dl_archive_path.is_file() - logger.info("Extracting %s to %s", self.dl_archive_path, extract_path) - with zipfile.ZipFile(self.dl_archive_path) as zf: - zf.extractall(extract_path) - assert self.gdk_extract_path.is_dir(), f"{self.gdk_extract_path} must exist" - - def extract_development_kit(self) -> None: - extract_dks_cmd = self.gdk_extract_path / "SetupScripts/ExtractXboxOneDKs.cmd" - assert extract_dks_cmd.is_file() - logger.info("Extracting GDK Development Kit: running %s", extract_dks_cmd) - cmd = ["cmd.exe", "/C", str(extract_dks_cmd), str(self.gdk_extract_path), str(self.gdk_path)] - logger.debug("Running %r", cmd) - subprocess.check_call(cmd) - - def detect_vs_version(self) -> str: - vs_regex = re.compile("VS([0-9]{4})") - supported_vs_versions = [] - for p in self.gaming_grdk_build_path.iterdir(): - if not p.is_dir(): - continue - if m := vs_regex.match(p.name): - supported_vs_versions.append(m.group(1)) - logger.info(f"Supported Visual Studio versions: {supported_vs_versions}") - vs_versions = set(self.vs_folder.parts).intersection(set(supported_vs_versions)) - if not vs_versions: - raise RuntimeError("Visual Studio version is incompatible") - if len(vs_versions) > 1: - raise RuntimeError(f"Too many compatible VS versions found ({vs_versions})") - vs_version = vs_versions.pop() - logger.info(f"Used Visual Studio version: {vs_version}") - return vs_version - - def detect_vs_toolset(self) -> str: - toolset_paths = [] - for ts_path in self.gdk_toolset_parent_path.iterdir(): - if not ts_path.is_dir(): - continue - ms_props = ts_path / "Microsoft.Cpp.props" - if not ms_props.is_file(): - continue - toolset_paths.append(ts_path.name) - logger.info("Detected Visual Studio toolsets: %s", toolset_paths) - assert toolset_paths, "Have we detected at least one toolset?" - - def toolset_number(toolset: str) -> int: - if m:= re.match("[^0-9]*([0-9]+).*", toolset): - return int(m.group(1)) - return -9 - - return max(toolset_paths, key=toolset_number) - - @property - def vs_version(self) -> str: - if self._vs_version is None: - self._vs_version = self.detect_vs_version() - return self._vs_version - - @property - def vs_toolset(self) -> str: - if self._vs_toolset is None: - self._vs_toolset = self.detect_vs_toolset() - return self._vs_toolset - - @staticmethod - def copy_files_and_merge_into(srcdir: Path, dstdir: Path) -> None: - logger.info(f"Copy {srcdir} to {dstdir}") - for root, _, files in os.walk(srcdir): - dest_root = dstdir / Path(root).relative_to(srcdir) - if not dest_root.is_dir(): - dest_root.mkdir() - for file in files: - srcfile = Path(root) / file - dstfile = dest_root / file - shutil.copy(srcfile, dstfile) - - def copy_msbuild(self) -> None: - vc_toolset_parent_path = self.vs_folder / "MSBuild/Microsoft/VC" - if 1: - logger.info(f"Detected compatible Visual Studio version: {self.vs_version}") - srcdir = vc_toolset_parent_path - dstdir = self.gdk_toolset_parent_path - assert srcdir.is_dir(), "Source directory must exist" - assert dstdir.is_dir(), "Destination directory must exist" - - self.copy_files_and_merge_into(srcdir=srcdir, dstdir=dstdir) - - @property - def game_dk_path(self) -> Path: - return self.gdk_path / "Microsoft GDK" - - @property - def game_dk_latest_path(self) -> Path: - return self.game_dk_path / self.gdk_edition - - @property - def windows_sdk_path(self) -> Path: - return self.gdk_path / "Windows Kits/10" - - @property - def gaming_grdk_build_path(self) -> Path: - return self.game_dk_latest_path / "GRDK" - - @property - def gdk_toolset_parent_path(self) -> Path: - return self.gaming_grdk_build_path / f"VS{self.vs_version}/flatDeployment/MSBuild/Microsoft/VC" - - @property - def env(self) -> dict[str, str]: - game_dk = self.game_dk_path - game_dk_latest = self.game_dk_latest_path - windows_sdk_dir = self.windows_sdk_path - gaming_grdk_build = self.gaming_grdk_build_path - - return { - "GRDKEDITION": f"{self.gdk_edition}", - "GameDK": f"{game_dk}\\", - "GameDKLatest": f"{ game_dk_latest }\\", - "WindowsSdkDir": f"{ windows_sdk_dir }\\", - "GamingGRDKBuild": f"{ gaming_grdk_build }\\", - "VSInstallDir": f"{ self.vs_folder }\\", - } - - def create_user_props(self, path: Path) -> None: - vc_targets_path = self.gaming_grdk_build_path / f"VS{ self.vs_version }/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" - vc_targets_path16 = self.gaming_grdk_build_path / f"VS2019/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" - vc_targets_path17 = self.gaming_grdk_build_path / f"VS2022/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" - additional_include_directories = ";".join(str(p) for p in self.gdk_include_paths) - additional_library_directories = ";".join(str(p) for p in self.gdk_library_paths) - durango_xdk_install_path = self.gdk_path / "Microsoft GDK" - with path.open("w") as f: - f.write(textwrap.dedent(f"""\ - - - - { vc_targets_path }\\ - { vc_targets_path16 }\\ - { vc_targets_path17 }\\ - { self.gaming_grdk_build_path }\\ - Gaming.Desktop.x64 - Debug - { self.gdk_edition } - { durango_xdk_install_path } - - $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ - $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ - $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ - $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ - - true - true - true - - - - { additional_include_directories };%(AdditionalIncludeDirectories) - - - { additional_library_directories };%(AdditionalLibraryDirectories) - - - - """)) - - @property - def gdk_include_paths(self) -> list[Path]: - return [ - self.gaming_grdk_build_path / "gamekit/include", - ] - - @property - def gdk_library_paths(self) -> list[Path]: - return [ - self.gaming_grdk_build_path / f"gamekit/lib/{self.arch}", - ] - - @property - def gdk_binary_path(self) -> list[Path]: - return [ - self.gaming_grdk_build_path / "bin", - self.game_dk_path / "bin", - ] - - @property - def build_env(self) -> dict[str, str]: - gdk_include = ";".join(str(p) for p in self.gdk_include_paths) - gdk_lib = ";".join(str(p) for p in self.gdk_library_paths) - gdk_path = ";".join(str(p) for p in self.gdk_binary_path) - return { - "GDK_INCLUDE": gdk_include, - "GDK_LIB": gdk_lib, - "GDK_PATH": gdk_path, - } - - def print_env(self) -> None: - for k, v in self.env.items(): - print(f"set \"{k}={v}\"") - print() - for k, v in self.build_env.items(): - print(f"set \"{k}={v}\"") - print() - print(f"set \"PATH=%GDK_PATH%;%PATH%\"") - print(f"set \"LIB=%GDK_LIB%;%LIB%\"") - print(f"set \"INCLUDE=%GDK_INCLUDE%;%INCLUDE%\"") - - -def main(): - logging.basicConfig(level=logging.INFO) - parser = argparse.ArgumentParser(allow_abbrev=False) - parser.add_argument("--arch", choices=["amd64"], default="amd64", help="Architecture") - parser.add_argument("--download", action="store_true", help="Download GDK") - parser.add_argument("--extract", action="store_true", help="Extract downloaded GDK") - parser.add_argument("--copy-msbuild", action="store_true", help="Copy MSBuild files") - parser.add_argument("--temp-folder", help="Temporary folder where to download and extract GDK") - parser.add_argument("--gdk-path", required=True, type=Path, help="Folder where to store the GDK") - parser.add_argument("--ref-edition", type=str, help="Git ref and GDK edition separated by comma") - parser.add_argument("--vs-folder", required=True, type=Path, help="Installation folder of Visual Studio") - parser.add_argument("--vs-version", required=False, type=int, help="Visual Studio version") - parser.add_argument("--vs-toolset", required=False, help="Visual Studio toolset (e.g. v150)") - parser.add_argument("--props-folder", required=False, type=Path, default=Path(), help="Visual Studio toolset (e.g. v150)") - parser.add_argument("--no-user-props", required=False, dest="user_props", action="store_false", help="Don't ") - args = parser.parse_args() - - logging.basicConfig(level=logging.INFO) - - git_ref = None - gdk_edition = None - if args.ref_edition is not None: - git_ref, gdk_edition = args.ref_edition.split(",", 1) - try: - int(gdk_edition) - except ValueError: - parser.error("Edition should be an integer (YYMMUU) (Y=year M=month U=update)") - - configurator = GdDesktopConfigurator( - arch=args.arch, - git_ref=git_ref, - gdk_edition=gdk_edition, - vs_folder=args.vs_folder, - vs_version=args.vs_version, - vs_toolset=args.vs_toolset, - gdk_path=args.gdk_path, - temp_folder=args.temp_folder, - ) - - if args.download: - configurator.download_archive() - - if args.extract: - configurator.extract_zip_archive() - - configurator.extract_development_kit() - - if args.copy_msbuild: - configurator.copy_msbuild() - - if args.user_props: - configurator.print_env() - configurator.create_user_props(args.props_folder / "Directory.Build.props") - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/contrib/SDL-3.2.8/build-scripts/showrev.sh b/contrib/SDL-3.2.8/build-scripts/showrev.sh deleted file mode 100755 index 764d3a4..0000000 --- a/contrib/SDL-3.2.8/build-scripts/showrev.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# -# Print the current source revision, if available - -SDL_ROOT=$(dirname $0)/.. -cd $SDL_ROOT - -if [ -e ./VERSION.txt ]; then - cat ./VERSION.txt - exit 0 -fi - -major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' include/SDL3/SDL_version.h) -minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' include/SDL3/SDL_version.h) -micro=$(sed -ne 's/^#define SDL_MICRO_VERSION *//p' include/SDL3/SDL_version.h) -version="${major}.${minor}.${micro}" - -if [ -x "$(command -v git)" ]; then - rev="$(git describe --tags --long 2>/dev/null)" - if [ -n "$rev" ]; then - # e.g. release-2.24.0-542-g96361fc47 - # or release-2.24.1-5-g36b987dab - # or prerelease-2.23.2-0-gcb46e1b3f - echo "$rev" - exit 0 - fi - - rev="$(git describe --always --tags --long 2>/dev/null)" - if [ -n "$rev" ]; then - # Just a truncated sha1, e.g. 96361fc47. - # Turn it into e.g. 2.25.0-g96361fc47 - echo "${version}-g${rev}" - exit 0 - fi -fi - -if [ -x "$(command -v p4)" ]; then - rev="$(p4 changes -m1 ./...\#have 2>/dev/null| awk '{print $2}')" - if [ $? = 0 ]; then - # e.g. 2.25.0-p7511446 - echo "${version}-p${rev}" - exit 0 - fi -fi - -# best we can do -echo "${version}-no-vcs" -exit 0 diff --git a/contrib/SDL-3.2.8/build-scripts/strip_fPIC.sh b/contrib/SDL-3.2.8/build-scripts/strip_fPIC.sh deleted file mode 100755 index 8719b89..0000000 --- a/contrib/SDL-3.2.8/build-scripts/strip_fPIC.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# -# libtool assumes that the compiler can handle the -fPIC flag -# This isn't always true (for example, nasm can't handle it) -command="" -while [ $# -gt 0 ]; do - case "$1" in - -?PIC) - # Ignore -fPIC and -DPIC options - ;; - -fno-common) - # Ignore -fPIC and -DPIC options - ;; - *) - command="$command $1" - ;; - esac - shift -done -echo $command -exec $command diff --git a/contrib/SDL-3.2.8/build-scripts/test-versioning.sh b/contrib/SDL-3.2.8/build-scripts/test-versioning.sh deleted file mode 100755 index 55e29a3..0000000 --- a/contrib/SDL-3.2.8/build-scripts/test-versioning.sh +++ /dev/null @@ -1,170 +0,0 @@ -#!/bin/sh -# Copyright 2022 Collabora Ltd. -# SPDX-License-Identifier: Zlib - -set -eu - -cd `dirname $0`/.. - -ref_major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' include/SDL3/SDL_version.h) -ref_minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' include/SDL3/SDL_version.h) -ref_micro=$(sed -ne 's/^#define SDL_MICRO_VERSION *//p' include/SDL3/SDL_version.h) -ref_version="${ref_major}.${ref_minor}.${ref_micro}" - -tests=0 -failed=0 - -ok () { - tests=$(( tests + 1 )) - echo "ok - $*" -} - -not_ok () { - tests=$(( tests + 1 )) - echo "not ok - $*" - failed=1 -} - -version=$(sed -Ene 's/^.* version ([0-9.]*)$/\1/p' include/SDL3/SDL.h) - -if [ "$ref_version" = "$version" ]; then - ok "SDL.h $version" -else - not_ok "SDL.h $version disagrees with SDL_version.h $ref_version" -fi - -version=$(sed -Ene 's/^project\(SDL[0-9]+ LANGUAGES C VERSION "([0-9.]*)"\)$/\1/p' CMakeLists.txt) - -if [ "$ref_version" = "$version" ]; then - ok "CMakeLists.txt $version" -else - not_ok "CMakeLists.txt $version disagrees with SDL_version.h $ref_version" -fi - -major=$(sed -ne 's/.*SDL_MAJOR_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java) -minor=$(sed -ne 's/.*SDL_MINOR_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java) -micro=$(sed -ne 's/.*SDL_MICRO_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java) -version="${major}.${minor}.${micro}" - -if [ "$ref_version" = "$version" ]; then - ok "SDLActivity.java $version" -else - not_ok "android-project/app/src/main/java/org/libsdl/app/SDLActivity.java $version disagrees with SDL_version.h $ref_version" -fi - -tuple=$(sed -ne 's/^ *FILEVERSION *//p' src/core/windows/version.rc | tr -d '\r') -ref_tuple="${ref_major},${ref_minor},${ref_micro},0" - -if [ "$ref_tuple" = "$tuple" ]; then - ok "version.rc FILEVERSION $tuple" -else - not_ok "version.rc FILEVERSION $tuple disagrees with SDL_version.h $ref_tuple" -fi - -tuple=$(sed -ne 's/^ *PRODUCTVERSION *//p' src/core/windows/version.rc | tr -d '\r') - -if [ "$ref_tuple" = "$tuple" ]; then - ok "version.rc PRODUCTVERSION $tuple" -else - not_ok "version.rc PRODUCTVERSION $tuple disagrees with SDL_version.h $ref_tuple" -fi - -tuple=$(sed -Ene 's/^ *VALUE "FileVersion", "([0-9, ]*)\\0"\r?$/\1/p' src/core/windows/version.rc | tr -d '\r') -ref_tuple="${ref_major}, ${ref_minor}, ${ref_micro}, 0" - -if [ "$ref_tuple" = "$tuple" ]; then - ok "version.rc FileVersion $tuple" -else - not_ok "version.rc FileVersion $tuple disagrees with SDL_version.h $ref_tuple" -fi - -tuple=$(sed -Ene 's/^ *VALUE "ProductVersion", "([0-9, ]*)\\0"\r?$/\1/p' src/core/windows/version.rc | tr -d '\r') - -if [ "$ref_tuple" = "$tuple" ]; then - ok "version.rc ProductVersion $tuple" -else - not_ok "version.rc ProductVersion $tuple disagrees with SDL_version.h $ref_tuple" -fi - -version=$(sed -Ene '/CFBundleShortVersionString/,+1 s/.*(.*)<\/string>.*/\1/p' Xcode/SDL/Info-Framework.plist) - -if [ "$ref_version" = "$version" ]; then - ok "Info-Framework.plist CFBundleShortVersionString $version" -else - not_ok "Info-Framework.plist CFBundleShortVersionString $version disagrees with SDL_version.h $ref_version" -fi - -version=$(sed -Ene '/CFBundleVersion/,+1 s/.*(.*)<\/string>.*/\1/p' Xcode/SDL/Info-Framework.plist) - -if [ "$ref_version" = "$version" ]; then - ok "Info-Framework.plist CFBundleVersion $version" -else - not_ok "Info-Framework.plist CFBundleVersion $version disagrees with SDL_version.h $ref_version" -fi - -version=$(sed -Ene 's/Title SDL (.*)/\1/p' Xcode/SDL/pkg-support/SDL.info) - -if [ "$ref_version" = "$version" ]; then - ok "SDL.info Title $version" -else - not_ok "SDL.info Title $version disagrees with SDL_version.h $ref_version" -fi - -marketing=$(sed -Ene 's/.*MARKETING_VERSION = (.*);/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) - -ref="$ref_version -$ref_version" - -if [ "$ref" = "$marketing" ]; then - ok "project.pbxproj MARKETING_VERSION is consistent" -else - not_ok "project.pbxproj MARKETING_VERSION is inconsistent, expected $ref, got $marketing" -fi - -# For simplicity this assumes we'll never break ABI before SDL 3. -dylib_compat=$(sed -Ene 's/.*DYLIB_COMPATIBILITY_VERSION = (.*);$/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) - -case "$ref_minor" in - (*[02468]) - major="$(( ref_minor * 100 + 1 ))" - minor="0" - ;; - (*) - major="$(( ref_minor * 100 + ref_micro + 1 ))" - minor="0" - ;; -esac - -ref="${major}.${minor}.0 -${major}.${minor}.0" - -if [ "$ref" = "$dylib_compat" ]; then - ok "project.pbxproj DYLIB_COMPATIBILITY_VERSION is consistent" -else - not_ok "project.pbxproj DYLIB_COMPATIBILITY_VERSION is inconsistent, expected $ref, got $dylib_compat" -fi - -dylib_cur=$(sed -Ene 's/.*DYLIB_CURRENT_VERSION = (.*);$/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) - -case "$ref_minor" in - (*[02468]) - major="$(( ref_minor * 100 + 1 ))" - minor="$ref_micro" - ;; - (*) - major="$(( ref_minor * 100 + ref_micro + 1 ))" - minor="0" - ;; -esac - -ref="${major}.${minor}.0 -${major}.${minor}.0" - -if [ "$ref" = "$dylib_cur" ]; then - ok "project.pbxproj DYLIB_CURRENT_VERSION is consistent" -else - not_ok "project.pbxproj DYLIB_CURRENT_VERSION is inconsistent, expected $ref, got $dylib_cur" -fi - -echo "1..$tests" -exit "$failed" diff --git a/contrib/SDL-3.2.8/build-scripts/update-copyright.sh b/contrib/SDL-3.2.8/build-scripts/update-copyright.sh deleted file mode 100755 index 9bb46ea..0000000 --- a/contrib/SDL-3.2.8/build-scripts/update-copyright.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -if [ "$SED" = "" ]; then - if type gsed >/dev/null; then - SED=gsed - else - SED=sed - fi -fi - -find . -type f \ -| grep -v \.git \ -| while read file; do \ - LC_ALL=C $SED -b -i "s/\(.*Copyright.*\)[0-9]\{4\}\( *Sam Lantinga\)/\1`date +%Y`\2/" "$file"; \ -done diff --git a/contrib/SDL-3.2.8/build-scripts/update-version.sh b/contrib/SDL-3.2.8/build-scripts/update-version.sh deleted file mode 100755 index 86ae816..0000000 --- a/contrib/SDL-3.2.8/build-scripts/update-version.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/sh - -#set -x - -cd `dirname $0`/.. - -ARGSOKAY=1 -if [ -z $1 ]; then - ARGSOKAY=0 -fi -if [ -z $2 ]; then - ARGSOKAY=0 -fi -if [ -z $3 ]; then - ARGSOKAY=0 -fi - -if [ "x$ARGSOKAY" = "x0" ]; then - echo "USAGE: $0 " 1>&2 - exit 1 -fi - -MAJOR="$1" -MINOR="$2" -MICRO="$3" -NEWVERSION="$MAJOR.$MINOR.$MICRO" - -echo "Updating version to '$NEWVERSION' ..." - -perl -w -pi -e 's/\A(.* version )[0-9.]+/${1}'$NEWVERSION'/;' include/SDL3/SDL.h - -# !!! FIXME: This first one is a kinda scary search/replace that might fail later if another X.Y.Z version is added to the file. -perl -w -pi -e 's/(\)\d+\.\d+\.\d+/${1}'$NEWVERSION'/;' Xcode/SDL/Info-Framework.plist - -perl -w -pi -e 's/(Title SDL )\d+\.\d+\.\d+/${1}'$NEWVERSION'/;' Xcode/SDL/pkg-support/SDL.info - -perl -w -pi -e 's/(MARKETING_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$NEWVERSION'/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj - -DYVER=`expr $MINOR \* 100 + 1` -perl -w -pi -e 's/(DYLIB_CURRENT_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj - -# Set compat to major.minor.0 by default. -perl -w -pi -e 's/(DYLIB_COMPATIBILITY_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj - -# non-zero patch? -if [ "x$MICRO" != "x0" ]; then - if [ `expr $MINOR % 2` = "0" ]; then - # If patch is not zero, but minor is even, it's a bugfix release. - perl -w -pi -e 's/(DYLIB_CURRENT_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.'$MICRO'.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj - - else - # If patch is not zero, but minor is odd, it's a development prerelease. - DYVER=`expr $MINOR \* 100 + $MICRO + 1` - perl -w -pi -e 's/(DYLIB_CURRENT_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj - perl -w -pi -e 's/(DYLIB_COMPATIBILITY_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj - fi -fi - -perl -w -pi -e 's/\A(project\(SDL[0-9]+ LANGUAGES C VERSION ")[0-9.]+/${1}'$NEWVERSION'/;' CMakeLists.txt - -perl -w -pi -e 's/\A(.* SDL_MAJOR_VERSION = )\d+/${1}'$MAJOR'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java -perl -w -pi -e 's/\A(.* SDL_MINOR_VERSION = )\d+/${1}'$MINOR'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java -perl -w -pi -e 's/\A(.* SDL_MICRO_VERSION = )\d+/${1}'$MICRO'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java - -perl -w -pi -e 's/(\#define SDL_MAJOR_VERSION\s+)\d+/${1}'$MAJOR'/;' include/SDL3/SDL_version.h -perl -w -pi -e 's/(\#define SDL_MINOR_VERSION\s+)\d+/${1}'$MINOR'/;' include/SDL3/SDL_version.h -perl -w -pi -e 's/(\#define SDL_MICRO_VERSION\s+)\d+/${1}'$MICRO'/;' include/SDL3/SDL_version.h - -perl -w -pi -e 's/(FILEVERSION\s+)\d+,\d+,\d+/${1}'$MAJOR','$MINOR','$MICRO'/;' src/core/windows/version.rc -perl -w -pi -e 's/(PRODUCTVERSION\s+)\d+,\d+,\d+/${1}'$MAJOR','$MINOR','$MICRO'/;' src/core/windows/version.rc -perl -w -pi -e 's/(VALUE "FileVersion", ")\d+, \d+, \d+/${1}'$MAJOR', '$MINOR', '$MICRO'/;' src/core/windows/version.rc -perl -w -pi -e 's/(VALUE "ProductVersion", ")\d+, \d+, \d+/${1}'$MAJOR', '$MINOR', '$MICRO'/;' src/core/windows/version.rc - -echo "Running build-scripts/test-versioning.sh to verify changes..." -./build-scripts/test-versioning.sh - -echo "All done." -echo "Run 'git diff' and make sure this looks correct, before 'git commit'." - -exit 0 - diff --git a/contrib/SDL-3.2.8/build-scripts/updaterev.sh b/contrib/SDL-3.2.8/build-scripts/updaterev.sh deleted file mode 100755 index 508c6dd..0000000 --- a/contrib/SDL-3.2.8/build-scripts/updaterev.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# -# Generate a header file with the current source revision - -outdir=`pwd` -cd `dirname $0` -srcdir=.. -header=$outdir/include/SDL3/SDL_revision.h -dist= -vendor= - -while [ "$#" -gt 0 ]; do - case "$1" in - (--dist) - dist=yes - shift - ;; - (--vendor) - vendor="$2" - shift 2 - ;; - (*) - echo "$0: Unknown option: $1" >&2 - exit 2 - ;; - esac -done - -rev=`sh showrev.sh 2>/dev/null` -if [ "$rev" != "" ]; then - if [ -n "$dist" ]; then - echo "$rev" > "$outdir/VERSION.txt" - fi - echo "/* Generated by updaterev.sh, do not edit */" >"$header.new" - if [ -n "$vendor" ]; then - echo "#define SDL_VENDOR_INFO \"$vendor\"" >>"$header.new" - fi - echo "#ifdef SDL_VENDOR_INFO" >>"$header.new" - echo "#define SDL_REVISION \"SDL-$rev (\" SDL_VENDOR_INFO \")\"" >>"$header.new" - echo "#else" >>"$header.new" - echo "#define SDL_REVISION \"SDL-$rev\"" >>"$header.new" - echo "#endif" >>"$header.new" - if diff $header $header.new >/dev/null 2>&1; then - rm "$header.new" - else - mv "$header.new" "$header" - fi -fi diff --git a/contrib/SDL-3.2.8/build-scripts/wikiheaders.pl b/contrib/SDL-3.2.8/build-scripts/wikiheaders.pl deleted file mode 100755 index 9859149..0000000 --- a/contrib/SDL-3.2.8/build-scripts/wikiheaders.pl +++ /dev/null @@ -1,3360 +0,0 @@ -#!/usr/bin/perl -w - -# Simple DirectMedia Layer -# Copyright (C) 1997-2025 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. - -use warnings; -use strict; -use File::Path; -use Text::Wrap; - -$Text::Wrap::huge = 'overflow'; - -my $projectfullname = 'Simple Directmedia Layer'; -my $projectshortname = 'SDL'; -my $wikisubdir = ''; -my $incsubdir = 'include'; -my $readmesubdir = undef; -my $apiprefixregex = undef; -my $versionfname = 'include/SDL_version.h'; -my $versionmajorregex = '\A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z'; -my $versionminorregex = '\A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z'; -my $versionmicroregex = '\A\#define\s+SDL_MICRO_VERSION\s+(\d+)\Z'; -my $mainincludefname = 'SDL.h'; -my $selectheaderregex = '\ASDL.*?\.h\Z'; -my $projecturl = 'https://libsdl.org/'; -my $wikiurl = 'https://wiki.libsdl.org'; -my $bugreporturl = 'https://github.com/libsdl-org/sdlwiki/issues/new'; -my $srcpath = undef; -my $wikipath = undef; -my $wikireadmesubdir = 'README'; -my $warn_about_missing = 0; -my $copy_direction = 0; -my $optionsfname = undef; -my $wikipreamble = undef; -my $wikiheaderfiletext = 'Defined in %fname%'; -my $manpageheaderfiletext = 'Defined in %fname%'; -my $manpagesymbolfilterregex = undef; -my $headercategoryeval = undef; -my $quickrefenabled = 0; -my @quickrefcategoryorder; -my $quickreftitle = undef; -my $quickrefurl = undef; -my $quickrefdesc = undef; -my $quickrefmacroregex = undef; -my $changeformat = undef; -my $manpath = undef; -my $gitrev = undef; - -foreach (@ARGV) { - $warn_about_missing = 1, next if $_ eq '--warn-about-missing'; - $copy_direction = 1, next if $_ eq '--copy-to-headers'; - $copy_direction = 1, next if $_ eq '--copy-to-header'; - $copy_direction = -1, next if $_ eq '--copy-to-wiki'; - $copy_direction = -2, next if $_ eq '--copy-to-manpages'; - $copy_direction = -3, next if $_ eq '--report-coverage-gaps'; - $copy_direction = -4, next if $_ eq '--copy-to-latex'; - if (/\A--options=(.*)\Z/) { - $optionsfname = $1; - next; - } elsif (/\A--changeformat=(.*)\Z/) { - $changeformat = $1; - next; - } elsif (/\A--manpath=(.*)\Z/) { - $manpath = $1; - next; - } elsif (/\A--rev=(.*)\Z/) { - $gitrev = $1; - next; - } - $srcpath = $_, next if not defined $srcpath; - $wikipath = $_, next if not defined $wikipath; -} - -my $default_optionsfname = '.wikiheaders-options'; -$default_optionsfname = "$srcpath/$default_optionsfname" if defined $srcpath; - -if ((not defined $optionsfname) && (-f $default_optionsfname)) { - $optionsfname = $default_optionsfname; -} - -if (defined $optionsfname) { - open OPTIONS, '<', $optionsfname or die("Failed to open options file '$optionsfname': $!\n"); - while () { - next if /\A\s*\#/; # Skip lines that start with (optional whitespace, then) '#' as comments. - - chomp; - if (/\A(.*?)\=(.*)\Z/) { - my $key = $1; - my $val = $2; - $key =~ s/\A\s+//; - $key =~ s/\s+\Z//; - $val =~ s/\A\s+//; - $val =~ s/\s+\Z//; - $warn_about_missing = int($val), next if $key eq 'warn_about_missing'; - $srcpath = $val, next if $key eq 'srcpath'; - $wikipath = $val, next if $key eq 'wikipath'; - $apiprefixregex = $val, next if $key eq 'apiprefixregex'; - $projectfullname = $val, next if $key eq 'projectfullname'; - $projectshortname = $val, next if $key eq 'projectshortname'; - $wikisubdir = $val, next if $key eq 'wikisubdir'; - $incsubdir = $val, next if $key eq 'incsubdir'; - $readmesubdir = $val, next if $key eq 'readmesubdir'; - $versionmajorregex = $val, next if $key eq 'versionmajorregex'; - $versionminorregex = $val, next if $key eq 'versionminorregex'; - $versionmicroregex = $val, next if $key eq 'versionmicroregex'; - $versionfname = $val, next if $key eq 'versionfname'; - $mainincludefname = $val, next if $key eq 'mainincludefname'; - $selectheaderregex = $val, next if $key eq 'selectheaderregex'; - $projecturl = $val, next if $key eq 'projecturl'; - $wikiurl = $val, next if $key eq 'wikiurl'; - $bugreporturl = $val, next if $key eq 'bugreporturl'; - $wikipreamble = $val, next if $key eq 'wikipreamble'; - $wikiheaderfiletext = $val, next if $key eq 'wikiheaderfiletext'; - $manpageheaderfiletext = $val, next if $key eq 'manpageheaderfiletext'; - $manpagesymbolfilterregex = $val, next if $key eq 'manpagesymbolfilterregex'; - $headercategoryeval = $val, next if $key eq 'headercategoryeval'; - $quickrefenabled = int($val), next if $key eq 'quickrefenabled'; - @quickrefcategoryorder = split(/,/, $val), next if $key eq 'quickrefcategoryorder'; - $quickreftitle = $val, next if $key eq 'quickreftitle'; - $quickrefurl = $val, next if $key eq 'quickrefurl'; - $quickrefdesc = $val, next if $key eq 'quickrefdesc'; - $quickrefmacroregex = $val, next if $key eq 'quickrefmacroregex'; - } - } - close(OPTIONS); -} - -sub escLaTeX { - my $str = shift; - $str =~ s/([_\#\&\^])/\\$1/g; - return $str; -} - -my $wordwrap_mode = 'mediawiki'; -sub wordwrap_atom { # don't call this directly. - my $str = shift; - my $retval = ''; - - # wordwrap but leave links intact, even if they overflow. - if ($wordwrap_mode eq 'mediawiki') { - while ($str =~ s/(.*?)\s*(\[https?\:\/\/.*?\s+.*?\])\s*//ms) { - $retval .= fill('', '', $1); # wrap it. - $retval .= "\n$2\n"; # don't wrap it. - } - } elsif ($wordwrap_mode eq 'md') { - while ($str =~ s/(.*?)\s*(\[.*?\]\(https?\:\/\/.*?\))\s*//ms) { - $retval .= fill('', '', $1); # wrap it. - $retval .= "\n$2\n"; # don't wrap it. - } - } - - return $retval . fill('', '', $str); -} - -sub wordwrap_with_bullet_indent { # don't call this directly. - my $bullet = shift; - my $str = shift; - my $retval = ''; - - #print("WORDWRAP BULLET ('$bullet'):\n\n$str\n\n"); - - # You _can't_ (at least with Pandoc) have a bullet item with a newline in - # MediaWiki, so _remove_ wrapping! - if ($wordwrap_mode eq 'mediawiki') { - $retval = "$bullet$str"; - $retval =~ s/\n/ /gms; - $retval =~ s/\s+$//gms; - #print("WORDWRAP BULLET DONE:\n\n$retval\n\n"); - return "$retval\n"; - } - - my $bulletlen = length($bullet); - - # wrap it and then indent each line to be under the bullet. - $Text::Wrap::columns -= $bulletlen; - my @wrappedlines = split /\n/, wordwrap_atom($str); - $Text::Wrap::columns += $bulletlen; - - my $prefix = $bullet; - my $usual_prefix = ' ' x $bulletlen; - - foreach (@wrappedlines) { - s/\s*\Z//; - $retval .= "$prefix$_\n"; - $prefix = $usual_prefix; - } - - return $retval; -} - -sub wordwrap_one_paragraph { # don't call this directly. - my $retval = ''; - my $p = shift; - #print "\n\n\nPARAGRAPH: [$p]\n\n\n"; - if ($p =~ s/\A([\*\-] )//) { # bullet list, starts with "* " or "- ". - my $bullet = $1; - my $item = ''; - my @items = split /\n/, $p; - foreach (@items) { - if (s/\A([\*\-] )//) { - $retval .= wordwrap_with_bullet_indent($bullet, $item); - $item = ''; - } - s/\A\s*//; - $item .= "$_\n"; # accumulate lines until we hit the end or another bullet. - } - if ($item ne '') { - $retval .= wordwrap_with_bullet_indent($bullet, $item); - } - } elsif ($p =~ /\A\s*\|.*\|\s*\n/) { # Markdown table - $retval = "$p\n"; # don't wrap it (!!! FIXME: but maybe parse by lines until we run out of table...) - } else { - $retval = wordwrap_atom($p) . "\n"; - } - - return $retval; -} - -sub wordwrap_paragraphs { # don't call this directly. - my $str = shift; - my $retval = ''; - my @paragraphs = split /\n\n/, $str; - foreach (@paragraphs) { - next if $_ eq ''; - $retval .= wordwrap_one_paragraph($_); - $retval .= "\n"; - } - return $retval; -} - -my $wordwrap_default_columns = 76; -sub wordwrap { - my $str = shift; - my $columns = shift; - - $columns = $wordwrap_default_columns if not defined $columns; - $columns += $wordwrap_default_columns if $columns < 0; - $Text::Wrap::columns = $columns; - - my $retval = ''; - - #print("\n\nWORDWRAP:\n\n$str\n\n\n"); - - $str =~ s/\A\n+//ms; - - while ($str =~ s/(.*?)(\`\`\`.*?\`\`\`|\)//ms) { - #print("\n\nWORDWRAP BLOCK:\n\n$1\n\n ===\n\n$2\n\n\n"); - $retval .= wordwrap_paragraphs($1); # wrap it. - $retval .= "$2\n\n"; # don't wrap it. - } - - $retval .= wordwrap_paragraphs($str); # wrap what's left. - $retval =~ s/\n+\Z//ms; - - #print("\n\nWORDWRAP DONE:\n\n$retval\n\n\n"); - return $retval; -} - -# This assumes you're moving from Markdown (in the Doxygen data) to Wiki, which -# is why the 'md' section is so sparse. -sub wikify_chunk { - my $wikitype = shift; - my $str = shift; - my $codelang = shift; - my $code = shift; - - #print("\n\nWIKIFY CHUNK:\n\n$str\n\n\n"); - - if ($wikitype eq 'mediawiki') { - # convert `code` things first, so they aren't mistaken for other markdown items. - my $codedstr = ''; - while ($str =~ s/\A(.*?)\`(.*?)\`//ms) { - my $codeblock = $2; - $codedstr .= wikify_chunk($wikitype, $1, undef, undef); - if (defined $apiprefixregex) { - # Convert obvious API things to wikilinks, even inside `code` blocks. - $codeblock =~ s/(\A|[^\/a-zA-Z0-9_])($apiprefixregex[a-zA-Z0-9_]+)/$1\[\[$2\]\]/gms; - } - $codedstr .= "$codeblock"; - } - - # Convert obvious API things to wikilinks. - if (defined $apiprefixregex) { - $str =~ s/(\A|[^\/a-zA-Z0-9_])($apiprefixregex[a-zA-Z0-9_]+)/$1\[\[$2\]\]/gms; - } - - # Make some Markdown things into MediaWiki... - - # links - $str =~ s/\[(.*?)\]\((https?\:\/\/.*?)\)/\[$2 $1\]/g; - - # bold+italic - $str =~ s/\*\*\*(.*?)\*\*\*/'''''$1'''''/gms; - - # bold - $str =~ s/\*\*(.*?)\*\*/'''$1'''/gms; - - # italic - $str =~ s/\*(.*?)\*/''$1''/gms; - - # bullets - $str =~ s/^\- /* /gm; - - $str = $codedstr . $str; - - if (defined $code) { - $str .= "$code<\/syntaxhighlight>"; - } - } elsif ($wikitype eq 'md') { - # convert `code` things first, so they aren't mistaken for other markdown items. - my $codedstr = ''; - while ($str =~ s/\A(.*?)(\`.*?\`)//ms) { - my $codeblock = $2; - $codedstr .= wikify_chunk($wikitype, $1, undef, undef); - if (defined $apiprefixregex) { - # Convert obvious API things to wikilinks, even inside `code` blocks, - # BUT ONLY IF the entire code block is the API thing, - # So something like "just call `SDL_Whatever`" will become - # "just call [`SDL_Whatever`](SDL_Whatever)", but - # "just call `SDL_Whatever(7)`" will not. It's just the safest - # way to do this without resorting to wrapping things in html tags. - $codeblock =~ s/\A\`($apiprefixregex[a-zA-Z0-9_]+)\`\Z/[`$1`]($1)/gms; - } - $codedstr .= $codeblock; - } - - # Convert obvious API things to wikilinks. - if (defined $apiprefixregex) { - $str =~ s/(\A|[^\/a-zA-Z0-9_])($apiprefixregex[a-zA-Z0-9_]+)/$1\[$2\]\($2\)/gms; - } - - $str = $codedstr . $str; - - if (defined $code) { - $str .= "```$codelang\n$code\n```\n"; - } - } - - #print("\n\nWIKIFY CHUNK DONE:\n\n$str\n\n\n"); - - return $str; -} - -sub wikify { - my $wikitype = shift; - my $str = shift; - my $retval = ''; - - #print("WIKIFY WHOLE:\n\n$str\n\n\n"); - - while ($str =~ s/\A(.*?)\`\`\`(.*?)\n(.*?)\n\`\`\`(\n|\Z)//ms) { - $retval .= wikify_chunk($wikitype, $1, $2, $3); - } - $retval .= wikify_chunk($wikitype, $str, undef, undef); - - #print("WIKIFY WHOLE DONE:\n\n$retval\n\n\n"); - - return $retval; -} - - -my $dewikify_mode = 'md'; -my $dewikify_manpage_code_indent = 1; - -sub dewikify_chunk { - my $wikitype = shift; - my $str = shift; - my $codelang = shift; - my $code = shift; - - #print("\n\nDEWIKIFY CHUNK:\n\n$str\n\n\n"); - - if ($dewikify_mode eq 'md') { - if ($wikitype eq 'mediawiki') { - # Doxygen supports Markdown (and it just simply looks better than MediaWiki - # when looking at the raw headers), so do some conversions here as necessary. - - # Dump obvious wikilinks. - if (defined $apiprefixregex) { - $str =~ s/\[\[($apiprefixregex[a-zA-Z0-9_]+)\]\]/$1/gms; - } - - # links - $str =~ s/\[(https?\:\/\/.*?)\s+(.*?)\]/\[$2\]\($1\)/g; - - # is also popular. :/ - $str =~ s/\(.*?)<\/code>/`$1`/gms; - - # bold+italic - $str =~ s/'''''(.*?)'''''/***$1***/gms; - - # bold - $str =~ s/'''(.*?)'''/**$1**/gms; - - # italic - $str =~ s/''(.*?)''/*$1*/gms; - - # bullets - $str =~ s/^\* /- /gm; - } elsif ($wikitype eq 'md') { - # Dump obvious wikilinks. The rest can just passthrough. - if (defined $apiprefixregex) { - $str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/$1/gms; - } - } - - if (defined $code) { - $str .= "\n```$codelang\n$code\n```\n"; - } - } elsif ($dewikify_mode eq 'manpage') { - $str =~ s/\./\\[char46]/gms; # make sure these can't become control codes. - if ($wikitype eq 'mediawiki') { - # Dump obvious wikilinks. - if (defined $apiprefixregex) { - $str =~ s/\s*\[\[($apiprefixregex[a-zA-Z0-9_]+)\]\]\s*/\n.BR $1\n/gms; - } - - # links - $str =~ s/\[(https?\:\/\/.*?)\s+(.*?)\]/\n.URL "$1" "$2"\n/g; - - # is also popular. :/ - $str =~ s/\s*\(.*?)<\/code>\s*/\n.BR $1\n/gms; - - # bold+italic (this looks bad, just make it bold). - $str =~ s/\s*'''''(.*?)'''''\s*/\n.B $1\n/gms; - - # bold - $str =~ s/\s*'''(.*?)'''\s*/\n.B $1\n/gms; - - # italic - $str =~ s/\s*''(.*?)''\s*/\n.I $1\n/gms; - - # bullets - $str =~ s/^\* /\n\\\(bu /gm; - } elsif ($wikitype eq 'md') { - # Dump obvious wikilinks. - if (defined $apiprefixregex) { - $str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/\n.BR $1\n/gms; - } - - # links - $str =~ s/\[(.*?)]\((https?\:\/\/.*?)\)/\n.URL "$2" "$1"\n/g; - - # is also popular. :/ - $str =~ s/\s*\`(.*?)\`\s*/\n.BR $1\n/gms; - - # bold+italic (this looks bad, just make it bold). - $str =~ s/\s*\*\*\*(.*?)\*\*\*\s*/\n.B $1\n/gms; - - # bold - $str =~ s/\s*\*\*(.*?)\*\*\s*/\n.B $1\n/gms; - - # italic - $str =~ s/\s*\*(.*?)\*\s*/\n.I $1\n/gms; - - # bullets - $str =~ s/^\- /\n\\\(bu /gm; - } - - if (defined $code) { - $code =~ s/\A\n+//gms; - $code =~ s/\n+\Z//gms; - if ($dewikify_manpage_code_indent) { - $str .= "\n.IP\n" - } else { - $str .= "\n.PP\n" - } - $str .= ".EX\n$code\n.EE\n.PP\n"; - } - } elsif ($dewikify_mode eq 'LaTeX') { - if ($wikitype eq 'mediawiki') { - # Dump obvious wikilinks. - if (defined $apiprefixregex) { - $str =~ s/\s*\[\[($apiprefixregex[a-zA-Z0-9_]+)\]\]/$1/gms; - } - - # links - $str =~ s/\[(https?\:\/\/.*?)\s+(.*?)\]/\\href{$1}{$2}/g; - - # is also popular. :/ - $str =~ s/\s*\(.*?)<\/code>/ \\texttt{$1}/gms; - - # bold+italic - $str =~ s/\s*'''''(.*?)'''''/ \\textbf{\\textit{$1}}/gms; - - # bold - $str =~ s/\s*'''(.*?)'''/ \\textbf{$1}/gms; - - # italic - $str =~ s/\s*''(.*?)''/ \\textit{$1}/gms; - - # bullets - $str =~ s/^\*\s+/ \\item /gm; - } elsif ($wikitype eq 'md') { - # Dump obvious wikilinks. - if (defined $apiprefixregex) { - $str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/$1/gms; - } - - # links - $str =~ s/\[(.*?)]\((https?\:\/\/.*?)\)/\\href{$2}{$1}/g; - - # is also popular. :/ - $str =~ s/\s*\`(.*?)\`/ \\texttt{$1}/gms; - - # bold+italic - $str =~ s/\s*\*\*\*(.*?)\*\*\*/ \\textbf{\\textit{$1}}/gms; - - # bold - $str =~ s/\s*\*\*(.*?)\*\*/ \\textbf{$1}/gms; - - # italic - $str =~ s/\s*\*(.*?)\*/ \\textit{$1}/gms; - - # bullets - $str =~ s/^\-\s+/ \\item /gm; - } - - # Wrap bullet lists in itemize blocks... - $str =~ s/^(\s*\\item .*?)(\n\n|\Z)/\n\\begin{itemize}\n$1$2\n\\end{itemize}\n\n/gms; - - $str = escLaTeX($str); - - if (defined $code) { - $code =~ s/\A\n+//gms; - $code =~ s/\n+\Z//gms; - - if (($codelang eq '') || ($codelang eq 'output')) { - $str .= "\\begin{verbatim}\n$code\n\\end{verbatim}\n"; - } else { - if ($codelang eq 'c') { - $codelang = 'C'; - } elsif ($codelang eq 'c++') { - $codelang = 'C++'; - } else { - die("Unexpected codelang '$codelang'"); - } - $str .= "\n\\lstset{language=$codelang}\n"; - $str .= "\\begin{lstlisting}\n$code\n\\end{lstlisting}\n"; - } - } - } else { - die("Unexpected dewikify_mode"); - } - - #print("\n\nDEWIKIFY CHUNK DONE:\n\n$str\n\n\n"); - - return $str; -} - -sub dewikify { - my $wikitype = shift; - my $str = shift; - return '' if not defined $str; - - #print("DEWIKIFY WHOLE:\n\n$str\n\n\n"); - - $str =~ s/\A[\s\n]*\= .*? \=\s*?\n+//ms; - $str =~ s/\A[\s\n]*\=\= .*? \=\=\s*?\n+//ms; - - my $retval = ''; - if ($wikitype eq 'mediawiki') { - while ($str =~ s/\A(.*?)(.*?)<\/syntaxhighlight\>//ms) { - $retval .= dewikify_chunk($wikitype, $1, $2, $3); - } - } elsif ($wikitype eq 'md') { - while ($str =~ s/\A(.*?)\n```(.*?)\n(.*?)\n```\n//ms) { - $retval .= dewikify_chunk($wikitype, $1, $2, $3); - } - } - $retval .= dewikify_chunk($wikitype, $str, undef, undef); - - #print("DEWIKIFY WHOLE DONE:\n\n$retval\n\n\n"); - - return $retval; -} - -sub filecopy { - my $src = shift; - my $dst = shift; - my $endline = shift; - $endline = "\n" if not defined $endline; - - open(COPYIN, '<', $src) or die("Failed to open '$src' for reading: $!\n"); - open(COPYOUT, '>', $dst) or die("Failed to open '$dst' for writing: $!\n"); - while () { - chomp; - s/[ \t\r\n]*\Z//; - print COPYOUT "$_$endline"; - } - close(COPYOUT); - close(COPYIN); -} - -sub usage { - die("USAGE: $0 [--copy-to-headers|--copy-to-wiki|--copy-to-manpages] [--warn-about-missing] [--manpath=]\n\n"); -} - -usage() if not defined $srcpath; -usage() if not defined $wikipath; -#usage() if $copy_direction == 0; - -if (not defined $manpath) { - $manpath = "$srcpath/man"; -} - -my @standard_wiki_sections = ( - 'Draft', - '[Brief]', - 'Deprecated', - 'Header File', - 'Syntax', - 'Function Parameters', - 'Macro Parameters', - 'Fields', - 'Values', - 'Return Value', - 'Remarks', - 'Thread Safety', - 'Version', - 'Code Examples', - 'See Also' -); - -# Sections that only ever exist in the wiki and shouldn't be deleted when -# not found in the headers. -my %only_wiki_sections = ( # The ones don't mean anything, I just need to check for key existence. - 'Draft', 1, - 'Code Examples', 1, - 'Header File', 1 -); - - -my %headers = (); # $headers{"SDL_audio.h"} -> reference to an array of all lines of text in SDL_audio.h. -my %headersyms = (); # $headersyms{"SDL_OpenAudio"} -> string of header documentation for SDL_OpenAudio, with comment '*' bits stripped from the start. Newlines embedded! -my %headerdecls = (); -my %headersymslocation = (); # $headersymslocation{"SDL_OpenAudio"} -> name of header holding SDL_OpenAudio define ("SDL_audio.h" in this case). -my %headersymschunk = (); # $headersymschunk{"SDL_OpenAudio"} -> offset in array in %headers that should be replaced for this symbol. -my %headersymshasdoxygen = (); # $headersymshasdoxygen{"SDL_OpenAudio"} -> 1 if there was no existing doxygen for this function. -my %headersymstype = (); # $headersymstype{"SDL_OpenAudio"} -> 1 (function), 2 (macro), 3 (struct), 4 (enum), 5 (other typedef) -my %headersymscategory = (); # $headersymscategory{"SDL_OpenAudio"} -> 'Audio' ... this is set with a `/* WIKI CATEGEORY: Audio */` comment in the headers that sets it on all symbols until a new comment changes it. So usually, once at the top of the header file. -my %headercategorydocs = (); # $headercategorydocs{"Audio"} -> (fake) symbol for this category's documentation. Undefined if not documented. -my %headersymsparaminfo = (); # $headersymsparaminfo{"SDL_OpenAudio"} -> reference to array of parameters, pushed by name, then C type string, repeating. Undef'd if void params, or not a function. -my %headersymsrettype = (); # $headersymsrettype{"SDL_OpenAudio"} -> string of C datatype of return value. Undef'd if not a function. -my %wikitypes = (); # contains string of wiki page extension, like $wikitypes{"SDL_OpenAudio"} == 'mediawiki' -my %wikisyms = (); # contains references to hash of strings, each string being the full contents of a section of a wiki page, like $wikisyms{"SDL_OpenAudio"}{"Remarks"}. -my %wikisectionorder = (); # contains references to array, each array item being a key to a wikipage section in the correct order, like $wikisectionorder{"SDL_OpenAudio"}[2] == 'Remarks' -my %quickreffuncorder = (); # contains references to array, each array item being a key to a category with functions in the order they appear in the headers, like $quickreffuncorder{"Audio"}[0] == 'SDL_GetNumAudioDrivers' - -my %referenceonly = (); # $referenceonly{"Y"} -> symbol name that this symbol is bound to. This makes wiki pages that say "See X" where "X" is a typedef and "Y" is a define attached to it. These pages are generated in the wiki only and do not bridge to the headers or manpages. - -my @coverage_gap = (); # array of strings that weren't part of documentation, or blank, or basic preprocessor logic. Lets you see what this script is missing! - -sub add_coverage_gap { - if ($copy_direction == -3) { # --report-coverage-gaps - my $text = shift; - my $dent = shift; - my $lineno = shift; - return if $text =~ /\A\s*\Z/; # skip blank lines - return if $text =~ /\A\s*\#\s*(if|el|endif|include)/; # skip preprocessor floof. - push @coverage_gap, "$dent:$lineno: $text"; - } -} - -sub print_undocumented_section { - my $fh = shift; - my $typestr = shift; - my $typeval = shift; - - print $fh "## $typestr defined in the headers, but not in the wiki\n\n"; - my $header_only_sym = 0; - foreach (sort keys %headersyms) { - my $sym = $_; - if ((not defined $wikisyms{$sym}) && ($headersymstype{$sym} == $typeval)) { - print $fh "- [$sym]($sym)\n"; - $header_only_sym = 1; - } - } - if (!$header_only_sym) { - print $fh "(none)\n"; - } - print $fh "\n"; - - if (0) { # !!! FIXME: this lists things that _shouldn't_ be in the headers, like MigrationGuide, etc, but also we don't know if they're functions, macros, etc at this point (can we parse that from the wiki page, though?) - print $fh "## $typestr defined in the wiki, but not in the headers\n\n"; - - my $wiki_only_sym = 0; - foreach (sort keys %wikisyms) { - my $sym = $_; - if ((not defined $headersyms{$sym}) && ($headersymstype{$sym} == $typeval)) { - print $fh "- [$sym]($sym)\n"; - $wiki_only_sym = 1; - } - } - if (!$wiki_only_sym) { - print $fh "(none)\n"; - } - print $fh "\n"; - } -} - -sub strip_fn_declaration_metadata { - my $decl = shift; - $decl =~ s/SDL_(PRINTF|SCANF)_FORMAT_STRING\s*//; # don't want this metadata as part of the documentation. - $decl =~ s/SDL_ALLOC_SIZE2?\(.*?\)\s*//; # don't want this metadata as part of the documentation. - $decl =~ s/SDL_MALLOC\s*//; # don't want this metadata as part of the documentation. - $decl =~ s/SDL_(IN|OUT|INOUT)_.*?CAP\s*\(.*?\)\s*//g; # don't want this metadata as part of the documentation. - $decl =~ s/\)(\s*SDL_[a-zA-Z_]+(\(.*?\)|))*;/);/; # don't want this metadata as part of the documentation. - return $decl; -} - -sub sanitize_c_typename { - my $str = shift; - $str =~ s/\A\s+//; - $str =~ s/\s+\Z//; - $str =~ s/const\s*(\*+)/const $1/g; # one space between `const` and pointer stars: `char const* const *` becomes `char const * const *`. - $str =~ s/\*\s+\*/**/g; # drop spaces between pointers: `void * *` becomes `void **`. - $str =~ s/\s*(\*+)\Z/ $1/; # one space between pointer stars and what it points to: `void**` becomes `void **`. - return $str; -} - -my %big_ascii = ( - 'A' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - 'B' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'C' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - 'D' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'E' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{255D}\x{20}\x{20}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - 'F' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{255D}\x{20}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{20}\x{20}\x{20}" ], - 'G' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'H' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - 'I' => [ "\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}" ], - 'J' => [ "\x{20}\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'K' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - 'L' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - 'M' => [ "\x{2588}\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2554}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{255A}\x{2588}\x{2588}\x{2554}\x{255D}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{255A}\x{2550}\x{255D}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{20}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - 'N' => [ "\x{2588}\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2554}\x{2588}\x{2588}\x{2557}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{255A}\x{2588}\x{2588}\x{2557}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{255D}" ], - 'O' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'P' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{20}\x{20}\x{20}" ], - 'Q' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{2584}\x{2584}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2580}\x{2580}\x{2550}\x{255D}\x{20}" ], - 'R' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - 'S' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'T' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{255D}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{20}" ], - 'U' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'V' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2557}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{20}\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}\x{20}" ], - 'W' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{20}\x{2588}\x{2557}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}\x{2588}\x{2588}\x{2588}\x{2557}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2554}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{255D}\x{255A}\x{2550}\x{2550}\x{255D}\x{20}" ], - 'X' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2588}\x{2588}\x{2557}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{20}\x{2588}\x{2588}\x{2554}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{255D}\x{20}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - 'Y' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2588}\x{2588}\x{2557}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{20}\x{20}\x{255A}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{20}" ], - 'Z' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{20}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{20}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}\x{20}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - ' ' => [ "\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}" ], - '.' => [ "\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{255D}" ], - ',' => [ "\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}", "\x{2584}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{255D}" ], - '/' => [ "\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{20}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}\x{20}", "\x{2588}\x{2588}\x{2554}\x{255D}\x{20}\x{20}\x{20}", "\x{255A}\x{2550}\x{255D}\x{20}\x{20}\x{20}\x{20}" ], - '!' => [ "\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{255D}", "\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{255D}" ], - '_' => [ "\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}\x{20}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - '0' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{2588}\x{2588}\x{2554}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - '1' => [ "\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2588}\x{2588}\x{2551}", "\x{20}\x{2588}\x{2588}\x{2551}", "\x{20}\x{2588}\x{2588}\x{2551}", "\x{20}\x{255A}\x{2550}\x{255D}" ], - '2' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - '3' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - '4' => [ "\x{2588}\x{2588}\x{2557}\x{20}\x{20}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2551}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}", "\x{20}\x{20}\x{20}\x{20}\x{20}\x{255A}\x{2550}\x{255D}" ], - '5' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}" ], - '6' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}", "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - '7' => [ "\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{20}\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2554}\x{255D}\x{20}", "\x{20}\x{20}\x{20}\x{2588}\x{2588}\x{2551}\x{20}\x{20}", "\x{20}\x{20}\x{20}\x{255A}\x{2550}\x{255D}\x{20}\x{20}" ], - '8' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], - '9' => [ "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2557}\x{20}", "\x{2588}\x{2588}\x{2554}\x{2550}\x{2550}\x{2588}\x{2588}\x{2557}", "\x{255A}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2551}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2588}\x{2588}\x{2551}", "\x{20}\x{2588}\x{2588}\x{2588}\x{2588}\x{2588}\x{2554}\x{255D}", "\x{20}\x{255A}\x{2550}\x{2550}\x{2550}\x{2550}\x{255D}\x{20}" ], -); - -sub print_big_ascii_string { - my $fh = shift; - my $str = shift; - my $comment = shift; - my $lowascii = shift; - $comment = '' if not defined $comment; - $lowascii = 0 if not defined $lowascii; - - my @chars = split //, $str; - my $charcount = scalar(@chars); - - binmode($fh, ":utf8"); - - my $maxrows = $lowascii ? 5 : 6; - - for(my $rownum = 0; $rownum < $maxrows; $rownum++){ - print $fh $comment; - my $charidx = 0; - foreach my $ch (@chars) { - my $rowsref = $big_ascii{uc($ch)}; - die("Don't have a big ascii entry for '$ch'!\n") if not defined $rowsref; - my $row = @$rowsref[$rownum]; - - if ($lowascii) { - my @x = split //, $row; - foreach (@x) { - my $v = ($_ eq "\x{2588}") ? 'X' : ' '; - print $fh $v; - } - } else { - print $fh $row; - } - - $charidx++; - - if ($charidx < $charcount) { - print $fh " "; - } - } - print $fh "\n"; - } -} - -sub generate_quickref { - my $briefsref = shift; - my $path = shift; - my $lowascii = shift; - - # !!! FIXME: this gitrev and majorver/etc stuff is copy/pasted a few times now. - if (!$gitrev) { - $gitrev = `cd "$srcpath" ; git rev-list HEAD~..`; - chomp($gitrev); - } - - # !!! FIXME - open(FH, '<', "$srcpath/$versionfname") or die("Can't open '$srcpath/$versionfname': $!\n"); - my $majorver = 0; - my $minorver = 0; - my $microver = 0; - while () { - chomp; - if (/$versionmajorregex/) { - $majorver = int($1); - } elsif (/$versionminorregex/) { - $minorver = int($1); - } elsif (/$versionmicroregex/) { - $microver = int($1); - } - } - close(FH); - my $fullversion = "$majorver.$minorver.$microver"; - - my $tmppath = "$path.tmp"; - open(my $fh, '>', $tmppath) or die("Can't open '$tmppath': $!\n"); - - if (not @quickrefcategoryorder) { - @quickrefcategoryorder = sort keys %headercategorydocs; - } - - #my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time); - #my $datestr = sprintf("%04d-%02d-%02d %02d:%02d:%02d GMT", $year+1900, $mon+1, $mday, $hour, $min, $sec); - - print $fh "\n\n"; - - # Just something to test big_ascii output. - #print_big_ascii_string($fh, "ABCDEFGHIJ", '', $lowascii); - #print_big_ascii_string($fh, "KLMNOPQRST", '', $lowascii); - #print_big_ascii_string($fh, "UVWXYZ0123", '', $lowascii); - #print_big_ascii_string($fh, "456789JT3A", '', $lowascii); - #print_big_ascii_string($fh, "hello, _a.b/c_!!", '', $lowascii); - - # Dan Bechard's work was on an SDL2 cheatsheet: - # https://blog.theprogrammingjunkie.com/post/sdl2-cheatsheet/ - - if ($lowascii) { - print $fh "# QuickReferenceNoUnicode\n\n"; - print $fh "If you want to paste this into a text editor that can handle\n"; - print $fh "fancy Unicode section headers, try using\n"; - print $fh "[QuickReference](QuickReference) instead.\n\n"; - } else { - print $fh "# QuickReference\n\n"; - print $fh "If you want to paste this into a text editor that can't handle\n"; - print $fh "the fancy Unicode section headers, try using\n"; - print $fh "[QuickReferenceNoUnicode](QuickReferenceNoUnicode) instead.\n\n"; - } - - print $fh "```c\n"; - print $fh "// $quickreftitle\n" if defined $quickreftitle; - print $fh "//\n"; - print $fh "// $quickrefurl\n//\n" if defined $quickrefurl; - print $fh "// $quickrefdesc\n" if defined $quickrefdesc; - #print $fh "// When this document was written: $datestr\n"; - print $fh "// Based on $projectshortname version $fullversion\n"; - #print $fh "// git revision $gitrev\n"; - print $fh "//\n"; - print $fh "// This can be useful in an IDE with search and syntax highlighting.\n"; - print $fh "//\n"; - print $fh "// Original idea for this document came from Dan Bechard (thanks!)\n"; - print $fh "// ASCII art generated by: https://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow (with modified 'S' for readability)\n\n"; - - foreach (@quickrefcategoryorder) { - my $cat = $_; - my $maxlen = 0; - my @csigs = (); - my $funcorderref = $quickreffuncorder{$cat}; - next if not defined $funcorderref; - - foreach (@$funcorderref) { - my $sym = $_; - my $csig = ''; - - if ($headersymstype{$sym} == 1) { # function - $csig = "${headersymsrettype{$sym}} $sym"; - my $fnsigparams = $headersymsparaminfo{$sym}; - if (not defined($fnsigparams)) { - $csig .= '(void);'; - } else { - my $sep = '('; - for (my $i = 0; $i < scalar(@$fnsigparams); $i += 2) { - my $paramname = @$fnsigparams[$i]; - my $paramtype = @$fnsigparams[$i+1]; - my $spc = ($paramtype =~ /\*\Z/) ? '' : ' '; - $csig .= "$sep$paramtype$spc$paramname"; - $sep = ', '; - } - $csig .= ");"; - } - } elsif ($headersymstype{$sym} == 2) { # macro - next if defined $quickrefmacroregex && not $sym =~ /$quickrefmacroregex/; - - $csig = (split /\n/, $headerdecls{$sym})[0]; # get the first line from a multiline string. - if (not $csig =~ s/\A(\#define [a-zA-Z0-9_]*\(.*?\))(\s+.*)?\Z/$1/) { - $csig =~ s/\A(\#define [a-zA-Z0-9_]*)(\s+.*)?\Z/$1/; - } - chomp($csig); - } - - my $len = length($csig); - $maxlen = $len if $len > $maxlen; - - push @csigs, $sym; - push @csigs, $csig; - } - - $maxlen += 2; - - next if (not @csigs); - - print $fh "\n"; - print_big_ascii_string($fh, $cat, '// ', $lowascii); - print $fh "\n"; - - while (@csigs) { - my $sym = shift @csigs; - my $csig = shift @csigs; - my $brief = $$briefsref{$sym}; - if (defined $brief) { - $brief = "$brief"; - chomp($brief); - my $thiswikitype = defined $wikitypes{$sym} ? $wikitypes{$sym} : 'md'; # default to MarkDown for new stuff. - $brief = dewikify($thiswikitype, $brief); - my $spaces = ' ' x ($maxlen - length($csig)); - $brief = "$spaces// $brief"; - } else { - $brief = ''; - } - print $fh "$csig$brief\n"; - } - } - - print $fh "```\n\n"; - - close($fh); - -# # Don't overwrite the file if nothing has changed besides the timestamp -# # and git revision. -# my $matches = 1; -# if ( not -f $path ) { -# $matches = 0; # always write if the file hasn't been created yet. -# } else { -# open(my $fh_a, '<', $tmppath) or die("Can't open '$tmppath': $!\n"); -# open(my $fh_b, '<', $path) or die("Can't open '$path': $!\n"); -# while (1) { -# my $a = <$fh_a>; -# my $b = <$fh_b>; -# $matches = 0, last if ((not defined $a) != (not defined $b)); -# last if ((not defined $a) || (not defined $b)); -# if ($a ne $b) { -# next if ($a =~ /\A\/\/ When this document was written:/); -# next if ($a =~ /\A\/\/ git revision /); -# $matches = 0; -# last; -# } -# } -# -# close($fh_a); -# close($fh_b); -# } -# -# if ($matches) { -# unlink($tmppath); # it's the same file except maybe the date/gitrev. Don't overwrite it. -# } else { -# rename($tmppath, $path) or die("Can't rename '$tmppath' to '$path': $!\n"); -# } - rename($tmppath, $path) or die("Can't rename '$tmppath' to '$path': $!\n"); -} - - -my $incpath = "$srcpath"; -$incpath .= "/$incsubdir" if $incsubdir ne ''; - -my $wikireadmepath = "$wikipath/$wikireadmesubdir"; -my $readmepath = undef; -if (defined $readmesubdir) { - $readmepath = "$srcpath/$readmesubdir"; -} - -opendir(DH, $incpath) or die("Can't opendir '$incpath': $!\n"); -while (my $d = readdir(DH)) { - my $dent = $d; - next if not $dent =~ /$selectheaderregex/; # just selected headers. - open(FH, '<', "$incpath/$dent") or die("Can't open '$incpath/$dent': $!\n"); - - # You can optionally set a wiki category with Perl code in .wikiheaders-options that gets eval()'d per-header, - # and also if you put `/* WIKI CATEGORY: blah */` on a line by itself, it'll change the category for any symbols - # below it in the same file. If no category is set, one won't be added for the symbol (beyond the standard CategoryFunction, etc) - my $current_wiki_category = undef; - if (defined $headercategoryeval) { - $_ = $dent; - $current_wiki_category = eval($headercategoryeval); - if (($current_wiki_category eq '') || ($current_wiki_category eq '-')) { - $current_wiki_category = undef; - } - #print("CATEGORY FOR '$dent' IS " . (defined($current_wiki_category) ? "'$current_wiki_category'" : '(undef)') . "\n"); - } - - my @contents = (); - my @function_order = (); - my $ignoring_lines = 0; - my $header_comment = -1; - my $saw_category_doxygen = -1; - my $lineno = 0; - - while () { - chomp; - $lineno++; - my $symtype = 0; # nothing, yet. - my $decl; - my @templines; - my $str; - my $has_doxygen = 1; - - # Since a lot of macros are just preprocessor logic spam and not all macros are worth documenting anyhow, we only pay attention to them when they have a Doxygen comment attached. - # Functions and other things are a different story, though! - - if ($header_comment == -1) { - $header_comment = /\A\/\*\s*\Z/ ? 1 : 0; - } elsif (($header_comment == 1) && (/\A\*\/\s*\Z/)) { - $header_comment = 0; - } - - if ($ignoring_lines && /\A\s*\#\s*endif\s*\Z/) { - $ignoring_lines = 0; - push @contents, $_; - next; - } elsif ($ignoring_lines) { - push @contents, $_; - next; - } elsif (/\A\s*\#\s*ifndef\s+SDL_WIKI_DOCUMENTATION_SECTION\s*\Z/) { - $ignoring_lines = 1; - push @contents, $_; - next; - } elsif (/\A\s*\/\*\s*WIKI CATEGORY:\s*(.*?)\s*\*\/\s*\Z/) { - $current_wiki_category = (($1 eq '') || ($1 eq '-')) ? undef : $1; - #print("CATEGORY FOR '$dent' CHANGED TO " . (defined($current_wiki_category) ? "'$current_wiki_category'" : '(undef)') . "\n"); - push @contents, $_; - next; - } elsif (/\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC/) { # a function declaration without a doxygen comment? - $symtype = 1; # function declaration - @templines = (); - $decl = $_; - $str = ''; - $has_doxygen = 0; - } elsif (/\A\s*SDL_FORCE_INLINE/) { # a (forced-inline) function declaration without a doxygen comment? - $symtype = 1; # function declaration - @templines = (); - $decl = $_; - $str = ''; - $has_doxygen = 0; - } elsif (not /\A\/\*\*\s*\Z/) { # not doxygen comment start? - push @contents, $_; - add_coverage_gap($_, $dent, $lineno) if ($header_comment == 0); - next; - } else { # Start of a doxygen comment, parse it out. - my $is_category_doxygen = 0; - - @templines = ( $_ ); - while () { - chomp; - $lineno++; - push @templines, $_; - last if /\A\s*\*\/\Z/; - if (s/\A\s*\*\s*\`\`\`/```/) { # this is a hack, but a lot of other code relies on the whitespace being trimmed, but we can't trim it in code blocks... - $str .= "$_\n"; - while () { - chomp; - $lineno++; - push @templines, $_; - s/\A\s*\*\s?//; - if (s/\A\s*\`\`\`/```/) { - $str .= "$_\n"; - last; - } else { - $str .= "$_\n"; - } - } - } else { - s/\A\s*\*\s*//; # Strip off the " * " at the start of the comment line. - - # To add documentation to Category Pages, the rule is it has to - # be the first Doxygen comment in the header, and it must start with `# CategoryX` - # (otherwise we'll treat it as documentation for whatever's below it). `X` is - # the category name, which doesn't _necessarily_ have to match - # $current_wiki_category, but it probably should. - # - # For compatibility with Doxygen, if there's a `\file` here instead of - # `# CategoryName`, we'll accept it and use the $current_wiki_category if set. - if ($saw_category_doxygen == -1) { - $saw_category_doxygen = defined($current_wiki_category) && /\A\\file\s+/; - if ($saw_category_doxygen) { - $_ = "# Category$current_wiki_category"; - } else { - $saw_category_doxygen = /\A\# Category/; - } - $is_category_doxygen = $saw_category_doxygen; - } - - $str .= "$_\n"; - } - } - - if ($is_category_doxygen) { - $str =~ s/\s*\Z//; - $decl = ''; - $symtype = -1; # not a symbol at all. - } else { - $decl = ; - $lineno++ if defined $decl; - $decl = '' if not defined $decl; - chomp($decl); - if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC/) { - $symtype = 1; # function declaration - } elsif ($decl =~ /\A\s*SDL_FORCE_INLINE/) { - $symtype = 1; # (forced-inline) function declaration - } elsif ($decl =~ /\A\s*\#\s*define\s+/) { - $symtype = 2; # macro - } elsif ($decl =~ /\A\s*(typedef\s+|)(struct|union)\s*([a-zA-Z0-9_]*?)\s*(\n|\{|\Z)/) { - $symtype = 3; # struct or union - } elsif ($decl =~ /\A\s*(typedef\s+|)enum\s*([a-zA-Z0-9_]*?)\s*(\n|\{|\Z)/) { - $symtype = 4; # enum - } elsif ($decl =~ /\A\s*typedef\s+.*\Z/) { - $symtype = 5; # other typedef - } else { - #print "Found doxygen but no function sig:\n$str\n\n"; - foreach (@templines) { - push @contents, $_; - add_coverage_gap($_, $dent, $lineno); - } - push @contents, $decl; - add_coverage_gap($decl, $dent, $lineno); - next; - } - } - } - - my @paraminfo = (); - my $rettype = undef; - my @decllines = ( $decl ); - my $sym = ''; - - if ($symtype == -1) { # category documentation with no symbol attached. - @decllines = (); - if ($str =~ /^#\s*Category(.*?)\s*$/m) { - $sym = "[category documentation] $1"; # make a fake, unique symbol that's not valid C. - } else { - die("Unexpected category documentation line '$str' in '$incpath/$dent' ...?"); - } - $headercategorydocs{$current_wiki_category} = $sym; - } elsif ($symtype == 1) { # a function - my $is_forced_inline = ($decl =~ /\A\s*SDL_FORCE_INLINE/); - - if ($is_forced_inline) { - if (not $decl =~ /\)\s*(\{.*|)\s*\Z/) { - while () { - chomp; - $lineno++; - push @decllines, $_; - s/\A\s+//; - s/\s+\Z//; - $decl .= " $_"; - last if /\)\s*(\{.*|)\s*\Z/; - } - } - $decl =~ s/\s*\)\s*(\{.*|)\s*\Z/);/; - } else { - if (not $decl =~ /;/) { - while () { - chomp; - $lineno++; - push @decllines, $_; - s/\A\s+//; - s/\s+\Z//; - $decl .= " $_"; - last if /;/; - } - } - $decl =~ s/\s+\);\Z/);/; - $decl =~ s/\s+;\Z/;/; - } - - $decl =~ s/\s+\Z//; - - $decl = strip_fn_declaration_metadata($decl); - - my $paramsstr = undef; - - if (!$is_forced_inline && $decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC\w*\s+(const\s+|)(unsigned\s+|)(.*?)([\*\s]+)(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) { - $sym = $8; - $rettype = "$3$4$5$6"; - $paramsstr = $9; - } elsif ($is_forced_inline && $decl =~ /\A\s*SDL_FORCE_INLINE\s+(SDL_DEPRECATED\s+|)(const\s+|)(unsigned\s+|)(.*?)([\*\s]+)(.*?)\s*\((.*?)\);/) { - $sym = $6; - $rettype = "$2$3$4$5"; - $paramsstr = $7; - } else { - #print "Found doxygen but no function sig:\n$str\n\n"; - foreach (@templines) { - push @contents, $_; - } - foreach (@decllines) { - push @contents, $_; - } - next; - } - - $rettype = sanitize_c_typename($rettype); - - if ($paramsstr =~ /\(/) { - die("\n\n$0 FAILURE!\n" . - "There's a '(' in the parameters for function '$sym' '$incpath/$dent'.\n" . - "This usually means there's a parameter that's a function pointer type.\n" . - "This causes problems for wikiheaders.pl and is less readable, too.\n" . - "Please put that function pointer into a typedef,\n" . - "and use the new type in this function's signature instead!\n\n"); - } - - my @params = split(/,/, $paramsstr); - my $dotdotdot = 0; - foreach (@params) { - my $p = $_; - $p =~ s/\A\s+//; - $p =~ s/\s+\Z//; - if (($p eq 'void') || ($p eq '')) { - die("Void parameter in a function with multiple params?! ('$sym' in '$incpath/$dent')") if (scalar(@params) != 1); - } elsif ($p eq '...') { - die("Mutiple '...' params?! ('$sym' in '$incpath/$dent')") if ($dotdotdot); - $dotdotdot = 1; - push @paraminfo, '...'; - push @paraminfo, '...'; - } elsif ($p =~ /\A(.*)\s+([a-zA-Z0-9_\*\[\]]+)\Z/) { - die("Parameter after '...' param?! ('$sym' in '$incpath/$dent')") if ($dotdotdot); - my $t = $1; - my $n = $2; - if ($n =~ s/\A(\*+)//) { - $t .= $1; # move any `*` that stuck to the name over. - } - if ($n =~ s/\[\]\Z//) { - $t = "$t*"; # move any `[]` that stuck to the name over, as a pointer. - } - $t = sanitize_c_typename($t); - #print("$t\n"); - #print("$n\n"); - push @paraminfo, $n; - push @paraminfo, $t; - } else { - die("Unexpected parameter '$p' in function '$sym' in '$incpath/$dent'!"); - } - } - - if (!$is_forced_inline) { # don't do with forced-inline because we don't want the implementation inserted in the wiki. - my $shrink_length = 0; - - $decl = ''; # rebuild this with the line breaks, since it looks better for syntax highlighting. - foreach (@decllines) { - if ($decl eq '') { - my $temp; - - $decl = $_; - $temp = $decl; - $temp =~ s/\Aextern\s+(SDL_DEPRECATED\s+|)(SDLMAIN_|SDL_)?DECLSPEC\w*\s+(.*?)\s+(\*?)SDLCALL\s+/$3$4 /; - $shrink_length = length($decl) - length($temp); - $decl = $temp; - } else { - my $trimmed = $_; - $trimmed =~ s/\A\s{$shrink_length}//; # shrink to match the removed "extern SDL_DECLSPEC SDLCALL " - $decl .= $trimmed; - } - $decl .= "\n"; - } - } - - $decl = strip_fn_declaration_metadata($decl); - - # !!! FIXME: code duplication with typedef processing, below. - # We assume any `#define`s directly after the function are related to it: probably bitflags for an integer typedef. - # We'll also allow some other basic preprocessor lines. - # Blank lines are allowed, anything else, even comments, are not. - my $blank_lines = 0; - my $lastpos = tell(FH); - my $lastlineno = $lineno; - my $additional_decl = ''; - my $saw_define = 0; - while () { - chomp; - - $lineno++; - - if (/\A\s*\Z/) { - $blank_lines++; - } elsif (/\A\s*\#\s*(define|if|else|elif|endif)(\s+|\Z)/) { - if (/\A\s*\#\s*define\s+([a-zA-Z0-9_]*)/) { - $referenceonly{$1} = $sym; - $saw_define = 1; - } elsif (!$saw_define) { - # if the first non-blank thing isn't a #define, assume we're done. - seek(FH, $lastpos, 0); # re-read eaten lines again next time. - $lineno = $lastlineno; - last; - } - - # update strings now that we know everything pending is to be applied to this declaration. Add pending blank lines and the new text. - - # At Sam's request, don't list property defines with functions. (See #9440) - my $is_property = /\A\s*\#\s*define\s+SDL_PROP_/; - if (!$is_property) { - if ($blank_lines > 0) { - while ($blank_lines > 0) { - $additional_decl .= "\n"; - push @decllines, ''; - $blank_lines--; - } - } - $additional_decl .= "\n$_"; - push @decllines, $_; - $lastpos = tell(FH); - } - } else { - seek(FH, $lastpos, 0); # re-read eaten lines again next time. - $lineno = $lastlineno; - last; - } - } - $decl .= $additional_decl; - } elsif ($symtype == 2) { # a macro - if ($decl =~ /\A\s*\#\s*define\s+(.*?)(\(.*?\)|)\s+/) { - $sym = $1; - } else { - #print "Found doxygen but no macro:\n$str\n\n"; - foreach (@templines) { - push @contents, $_; - } - foreach (@decllines) { - push @contents, $_; - } - next; - } - - while ($decl =~ /\\\Z/) { - my $l = ; - last if not $l; - $lineno++; - chomp($l); - push @decllines, $l; - #$l =~ s/\A\s+//; - $l =~ s/\s+\Z//; - $decl .= "\n$l"; - } - } elsif (($symtype == 3) || ($symtype == 4)) { # struct or union or enum - my $has_definition = 0; - if ($decl =~ /\A\s*(typedef\s+|)(struct|union|enum)\s*([a-zA-Z0-9_]*?)\s*(\n|\{|\;|\Z)/) { - my $ctype = $2; - my $origsym = $3; - my $ending = $4; - $sym = $origsym; - if ($sym =~ s/\A(.*?)(\s+)(.*?)\Z/$1/) { - die("Failed to parse '$origsym' correctly!") if ($sym ne $1); # Thought this was "typedef struct MySym MySym;" ... it was not. :( This is a hack! - } - if ($sym eq '') { - die("\n\n$0 FAILURE!\n" . - "There's a 'typedef $ctype' in $incpath/$dent without a name at the top.\n" . - "Instead of `typedef $ctype {} x;`, this should be `typedef $ctype x {} x;`.\n" . - "This causes problems for wikiheaders.pl and scripting language bindings.\n" . - "Please fix it!\n\n"); - } - $has_definition = ($ending ne ';'); - } else { - #print "Found doxygen but no datatype:\n$str\n\n"; - foreach (@templines) { - push @contents, $_; - } - foreach (@decllines) { - push @contents, $_; - } - next; - } - - # This block attempts to find the whole struct/union/enum definition by counting matching brackets. Kind of yucky. - # It also "parses" enums enough to find out the elements of it. - if ($has_definition) { - my $started = 0; - my $brackets = 0; - my $pending = $decl; - my $skipping_comment = 0; - - $decl = ''; - while (!$started || ($brackets != 0)) { - foreach my $seg (split(/([{}])/, $pending)) { # (this will pick up brackets in comments! Be careful!) - $decl .= $seg; - if ($seg eq '{') { - $started = 1; - $brackets++; - } elsif ($seg eq '}') { - die("Something is wrong with header $incpath/$dent while parsing $sym; is a bracket missing?\n") if ($brackets <= 0); - $brackets--; - } - } - - if ($skipping_comment) { - if ($pending =~ s/\A.*?\*\///) { - $skipping_comment = 0; - } - } - - if (!$skipping_comment && $started && ($symtype == 4)) { # Pick out elements of an enum. - my $stripped = "$pending"; - $stripped =~ s/\/\*.*?\*\///g; # dump /* comments */ that exist fully on one line. - if ($stripped =~ /\/\*/) { # uhoh, a /* comment */ that crosses newlines. - $skipping_comment = 1; - } elsif ($stripped =~ /\A\s*([a-zA-Z0-9_]+)(.*)\Z/) { #\s*(\=\s*.*?|)\s*,?(.*?)\Z/) { - if ($1 ne 'typedef') { # make sure we didn't just eat the first line by accident. :/ - #print("ENUM [$1] $incpath/$dent:$lineno\n"); - $referenceonly{$1} = $sym; - } - } - } - - if (!$started || ($brackets != 0)) { - $pending = ; - die("EOF/error reading $incpath/$dent while parsing $sym\n") if not $pending; - $lineno++; - chomp($pending); - push @decllines, $pending; - $decl .= "\n"; - } - } - # this currently assumes the struct/union/enum ends on the line with the final bracket. I'm not writing a C parser here, fix the header! - } - } elsif ($symtype == 5) { # other typedef - if ($decl =~ /\A\s*typedef\s+(.*)\Z/) { - my $tdstr = $1; - - if (not $decl =~ /;/) { - while () { - chomp; - $lineno++; - push @decllines, $_; - s/\A\s+//; - s/\s+\Z//; - $decl .= " $_"; - last if /;/; - } - } - $decl =~ s/\s+(\))?;\Z/$1;/; - - $tdstr =~ s/;\s*\Z//; - - #my $datatype; - if ($tdstr =~ /\A(.*?)\s*\((.*?)\s*\*\s*(.*?)\)\s*\((.*?)(\))?/) { # a function pointer type - $sym = $3; - #$datatype = "$1 ($2 *$sym)($4)"; - } elsif ($tdstr =~ /\A(.*[\s\*]+)(.*?)\s*\Z/) { - $sym = $2; - #$datatype = $1; - } else { - die("Failed to parse typedef '$tdstr' in $incpath/$dent!\n"); # I'm hitting a C grammar nail with a regexp hammer here, y'all. - } - - $sym =~ s/\A\s+//; - $sym =~ s/\s+\Z//; - #$datatype =~ s/\A\s+//; - #$datatype =~ s/\s+\Z//; - } else { - #print "Found doxygen but no datatype:\n$str\n\n"; - foreach (@templines) { - push @contents, $_; - } - foreach (@decllines) { - push @contents, $_; - } - next; - } - - # We assume any `#define`s directly after the typedef are related to it: probably bitflags for an integer typedef. - # We'll also allow some other basic preprocessor lines. - # Blank lines are allowed, anything else, even comments, are not. - my $blank_lines = 0; - my $lastpos = tell(FH); - my $lastlineno = $lineno; - my $additional_decl = ''; - my $saw_define = 0; - while () { - chomp; - - $lineno++; - - if (/\A\s*\Z/) { - $blank_lines++; - } elsif (/\A\s*\#\s*(define|if|else|elif|endif)(\s+|\Z)/) { - if (/\A\s*\#\s*define\s+([a-zA-Z0-9_]*)/) { - $referenceonly{$1} = $sym; - $saw_define = 1; - } elsif (!$saw_define) { - # if the first non-blank thing isn't a #define, assume we're done. - seek(FH, $lastpos, 0); # re-read eaten lines again next time. - $lineno = $lastlineno; - last; - } - # update strings now that we know everything pending is to be applied to this declaration. Add pending blank lines and the new text. - if ($blank_lines > 0) { - while ($blank_lines > 0) { - $additional_decl .= "\n"; - push @decllines, ''; - $blank_lines--; - } - } - $additional_decl .= "\n$_"; - push @decllines, $_; - $lastpos = tell(FH); - } else { - seek(FH, $lastpos, 0); # re-read eaten lines again next time. - $lineno = $lastlineno; - last; - } - } - $decl .= $additional_decl; - } else { - die("Unexpected symtype $symtype"); - } - - #print("DECL: [$decl]\n"); - - #print("$sym:\n$str\n\n"); - - # There might be multiple declarations of a function due to #ifdefs, - # and only one of them will have documentation. If we hit an - # undocumented one before, delete the placeholder line we left for - # it so it doesn't accumulate a new blank line on each run. - my $skipsym = 0; - if (defined $headersymshasdoxygen{$sym}) { - if ($headersymshasdoxygen{$sym} == 0) { # An undocumented declaration already exists, nuke its placeholder line. - delete $contents[$headersymschunk{$sym}]; # delete DOES NOT RENUMBER existing elements! - } else { # documented function already existed? - $skipsym = 1; # don't add this copy to the list of functions. - if ($has_doxygen) { - print STDERR "WARNING: Symbol '$sym' appears to be documented in multiple locations. Only keeping the first one we saw!\n"; - } - push @contents, join("\n", @decllines) if (scalar(@decllines) > 0); # just put the existing declation in as-is. - } - } - - if (!$skipsym) { - $headersymscategory{$sym} = $current_wiki_category if defined $current_wiki_category; - $headersyms{$sym} = $str; - $headerdecls{$sym} = $decl; - $headersymslocation{$sym} = $dent; - $headersymschunk{$sym} = scalar(@contents); - $headersymshasdoxygen{$sym} = $has_doxygen; - $headersymstype{$sym} = $symtype; - $headersymsparaminfo{$sym} = \@paraminfo if (scalar(@paraminfo) > 0); - $headersymsrettype{$sym} = $rettype if (defined($rettype)); - push @function_order, $sym if ($symtype == 1) || ($symtype == 2); - push @contents, join("\n", @templines); - push @contents, join("\n", @decllines) if (scalar(@decllines) > 0); - } - - } - close(FH); - - $headers{$dent} = \@contents; - $quickreffuncorder{$current_wiki_category} = \@function_order if defined $current_wiki_category; -} -closedir(DH); - - -opendir(DH, $wikipath) or die("Can't opendir '$wikipath': $!\n"); -while (my $d = readdir(DH)) { - my $dent = $d; - my $type = ''; - if ($dent =~ /\.(md|mediawiki)\Z/) { - $type = $1; - } else { - next; # only dealing with wiki pages. - } - - my $sym = $dent; - $sym =~ s/\..*\Z//; - - # (There are other pages to ignore, but these are known ones to not bother parsing.) - # Ignore FrontPage. - next if $sym eq 'FrontPage'; - - open(FH, '<', "$wikipath/$dent") or die("Can't open '$wikipath/$dent': $!\n"); - - if ($sym =~ /\ACategory(.*?)\Z/) { # Special case for Category pages. - # Find the end of the category documentation in the existing file and append everything else to the new file. - my $cat = $1; - my $docstr = ''; - my $notdocstr = ''; - my $docs = 1; - while () { - chomp; - if ($docs) { - $docs = 0 if /\A\-\-\-\-\Z/; # Hit a footer? We're done. - $docs = 0 if /\A) { - chomp; - my $orig = $_; - s/\A\s*//; - s/\s*\Z//; - - if ($type eq 'mediawiki') { - if (defined($wikipreamble) && $firstline && /\A\=\=\=\=\=\= (.*?) \=\=\=\=\=\=\Z/ && ($1 eq $wikipreamble)) { - $firstline = 0; # skip this. - next; - } elsif (/\A\= (.*?) \=\Z/) { - $firstline = 0; - $current_section = ($1 eq $sym) ? '[Brief]' : $1; - die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; - push @section_order, $current_section; - $sections{$current_section} = ''; - } elsif (/\A\=\= (.*?) \=\=\Z/) { - $firstline = 0; - $current_section = ($1 eq $sym) ? '[Brief]' : $1; - die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; - push @section_order, $current_section; - $sections{$current_section} = ''; - next; - } elsif (/\A\-\-\-\-\Z/) { - $firstline = 0; - $current_section = '[footer]'; - die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; - push @section_order, $current_section; - $sections{$current_section} = ''; - next; - } - } elsif ($type eq 'md') { - if (defined($wikipreamble) && $firstline && /\A\#\#\#\#\#\# (.*?)\Z/ && ($1 eq $wikipreamble)) { - $firstline = 0; # skip this. - next; - } elsif (/\A\#+ (.*?)\Z/) { - $firstline = 0; - $current_section = ($1 eq $sym) ? '[Brief]' : $1; - die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; - push @section_order, $current_section; - $sections{$current_section} = ''; - next; - } elsif (/\A\-\-\-\-\Z/) { - $firstline = 0; - $current_section = '[footer]'; - die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; - push @section_order, $current_section; - $sections{$current_section} = ''; - next; - } - } else { - die("Unexpected wiki file type. Fixme!"); - } - - if ($firstline) { - $firstline = ($_ ne ''); - } - if (!$firstline) { - $sections{$current_section} .= "$orig\n"; - } - } - close(FH); - - foreach (keys %sections) { - $sections{$_} =~ s/\A\n+//; - $sections{$_} =~ s/\n+\Z//; - $sections{$_} .= "\n"; - } - - # older section name we used, migrate over from it. - if (defined $sections{'Related Functions'}) { - if (not defined $sections{'See Also'}) { - $sections{'See Also'} = $sections{'Related Functions'}; - } - delete $sections{'Related Functions'}; - } - - if (0) { - foreach (@section_order) { - print("$sym SECTION '$_':\n"); - print($sections{$_}); - print("\n\n"); - } - } - - $wikitypes{$sym} = $type; - $wikisyms{$sym} = \%sections; - $wikisectionorder{$sym} = \@section_order; -} -closedir(DH); - -delete $wikisyms{"Undocumented"}; - -{ - my $path = "$wikipath/Undocumented.md"; - open(my $fh, '>', $path) or die("Can't open '$path': $!\n"); - - print $fh "# Undocumented\n\n"; - print_undocumented_section($fh, 'Functions', 1); - #print_undocumented_section($fh, 'Macros', 2); - - close($fh); -} - -if ($warn_about_missing) { - foreach (keys %wikisyms) { - my $sym = $_; - if (not defined $headersyms{$sym}) { - print STDERR "WARNING: $sym defined in the wiki but not the headers!\n"; - } - } - - foreach (keys %headersyms) { - my $sym = $_; - if (not defined $wikisyms{$sym}) { - print STDERR "WARNING: $sym defined in the headers but not the wiki!\n"; - } - } -} - -if ($copy_direction == 1) { # --copy-to-headers - my %changed_headers = (); - - $dewikify_mode = 'md'; - $wordwrap_mode = 'md'; # the headers use Markdown format. - - foreach (keys %headersyms) { - my $sym = $_; - next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it. - my $symtype = $headersymstype{$sym}; - my $wikitype = $wikitypes{$sym}; - my $sectionsref = $wikisyms{$sym}; - my $remarks = $sectionsref->{'Remarks'}; - my $returns = $sectionsref->{'Return Value'}; - my $threadsafety = $sectionsref->{'Thread Safety'}; - my $version = $sectionsref->{'Version'}; - my $related = $sectionsref->{'See Also'}; - my $deprecated = $sectionsref->{'Deprecated'}; - my $brief = $sectionsref->{'[Brief]'}; - my $addblank = 0; - my $str = ''; - - my $params = undef; - my $paramstr = undef; - - if ($symtype == -1) { # category documentation block. - # nothing to be done here. - } elsif (($symtype == 1) || (($symtype == 5))) { # we'll assume a typedef (5) with a \param is a function pointer typedef. - $params = $sectionsref->{'Function Parameters'}; - $paramstr = '\param'; - } elsif ($symtype == 2) { - $params = $sectionsref->{'Macro Parameters'}; - $paramstr = '\param'; - } elsif ($symtype == 3) { - $params = $sectionsref->{'Fields'}; - $paramstr = '\field'; - } elsif ($symtype == 4) { - $params = $sectionsref->{'Values'}; - $paramstr = '\value'; - } else { - die("Unexpected symtype $symtype"); - } - - $headersymshasdoxygen{$sym} = 1; # Added/changed doxygen for this header. - - $brief = dewikify($wikitype, $brief); - $brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. - my @briefsplit = split /\n/, $brief; - $brief = shift @briefsplit; - - if (defined $remarks) { - $remarks = join("\n", @briefsplit) . dewikify($wikitype, $remarks); - } - - if (defined $brief) { - $str .= "\n" if $addblank; $addblank = 1; - $str .= wordwrap($brief) . "\n"; - } - - if (defined $remarks) { - $str .= "\n" if $addblank; $addblank = 1; - $str .= wordwrap($remarks) . "\n"; - } - - if (defined $deprecated) { - # !!! FIXME: lots of code duplication in all of these. - $str .= "\n" if $addblank; $addblank = 1; - my $v = dewikify($wikitype, $deprecated); - my $whitespacelen = length("\\deprecated") + 1; - my $whitespace = ' ' x $whitespacelen; - $v = wordwrap($v, -$whitespacelen); - my @desclines = split /\n/, $v; - my $firstline = shift @desclines; - $str .= "\\deprecated $firstline\n"; - foreach (@desclines) { - $str .= "${whitespace}$_\n"; - } - } - - if (defined $params) { - $str .= "\n" if $addblank; $addblank = (defined $returns) ? 0 : 1; - my @lines = split /\n/, dewikify($wikitype, $params); - if ($wikitype eq 'mediawiki') { - die("Unexpected data parsing MediaWiki table") if (shift @lines ne '{|'); # Dump the '{|' start - while (scalar(@lines) >= 3) { - my $c_datatype = shift @lines; - my $name = shift @lines; - my $desc = shift @lines; - my $terminator; # the '|-' or '|}' line. - - if (($desc eq '|-') or ($desc eq '|}') or (not $desc =~ /\A\|/)) { # we seem to be out of cells, which means there was no datatype column on this one. - $terminator = $desc; - $desc = $name; - $name = $c_datatype; - $c_datatype = ''; - } else { - $terminator = shift @lines; - } - - last if ($terminator ne '|-') and ($terminator ne '|}'); # we seem to have run out of table. - $name =~ s/\A\|\s*//; - $name =~ s/\A\*\*(.*?)\*\*/$1/; - $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; - $desc =~ s/\A\|\s*//; - #print STDERR "SYM: $sym CDATATYPE: $c_datatype NAME: $name DESC: $desc TERM: $terminator\n"; - my $whitespacelen = length($name) + 8; - my $whitespace = ' ' x $whitespacelen; - $desc = wordwrap($desc, -$whitespacelen); - my @desclines = split /\n/, $desc; - my $firstline = shift @desclines; - $str .= "$paramstr $name $firstline\n"; - foreach (@desclines) { - $str .= "${whitespace}$_\n"; - } - } - } elsif ($wikitype eq 'md') { - my $l; - $l = shift @lines; - die("Unexpected data parsing Markdown table") if (not $l =~ /\A(\s*\|)?\s*\|\s*\|\s*\|\s*\Z/); - $l = shift @lines; - die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*(\|\s*\-*\s*)?\|\s*\-*\s*\|\s*\-*\s*\|\s*\Z/); - while (scalar(@lines) >= 1) { - $l = shift @lines; - my $name; - my $desc; - if ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { - # c datatype is $1, but we don't care about it here. - $name = $2; - $desc = $3; - } elsif ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { - $name = $1; - $desc = $2; - } else { - last; # we seem to have run out of table. - } - - $name =~ s/\A\*\*(.*?)\*\*/$1/; - $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; - #print STDERR "SYM: $sym NAME: $name DESC: $desc\n"; - my $whitespacelen = length($name) + 8; - my $whitespace = ' ' x $whitespacelen; - $desc = wordwrap($desc, -$whitespacelen); - my @desclines = split /\n/, $desc; - my $firstline = shift @desclines; - $str .= "$paramstr $name $firstline\n"; - foreach (@desclines) { - $str .= "${whitespace}$_\n"; - } - } - } else { - die("write me"); - } - } - - if (defined $returns) { - $str .= "\n" if $addblank; $addblank = 1; - my $r = dewikify($wikitype, $returns); - $r =~ s/\A\(.*?\)\s*//; # Chop datatype in parentheses off the front. - my $retstr = "\\returns"; - if ($r =~ s/\AReturn(s?)\s+//) { - $retstr = "\\return$1"; - } - - my $whitespacelen = length($retstr) + 1; - my $whitespace = ' ' x $whitespacelen; - $r = wordwrap($r, -$whitespacelen); - my @desclines = split /\n/, $r; - my $firstline = shift @desclines; - $str .= "$retstr $firstline\n"; - foreach (@desclines) { - $str .= "${whitespace}$_\n"; - } - } - - if (defined $threadsafety) { - # !!! FIXME: lots of code duplication in all of these. - $str .= "\n" if $addblank; $addblank = 1; - my $v = dewikify($wikitype, $threadsafety); - my $whitespacelen = length("\\threadsafety") + 1; - my $whitespace = ' ' x $whitespacelen; - $v = wordwrap($v, -$whitespacelen); - my @desclines = split /\n/, $v; - my $firstline = shift @desclines; - $str .= "\\threadsafety $firstline\n"; - foreach (@desclines) { - $str .= "${whitespace}$_\n"; - } - } - - if (defined $version) { - # !!! FIXME: lots of code duplication in all of these. - $str .= "\n" if $addblank; $addblank = 1; - my $v = dewikify($wikitype, $version); - my $whitespacelen = length("\\since") + 1; - my $whitespace = ' ' x $whitespacelen; - $v = wordwrap($v, -$whitespacelen); - my @desclines = split /\n/, $v; - my $firstline = shift @desclines; - $str .= "\\since $firstline\n"; - foreach (@desclines) { - $str .= "${whitespace}$_\n"; - } - } - - if (defined $related) { - # !!! FIXME: lots of code duplication in all of these. - $str .= "\n" if $addblank; $addblank = 1; - my $v = dewikify($wikitype, $related); - my @desclines = split /\n/, $v; - foreach (@desclines) { - s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" - s/\[\[(.*?)\]\]/$1/; # in case some wikilinks remain. - s/\[(.*?)\]\(.*?\)/$1/; # in case some wikilinks remain. - s/\A\/*//; - s/\A\s*[\:\*\-]\s*//; - s/\A\s+//; - s/\s+\Z//; - $str .= "\\sa $_\n"; - } - } - - my $header = $headersymslocation{$sym}; - my $contentsref = $headers{$header}; - my $chunk = $headersymschunk{$sym}; - - my @lines = split /\n/, $str; - - my $addnewline = (($chunk > 0) && ($$contentsref[$chunk-1] ne '')) ? "\n" : ''; - - my $output = "$addnewline/**\n"; - foreach (@lines) { - chomp; - s/\s*\Z//; - if ($_ eq '') { - $output .= " *\n"; - } else { - $output .= " * $_\n"; - } - } - $output .= " */"; - - #print("$sym:\n[$output]\n\n"); - - $$contentsref[$chunk] = $output; - #$$contentsref[$chunk+1] = $headerdecls{$sym}; - - $changed_headers{$header} = 1; - } - - foreach (keys %changed_headers) { - my $header = $_; - - # this is kinda inefficient, but oh well. - my @removelines = (); - foreach (keys %headersymslocation) { - my $sym = $_; - next if $headersymshasdoxygen{$sym}; - next if $headersymslocation{$sym} ne $header; - # the index of the blank line we put before the function declaration in case we needed to replace it with new content from the wiki. - push @removelines, $headersymschunk{$sym}; - } - - my $contentsref = $headers{$header}; - foreach (@removelines) { - delete $$contentsref[$_]; # delete DOES NOT RENUMBER existing elements! - } - - my $path = "$incpath/$header.tmp"; - open(FH, '>', $path) or die("Can't open '$path': $!\n"); - foreach (@$contentsref) { - print FH "$_\n" if defined $_; - } - close(FH); - rename($path, "$incpath/$header") or die("Can't rename '$path' to '$incpath/$header': $!\n"); - } - - if (defined $readmepath) { - if ( -d $wikireadmepath ) { - mkdir($readmepath); # just in case - opendir(DH, $wikireadmepath) or die("Can't opendir '$wikireadmepath': $!\n"); - while (readdir(DH)) { - my $dent = $_; - if ($dent =~ /\A(.*?)\.md\Z/) { # we only bridge Markdown files here. - next if $1 eq 'FrontPage'; - filecopy("$wikireadmepath/$dent", "$readmepath/README-$dent", "\n"); - } - } - closedir(DH); - } - } - -} elsif ($copy_direction == -1) { # --copy-to-wiki - - my %briefs = (); # $briefs{'SDL_OpenAudio'} -> the \brief string for the function. - - if (defined $changeformat) { - $dewikify_mode = $changeformat; - $wordwrap_mode = $changeformat; - } - - foreach (keys %headersyms) { - my $sym = $_; - next if not $headersymshasdoxygen{$sym}; - next if $sym =~ /\A\[category documentation\]/; # not real symbols, we handle this elsewhere. - my $symtype = $headersymstype{$sym}; - my $origwikitype = defined $wikitypes{$sym} ? $wikitypes{$sym} : 'md'; # default to MarkDown for new stuff. - my $wikitype = (defined $changeformat) ? $changeformat : $origwikitype; - die("Unexpected wikitype '$wikitype'") if (($wikitype ne 'mediawiki') and ($wikitype ne 'md') and ($wikitype ne 'manpage')); - - #print("$sym\n"); next; - - $wordwrap_mode = $wikitype; - - my $raw = $headersyms{$sym}; # raw doxygen text with comment characters stripped from start/end and start of each line. - next if not defined $raw; - $raw =~ s/\A\s*\\brief\s+//; # Technically we don't need \brief (please turn on JAVADOC_AUTOBRIEF if you use Doxygen), so just in case one is present, strip it. - - my @doxygenlines = split /\n/, $raw; - my $brief = ''; - while (@doxygenlines) { - last if $doxygenlines[0] =~ /\A\\/; # some sort of doxygen command, assume we're past the general remarks. - last if $doxygenlines[0] =~ /\A\s*\Z/; # blank line? End of paragraph, done. - my $l = shift @doxygenlines; - chomp($l); - $l =~ s/\A\s*//; - $l =~ s/\s*\Z//; - $brief .= "$l "; - } - - $brief =~ s/\s+\Z//; - $brief =~ s/\A(.*?\.) /$1\n\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. - my @briefsplit = split /\n/, $brief; - - next if not defined $briefsplit[0]; # No brief text? Probably a bogus Doxygen comment, skip it. - - $brief = wikify($wikitype, shift @briefsplit) . "\n"; - @doxygenlines = (@briefsplit, @doxygenlines); - - my $remarks = ''; - while (@doxygenlines) { - last if $doxygenlines[0] =~ /\A\\/; # some sort of doxygen command, assume we're past the general remarks. - my $l = shift @doxygenlines; - $remarks .= "$l\n"; - } - - #print("REMARKS:\n\n $remarks\n\n"); - - $remarks = wordwrap(wikify($wikitype, $remarks)); - $remarks =~ s/\A\s*//; - $remarks =~ s/\s*\Z//; - - my $decl = $headerdecls{$sym}; - - my $syntax = ''; - if ($wikitype eq 'mediawiki') { - $syntax = "\n$decl\n"; - } elsif ($wikitype eq 'md') { - $decl =~ s/\n+\Z//; - $syntax = "```c\n$decl\n```\n"; - } else { die("Expected wikitype '$wikitype'"); } - - my %sections = (); - $sections{'[Brief]'} = $brief; # include this section even if blank so we get a title line. - $sections{'Remarks'} = "$remarks\n" if $remarks ne ''; - $sections{'Syntax'} = $syntax; - - $briefs{$sym} = $brief; - - my %params = (); # have to parse these and build up the wiki tables after, since Markdown needs to know the length of the largest string. :/ - my @paramsorder = (); - my $fnsigparams = $headersymsparaminfo{$sym}; - my $has_returns = 0; - my $has_threadsafety = 0; - - while (@doxygenlines) { - my $l = shift @doxygenlines; - # We allow param/field/value interchangeably, even if it doesn't make sense. The next --copy-to-headers will correct it anyhow. - if ($l =~ /\A\\(param|field|value)\s+(.*?)\s+(.*)\Z/) { - my $arg = $2; - my $desc = $3; - while (@doxygenlines) { - my $subline = $doxygenlines[0]; - $subline =~ s/\A\s*//; - last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. - shift @doxygenlines; # dump this line from the array; we're using it. - if ($subline eq '') { # empty line, make sure it keeps the newline char. - $desc .= "\n"; - } else { - $desc .= " $subline"; - } - } - - $desc =~ s/[\s\n]+\Z//ms; - - if (0) { # !!! FIXME: disabled because it's not currently suitable for general use, but for manually inspecting the output, it can be useful. - if (($desc =~ /\A[A-Z]/) && (not $desc =~ /\ASDL_/)) { - print STDERR "WARNING: $sym\'s '\\param $arg' text starts with a capital letter: '$desc'. Fixing.\n"; - $desc = lcfirst($desc); - } - } - - if (not $desc =~ /[\.\!]\Z/) { - print STDERR "WARNING: $sym\'s '\\param $arg' text doesn't end with punctuation: '$desc'. Fixing.\n"; - $desc .= '.'; - } - - # Validate this param. - if (defined($params{$arg})) { - print STDERR "WARNING: Symbol '$sym' has multiple '\\param $arg' declarations! Only keeping the first one!\n"; - } elsif (defined $fnsigparams) { - my $found = 0; - for (my $i = 0; $i < scalar(@$fnsigparams); $i += 2) { - $found = 1, last if (@$fnsigparams[$i] eq $arg); - } - if (!$found) { - print STDERR "WARNING: Symbol '$sym' has a '\\param $arg' for a param that doesn't exist. It will be removed!\n"; - } - } - - # We need to know the length of the longest string to make Markdown tables, so we just store these off until everything is parsed. - $params{$arg} = $desc; - push @paramsorder, $arg; - } elsif ($l =~ /\A\\r(eturns?)\s+(.*)\Z/) { - $has_returns = 1; - # !!! FIXME: complain if this isn't a function or macro. - my $retstr = "R$1"; # "Return" or "Returns" - my $desc = $2; - - while (@doxygenlines) { - my $subline = $doxygenlines[0]; - $subline =~ s/\A\s*//; - last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. - shift @doxygenlines; # dump this line from the array; we're using it. - if ($subline eq '') { # empty line, make sure it keeps the newline char. - $desc .= "\n"; - } else { - $desc .= " $subline"; - } - } - $desc =~ s/[\s\n]+\Z//ms; - - if (0) { # !!! FIXME: disabled because it's not currently suitable for general use, but for manually inspecting the output, it can be useful. - if (($desc =~ /\A[A-Z]/) && (not $desc =~ /\ASDL_/)) { - print STDERR "WARNING: $sym\'s '\\returns' text starts with a capital letter: '$desc'. Fixing.\n"; - $desc = lcfirst($desc); - } - } - - if (not $desc =~ /[\.\!]\Z/) { - print STDERR "WARNING: $sym\'s '\\returns' text doesn't end with punctuation: '$desc'. Fixing.\n"; - $desc .= '.'; - } - - # Make sure the \returns info is valid. - my $rettype = $headersymsrettype{$sym}; - die("Don't have a rettype for '$sym' for some reason!") if (($symtype == 1) && (not defined($rettype))); - if (defined($sections{'Return Value'})) { - print STDERR "WARNING: Symbol '$sym' has multiple '\\return' declarations! Only keeping the first one!\n"; - } elsif (($symtype != 1) && ($symtype != 2) && ($symtype != 5)) { # !!! FIXME: if 5, make sure it's a function pointer typedef! - print STDERR "WARNING: Symbol '$sym' has a '\\return' declaration but isn't a function or macro! Removing it!\n"; - } elsif (($symtype == 1) && ($headersymsrettype{$sym} eq 'void')) { - print STDERR "WARNING: Function '$sym' has a '\\returns' declaration but function returns void! Removing it!\n"; - } else { - my $rettypestr = defined($rettype) ? ('(' . wikify($wikitype, $rettype) . ') ') : ''; - $sections{'Return Value'} = wordwrap("$rettypestr$retstr ". wikify($wikitype, $desc)) . "\n"; - } - } elsif ($l =~ /\A\\deprecated\s+(.*)\Z/) { - my $desc = $1; - while (@doxygenlines) { - my $subline = $doxygenlines[0]; - $subline =~ s/\A\s*//; - last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. - shift @doxygenlines; # dump this line from the array; we're using it. - if ($subline eq '') { # empty line, make sure it keeps the newline char. - $desc .= "\n"; - } else { - $desc .= " $subline"; - } - } - $desc =~ s/[\s\n]+\Z//ms; - $sections{'Deprecated'} = wordwrap(wikify($wikitype, $desc)) . "\n"; - } elsif ($l =~ /\A\\since\s+(.*)\Z/) { - my $desc = $1; - while (@doxygenlines) { - my $subline = $doxygenlines[0]; - $subline =~ s/\A\s*//; - last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. - shift @doxygenlines; # dump this line from the array; we're using it. - if ($subline eq '') { # empty line, make sure it keeps the newline char. - $desc .= "\n"; - } else { - $desc .= " $subline"; - } - } - $desc =~ s/[\s\n]+\Z//ms; - $sections{'Version'} = wordwrap(wikify($wikitype, $desc)) . "\n"; - } elsif ($l =~ /\A\\threadsafety\s+(.*)\Z/) { - my $desc = $1; - while (@doxygenlines) { - my $subline = $doxygenlines[0]; - $subline =~ s/\A\s*//; - last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. - shift @doxygenlines; # dump this line from the array; we're using it. - if ($subline eq '') { # empty line, make sure it keeps the newline char. - $desc .= "\n"; - } else { - $desc .= " $subline"; - } - } - $desc =~ s/[\s\n]+\Z//ms; - $sections{'Thread Safety'} = wordwrap(wikify($wikitype, $desc)) . "\n"; - $has_threadsafety = 1; - } elsif ($l =~ /\A\\sa\s+(.*)\Z/) { - my $sa = $1; - $sa =~ s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" - $sections{'See Also'} = '' if not defined $sections{'See Also'}; - if ($wikitype eq 'mediawiki') { - $sections{'See Also'} .= ":[[$sa]]\n"; - } elsif ($wikitype eq 'md') { - $sections{'See Also'} .= "- [$sa]($sa)\n"; - } else { die("Expected wikitype '$wikitype'"); } - } - } - - if (($symtype == 1) && ($headersymsrettype{$sym} ne 'void') && !$has_returns) { - print STDERR "WARNING: Function '$sym' has a non-void return type but no '\\returns' declaration\n"; - } - - # !!! FIXME: uncomment this when we're trying to clean this up in the headers. - #if (($symtype == 1) && !$has_threadsafety) { - # print STDERR "WARNING: Function '$sym' doesn't have a '\\threadsafety' declaration\n"; - #} - - # Make sure %params is in the same order as the actual function signature and add C datatypes... - my $params_has_c_datatype = 0; - my @final_params = (); - if (($symtype == 1) && (defined($headersymsparaminfo{$sym}))) { # is a function and we have param info for it... - my $fnsigparams = $headersymsparaminfo{$sym}; - for (my $i = 0; $i < scalar(@$fnsigparams); $i += 2) { - my $paramname = @$fnsigparams[$i]; - my $paramdesc = $params{$paramname}; - if (defined($paramdesc)) { - push @final_params, $paramname; # name - push @final_params, @$fnsigparams[$i+1]; # C datatype - push @final_params, $paramdesc; # description - $params_has_c_datatype = 1 if (defined(@$fnsigparams[$i+1])); - } else { - print STDERR "WARNING: Symbol '$sym' is missing a '\\param $paramname' declaration!\n"; - } - } - } else { - foreach (@paramsorder) { - my $paramname = $_; - my $paramdesc = $params{$paramname}; - if (defined($paramdesc)) { - push @final_params, $_; - push @final_params, undef; - push @final_params, $paramdesc; - } - } - } - - my $hfiletext = $wikiheaderfiletext; - $hfiletext =~ s/\%fname\%/$headersymslocation{$sym}/g; - $sections{'Header File'} = "$hfiletext\n"; - - # Make sure this ends with a double-newline. - $sections{'See Also'} .= "\n" if defined $sections{'See Also'}; - - if (0) { # !!! FIXME: this was a useful hack, but this needs to be generalized if we're going to do this always. - # Plug in a \since section if one wasn't listed. - if (not defined $sections{'Version'}) { - my $symtypename; - if ($symtype == 1) { - $symtypename = 'function'; - } elsif ($symtype == 2) { - $symtypename = 'macro'; - } elsif ($symtype == 3) { - $symtypename = 'struct'; - } elsif ($symtype == 4) { - $symtypename = 'enum'; - } elsif ($symtype == 5) { - $symtypename = 'datatype'; - } else { - die("Unexpected symbol type $symtype!"); - } - my $str = "This $symtypename is available since SDL 3.0.0."; - $sections{'Version'} = wordwrap(wikify($wikitype, $str)) . "\n"; - } - } - - # We can build the wiki table now that we have all the data. - if (scalar(@final_params) > 0) { - my $str = ''; - if ($wikitype eq 'mediawiki') { - while (scalar(@final_params) > 0) { - my $arg = shift @final_params; - my $c_datatype = shift @final_params; - my $desc = wikify($wikitype, shift @final_params); - $c_datatype = '' if not defined $c_datatype; - $str .= ($str eq '') ? "{|\n" : "|-\n"; - $str .= "|$c_datatype\n" if $params_has_c_datatype; - $str .= "|'''$arg'''\n"; - $str .= "|$desc\n"; - } - $str .= "|}\n"; - } elsif ($wikitype eq 'md') { - my $longest_arg = 0; - my $longest_c_datatype = 0; - my $longest_desc = 0; - my $which = 0; - foreach (@final_params) { - if ($which == 0) { - my $len = length($_); - $longest_arg = $len if ($len > $longest_arg); - $which = 1; - } elsif ($which == 1) { - if (defined($_)) { - my $len = length(wikify($wikitype, $_)); - $longest_c_datatype = $len if ($len > $longest_c_datatype); - } - $which = 2; - } else { - my $len = length(wikify($wikitype, $_)); - $longest_desc = $len if ($len > $longest_desc); - $which = 0; - } - } - - # Markdown tables are sort of obnoxious. - my $c_datatype_cell; - $c_datatype_cell = ($longest_c_datatype > 0) ? ('| ' . (' ' x ($longest_c_datatype)) . ' ') : ''; - $str .= $c_datatype_cell . '| ' . (' ' x ($longest_arg+4)) . ' | ' . (' ' x $longest_desc) . " |\n"; - $c_datatype_cell = ($longest_c_datatype > 0) ? ('| ' . ('-' x ($longest_c_datatype)) . ' ') : ''; - $str .= $c_datatype_cell . '| ' . ('-' x ($longest_arg+4)) . ' | ' . ('-' x $longest_desc) . " |\n"; - - while (@final_params) { - my $arg = shift @final_params; - my $c_datatype = shift @final_params; - $c_datatype_cell = ''; - if ($params_has_c_datatype) { - $c_datatype = defined($c_datatype) ? wikify($wikitype, $c_datatype) : ''; - $c_datatype_cell = ($longest_c_datatype > 0) ? ("| $c_datatype " . (' ' x ($longest_c_datatype - length($c_datatype)))) : ''; - } - my $desc = wikify($wikitype, shift @final_params); - $str .= $c_datatype_cell . "| **$arg** " . (' ' x ($longest_arg - length($arg))) . "| $desc" . (' ' x ($longest_desc - length($desc))) . " |\n"; - } - } else { - die("Unexpected wikitype!"); # should have checked this elsewhere. - } - $sections{'Function Parameters'} = $str; - } - - my $path = "$wikipath/$sym.${wikitype}.tmp"; - open(FH, '>', $path) or die("Can't open '$path': $!\n"); - - my $sectionsref = $wikisyms{$sym}; - - foreach (@standard_wiki_sections) { - # drop sections we either replaced or removed from the original wiki's contents. - if (not defined $only_wiki_sections{$_}) { - delete($$sectionsref{$_}); - } - } - - my $wikisectionorderref = $wikisectionorder{$sym}; - - # Make sure there's a footer in the wiki that puts this function in CategoryAPI... - if (not $$sectionsref{'[footer]'}) { - $$sectionsref{'[footer]'} = ''; - push @$wikisectionorderref, '[footer]'; - } - - # If changing format, convert things that otherwise are passed through unmolested. - if (defined $changeformat) { - if (($dewikify_mode eq 'md') and ($origwikitype eq 'mediawiki')) { - $$sectionsref{'[footer]'} =~ s/\[\[(Category[a-zA-Z0-9_]+)\]\]/[$1]($1)/g; - } elsif (($dewikify_mode eq 'mediawiki') and ($origwikitype eq 'md')) { - $$sectionsref{'[footer]'} =~ s/\[(Category[a-zA-Z0-9_]+)\]\(.*?\)/[[$1]]/g; - } - - foreach (keys %only_wiki_sections) { - my $sect = $_; - if (defined $$sectionsref{$sect}) { - $$sectionsref{$sect} = wikify($wikitype, dewikify($origwikitype, $$sectionsref{$sect})); - } - } - } - - if ($symtype != -1) { # Don't do these in category documentation block - my $footer = $$sectionsref{'[footer]'}; - - my $symtypename; - if ($symtype == 1) { - $symtypename = 'Function'; - } elsif ($symtype == 2) { - $symtypename = 'Macro'; - } elsif ($symtype == 3) { - $symtypename = 'Struct'; - } elsif ($symtype == 4) { - $symtypename = 'Enum'; - } elsif ($symtype == 5) { - $symtypename = 'Datatype'; - } else { - die("Unexpected symbol type $symtype!"); - } - - my $symcategory = $headersymscategory{$sym}; - if ($wikitype eq 'mediawiki') { - $footer =~ s/\[\[CategoryAPI\]\],?\s*//g; - $footer =~ s/\[\[CategoryAPI${symtypename}\]\],?\s*//g; - $footer =~ s/\[\[Category${symcategory}\]\],?\s*//g if defined $symcategory; - $footer = "[[CategoryAPI]], [[CategoryAPI$symtypename]]" . (defined $symcategory ? ", [[Category$symcategory]]" : '') . (($footer eq '') ? "\n" : ", $footer"); - } elsif ($wikitype eq 'md') { - $footer =~ s/\[CategoryAPI\]\(CategoryAPI\),?\s*//g; - $footer =~ s/\[CategoryAPI${symtypename}\]\(CategoryAPI${symtypename}\),?\s*//g; - $footer =~ s/\[Category${symcategory}\]\(Category${symcategory}\),?\s*//g if defined $symcategory; - $footer = "[CategoryAPI](CategoryAPI), [CategoryAPI$symtypename](CategoryAPI$symtypename)" . (defined $symcategory ? ", [Category$symcategory](Category$symcategory)" : '') . (($footer eq '') ? '' : ', ') . $footer; - } else { die("Unexpected wikitype '$wikitype'"); } - $$sectionsref{'[footer]'} = $footer; - - if (defined $wikipreamble) { - my $wikified_preamble = wikify($wikitype, $wikipreamble); - if ($wikitype eq 'mediawiki') { - print FH "====== $wikified_preamble ======\n"; - } elsif ($wikitype eq 'md') { - print FH "###### $wikified_preamble\n"; - } else { die("Unexpected wikitype '$wikitype'"); } - } - } - - my $prevsectstr = ''; - my @ordered_sections = (@standard_wiki_sections, defined $wikisectionorderref ? @$wikisectionorderref : ()); # this copies the arrays into one. - foreach (@ordered_sections) { - my $sect = $_; - next if $sect eq '[start]'; - next if (not defined $sections{$sect} and not defined $$sectionsref{$sect}); - my $section = defined $sections{$sect} ? $sections{$sect} : $$sectionsref{$sect}; - - if ($sect eq '[footer]') { - # Make sure previous section ends with two newlines. - if (substr($prevsectstr, -1) ne "\n") { - print FH "\n\n"; - } elsif (substr($prevsectstr, -2) ne "\n\n") { - print FH "\n"; - } - print FH "----\n"; # It's the same in Markdown and MediaWiki. - } elsif ($sect eq '[Brief]') { - if ($wikitype eq 'mediawiki') { - print FH "= $sym =\n\n"; - } elsif ($wikitype eq 'md') { - print FH "# $sym\n\n"; - } else { die("Unexpected wikitype '$wikitype'"); } - } else { - my $sectname = $sect; - if ($sectname eq 'Function Parameters') { # We use this same table for different things depending on what we're documenting, so rename it now. - if (($symtype == 1) || ($symtype == 5)) { # function (or typedef, in case it's a function pointer type). - } elsif ($symtype == 2) { # macro - $sectname = 'Macro Parameters'; - } elsif ($symtype == 3) { # struct/union - $sectname = 'Fields'; - } elsif ($symtype == 4) { # enum - $sectname = 'Values'; - } else { - die("Unexpected symtype $symtype"); - } - } - - if ($symtype != -1) { # Not for category documentation block - if ($wikitype eq 'mediawiki') { - print FH "\n== $sectname ==\n\n"; - } elsif ($wikitype eq 'md') { - print FH "\n## $sectname\n\n"; - } else { die("Unexpected wikitype '$wikitype'"); } - } - } - - my $sectstr = defined $sections{$sect} ? $sections{$sect} : $$sectionsref{$sect}; - print FH $sectstr; - - $prevsectstr = $sectstr; - - # make sure these don't show up twice. - delete($sections{$sect}); - delete($$sectionsref{$sect}); - } - - print FH "\n\n"; - close(FH); - - if (defined $changeformat and ($origwikitype ne $wikitype)) { - system("cd '$wikipath' ; git mv '$_.${origwikitype}' '$_.${wikitype}'"); - unlink("$wikipath/$_.${origwikitype}"); - } - - rename($path, "$wikipath/$_.${wikitype}") or die("Can't rename '$path' to '$wikipath/$_.${wikitype}': $!\n"); - } - - # Write out simple redirector pages if they don't already exist. - foreach (keys %referenceonly) { - my $sym = $_; - my $refersto = $referenceonly{$sym}; - my $path = "$wikipath/$sym.md"; # we only do Markdown for these. - next if (-f $path); # don't overwrite if it already exists. Delete the file if you need a rebuild! - open(FH, '>', $path) or die("Can't open '$path': $!\n"); - - if (defined $wikipreamble) { - my $wikified_preamble = wikify('md', $wikipreamble); - print FH "###### $wikified_preamble\n"; - } - - my $category = 'CategoryAPIMacro'; - if ($headersymstype{$refersto} == 4) { - $category = 'CategoryAPIEnumerators'; # NOT CategoryAPIEnum! - } - - print FH "# $sym\n\nPlease refer to [$refersto]($refersto) for details.\n\n"; - print FH "----\n"; - print FH "[CategoryAPI](CategoryAPI), [$category]($category)\n\n"; - - close(FH); - } - - # Write out Category pages... - foreach (keys %headercategorydocs) { - my $cat = $_; - my $sym = $headercategorydocs{$cat}; # fake symbol - my $raw = $headersyms{$sym}; # raw doxygen text with comment characters stripped from start/end and start of each line. - my $wikitype = defined($wikitypes{$sym}) ? $wikitypes{$sym} : 'md'; - my $path = "$wikipath/Category$cat.$wikitype"; - - $raw = wordwrap(wikify($wikitype, $raw)); - - my $tmppath = "$path.tmp"; - open(FH, '>', $tmppath) or die("Can't open '$tmppath': $!\n"); - print FH "$raw\n\n"; - - if (! -f $path) { # Doesn't exist at all? Write out a template file. - # If writing from scratch, it's always a Markdown file. - die("Unexpected wikitype '$wikitype'!") if $wikitype ne 'md'; - print FH <<__EOF__ - - - -## Functions - - - - - -## Datatypes - - - - - -## Structs - - - - - -## Enums - - - - - -## Macros - - - - - ----- -[CategoryAPICategory](CategoryAPICategory) - -__EOF__ -; - } else { - my $endstr = $wikisyms{$sym}->{'[footer]'}; - if (defined($endstr)) { - print FH $endstr; - } - } - - close(FH); - rename($tmppath, $path) or die("Can't rename '$tmppath' to '$path': $!\n"); - } - - # Write out READMEs... - if (defined $readmepath) { - if ( -d $readmepath ) { - mkdir($wikireadmepath); # just in case - opendir(DH, $readmepath) or die("Can't opendir '$readmepath': $!\n"); - while (my $d = readdir(DH)) { - my $dent = $d; - if ($dent =~ /\AREADME\-(.*?\.md)\Z/) { # we only bridge Markdown files here. - my $wikifname = $1; - next if $wikifname eq 'FrontPage.md'; - filecopy("$readmepath/$dent", "$wikireadmepath/$wikifname", "\n"); - } - } - closedir(DH); - - my @pages = (); - opendir(DH, $wikireadmepath) or die("Can't opendir '$wikireadmepath': $!\n"); - while (my $d = readdir(DH)) { - my $dent = $d; - if ($dent =~ /\A(.*?)\.(mediawiki|md)\Z/) { - my $wikiname = $1; - next if $wikiname eq 'FrontPage'; - push @pages, $wikiname; - } - } - closedir(DH); - - open(FH, '>', "$wikireadmepath/FrontPage.md") or die("Can't open '$wikireadmepath/FrontPage.md': $!\n"); - print FH "# All READMEs available here\n\n"; - foreach (sort @pages) { - my $wikiname = $_; - print FH "- [$wikiname]($wikiname)\n"; - } - close(FH); - } - } - - # Write out quick reference pages... - if ($quickrefenabled) { - generate_quickref(\%briefs, "$wikipath/QuickReference.md", 0); - generate_quickref(\%briefs, "$wikipath/QuickReferenceNoUnicode.md", 1); - } -} elsif ($copy_direction == -2) { # --copy-to-manpages - # This only takes from the wiki data, since it has sections we omit from the headers, like code examples. - - File::Path::make_path("$manpath/man3"); - - $dewikify_mode = 'manpage'; - $wordwrap_mode = 'manpage'; - - my $introtxt = ''; - if (0) { - open(FH, '<', "$srcpath/LICENSE.txt") or die("Can't open '$srcpath/LICENSE.txt': $!\n"); - while () { - chomp; - $introtxt .= ".\\\" $_\n"; - } - close(FH); - } - - if (!$gitrev) { - $gitrev = `cd "$srcpath" ; git rev-list HEAD~..`; - chomp($gitrev); - } - - # !!! FIXME - open(FH, '<', "$srcpath/$versionfname") or die("Can't open '$srcpath/$versionfname': $!\n"); - my $majorver = 0; - my $minorver = 0; - my $microver = 0; - while () { - chomp; - if (/$versionmajorregex/) { - $majorver = int($1); - } elsif (/$versionminorregex/) { - $minorver = int($1); - } elsif (/$versionmicroregex/) { - $microver = int($1); - } - } - close(FH); - my $fullversion = "$majorver.$minorver.$microver"; - - foreach (keys %headersyms) { - my $sym = $_; - next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it. - next if $sym =~ /\A\[category documentation\]/; # not real symbols - next if (defined $manpagesymbolfilterregex) && ($sym =~ /$manpagesymbolfilterregex/); - my $symtype = $headersymstype{$sym}; - my $wikitype = $wikitypes{$sym}; - my $sectionsref = $wikisyms{$sym}; - my $remarks = $sectionsref->{'Remarks'}; - my $params = $sectionsref->{'Function Parameters'}; - my $returns = $sectionsref->{'Return Value'}; - my $version = $sectionsref->{'Version'}; - my $threadsafety = $sectionsref->{'Thread Safety'}; - my $related = $sectionsref->{'See Also'}; - my $examples = $sectionsref->{'Code Examples'}; - my $deprecated = $sectionsref->{'Deprecated'}; - my $headerfile = $manpageheaderfiletext; - $headerfile =~ s/\%fname\%/$headersymslocation{$sym}/g; - $headerfile .= "\n"; - - my $mansection; - my $mansectionname; - if (($symtype == 1) || ($symtype == 2)) { # functions or macros - $mansection = '3'; - $mansectionname = 'FUNCTIONS'; - } elsif (($symtype >= 3) && ($symtype <= 5)) { # struct/union/enum/typedef - $mansection = '3type'; - $mansectionname = 'DATATYPES'; - } else { - die("Unexpected symtype $symtype"); - } - - my $brief = $sectionsref->{'[Brief]'}; - my $decl = $headerdecls{$sym}; - my $str = ''; - - # the "$brief" makes sure this is a copy of the string, which is doing some weird reference thing otherwise. - $brief = defined $brief ? "$brief" : ''; - $brief =~ s/\A[\s\n]*\= .*? \=\s*?\n+//ms; - $brief =~ s/\A[\s\n]*\=\= .*? \=\=\s*?\n+//ms; - $brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. - my @briefsplit = split /\n/, $brief; - $brief = shift @briefsplit; - $brief = dewikify($wikitype, $brief); - - if (defined $remarks) { - $remarks = dewikify($wikitype, join("\n", @briefsplit) . $remarks); - } - - $str .= $introtxt; - - $str .= ".\\\" This manpage content is licensed under Creative Commons\n"; - $str .= ".\\\" Attribution 4.0 International (CC BY 4.0)\n"; - $str .= ".\\\" https://creativecommons.org/licenses/by/4.0/\n"; - $str .= ".\\\" This manpage was generated from ${projectshortname}'s wiki page for $sym:\n"; - $str .= ".\\\" $wikiurl/$sym\n"; - $str .= ".\\\" Generated with SDL/build-scripts/wikiheaders.pl\n"; - $str .= ".\\\" revision $gitrev\n" if $gitrev ne ''; - $str .= ".\\\" Please report issues in this manpage's content at:\n"; - $str .= ".\\\" $bugreporturl\n"; - $str .= ".\\\" Please report issues in the generation of this manpage from the wiki at:\n"; - $str .= ".\\\" https://github.com/libsdl-org/SDL/issues/new?title=Misgenerated%20manpage%20for%20$sym\n"; - $str .= ".\\\" $projectshortname can be found at $projecturl\n"; - - # Define a .URL macro. The "www.tmac" thing decides if we're using GNU roff (which has a .URL macro already), and if so, overrides the macro we just created. - # This wizadry is from https://web.archive.org/web/20060102165607/http://people.debian.org/~branden/talks/wtfm/wtfm.pdf - $str .= ".de URL\n"; - $str .= '\\$2 \(laURL: \\$1 \(ra\\$3' . "\n"; - $str .= "..\n"; - $str .= '.if \n[.g] .mso www.tmac' . "\n"; - - $str .= ".TH $sym $mansection \"$projectshortname $fullversion\" \"$projectfullname\" \"$projectshortname$majorver $mansectionname\"\n"; - $str .= ".SH NAME\n"; - - $str .= "$sym"; - $str .= " \\- $brief" if (defined $brief); - $str .= "\n"; - - if (defined $deprecated) { - $str .= ".SH DEPRECATED\n"; - $str .= dewikify($wikitype, $deprecated) . "\n"; - } - - if (defined $headerfile) { - $str .= ".SH HEADER FILE\n"; - $str .= dewikify($wikitype, $headerfile) . "\n"; - } - - $str .= ".SH SYNOPSIS\n"; - $str .= ".nf\n"; - $str .= ".B #include \\(dq$mainincludefname\\(dq\n"; - $str .= ".PP\n"; - - my @decllines = split /\n/, $decl; - foreach (@decllines) { - $str .= ".BI \"$_\n"; - } - $str .= ".fi\n"; - - if (defined $remarks) { - $str .= ".SH DESCRIPTION\n"; - $str .= $remarks . "\n"; - } - - if (defined $params) { - if (($symtype == 1) || ($symtype == 5)) { - $str .= ".SH FUNCTION PARAMETERS\n"; - } elsif ($symtype == 2) { # macro - $str .= ".SH MACRO PARAMETERS\n"; - } elsif ($symtype == 3) { # struct/union - $str .= ".SH FIELDS\n"; - } elsif ($symtype == 4) { # enum - $str .= ".SH VALUES\n"; - } else { - die("Unexpected symtype $symtype"); - } - - my @lines = split /\n/, $params; - if ($wikitype eq 'mediawiki') { - die("Unexpected data parsing MediaWiki table") if (shift @lines ne '{|'); # Dump the '{|' start - while (scalar(@lines) >= 3) { - my $c_datatype = shift @lines; - my $name = shift @lines; - my $desc = shift @lines; - my $terminator; # the '|-' or '|}' line. - - if (($desc eq '|-') or ($desc eq '|}') or (not $desc =~ /\A\|/)) { # we seem to be out of cells, which means there was no datatype column on this one. - $terminator = $desc; - $desc = $name; - $name = $c_datatype; - $c_datatype = ''; - } else { - $terminator = shift @lines; - } - - last if ($terminator ne '|-') and ($terminator ne '|}'); # we seem to have run out of table. - $name =~ s/\A\|\s*//; - $name =~ s/\A\*\*(.*?)\*\*/$1/; - $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; - $desc =~ s/\A\|\s*//; - $desc = dewikify($wikitype, $desc); - #print STDERR "SYM: $sym CDATATYPE: $c_datatype NAME: $name DESC: $desc TERM: $terminator\n"; - - $str .= ".TP\n"; - $str .= ".I $name\n"; - $str .= "$desc\n"; - } - } elsif ($wikitype eq 'md') { - my $l; - $l = shift @lines; - die("Unexpected data parsing Markdown table") if (not $l =~ /\A(\s*\|)?\s*\|\s*\|\s*\|\s*\Z/); - $l = shift @lines; - die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*(\|\s*\-*\s*)?\|\s*\-*\s*\|\s*\-*\s*\|\s*\Z/); - while (scalar(@lines) >= 1) { - $l = shift @lines; - my $name; - my $desc; - if ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { - # c datatype is $1, but we don't care about it here. - $name = $2; - $desc = $3; - } elsif ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { - $name = $1; - $desc = $2; - } else { - last; # we seem to have run out of table. - } - - $name =~ s/\A\*\*(.*?)\*\*/$1/; - $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; - $desc = dewikify($wikitype, $desc); - - $str .= ".TP\n"; - $str .= ".I $name\n"; - $str .= "$desc\n"; - } - } else { - die("write me"); - } - } - - if (defined $returns) { - $returns = dewikify($wikitype, $returns); - $returns =~ s/\A\(.*?\)\s*//; # Chop datatype in parentheses off the front. - $str .= ".SH RETURN VALUE\n"; - $str .= "$returns\n"; - } - - if (defined $examples) { - $str .= ".SH CODE EXAMPLES\n"; - $dewikify_manpage_code_indent = 0; - $str .= dewikify($wikitype, $examples) . "\n"; - $dewikify_manpage_code_indent = 1; - } - - if (defined $threadsafety) { - $str .= ".SH THREAD SAFETY\n"; - $str .= dewikify($wikitype, $threadsafety) . "\n"; - } - - if (defined $version) { - $str .= ".SH AVAILABILITY\n"; - $str .= dewikify($wikitype, $version) . "\n"; - } - - if (defined $related) { - $str .= ".SH SEE ALSO\n"; - # !!! FIXME: lots of code duplication in all of these. - my $v = dewikify($wikitype, $related); - my @desclines = split /\n/, $v; - my $nextstr = ''; - foreach (@desclines) { - s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" - s/\[\[(.*?)\]\]/$1/; # in case some wikilinks remain. - s/\[(.*?)\]\(.*?\)/$1/; # in case some wikilinks remain. - s/\A\*\s*\Z//; - s/\A\/*//; - s/\A\.BR\s+//; # dewikify added this, but we want to handle it. - s/\A\.I\s+//; # dewikify added this, but we want to handle it. - s/\A\s*[\:\*\-]\s*//; - s/\A\s+//; - s/\s+\Z//; - next if $_ eq ''; - my $seealso_symtype = $headersymstype{$_}; - my $seealso_mansection = '3'; - if (defined($seealso_symtype) && ($seealso_symtype >= 3) && ($seealso_symtype <= 5)) { # struct/union/enum/typedef - $seealso_mansection = '3type'; - } - $str .= "$nextstr.BR $_ ($seealso_mansection)"; - $nextstr = ",\n"; - } - $str .= "\n"; - } - - if (0) { - $str .= ".SH COPYRIGHT\n"; - $str .= "This manpage is licensed under\n"; - $str .= ".UR https://creativecommons.org/licenses/by/4.0/\n"; - $str .= "Creative Commons Attribution 4.0 International (CC BY 4.0)\n"; - $str .= ".UE\n"; - $str .= ".PP\n"; - $str .= "This manpage was generated from\n"; - $str .= ".UR $wikiurl/$sym\n"; - $str .= "${projectshortname}'s wiki\n"; - $str .= ".UE\n"; - $str .= "using SDL/build-scripts/wikiheaders.pl"; - $str .= " revision $gitrev" if $gitrev ne ''; - $str .= ".\n"; - $str .= "Please report issues in this manpage at\n"; - $str .= ".UR $bugreporturl\n"; - $str .= "our bugtracker!\n"; - $str .= ".UE\n"; - } - - my $path = "$manpath/man3/$_.$mansection"; - my $tmppath = "$path.tmp"; - open(FH, '>', $tmppath) or die("Can't open '$tmppath': $!\n"); - print FH $str; - close(FH); - rename($tmppath, $path) or die("Can't rename '$tmppath' to '$path': $!\n"); - } - -} elsif ($copy_direction == -4) { # --copy-to-latex - # This only takes from the wiki data, since it has sections we omit from the headers, like code examples. - - print STDERR "\n(The --copy-to-latex code is known to not be ready for serious use; send patches, not bug reports, please.)\n\n"; - - $dewikify_mode = 'LaTeX'; - $wordwrap_mode = 'LaTeX'; - - # !!! FIXME: code duplication with --copy-to-manpages section. - - my $introtxt = ''; - if (0) { - open(FH, '<', "$srcpath/LICENSE.txt") or die("Can't open '$srcpath/LICENSE.txt': $!\n"); - while () { - chomp; - $introtxt .= ".\\\" $_\n"; - } - close(FH); - } - - if (!$gitrev) { - $gitrev = `cd "$srcpath" ; git rev-list HEAD~..`; - chomp($gitrev); - } - - # !!! FIXME - open(FH, '<', "$srcpath/$versionfname") or die("Can't open '$srcpath/$versionfname': $!\n"); - my $majorver = 0; - my $minorver = 0; - my $microver = 0; - while () { - chomp; - if (/$versionmajorregex/) { - $majorver = int($1); - } elsif (/$versionminorregex/) { - $minorver = int($1); - } elsif (/$versionmicroregex/) { - $microver = int($1); - } - } - close(FH); - my $fullversion = "$majorver.$minorver.$microver"; - - my $latex_fname = "$srcpath/$projectshortname.tex"; - my $latex_tmpfname = "$latex_fname.tmp"; - open(TEXFH, '>', "$latex_tmpfname") or die("Can't open '$latex_tmpfname' for writing: $!\n"); - - print TEXFH <<__EOF__ -\\documentclass{book} - -\\usepackage{listings} -\\usepackage{color} -\\usepackage{hyperref} - -\\definecolor{dkgreen}{rgb}{0,0.6,0} -\\definecolor{gray}{rgb}{0.5,0.5,0.5} -\\definecolor{mauve}{rgb}{0.58,0,0.82} - -\\setcounter{secnumdepth}{0} - -\\lstset{frame=tb, - language=C, - aboveskip=3mm, - belowskip=3mm, - showstringspaces=false, - columns=flexible, - basicstyle={\\small\\ttfamily}, - numbers=none, - numberstyle=\\tiny\\color{gray}, - keywordstyle=\\color{blue}, - commentstyle=\\color{dkgreen}, - stringstyle=\\color{mauve}, - breaklines=true, - breakatwhitespace=true, - tabsize=3 -} - -\\begin{document} -\\frontmatter - -\\title{$projectfullname $majorver.$minorver.$microver Reference Manual} -\\author{The $projectshortname Developers} -\\maketitle - -\\mainmatter - -__EOF__ -; - - # !!! FIXME: Maybe put this in the book intro? print TEXFH $introtxt; - - # Sort symbols by symbol type, then alphabetically. - my @headersymskeys = sort { - my $symtypea = $headersymstype{$a}; - my $symtypeb = $headersymstype{$b}; - $symtypea = 3 if ($symtypea > 3); - $symtypeb = 3 if ($symtypeb > 3); - my $rc = $symtypea <=> $symtypeb; - if ($rc == 0) { - $rc = lc($a) cmp lc($b); - } - return $rc; - } keys %headersyms; - - my $current_symtype = 0; - my $current_chapter = ''; - - foreach (@headersymskeys) { - my $sym = $_; - next if not defined $wikisyms{$sym}; # don't have a page for that function, skip it. - next if $sym =~ /\A\[category documentation\]/; # not real symbols. - my $symtype = $headersymstype{$sym}; - my $wikitype = $wikitypes{$sym}; - my $sectionsref = $wikisyms{$sym}; - my $remarks = $sectionsref->{'Remarks'}; - my $params = $sectionsref->{'Function Parameters'}; - my $returns = $sectionsref->{'Return Value'}; - my $version = $sectionsref->{'Version'}; - my $threadsafety = $sectionsref->{'Thread Safety'}; - my $related = $sectionsref->{'See Also'}; - my $examples = $sectionsref->{'Code Examples'}; - my $deprecated = $sectionsref->{'Deprecated'}; - my $headerfile = $manpageheaderfiletext; - $headerfile =~ s/\%fname\%/$headersymslocation{$sym}/g; - $headerfile .= "\n"; - - my $brief = $sectionsref->{'[Brief]'}; - my $decl = $headerdecls{$sym}; - my $str = ''; - - if ($current_symtype != $symtype) { - my $newchapter = ''; - if ($symtype == 1) { - $newchapter = 'Functions'; - } elsif ($symtype == 2) { - $newchapter = 'Macros'; - } else { - $newchapter = 'Datatypes'; - } - - if ($current_chapter ne $newchapter) { - $str .= "\n\n\\chapter{$projectshortname $newchapter}\n\n\\clearpage\n\n"; - $current_chapter = $newchapter; - } - $current_symtype = $symtype; - } - - $brief = "$brief"; - $brief =~ s/\A[\s\n]*\= .*? \=\s*?\n+//ms; - $brief =~ s/\A[\s\n]*\=\= .*? \=\=\s*?\n+//ms; - $brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. - my @briefsplit = split /\n/, $brief; - $brief = shift @briefsplit; - $brief = dewikify($wikitype, $brief); - - if (defined $remarks) { - $remarks = dewikify($wikitype, join("\n", @briefsplit) . $remarks); - } - - my $escapedsym = escLaTeX($sym); - $str .= "\\hypertarget{$sym}{%\n\\section{$escapedsym}\\label{$sym}}\n\n"; - $str .= $brief if (defined $brief); - $str .= "\n\n"; - - if (defined $deprecated) { - $str .= "\\subsection{Deprecated}\n\n"; - $str .= dewikify($wikitype, $deprecated) . "\n"; - } - - if (defined $headerfile) { - $str .= "\\subsection{Header File}\n\n"; - $str .= dewikify($wikitype, $headerfile) . "\n"; - } - - $str .= "\\subsection{Syntax}\n\n"; - $str .= "\\begin{lstlisting}\n$decl\n\\end{lstlisting}\n"; - - if (defined $params) { - if (($symtype == 1) || ($symtype == 5)) { - $str .= "\\subsection{Function Parameters}\n\n"; - } elsif ($symtype == 2) { # macro - $str .= "\\subsection{Macro Parameters}\n\n"; - } elsif ($symtype == 3) { # struct/union - $str .= "\\subsection{Fields}\n\n"; - } elsif ($symtype == 4) { # enum - $str .= "\\subsection{Values}\n\n"; - } else { - die("Unexpected symtype $symtype"); - } - - $str .= "\\begin{center}\n"; - $str .= " \\begin{tabular}{ | l | p{0.75\\textwidth} |}\n"; - $str .= " \\hline\n"; - - # !!! FIXME: this table parsing has gotten complicated and is pasted three times in this file; move it to a subroutine! - my @lines = split /\n/, $params; - if ($wikitype eq 'mediawiki') { - die("Unexpected data parsing MediaWiki table") if (shift @lines ne '{|'); # Dump the '{|' start - while (scalar(@lines) >= 3) { - my $name = shift @lines; - my $desc = shift @lines; - my $terminator = shift @lines; # the '|-' or '|}' line. - last if ($terminator ne '|-') and ($terminator ne '|}'); # we seem to have run out of table. - $name =~ s/\A\|\s*//; - $name =~ s/\A\*\*(.*?)\*\*/$1/; - $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; - $name = escLaTeX($name); - $desc =~ s/\A\|\s*//; - $desc = dewikify($wikitype, $desc); - #print STDERR "FN: $sym NAME: $name DESC: $desc TERM: $terminator\n"; - $str .= " \\textbf{$name} & $desc \\\\ \\hline\n"; - } - } elsif ($wikitype eq 'md') { - my $l; - $l = shift @lines; - die("Unexpected data parsing Markdown table") if (not $l =~ /\A(\s*\|)?\s*\|\s*\|\s*\|\s*\Z/); - $l = shift @lines; - die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*(\|\s*\-*\s*)?\|\s*\-*\s*\|\s*\-*\s*\|\s*\Z/); - while (scalar(@lines) >= 1) { - $l = shift @lines; - my $name; - my $desc; - if ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { - # c datatype is $1, but we don't care about it here. - $name = $2; - $desc = $3; - } elsif ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { - $name = $1; - $desc = $2; - } else { - last; # we seem to have run out of table. - } - - $name =~ s/\A\*\*(.*?)\*\*/$1/; - $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; - $name = escLaTeX($name); - $desc = dewikify($wikitype, $desc); - $str .= " \\textbf{$name} & $desc \\\\ \\hline\n"; - } - } else { - die("write me"); - } - - $str .= " \\end{tabular}\n"; - $str .= "\\end{center}\n"; - } - - if (defined $returns) { - $returns = dewikify($wikitype, $returns); - $returns =~ s/\A\(.*?\)\s*//; # Chop datatype in parentheses off the front. - $str .= "\\subsection{Return Value}\n\n"; - $str .= "$returns\n"; - } - - if (defined $remarks) { - $str .= "\\subsection{Remarks}\n\n"; - $str .= $remarks . "\n"; - } - - if (defined $examples) { - $str .= "\\subsection{Code Examples}\n\n"; - $dewikify_manpage_code_indent = 0; - $str .= dewikify($wikitype, $examples) . "\n"; - $dewikify_manpage_code_indent = 1; - } - - if (defined $threadsafety) { - $str .= "\\subsection{Thread Safety}\n\n"; - $str .= dewikify($wikitype, $threadsafety) . "\n"; - } - - if (defined $version) { - $str .= "\\subsection{Version}\n\n"; - $str .= dewikify($wikitype, $version) . "\n"; - } - - if (defined $related) { - $str .= "\\subsection{See Also}\n\n"; - $str .= "\\begin{itemize}\n"; - # !!! FIXME: lots of code duplication in all of these. - my $v = dewikify($wikitype, $related); - my @desclines = split /\n/, $v; - my $nextstr = ''; - foreach (@desclines) { - s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" - s/\[\[(.*?)\]\]/$1/; # in case some wikilinks remain. - s/\[(.*?)\]\(.*?\)/$1/; # in case some wikilinks remain. - s/\A\*\s*\Z//; - s/\A\s*\\item\s*//; - s/\A\/*//; - s/\A\s*[\:\*\-]\s*//; - s/\A\s+//; - s/\s+\Z//; - next if $_ eq ''; - next if $_ eq '\begin{itemize}'; - next if $_ eq '\end{itemize}'; - $str .= " \\item $_\n"; - } - $str .= "\\end{itemize}\n"; - $str .= "\n"; - } - - # !!! FIXME: Maybe put copyright in the book intro? - if (0) { - $str .= ".SH COPYRIGHT\n"; - $str .= "This manpage is licensed under\n"; - $str .= ".UR https://creativecommons.org/licenses/by/4.0/\n"; - $str .= "Creative Commons Attribution 4.0 International (CC BY 4.0)\n"; - $str .= ".UE\n"; - $str .= ".PP\n"; - $str .= "This manpage was generated from\n"; - $str .= ".UR $wikiurl/$sym\n"; - $str .= "${projectshortname}'s wiki\n"; - $str .= ".UE\n"; - $str .= "using SDL/build-scripts/wikiheaders.pl"; - $str .= " revision $gitrev" if $gitrev ne ''; - $str .= ".\n"; - $str .= "Please report issues in this manpage at\n"; - $str .= ".UR $bugreporturl\n"; - $str .= "our bugtracker!\n"; - $str .= ".UE\n"; - } - - $str .= "\\clearpage\n\n"; - - print TEXFH $str; - } - - print TEXFH "\\end{document}\n\n"; - close(TEXFH); - rename($latex_tmpfname, $latex_fname) or die("Can't rename '$latex_tmpfname' to '$latex_fname': $!\n"); - -} elsif ($copy_direction == -3) { # --report-coverage-gaps - foreach (@coverage_gap) { - print("$_\n"); - } -} - -# end of wikiheaders.pl ... - -- cgit v1.2.3