Browse Source

Update to physfs 3.2.0.

Brucey 2 years ago
parent
commit
026ccde705
30 changed files with 487 additions and 214 deletions
  1. 1 1
      physfs.mod/physfs/.gitignore
  2. 0 6
      physfs.mod/physfs/.hg_archival.txt
  3. 0 17
      physfs.mod/physfs/.hgtags
  4. 105 73
      physfs.mod/physfs/CMakeLists.txt
  5. 16 22
      physfs.mod/physfs/LICENSE.txt
  6. 1 1
      physfs.mod/physfs/docs/CHANGELOG.txt
  7. 3 3
      physfs.mod/physfs/extras/buildbot-checker.sh
  8. 93 0
      physfs.mod/physfs/extras/uninstall.sh
  9. 81 26
      physfs.mod/physfs/src/physfs.c
  10. 4 2
      physfs.mod/physfs/src/physfs.h
  11. 1 1
      physfs.mod/physfs/src/physfs_archiver_7z.c
  12. 1 1
      physfs.mod/physfs/src/physfs_archiver_grp.c
  13. 1 1
      physfs.mod/physfs/src/physfs_archiver_hog.c
  14. 3 2
      physfs.mod/physfs/src/physfs_archiver_iso9660.c
  15. 1 1
      physfs.mod/physfs/src/physfs_archiver_mvl.c
  16. 2 1
      physfs.mod/physfs/src/physfs_archiver_qpak.c
  17. 3 2
      physfs.mod/physfs/src/physfs_archiver_slb.c
  18. 2 2
      physfs.mod/physfs/src/physfs_archiver_unpacked.c
  19. 2 1
      physfs.mod/physfs/src/physfs_archiver_vdf.c
  20. 1 1
      physfs.mod/physfs/src/physfs_archiver_wad.c
  21. 12 4
      physfs.mod/physfs/src/physfs_archiver_zip.c
  22. 57 10
      physfs.mod/physfs/src/physfs_internal.h
  23. 3 0
      physfs.mod/physfs/src/physfs_lzmasdk.h
  24. 13 5
      physfs.mod/physfs/src/physfs_miniz.h
  25. 19 6
      physfs.mod/physfs/src/physfs_platform_apple.m
  26. 4 4
      physfs.mod/physfs/src/physfs_platform_os2.c
  27. 40 8
      physfs.mod/physfs/src/physfs_platform_posix.c
  28. 5 5
      physfs.mod/physfs/src/physfs_platform_windows.c
  29. 12 7
      physfs.mod/physfs/src/physfs_unicode.c
  30. 1 1
      physfs.mod/physfs/test/test_physfs.c

+ 1 - 1
physfs.mod/physfs/.hgignore → physfs.mod/physfs/.gitignore

@@ -1,2 +1,2 @@
-syntax:glob
 cmake-build
 cmake-build
+

+ 0 - 6
physfs.mod/physfs/.hg_archival.txt

@@ -1,6 +0,0 @@
-repo: 7672c9962ce627edaaa67ff54fe4ad8f9a46dc2b
-node: acdcf93d1f9b83e10728386354004f893d560d3b
-branch: default
-latesttag: release-3.0.0
-latesttagdistance: 45
-changessincelatesttag: 45

+ 0 - 17
physfs.mod/physfs/.hgtags

@@ -1,17 +0,0 @@
-0bb92a5f0fffd2452cc737346e8b796c213a5688 release-0.1.1
-2f2afcbd8abd784f738ac45b0368044763d63748 release-0.1.0
-3c7cf50a58fbf220154acd4bdfdf00a21f259eb7 release-0.1.8
-473b50402f55b2340fc286775d1b78d18a810362 release-0.1.3
-60b5f566a2585d78b2ffadd8d9c16299d0340820 release-1.0.0
-67aff4091bf129f7167ed87f937b15f31093e19e release-0.1.9
-6ad1722bbcaec1265cb74c9b7be13fe02a547d37 release-0.1.7
-8f3ccaaea1cd5dc19235882494d6102e5e9176fb release-0.1.2
-c966316c89981bea6ccaa2c2909bb303bfeeb82b release-0.1.6
-d2f04ab4b4127757234af6b30bfc98ad4ee9cb15 release-0.1.4
-d94f1ccac8095509c57ad640d54796aea0d260f0 release-0.1.5
-fe0c1d6f40afa6fca09a277a1ade59231f16c66f release-1.1.1
-5d70fca3be361258edfb59c3edaba5abe75a1e88 release-2.0.0
-df04959950eb3830c39adfa983789f70f86062d7 release-1.1.0
-3396e6dd19fbb52a3fa7e171ffb38ed9acb285a4 release-2.1.1
-ebe0ee3b78101fd526946f55367a69b30195e683 release-3.0.0
-fa8e38bcc3545000a38704b65b604a2c1b764d10 release-3.0.1

+ 105 - 73
physfs.mod/physfs/CMakeLists.txt

@@ -9,27 +9,29 @@
 #  compile, using preprocessor checks for platform-specific bits instead of
 #  compile, using preprocessor checks for platform-specific bits instead of
 #  testing in here.
 #  testing in here.
 
 
-cmake_minimum_required(VERSION 2.8.12)
+set(PHYSFS_VERSION 3.3.0)
 
 
-project(PhysicsFS)
-set(PHYSFS_VERSION 3.1.0)
+cmake_minimum_required(VERSION 3.0)
+
+project(PhysicsFS VERSION ${PHYSFS_VERSION} LANGUAGES C )
+
+include(GNUInstallDirs)
 
 
 # Increment this if/when we break backwards compatibility.
 # Increment this if/when we break backwards compatibility.
 set(PHYSFS_SOVERSION 1)
 set(PHYSFS_SOVERSION 1)
 
 
-# I hate that they define "WIN32" ... we're about to move to Win64...I hope!
-if(WIN32 AND NOT WINDOWS)
-    set(WINDOWS TRUE)
-endif()
+set(PHYSFS_M_SRCS)
+set(PHYSFS_CPP_SRCS)
 
 
-include_directories(./src)
+# I hate that they define "WIN32" ... we're about to move to Win64...I hope!
 
 
 if(APPLE)
 if(APPLE)
     set(OTHER_LDFLAGS ${OTHER_LDFLAGS} "-framework IOKit -framework Foundation")
     set(OTHER_LDFLAGS ${OTHER_LDFLAGS} "-framework IOKit -framework Foundation")
-    set(PHYSFS_M_SRCS src/physfs_platform_apple.m)
+    list(APPEND PHYSFS_M_SRCS src/physfs_platform_apple.m)
 endif()
 endif()
 
 
-if(CMAKE_COMPILER_IS_GNUCC)
+if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+    add_compile_options(-Wall)
     # Don't use -rpath.
     # Don't use -rpath.
     set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
     set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
 endif()
 endif()
@@ -42,10 +44,10 @@ endif()
 if(HAIKU)
 if(HAIKU)
     # We add this explicitly, since we don't want CMake to think this
     # We add this explicitly, since we don't want CMake to think this
     #  is a C++ project unless we're on Haiku.
     #  is a C++ project unless we're on Haiku.
-    set(PHYSFS_CPP_SRCS src/physfs_platform_haiku.cpp)
+    list(APPEND PHYSFS_CPP_SRCS src/physfs_platform_haiku.cpp)
     find_library(BE_LIBRARY be)
     find_library(BE_LIBRARY be)
     find_library(ROOT_LIBRARY root)
     find_library(ROOT_LIBRARY root)
-    set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${BE_LIBRARY} ${ROOT_LIBRARY})
+    list(APPEND OPTIONAL_LIBRARY_LIBS ${BE_LIBRARY} ${ROOT_LIBRARY})
 endif()
 endif()
 
 
 if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" OR CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
 if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" OR CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
@@ -53,16 +55,20 @@ if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" OR CMAKE_SYSTEM_NAME STREQUAL "Wind
 endif()
 endif()
 
 
 if(WINRT)
 if(WINRT)
-    set(PHYSFS_CPP_SRCS src/physfs_platform_winrt.cpp)
+    list(APPEND PHYSFS_CPP_SRCS src/physfs_platform_winrt.cpp)
 endif()
 endif()
 
 
-if(UNIX AND NOT WINDOWS AND NOT APPLE)  # (MingW and such might be UNIX _and_ WINDOWS!)
+if(UNIX AND NOT WIN32 AND NOT APPLE)  # (MingW and such might be UNIX _and_ WINDOWS!)
     find_library(PTHREAD_LIBRARY pthread)
     find_library(PTHREAD_LIBRARY pthread)
     if(PTHREAD_LIBRARY)
     if(PTHREAD_LIBRARY)
         set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${PTHREAD_LIBRARY})
         set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${PTHREAD_LIBRARY})
     endif()
     endif()
 endif()
 endif()
 
 
+if(PHYSFS_CPP_SRCS)
+    enable_language(CXX)
+endif()
+
 # Almost everything is "compiled" here, but things that don't apply to the
 # Almost everything is "compiled" here, but things that don't apply to the
 #  build are #ifdef'd out. This is to make it easy to embed PhysicsFS into
 #  build are #ifdef'd out. This is to make it easy to embed PhysicsFS into
 #  another project or bring up a new build system: just compile all the source
 #  another project or bring up a new build system: just compile all the source
@@ -152,6 +158,8 @@ endif()
 option(PHYSFS_BUILD_STATIC "Build static library" TRUE)
 option(PHYSFS_BUILD_STATIC "Build static library" TRUE)
 if(PHYSFS_BUILD_STATIC)
 if(PHYSFS_BUILD_STATIC)
     add_library(physfs-static STATIC ${PHYSFS_SRCS})
     add_library(physfs-static STATIC ${PHYSFS_SRCS})
+    add_library(PhysFS::PhysFS-static ALIAS physfs-static)
+    set_target_properties(physfs-static PROPERTIES EXPORT_NAME PhysFS-static)
     # Don't rename this on Windows, since DLLs will also produce an import
     # Don't rename this on Windows, since DLLs will also produce an import
     #  library named "physfs.lib" which would conflict; Unix tend to like the
     #  library named "physfs.lib" which would conflict; Unix tend to like the
     #  same library name with a different extension for static libs, but
     #  same library name with a different extension for static libs, but
@@ -164,23 +172,34 @@ if(PHYSFS_BUILD_STATIC)
 		set_target_properties(physfs-static PROPERTIES VS_WINRT_COMPONENT True)
 		set_target_properties(physfs-static PROPERTIES VS_WINRT_COMPONENT True)
         set_target_properties(physfs-static PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264")
         set_target_properties(physfs-static PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264")
     endif()
     endif()
-
+    if(WIN32 OR WINRT OR OS2)
+        # no dll exports from the static library
+        target_compile_definitions(physfs-static PRIVATE "PHYSFS_STATIC")
+    endif()
+    target_include_directories(physfs-static PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>")
+    target_link_libraries(physfs-static PRIVATE ${OPTIONAL_LIBRARY_LIBS} ${OTHER_LDFLAGS})
     set(PHYSFS_LIB_TARGET physfs-static)
     set(PHYSFS_LIB_TARGET physfs-static)
-    set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs-static")
+    list(APPEND PHYSFS_INSTALL_TARGETS "physfs-static")
 endif()
 endif()
 
 
 option(PHYSFS_BUILD_SHARED "Build shared library" TRUE)
 option(PHYSFS_BUILD_SHARED "Build shared library" TRUE)
 if(PHYSFS_BUILD_SHARED)
 if(PHYSFS_BUILD_SHARED)
     add_library(physfs SHARED ${PHYSFS_SRCS})
     add_library(physfs SHARED ${PHYSFS_SRCS})
+    add_library(PhysFS::PhysFS ALIAS physfs)
     set_target_properties(physfs PROPERTIES MACOSX_RPATH 1)
     set_target_properties(physfs PROPERTIES MACOSX_RPATH 1)
     set_target_properties(physfs PROPERTIES VERSION ${PHYSFS_VERSION})
     set_target_properties(physfs PROPERTIES VERSION ${PHYSFS_VERSION})
     set_target_properties(physfs PROPERTIES SOVERSION ${PHYSFS_SOVERSION})
     set_target_properties(physfs PROPERTIES SOVERSION ${PHYSFS_SOVERSION})
+    set_target_properties(physfs PROPERTIES EXPORT_NAME PhysFS)
     if(WINRT)
     if(WINRT)
 		set_target_properties(physfs PROPERTIES VS_WINRT_COMPONENT True)
 		set_target_properties(physfs PROPERTIES VS_WINRT_COMPONENT True)
     endif()
     endif()
-    target_link_libraries(physfs ${OPTIONAL_LIBRARY_LIBS} ${OTHER_LDFLAGS})
+    if(OS2) # OS/2 does not support a DLL name longer than 8 characters.
+        set_target_properties(physfs PROPERTIES OUTPUT_NAME "physfs")
+    endif()
+    target_include_directories(physfs PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>")
+    target_link_libraries(physfs PRIVATE ${OPTIONAL_LIBRARY_LIBS} ${OTHER_LDFLAGS})
     set(PHYSFS_LIB_TARGET physfs)
     set(PHYSFS_LIB_TARGET physfs)
-    set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs")
+    list(APPEND PHYSFS_INSTALL_TARGETS "physfs")
 endif()
 endif()
 
 
 if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
 if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
@@ -188,7 +207,7 @@ if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
 endif()
 endif()
 
 
 # CMake FAQ says I need this...
 # CMake FAQ says I need this...
-if(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC AND NOT WINDOWS)
+if(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC AND NOT WIN32)
     set_target_properties(physfs PROPERTIES CLEAN_DIRECT_OUTPUT 1)
     set_target_properties(physfs PROPERTIES CLEAN_DIRECT_OUTPUT 1)
     set_target_properties(physfs-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
     set_target_properties(physfs-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
 endif()
 endif()
@@ -200,64 +219,88 @@ if(PHYSFS_BUILD_TEST)
     find_path(HISTORY_H readline/history.h)
     find_path(HISTORY_H readline/history.h)
     if(READLINE_H AND HISTORY_H)
     if(READLINE_H AND HISTORY_H)
         find_library(CURSES_LIBRARY NAMES curses ncurses)
         find_library(CURSES_LIBRARY NAMES curses ncurses)
-        set(CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
-        find_library(READLINE_LIBRARY readline)
-        if(READLINE_LIBRARY)
-            set(HAVE_SYSTEM_READLINE TRUE)
-            set(TEST_PHYSFS_LIBS ${TEST_PHYSFS_LIBS} ${READLINE_LIBRARY} ${CURSES_LIBRARY})
-            include_directories(SYSTEM ${READLINE_H} ${HISTORY_H})
-            add_definitions(-DPHYSFS_HAVE_READLINE=1)
+        if(CURSES_LIBRARY)
+            set(CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
+            find_library(READLINE_LIBRARY readline)
+            if(READLINE_LIBRARY)
+                set(HAVE_SYSTEM_READLINE TRUE)
+                list(APPEND TEST_PHYSFS_LIBS ${READLINE_LIBRARY} ${CURSES_LIBRARY})
+                include_directories(SYSTEM ${READLINE_H} ${HISTORY_H})
+                add_definitions(-DPHYSFS_HAVE_READLINE=1)
+            endif()
         endif()
         endif()
     endif()
     endif()
     add_executable(test_physfs test/test_physfs.c)
     add_executable(test_physfs test/test_physfs.c)
-    target_link_libraries(test_physfs ${PHYSFS_LIB_TARGET} ${TEST_PHYSFS_LIBS} ${OTHER_LDFLAGS})
-    set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";test_physfs")
+    target_link_libraries(test_physfs PRIVATE ${PHYSFS_LIB_TARGET} ${TEST_PHYSFS_LIBS} ${OTHER_LDFLAGS})
+    list(APPEND PHYSFS_INSTALL_TARGETS test_physfs)
 endif()
 endif()
 
 
-install(TARGETS ${PHYSFS_INSTALL_TARGETS} EXPORT PhysFSExport
-        RUNTIME DESTINATION bin
-        LIBRARY DESTINATION lib${LIB_SUFFIX}
-        ARCHIVE DESTINATION lib${LIB_SUFFIX}
-        INCLUDES DESTINATION include)
-install(FILES src/physfs.h DESTINATION include)
-
-install(EXPORT PhysFSExport
-        DESTINATION "lib${LIB_SUFFIX}/cmake/PhysFS"
-        FILE PhysFSConfig.cmake
-)
+option(PHYSFS_DISABLE_INSTALL "Disable installing PhysFS" OFF)
+if(NOT PHYSFS_DISABLE_INSTALL)
 
 
+    install(TARGETS ${PHYSFS_INSTALL_TARGETS} EXPORT PhysFSExport
+            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+    install(FILES src/physfs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 
 
-find_package(Doxygen)
-if(DOXYGEN_FOUND)
-    set(PHYSFS_OUTPUT_DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
-    configure_file(
-        "${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile"
-        "${PHYSFS_OUTPUT_DOXYFILE}"
-        COPYONLY
+    install(EXPORT PhysFSExport
+            DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PhysFS"
+            FILE PhysFSConfig.cmake
+            NAMESPACE PhysFS::
     )
     )
-    file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "\n\n# Below auto-generated by cmake...\n\n")
-    file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "PROJECT_NUMBER = \"${PHYSFS_VERSION}\"\n")
-    file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "OUTPUT_DIRECTORY = \"${CMAKE_CURRENT_BINARY_DIR}/docs\"\n")
-    file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "\n# End auto-generated section.\n\n")
 
 
-    set(PHYSFS_TARGETNAME_DOCS "docs" CACHE STRING "Name of 'docs' build target")
-    add_custom_target(
-        ${PHYSFS_TARGETNAME_DOCS}
-        ${DOXYGEN_EXECUTABLE} "${PHYSFS_OUTPUT_DOXYFILE}"
-        WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
-        COMMENT "Building documentation in 'docs' directory..."
-    )
-else()
-    message(STATUS "Doxygen not found. You won't be able to build documentation.")
+    if(NOT MSVC)
+        configure_file(
+            "extras/physfs.pc.in"
+            "extras/physfs.pc"
+            @ONLY
+        )
+
+        install(
+            FILES "${CMAKE_CURRENT_BINARY_DIR}/extras/physfs.pc"
+            DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
+        )
+    endif()
+endif()
+
+option(PHYSFS_BUILD_DOCS "Build doxygen based documentation" TRUE)
+if(PHYSFS_BUILD_DOCS)
+    find_package(Doxygen)
+    if(DOXYGEN_FOUND)
+        set(PHYSFS_OUTPUT_DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
+        configure_file(
+            "${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile"
+            "${PHYSFS_OUTPUT_DOXYFILE}"
+            COPYONLY
+        )
+        file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "\n\n# Below auto-generated by cmake...\n\n")
+        file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "PROJECT_NUMBER = \"${PHYSFS_VERSION}\"\n")
+        file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "OUTPUT_DIRECTORY = \"${CMAKE_CURRENT_BINARY_DIR}/docs\"\n")
+        file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "\n# End auto-generated section.\n\n")
+
+        set(PHYSFS_TARGETNAME_DOCS "docs" CACHE STRING "Name of 'docs' build target")
+
+        add_custom_target(
+            ${PHYSFS_TARGETNAME_DOCS}
+            ${DOXYGEN_EXECUTABLE} "${PHYSFS_OUTPUT_DOXYFILE}"
+            WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+            COMMENT "Building documentation in 'docs' directory..."
+        )
+
+    else()
+        message(STATUS "Doxygen not found. You won't be able to build documentation.")
+    endif()
 endif()
 endif()
 
 
 if(UNIX)
 if(UNIX)
-    set(PHYSFS_TARBALL "${CMAKE_CURRENT_SOURCE_DIR}/../physfs-${PHYSFS_VERSION}.tar.bz2")
+    set(PHYSFS_TARBALL "${CMAKE_CURRENT_SOURCE_DIR}/../physfs-${PHYSFS_VERSION}.tar.gz")
 
 
     set(PHYSFS_TARGETNAME_DIST "dist" CACHE STRING "Name of 'dist' build target")
     set(PHYSFS_TARGETNAME_DIST "dist" CACHE STRING "Name of 'dist' build target")
     add_custom_target(
     add_custom_target(
         ${PHYSFS_TARGETNAME_DIST}
         ${PHYSFS_TARGETNAME_DIST}
-        hg archive -t tbz2 "${PHYSFS_TARBALL}"
+        git archive --prefix="physfs-${PHYSFS_VERSION}/" --output="${PHYSFS_TARBALL}" HEAD
         WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
         WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
         COMMENT "Building source tarball '${PHYSFS_TARBALL}'..."
         COMMENT "Building source tarball '${PHYSFS_TARBALL}'..."
     )
     )
@@ -271,17 +314,6 @@ if(UNIX)
     )
     )
 endif()
 endif()
 
 
-if(NOT MSVC)
-    configure_file(
-        "extras/physfs.pc.in"
-        "extras/physfs.pc"
-        @ONLY
-    )
-    install(
-        FILES "${CMAKE_CURRENT_BINARY_DIR}/extras/physfs.pc"
-        DESTINATION "lib${LIB_SUFFIX}/pkgconfig"
-    )
-endif()
 
 
 macro(message_bool_option _NAME _VALUE)
 macro(message_bool_option _NAME _VALUE)
     if(${_VALUE})
     if(${_VALUE})
@@ -305,9 +337,9 @@ message_bool_option("ISO9660 support" PHYSFS_ARCHIVE_ISO9660)
 message_bool_option("Build static library" PHYSFS_BUILD_STATIC)
 message_bool_option("Build static library" PHYSFS_BUILD_STATIC)
 message_bool_option("Build shared library" PHYSFS_BUILD_SHARED)
 message_bool_option("Build shared library" PHYSFS_BUILD_SHARED)
 message_bool_option("Build stdio test program" PHYSFS_BUILD_TEST)
 message_bool_option("Build stdio test program" PHYSFS_BUILD_TEST)
+message_bool_option("Build Doxygen documentation" PHYSFS_BUILD_DOCS)
 if(PHYSFS_BUILD_TEST)
 if(PHYSFS_BUILD_TEST)
     message_bool_option("  Use readline in test program" HAVE_SYSTEM_READLINE)
     message_bool_option("  Use readline in test program" HAVE_SYSTEM_READLINE)
 endif()
 endif()
 
 
 # end of CMakeLists.txt ...
 # end of CMakeLists.txt ...
-

+ 16 - 22
physfs.mod/physfs/LICENSE.txt

@@ -1,23 +1,17 @@
-
-   Copyright (c) 2001-2020 Ryan C. Gordon and others.
-
-   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
+Copyright (c) 2001-2022 Ryan C. Gordon <[email protected]> and others.
+  
+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.
    misrepresented as being the original software.
-
-   3. This notice may not be removed or altered from any source distribution.
-
-       Ryan C. Gordon <[email protected]>
-
+3. This notice may not be removed or altered from any source distribution.

+ 1 - 1
physfs.mod/physfs/docs/CHANGELOG.txt

@@ -6,6 +6,6 @@ The changelog is no longer maintained by hand. It made sense to have a single
 If you want a list of changes, updated in real time, just point your web
 If you want a list of changes, updated in real time, just point your web
  browser here:
  browser here:
 
 
-    https://hg.icculus.org/icculus/physfs/
+    https://github.com/icculus/physfs/commits/
 
 
 
 

+ 3 - 3
physfs.mod/physfs/extras/buildbot-checker.sh

@@ -1,7 +1,7 @@
 prefix=@CMAKE_INSTALL_PREFIX@
 prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@CMAKE_INSTALL_FULL_LIBDIR@
+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
 
 
 Name: PhysicsFS
 Name: PhysicsFS
 Description: PhysicsFS is a library to provide abstract access to various archives.
 Description: PhysicsFS is a library to provide abstract access to various archives.

+ 93 - 0
physfs.mod/physfs/extras/uninstall.sh

@@ -0,0 +1,93 @@
+# Open Watcom makefile to build PhysicsFS for OS/2
+# wmake -f Makefile.os2
+
+LIBNAME = physfs
+VERSION = 3.3.0
+
+LIBFILE = $(LIBNAME).lib
+DLLFILE = $(LIBNAME).dll
+LNKFILE = $(LIBNAME).lnk
+
+TITLENAME = $(LIBNAME) $(VERSION)
+
+SRCS = physfs.c                   &
+       physfs_byteorder.c         &
+       physfs_unicode.c           &
+       physfs_platform_os2.c      &
+       physfs_archiver_dir.c      &
+       physfs_archiver_unpacked.c &
+       physfs_archiver_grp.c      &
+       physfs_archiver_hog.c      &
+       physfs_archiver_7z.c       &
+       physfs_archiver_mvl.c      &
+       physfs_archiver_qpak.c     &
+       physfs_archiver_wad.c      &
+       physfs_archiver_zip.c      &
+       physfs_archiver_slb.c      &
+       physfs_archiver_iso9660.c  &
+       physfs_archiver_vdf.c
+
+
+OBJS = $(SRCS:.c=.obj)
+
+CFLAGS_BASE = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oeatxh -ei -j
+CFLAGS_BASE+= -DNDEBUG
+# warnings:
+CFLAGS_BASE+= -wx
+# newer OpenWatcom versions enable W303 by default
+CFLAGS_BASE+= -wcd=303
+# include paths:
+CFLAGS_BASE+= -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h"
+CFLAGS = $(CFLAGS_BASE)
+# to build a dll:
+CFLAGS+= -bd
+
+.extensions:
+.extensions: .lib .dll .obj .c
+
+all: $(DLLFILE) test_physfs.exe
+
+.c: decoders
+.c: examples
+
+$(LIBFILE): $(DLLFILE)
+  @echo * Create library: $@...
+  wlib -b -n -q -c -pa -s -t -zld -ii -io $@ $(DLLFILE)
+
+$(DLLFILE): $(OBJS) $(MODPLIB) $(TIMILIB) $(LNKFILE)
+  @echo * Link: $@
+  wlink @$(LNKFILE)
+
+$(LNKFILE):
+  @%create $@
+  @%append $@ SYSTEM os2v2_dll INITINSTANCE TERMINSTANCE
+  @%append $@ NAME $(LIBNAME)
+  @for %i in ($(OBJS)) do @%append $@ FILE %i
+  @%append $@ OPTION QUIET
+  @%append $@ OPTION DESCRIPTION '@$#icculus org:$(VERSION)$#@PhysicsFS'
+  @%append $@ OPTION MAP=$^&.map
+  @%append $@ OPTION ELIMINATE
+  @%append $@ OPTION MANYAUTODATA
+  @%append $@ OPTION OSNAME='OS/2 and eComStation'
+  @%append $@ OPTION SHOWDEAD
+
+.c.obj:
+  wcc386 $(CFLAGS) -fo=$^@ $<
+
+test_physfs.obj: "../test/test_physfs.c"
+  wcc386 $(CFLAGS_BASE) -fo=$^@ $<
+
+test_physfs.exe: $(LIBFILE) test_physfs.obj
+  @echo * Link: $@
+  wlink SYS os2v2 LIBR {$(LIBFILE)} op q op el F {test_physfs.obj} N test_physfs.exe
+
+clean: .SYMBOLIC
+  @echo * Clean: $(TITLENAME)
+  @if exist *.obj rm *.obj
+  @if exist *.err rm *.err
+  @if exist $(LNKFILE) rm $(LNKFILE)
+distclean: .SYMBOLIC clean
+  @if exist $(DLLFILE) rm $(DLLFILE)
+  @if exist $(LIBFILE) rm $(LIBFILE)
+  @if exist *.map rm *.map
+  @if exist *.exe rm *.exe

+ 81 - 26
physfs.mod/physfs/src/physfs.c

@@ -12,8 +12,6 @@
 #include "physfs_internal.h"
 #include "physfs_internal.h"
 
 
 #if defined(_MSC_VER)
 #if defined(_MSC_VER)
-#include <stdarg.h>
-
 /* this code came from https://stackoverflow.com/a/8712996 */
 /* this code came from https://stackoverflow.com/a/8712996 */
 int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
 int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
 {
 {
@@ -104,8 +102,8 @@ static inline int __PHYSFS_atomicAdd(int *ptrval, const int val)
 {
 {
     int retval;
     int retval;
     __PHYSFS_platformGrabMutex(stateLock);
     __PHYSFS_platformGrabMutex(stateLock);
+    *ptrval += val;
     retval = *ptrval;
     retval = *ptrval;
-    *ptrval = retval + val;
     __PHYSFS_platformReleaseMutex(stateLock);
     __PHYSFS_platformReleaseMutex(stateLock);
     return retval;
     return retval;
 } /* __PHYSFS_atomicAdd */
 } /* __PHYSFS_atomicAdd */
@@ -923,12 +921,12 @@ static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
             retval = tryOpenDir(io, *i, d, forWriting, &claimed);
             retval = tryOpenDir(io, *i, d, forWriting, &claimed);
     } /* else */
     } /* else */
 
 
-    errcode = currentErrorCode();
+    errcode = claimed ? currentErrorCode() : PHYSFS_ERR_UNSUPPORTED;
 
 
     if ((!retval) && (created_io))
     if ((!retval) && (created_io))
         io->destroy(io);
         io->destroy(io);
 
 
-    BAIL_IF(!retval, claimed ? errcode : PHYSFS_ERR_UNSUPPORTED, NULL);
+    BAIL_IF(!retval, errcode, NULL);
     return retval;
     return retval;
 } /* openDirectory */
 } /* openDirectory */
 
 
@@ -1095,6 +1093,8 @@ static int freeDirHandle(DirHandle *dh, FileHandle *openList)
         BAIL_IF(i->dirHandle == dh, PHYSFS_ERR_FILES_STILL_OPEN, 0);
         BAIL_IF(i->dirHandle == dh, PHYSFS_ERR_FILES_STILL_OPEN, 0);
 
 
     dh->funcs->closeArchive(dh->opaque);
     dh->funcs->closeArchive(dh->opaque);
+
+    if (dh->root) allocator.Free(dh->root);
     allocator.Free(dh->dirName);
     allocator.Free(dh->dirName);
     allocator.Free(dh->mountPoint);
     allocator.Free(dh->mountPoint);
     allocator.Free(dh);
     allocator.Free(dh);
@@ -1435,15 +1435,60 @@ char *__PHYSFS_strdup(const char *str)
 } /* __PHYSFS_strdup */
 } /* __PHYSFS_strdup */
 
 
 
 
-PHYSFS_uint32 __PHYSFS_hashString(const char *str, size_t len)
+PHYSFS_uint32 __PHYSFS_hashString(const char *str)
 {
 {
     PHYSFS_uint32 hash = 5381;
     PHYSFS_uint32 hash = 5381;
-    while (len--)
-        hash = ((hash << 5) + hash) ^ *(str++);
+    while (1)
+    {
+        const char ch = *(str++);
+        if (ch == 0)
+            break;
+        hash = ((hash << 5) + hash) ^ ch;
+    } /* while */
     return hash;
     return hash;
 } /* __PHYSFS_hashString */
 } /* __PHYSFS_hashString */
 
 
 
 
+PHYSFS_uint32 __PHYSFS_hashStringCaseFold(const char *str)
+{
+    PHYSFS_uint32 hash = 5381;
+    while (1)
+    {
+        const PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&str);
+        if (cp == 0)
+            break;
+        else
+        {
+            PHYSFS_uint32 folded[3];
+            const int numbytes = (int) (PHYSFS_caseFold(cp, folded) * sizeof (PHYSFS_uint32));
+            const char *bytes = (const char *) folded;
+            int i;
+            for (i = 0; i < numbytes; i++)
+                hash = ((hash << 5) + hash) ^ *(bytes++);
+        } /* else */
+    } /* while */
+
+    return hash;
+} /* __PHYSFS_hashStringCaseFold */
+
+
+PHYSFS_uint32 __PHYSFS_hashStringCaseFoldUSAscii(const char *str)
+{
+    PHYSFS_uint32 hash = 5381;
+    while (1)
+    {
+        char ch = *(str++);
+        if (ch == 0)
+            break;
+        else if ((ch >= 'A') && (ch <= 'Z'))
+            ch -= ('A' - 'a');
+
+        hash = ((hash << 5) + hash) ^ ch;
+    } /* while */
+    return hash;
+} /* __PHYSFS_hashStringCaseFoldUSAscii */
+
+
 /* MAKE SURE you hold stateLock before calling this! */
 /* MAKE SURE you hold stateLock before calling this! */
 static int doRegisterArchiver(const PHYSFS_Archiver *_archiver)
 static int doRegisterArchiver(const PHYSFS_Archiver *_archiver)
 {
 {
@@ -1735,10 +1780,10 @@ int PHYSFS_setRoot(const char *archive, const char *subdir)
                 if (i->root)
                 if (i->root)
                     allocator.Free(i->root);
                     allocator.Free(i->root);
                 i->root = ptr;
                 i->root = ptr;
-                i->rootlen = len;
+                i->rootlen = strlen(i->root);  /* in case sanitizePlatformIndependentPath changed subdir */
 
 
-                if (longest_root < len)
-                    longest_root = len;
+                if (longest_root < i->rootlen)
+                    longest_root = i->rootlen;
             } /* else */
             } /* else */
 
 
             break;
             break;
@@ -2109,10 +2154,10 @@ static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
     if (h->root)
     if (h->root)
     {
     {
         const int isempty = (*fname == '\0');
         const int isempty = (*fname == '\0');
-        fname -= h->rootlen - 1;
+        fname -= h->rootlen + (isempty ? 0 : 1);
         strcpy(fname, h->root);
         strcpy(fname, h->root);
         if (!isempty)
         if (!isempty)
-            fname[h->rootlen - 2] = '/';
+            fname[h->rootlen] = '/';
         *_fname = fname;
         *_fname = fname;
     } /* if */
     } /* if */
 
 
@@ -2189,7 +2234,12 @@ static int doMkdir(const char *_dname, char *dname)
             const int rc = h->funcs->stat(h->opaque, dname, &statbuf);
             const int rc = h->funcs->stat(h->opaque, dname, &statbuf);
             if ((!rc) && (currentErrorCode() == PHYSFS_ERR_NOT_FOUND))
             if ((!rc) && (currentErrorCode() == PHYSFS_ERR_NOT_FOUND))
                 exists = 0;
                 exists = 0;
-            retval = ((rc) && (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY));
+            /* verifyPath made sure that (dname) doesn't have symlinks if they aren't
+               allowed, but it's possible the mounted writeDir itself has symlinks in it,
+               (for example "/var" on iOS is a symlink, and the prefpath will be somewhere
+               under that)...if we mounted that writeDir, we must allow those symlinks here
+               unconditionally. */
+            retval = ( (rc) && ((statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY) || (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)) );
         } /* if */
         } /* if */
 
 
         if (!exists)
         if (!exists)
@@ -2267,10 +2317,10 @@ static DirHandle *getRealDirHandle(const char *_fname)
     BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
     BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
 
 
     __PHYSFS_platformGrabMutex(stateLock);
     __PHYSFS_platformGrabMutex(stateLock);
-    len = strlen(_fname) + longest_root + 1;
+    len = strlen(_fname) + longest_root + 2;
     allocated_fname = __PHYSFS_smallAlloc(len);
     allocated_fname = __PHYSFS_smallAlloc(len);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, NULL);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, NULL);
-    fname = allocated_fname + longest_root;
+    fname = allocated_fname + longest_root + 1;
     if (sanitizePlatformIndependentPath(_fname, fname))
     if (sanitizePlatformIndependentPath(_fname, fname))
     {
     {
         DirHandle *i;
         DirHandle *i;
@@ -2498,10 +2548,10 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data)
 
 
     __PHYSFS_platformGrabMutex(stateLock);
     __PHYSFS_platformGrabMutex(stateLock);
 
 
-    len = strlen(_fn) + longest_root + 1;
+    len = strlen(_fn) + longest_root + 2;
     allocated_fname = (char *) __PHYSFS_smallAlloc(len);
     allocated_fname = (char *) __PHYSFS_smallAlloc(len);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
-    fname = allocated_fname + longest_root;
+    fname = allocated_fname + longest_root + 1;
     if (!sanitizePlatformIndependentPath(_fn, fname))
     if (!sanitizePlatformIndependentPath(_fn, fname))
         retval = PHYSFS_ENUM_STOP;
         retval = PHYSFS_ENUM_STOP;
     else
     else
@@ -2704,10 +2754,10 @@ PHYSFS_File *PHYSFS_openRead(const char *_fname)
 
 
     BAIL_IF_MUTEX(!searchPath, PHYSFS_ERR_NOT_FOUND, stateLock, 0);
     BAIL_IF_MUTEX(!searchPath, PHYSFS_ERR_NOT_FOUND, stateLock, 0);
 
 
-    len = strlen(_fname) + longest_root + 1;
+    len = strlen(_fname) + longest_root + 2;
     allocated_fname = (char *) __PHYSFS_smallAlloc(len);
     allocated_fname = (char *) __PHYSFS_smallAlloc(len);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
-    fname = allocated_fname + longest_root;
+    fname = allocated_fname + longest_root + 1;
 
 
     if (sanitizePlatformIndependentPath(_fname, fname))
     if (sanitizePlatformIndependentPath(_fname, fname))
     {
     {
@@ -3095,10 +3145,10 @@ int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
     stat->readonly = 1;
     stat->readonly = 1;
 
 
     __PHYSFS_platformGrabMutex(stateLock);
     __PHYSFS_platformGrabMutex(stateLock);
-    len = strlen(_fname) + longest_root + 1;
+    len = strlen(_fname) + longest_root + 2;
     allocated_fname = (char *) __PHYSFS_smallAlloc(len);
     allocated_fname = (char *) __PHYSFS_smallAlloc(len);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
     BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
-    fname = allocated_fname + longest_root;
+    fname = allocated_fname + longest_root + 1;
 
 
     if (sanitizePlatformIndependentPath(_fname, fname))
     if (sanitizePlatformIndependentPath(_fname, fname))
     {
     {
@@ -3231,7 +3281,7 @@ static void setDefaultAllocator(void)
 } /* setDefaultAllocator */
 } /* setDefaultAllocator */
 
 
 
 
-int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen)
+int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen, const int case_sensitive, const int only_usascii)
 {
 {
     static char rootpath[2] = { '/', '\0' };
     static char rootpath[2] = { '/', '\0' };
     size_t alloclen;
     size_t alloclen;
@@ -3239,6 +3289,8 @@ int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen)
     assert(entrylen >= sizeof (__PHYSFS_DirTreeEntry));
     assert(entrylen >= sizeof (__PHYSFS_DirTreeEntry));
 
 
     memset(dt, '\0', sizeof (*dt));
     memset(dt, '\0', sizeof (*dt));
+    dt->case_sensitive = case_sensitive;
+    dt->only_usascii = only_usascii;
 
 
     dt->root = (__PHYSFS_DirTreeEntry *) allocator.Malloc(entrylen);
     dt->root = (__PHYSFS_DirTreeEntry *) allocator.Malloc(entrylen);
     BAIL_IF(!dt->root, PHYSFS_ERR_OUT_OF_MEMORY, 0);
     BAIL_IF(!dt->root, PHYSFS_ERR_OUT_OF_MEMORY, 0);
@@ -3259,9 +3311,10 @@ int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen)
 } /* __PHYSFS_DirTreeInit */
 } /* __PHYSFS_DirTreeInit */
 
 
 
 
-static inline PHYSFS_uint32 hashPathName(__PHYSFS_DirTree *dt, const char *name)
+static PHYSFS_uint32 hashPathName(__PHYSFS_DirTree *dt, const char *name)
 {
 {
-    return __PHYSFS_hashString(name, strlen(name)) % dt->hashBuckets;
+    const PHYSFS_uint32 hashval = dt->case_sensitive ? __PHYSFS_hashString(name) : dt->only_usascii ? __PHYSFS_hashStringCaseFoldUSAscii(name) : __PHYSFS_hashStringCaseFold(name);
+    return hashval % dt->hashBuckets;
 } /* hashPathName */
 } /* hashPathName */
 
 
 
 
@@ -3322,6 +3375,7 @@ void *__PHYSFS_DirTreeAdd(__PHYSFS_DirTree *dt, char *name, const int isdir)
 /* Find the __PHYSFS_DirTreeEntry for a path in platform-independent notation. */
 /* Find the __PHYSFS_DirTreeEntry for a path in platform-independent notation. */
 void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path)
 void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path)
 {
 {
+    const int cs = dt->case_sensitive;
     PHYSFS_uint32 hashval;
     PHYSFS_uint32 hashval;
     __PHYSFS_DirTreeEntry *prev = NULL;
     __PHYSFS_DirTreeEntry *prev = NULL;
     __PHYSFS_DirTreeEntry *retval;
     __PHYSFS_DirTreeEntry *retval;
@@ -3332,7 +3386,8 @@ void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path)
     hashval = hashPathName(dt, path);
     hashval = hashPathName(dt, path);
     for (retval = dt->hash[hashval]; retval; retval = retval->hashnext)
     for (retval = dt->hash[hashval]; retval; retval = retval->hashnext)
     {
     {
-        if (strcmp(retval->name, path) == 0)
+        const int cmp = cs ? strcmp(retval->name, path) : PHYSFS_utf8stricmp(retval->name, path);
+        if (cmp == 0)
         {
         {
             if (prev != NULL)  /* move this to the front of the list */
             if (prev != NULL)  /* move this to the front of the list */
             {
             {

+ 4 - 2
physfs.mod/physfs/src/physfs.h

@@ -225,7 +225,9 @@ extern "C" {
 
 
 #if defined(PHYSFS_DECL)
 #if defined(PHYSFS_DECL)
 /* do nothing. */
 /* do nothing. */
-#elif defined(_MSC_VER)
+#elif defined(PHYSFS_STATIC)
+#define PHYSFS_DECL   /**/
+#elif defined(_WIN32) || defined(__OS2__)
 #define PHYSFS_DECL __declspec(dllexport)
 #define PHYSFS_DECL __declspec(dllexport)
 #elif defined(__SUNPRO_C)
 #elif defined(__SUNPRO_C)
 #define PHYSFS_DECL __global
 #define PHYSFS_DECL __global
@@ -433,7 +435,7 @@ typedef struct PHYSFS_Version
 
 
 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
 #define PHYSFS_VER_MAJOR 3
 #define PHYSFS_VER_MAJOR 3
-#define PHYSFS_VER_MINOR 1
+#define PHYSFS_VER_MINOR 3
 #define PHYSFS_VER_PATCH 0
 #define PHYSFS_VER_PATCH 0
 #endif  /* DOXYGEN_SHOULD_IGNORE_THIS */
 #endif  /* DOXYGEN_SHOULD_IGNORE_THIS */
 
 

+ 1 - 1
physfs.mod/physfs/src/physfs_archiver_7z.c

@@ -185,7 +185,7 @@ static int szipLoadEntries(SZIPinfo *info)
 {
 {
     int retval = 0;
     int retval = 0;
 
 
-    if (__PHYSFS_DirTreeInit(&info->tree, sizeof (SZIPentry)))
+    if (__PHYSFS_DirTreeInit(&info->tree, sizeof (SZIPentry), 1, 0))
     {
     {
         const PHYSFS_uint32 count = info->db.NumFiles;
         const PHYSFS_uint32 count = info->db.NumFiles;
         PHYSFS_uint32 i;
         PHYSFS_uint32 i;

+ 1 - 1
physfs.mod/physfs/src/physfs_archiver_grp.c

@@ -76,7 +76,7 @@ static void *GRP_openArchive(PHYSFS_Io *io, const char *name,
     BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
     BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
     count = PHYSFS_swapULE32(count);
     count = PHYSFS_swapULE32(count);
 
 
-    unpkarc = UNPK_openArchive(io);
+    unpkarc = UNPK_openArchive(io, 0, 1);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!grpLoadEntries(io, count, unpkarc))
     if (!grpLoadEntries(io, count, unpkarc))

+ 1 - 1
physfs.mod/physfs/src/physfs_archiver_hog.c

@@ -130,7 +130,7 @@ static void *HOG_openArchive(PHYSFS_Io *io, const char *name,
 
 
     *claimed = 1;
     *claimed = 1;
 
 
-    unpkarc = UNPK_openArchive(io);
+    unpkarc = UNPK_openArchive(io, 0, 1);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!(hog1 ? hog1LoadEntries(io, unpkarc) : hog2LoadEntries(io, unpkarc)))
     if (!(hog1 ? hog1LoadEntries(io, unpkarc) : hog2LoadEntries(io, unpkarc)))

+ 3 - 2
physfs.mod/physfs/src/physfs_archiver_iso9660.c

@@ -251,7 +251,7 @@ static int parseVolumeDescriptor(PHYSFS_Io *io, PHYSFS_uint64 *_rootpos,
         pos += 2048;  /* each volume descriptor is 2048 bytes */
         pos += 2048;  /* each volume descriptor is 2048 bytes */
 
 
         BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &type, 1), 0);
         BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &type, 1), 0);
-        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &identifier, 5), 0);
+        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, identifier, 5), 0);
 
 
         if (memcmp(identifier, "CD001", 5) != 0)  /* maybe not an iso? */
         if (memcmp(identifier, "CD001", 5) != 0)  /* maybe not an iso? */
         {
         {
@@ -346,7 +346,8 @@ static void *ISO9660_openArchive(PHYSFS_Io *io, const char *filename,
     if (!parseVolumeDescriptor(io, &rootpos, &len, &joliet, claimed))
     if (!parseVolumeDescriptor(io, &rootpos, &len, &joliet, claimed))
         return NULL;
         return NULL;
 
 
-    unpkarc = UNPK_openArchive(io);
+    /* !!! FIXME: check case_sensitive and only_usascii params for this archive. */
+    unpkarc = UNPK_openArchive(io, 1, 0);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!iso9660LoadEntries(io, joliet, "", rootpos, rootpos + len, unpkarc))
     if (!iso9660LoadEntries(io, joliet, "", rootpos, rootpos + len, unpkarc))

+ 1 - 1
physfs.mod/physfs/src/physfs_archiver_mvl.c

@@ -70,7 +70,7 @@ static void *MVL_openArchive(PHYSFS_Io *io, const char *name,
     BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
     BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
     count = PHYSFS_swapULE32(count);
     count = PHYSFS_swapULE32(count);
 
 
-    unpkarc = UNPK_openArchive(io);
+    unpkarc = UNPK_openArchive(io, 0, 1);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!mvlLoadEntries(io, count, unpkarc))
     if (!mvlLoadEntries(io, count, unpkarc))

+ 2 - 1
physfs.mod/physfs/src/physfs_archiver_qpak.c

@@ -86,7 +86,8 @@ static void *QPAK_openArchive(PHYSFS_Io *io, const char *name,
 
 
     BAIL_IF_ERRPASS(!io->seek(io, pos), NULL);
     BAIL_IF_ERRPASS(!io->seek(io, pos), NULL);
 
 
-    unpkarc = UNPK_openArchive(io);
+    /* !!! FIXME: check case_sensitive and only_usascii params for this archive. */
+    unpkarc = UNPK_openArchive(io, 1, 0);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!qpakLoadEntries(io, count, unpkarc))
     if (!qpakLoadEntries(io, count, unpkarc))

+ 3 - 2
physfs.mod/physfs/src/physfs_archiver_slb.c

@@ -36,7 +36,7 @@ static int slbLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
         BAIL_IF(backslash != '\\', PHYSFS_ERR_CORRUPT, 0);
         BAIL_IF(backslash != '\\', PHYSFS_ERR_CORRUPT, 0);
 
 
         /* read the rest of the buffer, 63 bytes */
         /* read the rest of the buffer, 63 bytes */
-        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &name, 63), 0);
+        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 63), 0);
         name[63] = '\0'; /* in case the name lacks the null terminator */
         name[63] = '\0'; /* in case the name lacks the null terminator */
 
 
         /* convert backslashes */
         /* convert backslashes */
@@ -94,7 +94,8 @@ static void *SLB_openArchive(PHYSFS_Io *io, const char *name,
     /* seek to the table of contents */
     /* seek to the table of contents */
     BAIL_IF_ERRPASS(!io->seek(io, tocPos), NULL);
     BAIL_IF_ERRPASS(!io->seek(io, tocPos), NULL);
 
 
-    unpkarc = UNPK_openArchive(io);
+    /* !!! FIXME: check case_sensitive and only_usascii params for this archive. */
+    unpkarc = UNPK_openArchive(io, 1, 0);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!slbLoadEntries(io, count, unpkarc))
     if (!slbLoadEntries(io, count, unpkarc))

+ 2 - 2
physfs.mod/physfs/src/physfs_archiver_unpacked.c

@@ -285,12 +285,12 @@ void *UNPK_addEntry(void *opaque, char *name, const int isdir,
 } /* UNPK_addEntry */
 } /* UNPK_addEntry */
 
 
 
 
-void *UNPK_openArchive(PHYSFS_Io *io)
+void *UNPK_openArchive(PHYSFS_Io *io, const int case_sensitive, const int only_usascii)
 {
 {
     UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
     UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
     BAIL_IF(!info, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
     BAIL_IF(!info, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
 
 
-    if (!__PHYSFS_DirTreeInit(&info->tree, sizeof (UNPKentry)))
+    if (!__PHYSFS_DirTreeInit(&info->tree, sizeof (UNPKentry), case_sensitive, only_usascii))
     {
     {
         allocator.Free(info);
         allocator.Free(info);
         return NULL;
         return NULL;

+ 2 - 1
physfs.mod/physfs/src/physfs_archiver_vdf.c

@@ -129,7 +129,8 @@ static void *VDF_openArchive(PHYSFS_Io *io, const char *name,
 
 
     BAIL_IF_ERRPASS(!io->seek(io, rootCatOffset), NULL);
     BAIL_IF_ERRPASS(!io->seek(io, rootCatOffset), NULL);
 
 
-    unpkarc = UNPK_openArchive(io);
+    /* !!! FIXME: check case_sensitive and only_usascii params for this archive. */
+    unpkarc = UNPK_openArchive(io, 1, 0);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!vdfLoadEntries(io, count, vdfDosTimeToEpoch(timestamp), unpkarc))
     if (!vdfLoadEntries(io, count, vdfDosTimeToEpoch(timestamp), unpkarc))

+ 1 - 1
physfs.mod/physfs/src/physfs_archiver_wad.c

@@ -95,7 +95,7 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name,
 
 
     BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), 0);
     BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), 0);
 
 
-    unpkarc = UNPK_openArchive(io);
+    unpkarc = UNPK_openArchive(io, 0, 1);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
     BAIL_IF_ERRPASS(!unpkarc, NULL);
 
 
     if (!wadLoadEntries(io, count, unpkarc))
     if (!wadLoadEntries(io, count, unpkarc))

+ 12 - 4
physfs.mod/physfs/src/physfs_archiver_zip.c

@@ -15,6 +15,11 @@
 #include <errno.h>
 #include <errno.h>
 #include <time.h>
 #include <time.h>
 
 
+#if (PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN)
+#define MINIZ_LITTLE_ENDIAN 1
+#else
+#define MINIZ_LITTLE_ENDIAN 0
+#endif
 #include "physfs_miniz.h"
 #include "physfs_miniz.h"
 
 
 /*
 /*
@@ -568,7 +573,7 @@ static PHYSFS_sint64 zip_find_end_of_central_dir(PHYSFS_Io *io, PHYSFS_sint64 *l
         {
         {
             if (!__PHYSFS_readAll(io, buf, maxread - 4))
             if (!__PHYSFS_readAll(io, buf, maxread - 4))
                 return -1;
                 return -1;
-            memcpy(&buf[maxread - 4], &extra, sizeof (extra));
+            memcpy(&buf[maxread - 4], extra, sizeof (extra));
             totalread += maxread - 4;
             totalread += maxread - 4;
         } /* if */
         } /* if */
         else
         else
@@ -578,7 +583,7 @@ static PHYSFS_sint64 zip_find_end_of_central_dir(PHYSFS_Io *io, PHYSFS_sint64 *l
             totalread += maxread;
             totalread += maxread;
         } /* else */
         } /* else */
 
 
-        memcpy(&extra, buf, sizeof (extra));
+        memcpy(extra, buf, sizeof (extra));
 
 
         for (i = maxread - 4; i > 0; i--)
         for (i = maxread - 4; i > 0; i--)
         {
         {
@@ -833,7 +838,10 @@ static int zip_parse_local(PHYSFS_Io *io, ZIPentry *entry)
     BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
     BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
     BAIL_IF(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 0);
     BAIL_IF(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 0);
     BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
     BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
-    BAIL_IF(ui16 != entry->version_needed, PHYSFS_ERR_CORRUPT, 0);
+    /* Windows Explorer might rewrite the entire central directory, setting
+       this field to 2.0/MS-DOS for all files, so favor the local version,
+       which it leaves intact if it didn't alter that specific file. */
+    entry->version_needed = ui16;
     BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);  /* general bits. */
     BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);  /* general bits. */
     BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
     BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
     BAIL_IF(ui16 != entry->compression_method, PHYSFS_ERR_CORRUPT, 0);
     BAIL_IF(ui16 != entry->compression_method, PHYSFS_ERR_CORRUPT, 0);
@@ -1482,7 +1490,7 @@ static void *ZIP_openArchive(PHYSFS_Io *io, const char *name,
 
 
     if (!zip_parse_end_of_central_dir(info, &dstart, &cdir_ofs, &count))
     if (!zip_parse_end_of_central_dir(info, &dstart, &cdir_ofs, &count))
         goto ZIP_openarchive_failed;
         goto ZIP_openarchive_failed;
-    else if (!__PHYSFS_DirTreeInit(&info->tree, sizeof (ZIPentry)))
+    else if (!__PHYSFS_DirTreeInit(&info->tree, sizeof (ZIPentry), 1, 0))
         goto ZIP_openarchive_failed;
         goto ZIP_openarchive_failed;
 
 
     root = (ZIPentry *) info->tree.root;
     root = (ZIPentry *) info->tree.root;

+ 57 - 10
physfs.mod/physfs/src/physfs_internal.h

@@ -38,7 +38,7 @@
 #include <malloc.h>
 #include <malloc.h>
 #endif
 #endif
 
 
-#ifdef PHYSFS_PLATFORM_SOLARIS
+#if defined(PHYSFS_PLATFORM_SOLARIS) || defined(PHYSFS_PLATFORM_LINUX)
 #include <alloca.h>
 #include <alloca.h>
 #endif
 #endif
 
 
@@ -69,7 +69,7 @@ extern "C" {
    All file-private symbols need to be marked "static".
    All file-private symbols need to be marked "static".
    Everything shared between PhysicsFS sources needs to be in this
    Everything shared between PhysicsFS sources needs to be in this
    file between the visibility pragma blocks. */
    file between the visibility pragma blocks. */
-#if PHYSFS_MINIMUM_GCC_VERSION(4,0) || defined(__clang__)
+#if !defined(_WIN32) && (PHYSFS_MINIMUM_GCC_VERSION(4,0) || defined(__clang__))
 #define PHYSFS_HAVE_PRAGMA_VISIBILITY 1
 #define PHYSFS_HAVE_PRAGMA_VISIBILITY 1
 #endif
 #endif
 
 
@@ -95,6 +95,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
 /* a real C99-compliant snprintf() is in Visual Studio 2015,
 /* a real C99-compliant snprintf() is in Visual Studio 2015,
    but just use this everywhere for binary compatibility. */
    but just use this everywhere for binary compatibility. */
 #if defined(_MSC_VER)
 #if defined(_MSC_VER)
+#include <stdarg.h>
 int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap);
 int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap);
 int __PHYSFS_msvc_snprintf(char *outBuf, size_t size, const char *format, ...);
 int __PHYSFS_msvc_snprintf(char *outBuf, size_t size, const char *format, ...);
 #define vsnprintf __PHYSFS_msvc_vsnprintf
 #define vsnprintf __PHYSFS_msvc_vsnprintf
@@ -108,14 +109,24 @@ const void *__PHYSFS_winrtCalcPrefDir(void);
 #endif
 #endif
 
 
 /* atomic operations. */
 /* atomic operations. */
+/* increment/decrement operations return the final incremented/decremented value. */
 #if defined(_MSC_VER) && (_MSC_VER >= 1500)
 #if defined(_MSC_VER) && (_MSC_VER >= 1500)
 #include <intrin.h>
 #include <intrin.h>
 __PHYSFS_COMPILE_TIME_ASSERT(LongEqualsInt, sizeof (int) == sizeof (long));
 __PHYSFS_COMPILE_TIME_ASSERT(LongEqualsInt, sizeof (int) == sizeof (long));
 #define __PHYSFS_ATOMIC_INCR(ptrval) _InterlockedIncrement((long*)(ptrval))
 #define __PHYSFS_ATOMIC_INCR(ptrval) _InterlockedIncrement((long*)(ptrval))
 #define __PHYSFS_ATOMIC_DECR(ptrval) _InterlockedDecrement((long*)(ptrval))
 #define __PHYSFS_ATOMIC_DECR(ptrval) _InterlockedDecrement((long*)(ptrval))
 #elif defined(__clang__) || (defined(__GNUC__) && (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100)) >= 40100))
 #elif defined(__clang__) || (defined(__GNUC__) && (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100)) >= 40100))
-#define __PHYSFS_ATOMIC_INCR(ptrval) __sync_fetch_and_add(ptrval, 1)
-#define __PHYSFS_ATOMIC_DECR(ptrval) __sync_fetch_and_add(ptrval, -1)
+#define __PHYSFS_ATOMIC_INCR(ptrval) __sync_add_and_fetch(ptrval, 1)
+#define __PHYSFS_ATOMIC_DECR(ptrval) __sync_add_and_fetch(ptrval, -1)
+#elif defined(__WATCOMC__) && defined(__386__)
+extern __inline int _xadd_watcom(volatile int *a, int v);
+#pragma aux _xadd_watcom = \
+  "lock xadd [ecx], eax" \
+  parm [ecx] [eax] \
+  value [eax] \
+  modify exact [eax];
+#define __PHYSFS_ATOMIC_INCR(ptrval) (_xadd_watcom(ptrval, 1)+1)
+#define __PHYSFS_ATOMIC_DECR(ptrval) (_xadd_watcom(ptrval, -1)-1)
 #else
 #else
 #define PHYSFS_NEED_ATOMIC_OP_FALLBACK 1
 #define PHYSFS_NEED_ATOMIC_OP_FALLBACK 1
 int __PHYSFS_ATOMIC_INCR(int *ptrval);
 int __PHYSFS_ATOMIC_INCR(int *ptrval);
@@ -213,6 +224,7 @@ extern void SZIP_global_init(void);
 /* The latest supported PHYSFS_Archiver::version value. */
 /* The latest supported PHYSFS_Archiver::version value. */
 #define CURRENT_PHYSFS_ARCHIVER_API_VERSION 0
 #define CURRENT_PHYSFS_ARCHIVER_API_VERSION 0
 
 
+
 /* This byteorder stuff was lifted from SDL. https://www.libsdl.org/ */
 /* This byteorder stuff was lifted from SDL. https://www.libsdl.org/ */
 #define PHYSFS_LIL_ENDIAN  1234
 #define PHYSFS_LIL_ENDIAN  1234
 #define PHYSFS_BIG_ENDIAN  4321
 #define PHYSFS_BIG_ENDIAN  4321
@@ -220,11 +232,26 @@ extern void SZIP_global_init(void);
 #ifdef __linux__
 #ifdef __linux__
 #include <endian.h>
 #include <endian.h>
 #define PHYSFS_BYTEORDER  __BYTE_ORDER
 #define PHYSFS_BYTEORDER  __BYTE_ORDER
-#else /* __linux__ */
+#elif defined(__OpenBSD__) || defined(__DragonFly__)
+#include <endian.h>
+#define PHYSFS_BYTEORDER  BYTE_ORDER
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+#include <sys/endian.h>
+#define PHYSFS_BYTEORDER  BYTE_ORDER
+/* predefs from newer gcc and clang versions: */
+#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__)
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#define PHYSFS_BYTEORDER   PHYSFS_LIL_ENDIAN
+#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define PHYSFS_BYTEORDER   PHYSFS_BIG_ENDIAN
+#else
+#error Unsupported endianness
+#endif /**/
+#else
 #if defined(__hppa__) || \
 #if defined(__hppa__) || \
     defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
     defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
-    (defined(__MIPS__) && defined(__MISPEB__)) || \
-    defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
+    (defined(__MIPS__) && defined(__MIPSEB__)) || \
+    defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \
     defined(__sparc__)
     defined(__sparc__)
 #define PHYSFS_BYTEORDER   PHYSFS_BIG_ENDIAN
 #define PHYSFS_BYTEORDER   PHYSFS_BIG_ENDIAN
 #else
 #else
@@ -312,7 +339,18 @@ char *__PHYSFS_strdup(const char *str);
 /*
 /*
  * Give a hash value for a C string (uses djb's xor hashing algorithm).
  * Give a hash value for a C string (uses djb's xor hashing algorithm).
  */
  */
-PHYSFS_uint32 __PHYSFS_hashString(const char *str, size_t len);
+PHYSFS_uint32 __PHYSFS_hashString(const char *str);
+
+/*
+ * Give a hash value for a C string (uses djb's xor hashing algorithm), case folding as it goes.
+ */
+PHYSFS_uint32 __PHYSFS_hashStringCaseFold(const char *str);
+
+/*
+ * Give a hash value for a C string (uses djb's xor hashing algorithm), case folding as it goes,
+ *  assuming that this is only US-ASCII chars (one byte per char, only 'A' through 'Z' need folding).
+ */
+PHYSFS_uint32 __PHYSFS_hashStringCaseFoldUSAscii(const char *str);
 
 
 
 
 /*
 /*
@@ -348,9 +386,10 @@ int __PHYSFS_readAll(PHYSFS_Io *io, void *buf, const size_t len);
 
 
 /* These are shared between some archivers. */
 /* These are shared between some archivers. */
 
 
+/* LOTS of legacy formats that only use US ASCII, not actually UTF-8, so let them optimize here. */
+void *UNPK_openArchive(PHYSFS_Io *io, const int case_sensitive, const int only_usascii);
 void UNPK_abandonArchive(void *opaque);
 void UNPK_abandonArchive(void *opaque);
 void UNPK_closeArchive(void *opaque);
 void UNPK_closeArchive(void *opaque);
-void *UNPK_openArchive(PHYSFS_Io *io);
 void *UNPK_addEntry(void *opaque, char *name, const int isdir,
 void *UNPK_addEntry(void *opaque, char *name, const int isdir,
                     const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime,
                     const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime,
                     const PHYSFS_uint64 pos, const PHYSFS_uint64 len);
                     const PHYSFS_uint64 pos, const PHYSFS_uint64 len);
@@ -382,10 +421,13 @@ typedef struct __PHYSFS_DirTree
     __PHYSFS_DirTreeEntry **hash;  /* all entries hashed for fast lookup. */
     __PHYSFS_DirTreeEntry **hash;  /* all entries hashed for fast lookup. */
     size_t hashBuckets;            /* number of buckets in hash.          */
     size_t hashBuckets;            /* number of buckets in hash.          */
     size_t entrylen;    /* size in bytes of entries (including subclass). */
     size_t entrylen;    /* size in bytes of entries (including subclass). */
+    int case_sensitive;  /* non-zero to treat entries as case-sensitive in DirTreeFind */
+    int only_usascii;  /* non-zero to treat paths as US ASCII only (one byte per char, only 'A' through 'Z' are considered for case folding). */
 } __PHYSFS_DirTree;
 } __PHYSFS_DirTree;
 
 
 
 
-int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen);
+/* LOTS of legacy formats that only use US ASCII, not actually UTF-8, so let them optimize here. */
+int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen, const int case_sensitive, const int only_usascii);
 void *__PHYSFS_DirTreeAdd(__PHYSFS_DirTree *dt, char *name, const int isdir);
 void *__PHYSFS_DirTreeAdd(__PHYSFS_DirTree *dt, char *name, const int isdir);
 void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path);
 void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path);
 PHYSFS_EnumerateCallbackResult __PHYSFS_DirTreeEnumerate(void *opaque,
 PHYSFS_EnumerateCallbackResult __PHYSFS_DirTreeEnumerate(void *opaque,
@@ -715,6 +757,11 @@ int __PHYSFS_platformGrabMutex(void *mutex);
  */
  */
 void __PHYSFS_platformReleaseMutex(void *mutex);
 void __PHYSFS_platformReleaseMutex(void *mutex);
 
 
+
+/* !!! FIXME: move to public API? */
+PHYSFS_uint32 __PHYSFS_utf8codepoint(const char **_str);
+
+
 #if PHYSFS_HAVE_PRAGMA_VISIBILITY
 #if PHYSFS_HAVE_PRAGMA_VISIBILITY
 #pragma GCC visibility pop
 #pragma GCC visibility pop
 #endif
 #endif

+ 3 - 0
physfs.mod/physfs/src/physfs_lzmasdk.h

@@ -506,6 +506,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
 #endif
 #endif
 
 
 #if defined(MY_CPU_AMD64) \
 #if defined(MY_CPU_AMD64) \
+    || defined(_M_ARM64) \
     || defined(_M_IA64) \
     || defined(_M_IA64) \
     || defined(__AARCH64EL__) \
     || defined(__AARCH64EL__) \
     || defined(__AARCH64EB__)
     || defined(__AARCH64EB__)
@@ -531,6 +532,8 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
 
 
 #if defined(_WIN32) && defined(_M_ARM)
 #if defined(_WIN32) && defined(_M_ARM)
 #define MY_CPU_ARM_LE
 #define MY_CPU_ARM_LE
+#elif defined(_WIN64) && defined(_M_ARM64)
+#define MY_CPU_ARM_LE
 #endif
 #endif
 
 
 #if defined(_WIN32) && defined(_M_IA64)
 #if defined(_WIN32) && defined(_M_IA64)

+ 13 - 5
physfs.mod/physfs/src/physfs_miniz.h

@@ -22,12 +22,14 @@ typedef unsigned long mz_ulong;
 typedef void *(*mz_alloc_func)(void *opaque, unsigned int items, unsigned int size);
 typedef void *(*mz_alloc_func)(void *opaque, unsigned int items, unsigned int size);
 typedef void (*mz_free_func)(void *opaque, void *address);
 typedef void (*mz_free_func)(void *opaque, void *address);
 
 
+#ifndef MINIZ_LITTLE_ENDIAN /* if not defined by PHYSFS */
 #if defined(_M_IX86) || defined(_M_X64)
 #if defined(_M_IX86) || defined(_M_X64)
 /* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster). */
 /* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster). */
 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
 /* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
 /* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
 #define MINIZ_LITTLE_ENDIAN 1
 #define MINIZ_LITTLE_ENDIAN 1
 #endif
 #endif
+#endif /**/
 
 
 #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
 #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
 /* Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator) */
 /* Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator) */
@@ -117,6 +119,8 @@ struct tinfl_decompressor_tag
 #define MZ_MAX(a,b) (((a)>(b))?(a):(b))
 #define MZ_MAX(a,b) (((a)>(b))?(a):(b))
 #define MZ_MIN(a,b) (((a)<(b))?(a):(b))
 #define MZ_MIN(a,b) (((a)<(b))?(a):(b))
 #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
 #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
+#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj))
+#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj))
 
 
 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
   #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
   #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
@@ -166,13 +170,17 @@ struct tinfl_decompressor_tag
     if (temp >= 0) { \
     if (temp >= 0) { \
       code_len = temp >> 9; \
       code_len = temp >> 9; \
       if ((code_len) && (num_bits >= code_len)) \
       if ((code_len) && (num_bits >= code_len)) \
-      break; \
+          break; \
     } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
     } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
        code_len = TINFL_FAST_LOOKUP_BITS; \
        code_len = TINFL_FAST_LOOKUP_BITS; \
        do { \
        do { \
           temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
           temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
-       } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
-    } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
+       } while ((temp < 0) && (num_bits >= (code_len + 1))); \
+       if (temp >= 0) break; \
+    } \
+    TINFL_GET_BYTE(state_index, c); \
+    bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
+    num_bits += 8; \
   } while (num_bits < 15);
   } while (num_bits < 15);
 
 
 /* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
 /* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
@@ -274,13 +282,13 @@ static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_
       else
       else
       {
       {
         for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
         for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
-        MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
+        MZ_CLEAR_ARR(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
         r->m_table_sizes[2] = 19;
         r->m_table_sizes[2] = 19;
       }
       }
       for ( ; (int)r->m_type >= 0; r->m_type--)
       for ( ; (int)r->m_type >= 0; r->m_type--)
       {
       {
         int tree_next, tree_cur; tinfl_huff_table *pTable;
         int tree_next, tree_cur; tinfl_huff_table *pTable;
-        mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
+        mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_ARR(total_syms); MZ_CLEAR_ARR(pTable->m_look_up); MZ_CLEAR_ARR(pTable->m_tree);
         for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
         for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
         used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
         used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
         for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
         for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }

+ 19 - 6
physfs.mod/physfs/src/physfs_platform_apple.m

@@ -12,6 +12,7 @@
 #ifdef PHYSFS_PLATFORM_APPLE
 #ifdef PHYSFS_PLATFORM_APPLE
 
 
 #include <Foundation/Foundation.h>
 #include <Foundation/Foundation.h>
+#include <dlfcn.h>
 
 
 #include "physfs_internal.h"
 #include "physfs_internal.h"
 
 
@@ -99,7 +100,7 @@ static int darwinIsWholeMedia(io_service_t service)
 } /* darwinIsWholeMedia */
 } /* darwinIsWholeMedia */
 
 
 
 
-static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
+static int darwinIsMountedDisc(char *bsdName, mach_port_t mainPort)
 {
 {
     int retval = 0;
     int retval = 0;
     CFMutableDictionaryRef matchingDict;
     CFMutableDictionaryRef matchingDict;
@@ -107,10 +108,10 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
     io_iterator_t iter;
     io_iterator_t iter;
     io_service_t service;
     io_service_t service;
 
 
-    if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
+    if ((matchingDict = IOBSDNameMatching(mainPort, 0, bsdName)) == NULL)
         return 0;
         return 0;
 
 
-    rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
+    rc = IOServiceGetMatchingServices(mainPort, matchingDict, &iter);
     if ((rc != KERN_SUCCESS) || (!iter))
     if ((rc != KERN_SUCCESS) || (!iter))
         return 0;
         return 0;
 
 
@@ -158,13 +159,25 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
 void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
 void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
 {
 {
 #if !defined(PHYSFS_NO_CDROM_SUPPORT)
 #if !defined(PHYSFS_NO_CDROM_SUPPORT)
+    /* macOS 12.0 changed "master" names to "main". */
+    typedef kern_return_t (*ioMainPortFn)(mach_port_t, mach_port_t *);
+    static ioMainPortFn ioMainPort = NULL;
     const char *devPrefix = "/dev/";
     const char *devPrefix = "/dev/";
     const int prefixLen = strlen(devPrefix);
     const int prefixLen = strlen(devPrefix);
-    mach_port_t masterPort = 0;
+    mach_port_t mainPort = 0;
     struct statfs *mntbufp;
     struct statfs *mntbufp;
     int i, mounts;
     int i, mounts;
 
 
-    if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
+    if (ioMainPort == NULL)
+    {
+        ioMainPort = (ioMainPortFn) dlsym(RTLD_DEFAULT, "IOMainPort");
+        if (!ioMainPort)
+            ioMainPort = (ioMainPortFn) dlsym(RTLD_DEFAULT, "IOMasterPort");
+        if (!ioMainPort)
+            return; /* oh well, no CD-ROMs for you. */
+    } /* if */
+
+    if (ioMainPort(MACH_PORT_NULL, &mainPort) != KERN_SUCCESS)
         BAIL(PHYSFS_ERR_OS_ERROR, ) /*return void*/;
         BAIL(PHYSFS_ERR_OS_ERROR, ) /*return void*/;
 
 
     mounts = getmntinfo(&mntbufp, MNT_WAIT);  /* NOT THREAD SAFE! */
     mounts = getmntinfo(&mntbufp, MNT_WAIT);  /* NOT THREAD SAFE! */
@@ -176,7 +189,7 @@ void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
             continue;
             continue;
 
 
         dev += prefixLen;
         dev += prefixLen;
-        if (darwinIsMountedDisc(dev, masterPort))
+        if (darwinIsMountedDisc(dev, mainPort))
             cb(data, mnt);
             cb(data, mnt);
     } /* for */
     } /* for */
 #endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
 #endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */

+ 4 - 4
physfs.mod/physfs/src/physfs_platform_os2.c

@@ -222,7 +222,7 @@ static char *cvtPathToCorrectCase(char *buf)
         if (ptr != NULL)  /* isolate element to find (fname is the start). */
         if (ptr != NULL)  /* isolate element to find (fname is the start). */
             *ptr = '\0';
             *ptr = '\0';
 
 
-        rc = DosFindFirst((unsigned char *) spec, &hdir, FILE_DIRECTORY,
+        rc = DosFindFirst(spec, &hdir, FILE_DIRECTORY,
                           &fb, sizeof (fb), &count, FIL_STANDARD);
                           &fb, sizeof (fb), &count, FIL_STANDARD);
         if (rc == NO_ERROR)
         if (rc == NO_ERROR)
         {
         {
@@ -331,7 +331,7 @@ static int isCdRomDrive(ULONG drive)
     ULONG ul1, ul2;
     ULONG ul1, ul2;
     APIRET rc;
     APIRET rc;
     HFILE hfile = NULLHANDLE;
     HFILE hfile = NULLHANDLE;
-    unsigned char drivename[3] = { 0, ':', '\0' };
+    char drivename[3] = { 0, ':', '\0' };
 
 
     drivename[0] = 'A' + drive;
     drivename[0] = 'A' + drive;
 
 
@@ -443,7 +443,7 @@ PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
     __PHYSFS_smallFree(utf8);
     __PHYSFS_smallFree(utf8);
     BAIL_IF_ERRPASS(!cpspec, PHYSFS_ENUM_ERROR);
     BAIL_IF_ERRPASS(!cpspec, PHYSFS_ENUM_ERROR);
 
 
-    rc = DosFindFirst((unsigned char *) cpspec, &hdir,
+    rc = DosFindFirst(cpspec, &hdir,
                       FILE_DIRECTORY | FILE_ARCHIVED |
                       FILE_DIRECTORY | FILE_ARCHIVED |
                       FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM,
                       FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM,
                       &fb, sizeof (fb), &count, FIL_STANDARD);
                       &fb, sizeof (fb), &count, FIL_STANDARD);
@@ -535,7 +535,7 @@ int __PHYSFS_platformMkDir(const char *filename)
     APIRET rc;
     APIRET rc;
     char *cpstr = cvtUtf8ToCodepage(filename);
     char *cpstr = cvtUtf8ToCodepage(filename);
     BAIL_IF_ERRPASS(!cpstr, 0);
     BAIL_IF_ERRPASS(!cpstr, 0);
-    rc = DosCreateDir((unsigned char *) cpstr, NULL);
+    rc = DosCreateDir(cpstr, NULL);
     allocator.Free(cpstr);
     allocator.Free(cpstr);
     BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), 0);
     BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), 0);
     return 1;
     return 1;

+ 40 - 8
physfs.mod/physfs/src/physfs_platform_posix.c

@@ -6,8 +6,6 @@
  *  This file written by Ryan C. Gordon.
  *  This file written by Ryan C. Gordon.
  */
  */
 
 
-/* !!! FIXME: check for EINTR? */
-
 #define __PHYSICSFS_INTERNAL__
 #define __PHYSICSFS_INTERNAL__
 #include "physfs_platforms.h"
 #include "physfs_platforms.h"
 
 
@@ -157,19 +155,41 @@ int __PHYSFS_platformMkDir(const char *path)
 } /* __PHYSFS_platformMkDir */
 } /* __PHYSFS_platformMkDir */
 
 
 
 
+#if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
+static inline void set_CLOEXEC(int fildes)
+{
+    int flags = fcntl(fildes, F_GETFD);
+    if (flags != -1) {
+        fcntl(fildes, F_SETFD, flags | FD_CLOEXEC);
+    }
+}
+#endif
+
 static void *doOpen(const char *filename, int mode)
 static void *doOpen(const char *filename, int mode)
 {
 {
     const int appending = (mode & O_APPEND);
     const int appending = (mode & O_APPEND);
     int fd;
     int fd;
     int *retval;
     int *retval;
+
     errno = 0;
     errno = 0;
 
 
     /* O_APPEND doesn't actually behave as we'd like. */
     /* O_APPEND doesn't actually behave as we'd like. */
     mode &= ~O_APPEND;
     mode &= ~O_APPEND;
 
 
-    fd = open(filename, mode, S_IRUSR | S_IWUSR);
+#ifdef O_CLOEXEC
+    /* Add O_CLOEXEC if defined */
+    mode |= O_CLOEXEC;
+#endif
+
+    do {
+        fd = open(filename, mode, S_IRUSR | S_IWUSR);
+    } while ((fd < 0) && (errno == EINTR));
     BAIL_IF(fd < 0, errcodeFromErrno(), NULL);
     BAIL_IF(fd < 0, errcodeFromErrno(), NULL);
 
 
+#if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
+    set_CLOEXEC(fd);
+#endif
+
     if (appending)
     if (appending)
     {
     {
         if (lseek(fd, 0, SEEK_END) < 0)
         if (lseek(fd, 0, SEEK_END) < 0)
@@ -219,7 +239,9 @@ PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
     if (!__PHYSFS_ui64FitsAddressSpace(len))
     if (!__PHYSFS_ui64FitsAddressSpace(len))
         BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
         BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
 
 
-    rc = read(fd, buffer, (size_t) len);
+    do {
+        rc = read(fd, buffer, (size_t) len);
+    } while ((rc == -1) && (errno == EINTR));
     BAIL_IF(rc == -1, errcodeFromErrno(), -1);
     BAIL_IF(rc == -1, errcodeFromErrno(), -1);
     assert(rc >= 0);
     assert(rc >= 0);
     assert(rc <= len);
     assert(rc <= len);
@@ -236,7 +258,9 @@ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
     if (!__PHYSFS_ui64FitsAddressSpace(len))
     if (!__PHYSFS_ui64FitsAddressSpace(len))
         BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
         BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
 
 
-    rc = write(fd, (void *) buffer, (size_t) len);
+    do {
+        rc = write(fd, (void *) buffer, (size_t) len);
+    } while ((rc == -1) && (errno == EINTR));
     BAIL_IF(rc == -1, errcodeFromErrno(), rc);
     BAIL_IF(rc == -1, errcodeFromErrno(), rc);
     assert(rc >= 0);
     assert(rc >= 0);
     assert(rc <= len);
     assert(rc <= len);
@@ -275,8 +299,13 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
 int __PHYSFS_platformFlush(void *opaque)
 int __PHYSFS_platformFlush(void *opaque)
 {
 {
     const int fd = *((int *) opaque);
     const int fd = *((int *) opaque);
-    if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY)
-        BAIL_IF(fsync(fd) == -1, errcodeFromErrno(), 0);
+    int rc = -1;
+    if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY) {
+        do {
+            rc = fsync(fd);
+        } while ((rc == -1) && (errno == EINTR));
+        BAIL_IF(rc == -1, errcodeFromErrno(), 0);
+    }
     return 1;
     return 1;
 } /* __PHYSFS_platformFlush */
 } /* __PHYSFS_platformFlush */
 
 
@@ -284,7 +313,10 @@ int __PHYSFS_platformFlush(void *opaque)
 void __PHYSFS_platformClose(void *opaque)
 void __PHYSFS_platformClose(void *opaque)
 {
 {
     const int fd = *((int *) opaque);
     const int fd = *((int *) opaque);
-    (void) close(fd);  /* we don't check this. You should have used flush! */
+    int rc = -1;
+    do {
+        rc = close(fd);  /* we don't check this. You should have used flush! */
+    } while ((rc == -1) && (errno == EINTR));
     allocator.Free(opaque);
     allocator.Free(opaque);
 } /* __PHYSFS_platformClose */
 } /* __PHYSFS_platformClose */
 
 

+ 5 - 5
physfs.mod/physfs/src/physfs_platform_windows.c

@@ -101,7 +101,7 @@ static char *unicodeToUtf8Heap(const WCHAR *w_str)
 
 
 static inline HANDLE winFindFirstFileW(const WCHAR *path, LPWIN32_FIND_DATAW d)
 static inline HANDLE winFindFirstFileW(const WCHAR *path, LPWIN32_FIND_DATAW d)
 {
 {
-    #ifdef PHYSFS_PLATFORM_WINRT
+    #if defined(PHYSFS_PLATFORM_WINRT) || (_WIN32_WINNT >= 0x0501) // Windows XP+
     return FindFirstFileExW(path, FindExInfoStandard, d,
     return FindFirstFileExW(path, FindExInfoStandard, d,
                             FindExSearchNameMatch, NULL, 0);
                             FindExSearchNameMatch, NULL, 0);
     #else
     #else
@@ -111,7 +111,7 @@ static inline HANDLE winFindFirstFileW(const WCHAR *path, LPWIN32_FIND_DATAW d)
 
 
 static inline BOOL winInitializeCriticalSection(LPCRITICAL_SECTION lpcs)
 static inline BOOL winInitializeCriticalSection(LPCRITICAL_SECTION lpcs)
 {
 {
-    #ifdef PHYSFS_PLATFORM_WINRT
+    #if defined(PHYSFS_PLATFORM_WINRT) || (_WIN32_WINNT >= 0x0600) // Windows Vista+
     return InitializeCriticalSectionEx(lpcs, 2000, 0);
     return InitializeCriticalSectionEx(lpcs, 2000, 0);
     #else
     #else
     InitializeCriticalSection(lpcs);
     InitializeCriticalSection(lpcs);
@@ -123,7 +123,7 @@ static inline HANDLE winCreateFileW(const WCHAR *wfname, const DWORD mode,
                                     const DWORD creation)
                                     const DWORD creation)
 {
 {
     const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
     const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
-    #ifdef PHYSFS_PLATFORM_WINRT
+    #if defined(PHYSFS_PLATFORM_WINRT) || (_WIN32_WINNT >= 0x0602) // Windows 8+
     return CreateFile2(wfname, mode, share, creation, NULL);
     return CreateFile2(wfname, mode, share, creation, NULL);
     #else
     #else
     return CreateFileW(wfname, mode, share, NULL, creation,
     return CreateFileW(wfname, mode, share, NULL, creation,
@@ -134,7 +134,7 @@ static inline HANDLE winCreateFileW(const WCHAR *wfname, const DWORD mode,
 static BOOL winSetFilePointer(HANDLE h, const PHYSFS_sint64 pos,
 static BOOL winSetFilePointer(HANDLE h, const PHYSFS_sint64 pos,
                               PHYSFS_sint64 *_newpos, const DWORD whence)
                               PHYSFS_sint64 *_newpos, const DWORD whence)
 {
 {
-    #ifdef PHYSFS_PLATFORM_WINRT
+    #if defined(PHYSFS_PLATFORM_WINRT) || (_WIN32_WINNT >= 0x0501) // Windows XP+
     LARGE_INTEGER lipos;
     LARGE_INTEGER lipos;
     LARGE_INTEGER linewpos;
     LARGE_INTEGER linewpos;
     BOOL rc;
     BOOL rc;
@@ -158,7 +158,7 @@ static BOOL winSetFilePointer(HANDLE h, const PHYSFS_sint64 pos,
 
 
 static PHYSFS_sint64 winGetFileSize(HANDLE h)
 static PHYSFS_sint64 winGetFileSize(HANDLE h)
 {
 {
-    #ifdef PHYSFS_PLATFORM_WINRT
+    #if defined(PHYSFS_PLATFORM_WINRT) || (_WIN32_WINNT >= 0x0600) // Windows Vista+
     FILE_STANDARD_INFO info;
     FILE_STANDARD_INFO info;
     const BOOL rc = GetFileInformationByHandleEx(h, FileStandardInfo,
     const BOOL rc = GetFileInformationByHandleEx(h, FileStandardInfo,
                                                  &info, sizeof (info));
                                                  &info, sizeof (info));

+ 12 - 7
physfs.mod/physfs/src/physfs_unicode.c

@@ -21,8 +21,8 @@
 /*
 /*
  * This may not be the best value, but it's one that isn't represented
  * This may not be the best value, but it's one that isn't represented
  *  in Unicode (0x10FFFF is the largest codepoint value). We return this
  *  in Unicode (0x10FFFF is the largest codepoint value). We return this
- *  value from utf8codepoint() if there's bogus bits in the
- *  stream. utf8codepoint() will turn this value into something
+ *  value from __PHYSFS_utf8codepoint() if there's bogus bits in the
+ *  stream. __PHYSFS_utf8codepoint() will turn this value into something
  *  reasonable (like a question mark), for text that wants to try to recover,
  *  reasonable (like a question mark), for text that wants to try to recover,
  *  whereas utf8valid() will use the value to determine if a string has bad
  *  whereas utf8valid() will use the value to determine if a string has bad
  *  bits.
  *  bits.
@@ -35,7 +35,7 @@
  */
  */
 #define UNICODE_BOGUS_CHAR_CODEPOINT '?'
 #define UNICODE_BOGUS_CHAR_CODEPOINT '?'
 
 
-static PHYSFS_uint32 utf8codepoint(const char **_str)
+PHYSFS_uint32 __PHYSFS_utf8codepoint(const char **_str)
 {
 {
     const char *str = *_str;
     const char *str = *_str;
     PHYSFS_uint32 retval = 0;
     PHYSFS_uint32 retval = 0;
@@ -188,6 +188,11 @@ static PHYSFS_uint32 utf8codepoint(const char **_str)
     } /* else if */
     } /* else if */
 
 
     return UNICODE_BOGUS_CHAR_VALUE;
     return UNICODE_BOGUS_CHAR_VALUE;
+} /* __PHYSFS_utf8codepoint */
+
+static inline PHYSFS_uint32 utf8codepoint(const char **_str)
+{
+    return __PHYSFS_utf8codepoint(_str);
 } /* utf8codepoint */
 } /* utf8codepoint */
 
 
 static PHYSFS_uint32 utf16codepoint(const PHYSFS_uint16 **_str)
 static PHYSFS_uint32 utf16codepoint(const PHYSFS_uint16 **_str)
@@ -210,7 +215,7 @@ static PHYSFS_uint32 utf16codepoint(const PHYSFS_uint16 **_str)
         else
         else
         {
         {
             src++;  /* eat the other surrogate. */
             src++;  /* eat the other surrogate. */
-            cp = (((cp - 0xD800) << 10) | (pair - 0xDC00));
+            cp = 0x10000 + (((cp - 0xD800) << 10) | (pair - 0xDC00));
         } /* else */
         } /* else */
     } /* else if */
     } /* else if */
 
 
@@ -238,7 +243,7 @@ void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
     len -= sizeof (PHYSFS_uint32);   /* save room for null char. */
     len -= sizeof (PHYSFS_uint32);   /* save room for null char. */
     while (len >= sizeof (PHYSFS_uint32))
     while (len >= sizeof (PHYSFS_uint32))
     {
     {
-        PHYSFS_uint32 cp = utf8codepoint(&src);
+        PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&src);
         if (cp == 0)
         if (cp == 0)
             break;
             break;
         else if (cp == UNICODE_BOGUS_CHAR_VALUE)
         else if (cp == UNICODE_BOGUS_CHAR_VALUE)
@@ -256,7 +261,7 @@ void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
     len -= sizeof (PHYSFS_uint16);   /* save room for null char. */
     len -= sizeof (PHYSFS_uint16);   /* save room for null char. */
     while (len >= sizeof (PHYSFS_uint16))
     while (len >= sizeof (PHYSFS_uint16))
     {
     {
-        PHYSFS_uint32 cp = utf8codepoint(&src);
+        PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&src);
         if (cp == 0)
         if (cp == 0)
             break;
             break;
         else if (cp == UNICODE_BOGUS_CHAR_VALUE)
         else if (cp == UNICODE_BOGUS_CHAR_VALUE)
@@ -278,7 +283,7 @@ void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
     len -= sizeof (PHYSFS_uint16);   /* save room for null char. */
     len -= sizeof (PHYSFS_uint16);   /* save room for null char. */
     while (len >= sizeof (PHYSFS_uint16))
     while (len >= sizeof (PHYSFS_uint16))
     {
     {
-        PHYSFS_uint32 cp = utf8codepoint(&src);
+        PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&src);
         if (cp == 0)
         if (cp == 0)
             break;
             break;
         else if (cp == UNICODE_BOGUS_CHAR_VALUE)
         else if (cp == UNICODE_BOGUS_CHAR_VALUE)

+ 1 - 1
physfs.mod/physfs/test/test_physfs.c

@@ -31,7 +31,7 @@
 #include "physfs.h"
 #include "physfs.h"
 
 
 #define TEST_VERSION_MAJOR  3
 #define TEST_VERSION_MAJOR  3
-#define TEST_VERSION_MINOR  1
+#define TEST_VERSION_MINOR  3
 #define TEST_VERSION_PATCH  0
 #define TEST_VERSION_PATCH  0
 
 
 static FILE *history_file = NULL;
 static FILE *history_file = NULL;