Compare commits
123 Commits
release-2.
...
main
Author | SHA1 | Date |
---|---|---|
Ryan C. Gordon | 9266e773d3 | |
Ryan C. Gordon | fdd38a3f8a | |
Ryan C. Gordon | 6a7625cd77 | |
Ozkan Sezer | 49662cd826 | |
Ryan C. Gordon | 4d9bcc3d1a | |
Ryan C. Gordon | 496817a9e8 | |
Ozkan Sezer | 0d4e9aac45 | |
Ozkan Sezer | 65195f9c1a | |
Ozkan Sezer | fb0901b10f | |
Ryan C. Gordon | f0c7367b0f | |
Ozkan Sezer | e32221a104 | |
Ozkan Sezer | cfbbb255a2 | |
Anonymous Maarten | 2a90b1f469 | |
Anonymous Maarten | 88ef84c053 | |
Anonymous Maarten | 9bc66b6469 | |
Anonymous Maarten | aabb732caf | |
Ryan C. Gordon | 6925c1067d | |
Ryan C. Gordon | 64807353df | |
Ryan C. Gordon | ed4ab15524 | |
Ryan C. Gordon | 48e7c2e3af | |
Ryan C. Gordon | 497934818b | |
Ryan C. Gordon | 17b691b0ea | |
Ozkan Sezer | 14691399cd | |
Ozkan Sezer | 20e90ed3c4 | |
Ozkan Sezer | eec3f7f79a | |
Ryan C. Gordon | 3a3c552e50 | |
Ryan C. Gordon | b975bb679b | |
Ozkan Sezer | 0ae9467685 | |
Ozkan Sezer | cd2e055454 | |
Ozkan Sezer | 141dccb087 | |
Ozkan Sezer | 3abe069870 | |
Ozkan Sezer | 02b6a7f084 | |
Ryan C. Gordon | 045ee2cb7f | |
Ryan C. Gordon | a329a35993 | |
Semphris | 7305ee92a2 | |
past-due | a0dfe220ff | |
alfadur | b3cca6a026 | |
alfadur | 8eab55d173 | |
Arthur Brianville (Ybalrid) | 23690f316d | |
pastdue | b8fa8fdcac | |
pastdue | a9cb20772b | |
James Le Cuirot | d8ba1a935c | |
Ryan C. Gordon | 0145431345 | |
Ryan C. Gordon | b7410d673e | |
Ryan C. Gordon | fdf308fa88 | |
Matthew Albrecht | d24ce15922 | |
Ryan C. Gordon | 69a7428787 | |
Ryan C. Gordon | ebe02ceb02 | |
Ryan C. Gordon | 9b83066716 | |
Ryan C. Gordon | 13f00546a9 | |
Ryan C. Gordon | 5ea6ba7557 | |
Ryan C. Gordon | 009be5ab20 | |
Ryan C. Gordon | 55c3d9f9d8 | |
Ryan C. Gordon | 22297e7ea2 | |
Ryan C. Gordon | 00599b7dac | |
Ryan C. Gordon | 3169a5e9d3 | |
Ryan C. Gordon | 101ec3c831 | |
Ryan C. Gordon | e3231d1cb0 | |
Ryan C. Gordon | 9d61fadd3e | |
Ryan C. Gordon | 235e31c420 | |
Ryan C. Gordon | 291cad07b7 | |
Ryan C. Gordon | 0d1df744ba | |
Ryan C. Gordon | 08dc47a72b | |
Ryan C. Gordon | 1daf787fb2 | |
Ryan C. Gordon | 56aaae4949 | |
Ryan C. Gordon | 19ea59109d | |
Ryan C. Gordon | a8180f0e4c | |
Ryan C. Gordon | 9cb45dc6cb | |
Kevin d'Orange | 8791811909 | |
Ryan C. Gordon | f94ce0613d | |
Ryan C. Gordon | 6b0839051f | |
Ryan C. Gordon | 5cbb460bcd | |
Ryan C. Gordon | e549fe0e0f | |
Ryan C. Gordon | 736d0b371a | |
Ryan C. Gordon | 28ac5794b1 | |
Ryan C. Gordon | 500033f37d | |
Ryan C. Gordon | b57d8960e8 | |
Ryan C. Gordon | 5786a58628 | |
Ryan C. Gordon | 73d66441e3 | |
Ryan C. Gordon | 7d194a8a62 | |
Ryan C. Gordon | 8ce294a458 | |
Ryan C. Gordon | 15dd00659a | |
Ryan C. Gordon | 7394c07d6b | |
Ryan C. Gordon | 0bad12d401 | |
Ryan C. Gordon | 89d4809f28 | |
Ryan C. Gordon | ea90a92016 | |
Ryan C. Gordon | 3597a7b69a | |
Ryan C. Gordon | c86895264b | |
Ryan C. Gordon | 47b0e834dc | |
Ryan C. Gordon | 90dfc49f6d | |
Ryan C. Gordon | a45afc5d50 | |
Ryan C. Gordon | 62d24e228f | |
Ryan C. Gordon | 26db9376da | |
Ryan C. Gordon | 1c7945461d | |
Ryan C. Gordon | f5e5b586c7 | |
Ryan C. Gordon | fbb8ce7e2d | |
Ryan C. Gordon | 347bb7b6c8 | |
Ryan C. Gordon | 9e756312d5 | |
Ryan C. Gordon | 975b7a577b | |
R?mi Verschelde | 3167a48675 | |
Ryan C. Gordon | bb2c38cdea | |
Ryan C. Gordon | 9b42fe23fd | |
Ryan C. Gordon | 300beeda72 | |
Ryan C. Gordon | 1722e9ba92 | |
Ryan C. Gordon | 4ca60a090b | |
Ryan C. Gordon | 3d8817346d | |
Ryan C. Gordon | 425131ccda | |
Ryan C. Gordon | 2b78f64c11 | |
Ryan C. Gordon | 395b2b02dd | |
Ryan C. Gordon | 69d3df3286 | |
Ryan C. Gordon | 7a26b83733 | |
Francesco Bertolaccini | e728c65912 | |
Marty Plummer | db700fd327 | |
Ryan C. Gordon | 21b2fd39f2 | |
Ryan C. Gordon | bc2ddf0a53 | |
Ryan C. Gordon | 9f8ecb91cb | |
Ryan C. Gordon | eb75883226 | |
Ryan C. Gordon | 689333dc8f | |
Ryan C. Gordon | 6ad71878fe | |
Ryan C. Gordon | 4e0d3d55e9 | |
Ryan C. Gordon | 5fb9119ebc | |
Ryan C. Gordon | 7607eeeb00 | |
Ryan C. Gordon | e19422cc06 |
|
@ -0,0 +1,2 @@
|
|||
github: [icculus]
|
||||
patreon: icculus
|
|
@ -0,0 +1,30 @@
|
|||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
name: ${{ matrix.platform.name }}
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform: # !!! FIXME: figure out an efficient way to get SDL2 on the Windows/Mac bots.
|
||||
- { name: Linux, os: ubuntu-20.04, flags: -GNinja }
|
||||
- { name: MinGW, os: windows-latest, flags: -GNinja -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_SYSTEM_NAME=Windows }
|
||||
- { name: Windows, os: windows-latest }
|
||||
- { name: MacOS, os: macos-latest }
|
||||
steps:
|
||||
- name: Setup Linux dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install ninja-build
|
||||
- name: Setup MinGW dependencies
|
||||
if: contains(matrix.platform.name, 'MinGW')
|
||||
run: choco install ninja
|
||||
- name: Get PhysicsFS sources
|
||||
uses: actions/checkout@v2
|
||||
- name: Configure CMake
|
||||
run: cmake -B build ${{ matrix.platform.flags }}
|
||||
- name: Build
|
||||
run: cmake --build build/
|
|
@ -0,0 +1,20 @@
|
|||
name: Build (OS/2)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
os2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: open-watcom/setup-watcom@v0
|
||||
- name: Build physfs.dll
|
||||
run: |
|
||||
cd src
|
||||
wmake -f Makefile.os2
|
||||
cd ..
|
||||
- name: distclean
|
||||
run: |
|
||||
cd src
|
||||
wmake -f Makefile.os2 distclean
|
||||
cd ..
|
|
@ -1,2 +1,2 @@
|
|||
syntax:glob
|
||||
cmake-build
|
||||
|
184
CMakeLists.txt
184
CMakeLists.txt
|
@ -9,27 +9,29 @@
|
|||
# compile, using preprocessor checks for platform-specific bits instead of
|
||||
# testing in here.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
set(PHYSFS_VERSION 3.3.0)
|
||||
|
||||
project(PhysicsFS)
|
||||
set(PHYSFS_VERSION 2.1.1)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(PhysicsFS VERSION ${PHYSFS_VERSION} LANGUAGES C )
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Increment this if/when we break backwards compatibility.
|
||||
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)
|
||||
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()
|
||||
|
||||
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.
|
||||
set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
|
||||
endif()
|
||||
|
@ -42,10 +44,10 @@ endif()
|
|||
if(HAIKU)
|
||||
# We add this explicitly, since we don't want CMake to think this
|
||||
# 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(ROOT_LIBRARY root)
|
||||
set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${BE_LIBRARY} ${ROOT_LIBRARY})
|
||||
list(APPEND OPTIONAL_LIBRARY_LIBS ${BE_LIBRARY} ${ROOT_LIBRARY})
|
||||
endif()
|
||||
|
||||
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()
|
||||
|
||||
if(WINRT)
|
||||
set(PHYSFS_CPP_SRCS src/physfs_platform_winrt.cpp)
|
||||
list(APPEND PHYSFS_CPP_SRCS src/physfs_platform_winrt.cpp)
|
||||
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)
|
||||
if(PTHREAD_LIBRARY)
|
||||
set(OPTIONAL_LIBRARY_LIBS ${OPTIONAL_LIBRARY_LIBS} ${PTHREAD_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(PHYSFS_CPP_SRCS)
|
||||
enable_language(CXX)
|
||||
endif()
|
||||
|
||||
# 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
|
||||
# another project or bring up a new build system: just compile all the source
|
||||
|
@ -75,6 +81,8 @@ set(PHYSFS_SRCS
|
|||
src/physfs_platform_unix.c
|
||||
src/physfs_platform_windows.c
|
||||
src/physfs_platform_os2.c
|
||||
src/physfs_platform_qnx.c
|
||||
src/physfs_platform_android.c
|
||||
src/physfs_archiver_dir.c
|
||||
src/physfs_archiver_unpacked.c
|
||||
src/physfs_archiver_grp.c
|
||||
|
@ -150,11 +158,13 @@ endif()
|
|||
option(PHYSFS_BUILD_STATIC "Build static library" TRUE)
|
||||
if(PHYSFS_BUILD_STATIC)
|
||||
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
|
||||
# library named "physfs.lib" which would conflict; Unix tend to like the
|
||||
# same library name with a different extension for static libs, but
|
||||
# Windows can just have a separate name.
|
||||
if(NOT WINDOWS)
|
||||
if(NOT MSVC)
|
||||
set_target_properties(physfs-static PROPERTIES OUTPUT_NAME "physfs")
|
||||
endif()
|
||||
if(WINRT)
|
||||
|
@ -162,23 +172,34 @@ if(PHYSFS_BUILD_STATIC)
|
|||
set_target_properties(physfs-static PROPERTIES VS_WINRT_COMPONENT True)
|
||||
set_target_properties(physfs-static PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264")
|
||||
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_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs-static")
|
||||
list(APPEND PHYSFS_INSTALL_TARGETS "physfs-static")
|
||||
endif()
|
||||
|
||||
option(PHYSFS_BUILD_SHARED "Build shared library" TRUE)
|
||||
if(PHYSFS_BUILD_SHARED)
|
||||
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 VERSION ${PHYSFS_VERSION})
|
||||
set_target_properties(physfs PROPERTIES SOVERSION ${PHYSFS_SOVERSION})
|
||||
set_target_properties(physfs PROPERTIES EXPORT_NAME PhysFS)
|
||||
if(WINRT)
|
||||
set_target_properties(physfs PROPERTIES VS_WINRT_COMPONENT True)
|
||||
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_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs")
|
||||
list(APPEND PHYSFS_INSTALL_TARGETS "physfs")
|
||||
endif()
|
||||
|
||||
if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
|
||||
|
@ -186,7 +207,7 @@ if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
|
|||
endif()
|
||||
|
||||
# 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-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
endif()
|
||||
|
@ -198,76 +219,101 @@ if(PHYSFS_BUILD_TEST)
|
|||
find_path(HISTORY_H readline/history.h)
|
||||
if(READLINE_H AND HISTORY_H)
|
||||
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(${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()
|
||||
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()
|
||||
|
||||
install(TARGETS ${PHYSFS_INSTALL_TARGETS}
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
install(FILES src/physfs.h DESTINATION include)
|
||||
option(PHYSFS_DISABLE_INSTALL "Disable installing PhysFS" OFF)
|
||||
if(NOT PHYSFS_DISABLE_INSTALL)
|
||||
|
||||
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")
|
||||
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})
|
||||
|
||||
add_custom_target(
|
||||
docs
|
||||
${DOXYGEN_EXECUTABLE} "${PHYSFS_OUTPUT_DOXYFILE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Building documentation in 'docs' directory..."
|
||||
install(EXPORT PhysFSExport
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PhysFS"
|
||||
FILE PhysFSConfig.cmake
|
||||
NAMESPACE PhysFS::
|
||||
)
|
||||
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()
|
||||
|
||||
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")
|
||||
add_custom_target(
|
||||
dist
|
||||
hg archive -t tbz2 "${PHYSFS_TARBALL}"
|
||||
${PHYSFS_TARGETNAME_DIST}
|
||||
git archive --prefix="physfs-${PHYSFS_VERSION}/" --output="${PHYSFS_TARBALL}" HEAD
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Building source tarball '${PHYSFS_TARBALL}'..."
|
||||
)
|
||||
|
||||
set(PHYSFS_TARGETNAME_UNINSTALL "uninstall" CACHE STRING "Name of 'uninstall' build target")
|
||||
add_custom_target(
|
||||
uninstall
|
||||
${PHYSFS_TARGETNAME_UNINSTALL}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/extras/uninstall.sh"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
COMMENT "Uninstall the project..."
|
||||
)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
configure_file(
|
||||
"extras/physfs.pc.in"
|
||||
"extras/physfs.pc"
|
||||
@ONLY
|
||||
)
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/extras/physfs.pc"
|
||||
DESTINATION "lib/pkgconfig"
|
||||
)
|
||||
endif()
|
||||
|
||||
macro(message_bool_option _NAME _VALUE)
|
||||
if(${_VALUE})
|
||||
|
@ -291,9 +337,9 @@ message_bool_option("ISO9660 support" PHYSFS_ARCHIVE_ISO9660)
|
|||
message_bool_option("Build static library" PHYSFS_BUILD_STATIC)
|
||||
message_bool_option("Build shared library" PHYSFS_BUILD_SHARED)
|
||||
message_bool_option("Build stdio test program" PHYSFS_BUILD_TEST)
|
||||
message_bool_option("Build Doxygen documentation" PHYSFS_BUILD_DOCS)
|
||||
if(PHYSFS_BUILD_TEST)
|
||||
message_bool_option(" Use readline in test program" HAVE_SYSTEM_READLINE)
|
||||
endif()
|
||||
|
||||
# end of CMakeLists.txt ...
|
||||
|
||||
|
|
36
LICENSE.txt
36
LICENSE.txt
|
@ -1,23 +1,17 @@
|
|||
Copyright (c) 2001-2022 Ryan C. Gordon <icculus@icculus.org> 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.
|
||||
|
||||
Copyright (c) 2001-2017 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
|
||||
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.
|
||||
|
||||
Ryan C. Gordon <icculus@icculus.org>
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
|
|
@ -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
|
||||
browser here:
|
||||
|
||||
https://hg.icculus.org/icculus/physfs/
|
||||
https://github.com/icculus/physfs/commits/
|
||||
|
||||
|
||||
|
|
|
@ -158,6 +158,15 @@ Bug fixes,
|
|||
VDF archiver:
|
||||
Francesco Bertolaccini
|
||||
|
||||
CMake fixes:
|
||||
Tobias Markus
|
||||
|
||||
Bug fixes,
|
||||
Rémi Verschelde
|
||||
|
||||
Bug fixes:
|
||||
Rob Loach
|
||||
|
||||
Other stuff:
|
||||
Your name here! Patches go to icculus@icculus.org ...
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ If this all worked for your specific project, you can stop reading now.
|
|||
|
||||
|
||||
|
||||
UNIX:
|
||||
Unix:
|
||||
|
||||
You will need CMake (https://www.cmake.org/) 2.4 or later installed.
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
The API documentation is readable in a few ways:
|
||||
|
||||
- Read physfs.h; it's _heavily_ documented and the primary source of reference
|
||||
documentation for the library.
|
||||
- Run Doxygen over the header, which produces nicer-to-browse documentation in
|
||||
HTML, LaTeX, manpage, etc formats. This is done for you if Doxygen is
|
||||
installed and you build the "docs" target in whatever project files CMake
|
||||
generated for you.
|
||||
- Too much trouble? We generated the HTML reference for you, online here:
|
||||
|
||||
https://icculus.org/physfs/docs/
|
||||
|
||||
- We would love well-written tutorials for the latest version of PhysicsFS!
|
||||
If you write one, we would love to list it here. Drop me a line about it:
|
||||
icculus@icculus.org ... Thanks!
|
||||
|
||||
--ryan.
|
||||
|
|
@ -1,53 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This is a script used by some Buildbot buildslaves to push the project
|
||||
# This is a script used by some Buildbot 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 Mac OS X, apt-get install clang
|
||||
# on Ubuntu, etc),
|
||||
# or download checker at http://clang-analyzer.llvm.org/ and unpack it in
|
||||
# /usr/local ... update CHECKERDIR as appropriate.
|
||||
# on Ubuntu, etc), Make sure "scan-build" is in your $PATH.
|
||||
|
||||
FINALDIR="$1"
|
||||
|
||||
CHECKERDIR="/usr/local/checker-279"
|
||||
if [ ! -d "$CHECKERDIR" ]; then
|
||||
echo "$CHECKERDIR not found. Trying /usr/share/clang ..." 1>&2
|
||||
CHECKERDIR="/usr/share/clang/scan-build"
|
||||
fi
|
||||
|
||||
if [ ! -d "$CHECKERDIR" ]; then
|
||||
echo "$CHECKERDIR not found. Giving up." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$MAKE" ]; then
|
||||
OSTYPE=`uname -s`
|
||||
if [ "$OSTYPE" == "Linux" ]; then
|
||||
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
|
||||
let NCPU=$NCPU+1
|
||||
elif [ "$OSTYPE" = "Darwin" ]; then
|
||||
NCPU=`sysctl -n hw.ncpu`
|
||||
elif [ "$OSTYPE" = "SunOS" ]; then
|
||||
NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'`
|
||||
else
|
||||
NCPU=1
|
||||
fi
|
||||
|
||||
if [ -z "$NCPU" ]; then
|
||||
NCPU=1
|
||||
elif [ "$NCPU" = "0" ]; then
|
||||
NCPU=1
|
||||
fi
|
||||
|
||||
MAKE="make -j$NCPU"
|
||||
fi
|
||||
|
||||
echo "\$MAKE is '$MAKE'"
|
||||
MAKECMD="$MAKE"
|
||||
unset MAKE # prevent warnings about jobserver mode.
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
|
@ -66,13 +27,10 @@ cd checker-buildbot
|
|||
# The -Wno-liblto is new since our checker-279 upgrade, I think; checker otherwise warns "libLTO.dylib relative to clang installed dir not found"
|
||||
|
||||
# You might want to do this for CMake-backed builds instead...
|
||||
PATH="$CHECKERDIR/bin:$PATH" scan-build -o analysis cmake -Wno-dev -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_EXE_LINKER_FLAGS="-Wno-liblto" ..
|
||||
|
||||
# ...or run configure without the scan-build wrapper...
|
||||
#CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0 -Wno-deprecated-declarations" LDFLAGS="-Wno-liblto" ../configure --enable-assertions=enabled
|
||||
scan-build -o analysis cmake -G Ninja -Wno-dev -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_EXE_LINKER_FLAGS="-Wno-liblto" ..
|
||||
|
||||
rm -rf analysis
|
||||
PATH="$CHECKERDIR/bin:$PATH" scan-build -o analysis $MAKECMD
|
||||
scan-build -o analysis cmake --build . --config Debug
|
||||
|
||||
if [ `ls -A analysis |wc -l` == 0 ] ; then
|
||||
mkdir analysis/zarro
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$SDKDIR" ]; then
|
||||
SDKDIR="/emsdk_portable"
|
||||
SDKDIR="/emsdk"
|
||||
fi
|
||||
|
||||
ENVSCRIPT="$SDKDIR/emsdk_env.sh"
|
||||
|
@ -20,32 +20,6 @@ cd `dirname "$0"`
|
|||
cd ..
|
||||
PHYSFSBASE=`pwd`
|
||||
|
||||
if [ -z "$MAKE" ]; then
|
||||
OSTYPE=`uname -s`
|
||||
if [ "$OSTYPE" == "Linux" ]; then
|
||||
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
|
||||
let NCPU=$NCPU+1
|
||||
elif [ "$OSTYPE" = "Darwin" ]; then
|
||||
NCPU=`sysctl -n hw.ncpu`
|
||||
elif [ "$OSTYPE" = "SunOS" ]; then
|
||||
NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'`
|
||||
else
|
||||
NCPU=1
|
||||
fi
|
||||
|
||||
if [ -z "$NCPU" ]; then
|
||||
NCPU=1
|
||||
elif [ "$NCPU" = "0" ]; then
|
||||
NCPU=1
|
||||
fi
|
||||
|
||||
MAKE="make -j$NCPU"
|
||||
fi
|
||||
|
||||
echo "\$MAKE is '$MAKE'"
|
||||
MAKECMD="$MAKE"
|
||||
unset MAKE # prevent warnings about jobserver mode.
|
||||
|
||||
echo "Setting up Emscripten SDK environment..."
|
||||
source "$ENVSCRIPT"
|
||||
|
||||
|
@ -56,10 +30,10 @@ mkdir buildbot
|
|||
cd buildbot
|
||||
|
||||
echo "Configuring..."
|
||||
emcmake cmake -G "Unix Makefiles" -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=MinSizeRel .. || exit $?
|
||||
emcmake cmake -G "Ninja" -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=MinSizeRel .. || exit $?
|
||||
|
||||
echo "Building..."
|
||||
emmake $MAKECMD || exit $?
|
||||
emmake cmake --build . --config MinSizeRel || exit $?
|
||||
|
||||
set -e
|
||||
rm -rf "$TARBALL" physfs-emscripten
|
||||
|
|
|
@ -15,24 +15,7 @@ if [ -z $1 ]; then
|
|||
TARBALL=physfs-raspberrypi.tar.xz
|
||||
fi
|
||||
|
||||
OSTYPE=`uname -s`
|
||||
if [ "$OSTYPE" != "Linux" ]; then
|
||||
# !!! FIXME
|
||||
echo "This only works on x86 or x64-64 Linux at the moment." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "x$MAKE" == "x" ]; then
|
||||
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
|
||||
let NCPU=$NCPU+1
|
||||
MAKE="make -j$NCPU"
|
||||
fi
|
||||
|
||||
echo "\$MAKE is '$MAKE'"
|
||||
MAKECMD="$MAKE"
|
||||
unset MAKE # prevent warnings about jobserver mode.
|
||||
|
||||
BUILDBOTDIR="raspberrypi-buildbot"
|
||||
BUILDBOTDIR="buildbot"
|
||||
PARENTDIR="$PWD"
|
||||
|
||||
set -e
|
||||
|
@ -42,8 +25,9 @@ rm -rf $BUILDBOTDIR
|
|||
mkdir -p $BUILDBOTDIR
|
||||
pushd $BUILDBOTDIR
|
||||
|
||||
# the '-G "Ninja"' can be '-G "Unix Makefiles"' if you prefer to use GNU Make.
|
||||
SYSROOT="/opt/rpi-sysroot"
|
||||
cmake -G "Unix Makefiles" \
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_C_COMPILER="/opt/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc" \
|
||||
-DCMAKE_BUILD_TYPE=MinSizeRel \
|
||||
-DCMAKE_SYSROOT="$SYSROOT" \
|
||||
|
@ -55,7 +39,7 @@ cmake -G "Unix Makefiles" \
|
|||
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
|
||||
..
|
||||
|
||||
$MAKECMD
|
||||
cmake --build . --config MinSizeRel
|
||||
|
||||
rm -rf "$TARBALL" physfs-raspberrypi
|
||||
mkdir -p physfs-raspberrypi
|
||||
|
|
|
@ -208,13 +208,13 @@ int main(int argc, char **argv)
|
|||
|
||||
if (!PHYSFS_init(argv[0]))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return 1;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_addToSearchPath(".", 1))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
|
|
@ -50,18 +50,22 @@ static int locateOneElement(char *buf)
|
|||
ptr++; /* point past dirsep to entry itself. */
|
||||
} /* else */
|
||||
|
||||
for (i = rc; *i != NULL; i++)
|
||||
if (rc != NULL)
|
||||
{
|
||||
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
|
||||
for (i = rc; *i != NULL; i++)
|
||||
{
|
||||
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
||||
PHYSFS_freeList(rc);
|
||||
return 1;
|
||||
} /* if */
|
||||
} /* for */
|
||||
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
|
||||
{
|
||||
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
||||
PHYSFS_freeList(rc);
|
||||
return 1;
|
||||
} /* if */
|
||||
} /* for */
|
||||
|
||||
PHYSFS_freeList(rc);
|
||||
} /* if */
|
||||
|
||||
/* no match at all... */
|
||||
PHYSFS_freeList(rc);
|
||||
return 0;
|
||||
} /* locateOneElement */
|
||||
|
||||
|
@ -101,34 +105,34 @@ int main(int argc, char **argv)
|
|||
|
||||
if (!PHYSFS_init(argv[0]))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return 1;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_addToSearchPath(".", 1))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_setWriteDir("."))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_mkdir("/a/b/c"))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_mkdir("/a/b/C"))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
@ -137,7 +141,7 @@ int main(int argc, char **argv)
|
|||
PHYSFS_close(f);
|
||||
if (f == NULL)
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
@ -146,7 +150,7 @@ int main(int argc, char **argv)
|
|||
PHYSFS_close(f);
|
||||
if (f == NULL)
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
PHYSFS_deinit();
|
||||
return 1;
|
||||
} /* if */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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
|
||||
Description: PhysicsFS is a library to provide abstract access to various archives.
|
||||
|
|
|
@ -32,10 +32,16 @@
|
|||
#endif
|
||||
|
||||
#if !TARGET_SDL2
|
||||
#ifndef RW_SEEK_SET
|
||||
#define RW_SEEK_SET SEEK_SET
|
||||
#endif
|
||||
#ifndef RW_SEEK_CUR
|
||||
#define RW_SEEK_CUR SEEK_CUR
|
||||
#endif
|
||||
#ifndef RW_SEEK_END
|
||||
#define RW_SEEK_END SEEK_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TARGET_SDL2
|
||||
static Sint64 SDLCALL physfsrwops_size(struct SDL_RWops *rw)
|
||||
|
@ -64,7 +70,7 @@ static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
|
|||
if (current == -1)
|
||||
{
|
||||
SDL_SetError("Can't find position in file: %s",
|
||||
PHYSFS_getLastError());
|
||||
PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return -1;
|
||||
} /* if */
|
||||
|
||||
|
@ -85,7 +91,7 @@ static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
|
|||
const PHYSFS_sint64 len = PHYSFS_fileLength(handle);
|
||||
if (len == -1)
|
||||
{
|
||||
SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
|
||||
SDL_SetError("Can't find end of file: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return -1;
|
||||
} /* if */
|
||||
|
||||
|
@ -106,7 +112,7 @@ static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
|
|||
|
||||
if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
|
||||
{
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return -1;
|
||||
} /* if */
|
||||
|
||||
|
@ -132,7 +138,7 @@ static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
|
|||
{
|
||||
if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
|
||||
{
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
|
||||
#if TARGET_SDL2
|
||||
return 0;
|
||||
|
@ -161,7 +167,7 @@ static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
|
|||
const PHYSFS_uint64 writelen = (PHYSFS_uint64) (num * size);
|
||||
const PHYSFS_sint64 rc = PHYSFS_writeBytes(handle, ptr, writelen);
|
||||
if (rc != ((PHYSFS_sint64) writelen))
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
|
||||
#if TARGET_SDL2
|
||||
return (size_t) rc;
|
||||
|
@ -176,7 +182,7 @@ static int physfsrwops_close(SDL_RWops *rw)
|
|||
PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
|
||||
if (!PHYSFS_close(handle))
|
||||
{
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return -1;
|
||||
} /* if */
|
||||
|
||||
|
@ -190,7 +196,7 @@ static SDL_RWops *create_rwops(PHYSFS_File *handle)
|
|||
SDL_RWops *retval = NULL;
|
||||
|
||||
if (handle == NULL)
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
else
|
||||
{
|
||||
retval = SDL_AllocRW();
|
||||
|
|
|
@ -28,7 +28,7 @@ static void modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
|
|||
static void fail(const char *what, const char *why)
|
||||
{
|
||||
if (why == NULL)
|
||||
why = PHYSFS_getLastError();
|
||||
why = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
|
||||
fprintf(stderr, "%s failed: %s\n", what, why);
|
||||
failure = 1;
|
||||
} /* fail */
|
||||
|
@ -150,21 +150,21 @@ int main(int argc, char **argv)
|
|||
|
||||
if (!PHYSFS_init(argv[0]))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
|
||||
fprintf(stderr, "PHYSFS_init() failed: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return 2;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_setWriteDir(argv[2]))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_setWriteDir('%s') failed: %s\n",
|
||||
argv[2], PHYSFS_getLastError());
|
||||
argv[2], PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return 3;
|
||||
} /* if */
|
||||
|
||||
if (!PHYSFS_mount(argv[1], NULL, 1))
|
||||
{
|
||||
fprintf(stderr, "PHYSFS_mount('%s') failed: %s\n",
|
||||
argv[1], PHYSFS_getLastError());
|
||||
argv[1], PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return 4;
|
||||
} /* if */
|
||||
|
||||
|
|
|
@ -40,14 +40,14 @@ int main(int argc, char **argv)
|
|||
|
||||
if (!PHYSFS_init(argv[0]))
|
||||
{
|
||||
printf("PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
|
||||
printf("PHYSFS_init() failed: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
return 42;
|
||||
} /* if */
|
||||
|
||||
rc = PHYSFS_addToSearchPath(argv[0], 0);
|
||||
if (!rc)
|
||||
{
|
||||
printf("Couldn't find self-extract data: %s\n", PHYSFS_getLastError());
|
||||
printf("Couldn't find self-extract data: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
printf("This might mean you didn't append a zipfile to the binary.\n");
|
||||
return 42;
|
||||
} /* if */
|
||||
|
|
|
@ -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
|
637
src/physfs.c
637
src/physfs.c
File diff suppressed because it is too large
Load Diff
348
src/physfs.h
348
src/physfs.h
|
@ -145,11 +145,11 @@
|
|||
* - .ISO (ISO9660 files, CD-ROM images)
|
||||
* - .GRP (Build Engine groupfile archives)
|
||||
* - .PAK (Quake I/II archive format)
|
||||
* - .HOG (Descent I/II HOG file archives)
|
||||
* - .HOG (Descent I/II/III HOG file archives)
|
||||
* - .MVL (Descent II movielib archives)
|
||||
* - .WAD (DOOM engine archives)
|
||||
* - .VDF (Gothic I/II engine archives)
|
||||
*
|
||||
* - .SLB (Independence War archives)
|
||||
*
|
||||
* String policy for PhysicsFS 2.0 and later:
|
||||
*
|
||||
|
@ -170,14 +170,14 @@
|
|||
* should convert them to UTF-8 before handing them to PhysicsFS with
|
||||
* PHYSFS_utf8FromUtf16(), which handles both UTF-16 and UCS-2. If you're
|
||||
* using Unix or Mac OS X, your wchar_t strings are four bytes per character
|
||||
* ("UCS-4 encoding"). Use PHYSFS_utf8FromUcs4(). Mac OS X can give you UTF-8
|
||||
* directly from a CFString or NSString, and many Unixes generally give you C
|
||||
* strings in UTF-8 format everywhere. If you have a single-byte high ASCII
|
||||
* charset, like so-many European "codepages" you may be out of luck. We'll
|
||||
* convert from "Latin1" to UTF-8 only, and never back to Latin1. If you're
|
||||
* above ASCII 127, all bets are off: move to Unicode or use your platform's
|
||||
* facilities. Passing a C string with high-ASCII data that isn't UTF-8
|
||||
* encoded will NOT do what you expect!
|
||||
* ("UCS-4 encoding", sometimes called "UTF-32"). Use PHYSFS_utf8FromUcs4().
|
||||
* Mac OS X can give you UTF-8 directly from a CFString or NSString, and many
|
||||
* Unixes generally give you C strings in UTF-8 format everywhere. If you
|
||||
* have a single-byte high ASCII charset, like so-many European "codepages"
|
||||
* you may be out of luck. We'll convert from "Latin1" to UTF-8 only, and
|
||||
* never back to Latin1. If you're above ASCII 127, all bets are off: move
|
||||
* to Unicode or use your platform's facilities. Passing a C string with
|
||||
* high-ASCII data that isn't UTF-8 encoded will NOT do what you expect!
|
||||
*
|
||||
* Naturally, there's also PHYSFS_utf8ToUcs2(), PHYSFS_utf8ToUtf16(), and
|
||||
* PHYSFS_utf8ToUcs4() to get data back into a format you like. Behind the
|
||||
|
@ -225,11 +225,13 @@ extern "C" {
|
|||
|
||||
#if defined(PHYSFS_DECL)
|
||||
/* do nothing. */
|
||||
#elif (defined _MSC_VER)
|
||||
#elif defined(PHYSFS_STATIC)
|
||||
#define PHYSFS_DECL /**/
|
||||
#elif defined(_WIN32) || defined(__OS2__)
|
||||
#define PHYSFS_DECL __declspec(dllexport)
|
||||
#elif (defined __SUNPRO_C)
|
||||
#elif defined(__SUNPRO_C)
|
||||
#define PHYSFS_DECL __global
|
||||
#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
|
||||
#elif ((__GNUC__ >= 3) && (!defined(__EMX__)) && (!defined(sun)))
|
||||
#define PHYSFS_DECL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define PHYSFS_DECL
|
||||
|
@ -432,9 +434,9 @@ typedef struct PHYSFS_Version
|
|||
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
#define PHYSFS_VER_MAJOR 2
|
||||
#define PHYSFS_VER_MINOR 1
|
||||
#define PHYSFS_VER_PATCH 1
|
||||
#define PHYSFS_VER_MAJOR 3
|
||||
#define PHYSFS_VER_MINOR 3
|
||||
#define PHYSFS_VER_PATCH 0
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
|
||||
|
||||
|
@ -493,6 +495,14 @@ typedef struct PHYSFS_Version
|
|||
PHYSFS_DECL void PHYSFS_getLinkedVersion(PHYSFS_Version *ver);
|
||||
|
||||
|
||||
#ifdef __ANDROID__
|
||||
typedef struct PHYSFS_AndroidInit
|
||||
{
|
||||
void *jnienv;
|
||||
void *context;
|
||||
} PHYSFS_AndroidInit;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_init(const char *argv0)
|
||||
* \brief Initialize the PhysicsFS library.
|
||||
|
@ -502,11 +512,22 @@ PHYSFS_DECL void PHYSFS_getLinkedVersion(PHYSFS_Version *ver);
|
|||
* This should be called prior to any attempts to change your process's
|
||||
* current working directory.
|
||||
*
|
||||
* \warning On Android, argv0 should be a non-NULL pointer to a
|
||||
* PHYSFS_AndroidInit struct. This struct must hold a valid JNIEnv *
|
||||
* and a JNI jobject of a Context (either the application context or
|
||||
* the current Activity is fine). Both are cast to a void * so we
|
||||
* don't need jni.h included wherever physfs.h is. PhysicsFS
|
||||
* uses these objects to query some system details. PhysicsFS does
|
||||
* not hold a reference to the JNIEnv or Context past the call to
|
||||
* PHYSFS_init(). If you pass a NULL here, PHYSFS_init can still
|
||||
* succeed, but PHYSFS_getBaseDir() and PHYSFS_getPrefDir() will be
|
||||
* incorrect.
|
||||
*
|
||||
* \param argv0 the argv[0] string passed to your program's mainline.
|
||||
* This may be NULL on most platforms (such as ones without a
|
||||
* standard main() function), but you should always try to pass
|
||||
* something in here. Unix-like systems such as Linux _need_ to
|
||||
* pass argv[0] from main() in here.
|
||||
* something in here. Many Unix-like systems _need_ to pass argv[0]
|
||||
* from main() in here. See warning about Android, too!
|
||||
* \return nonzero on success, zero on error. Specifics of the error can be
|
||||
* gleaned from PHYSFS_getLastError().
|
||||
*
|
||||
|
@ -762,6 +783,15 @@ PHYSFS_DECL char **PHYSFS_getCdRomDirs(void);
|
|||
*
|
||||
* You should probably use the base dir in your search path.
|
||||
*
|
||||
* \warning On most platforms, this is a directory; on Android, this gives
|
||||
* you the path to the app's package (APK) file. As APK files are
|
||||
* just .zip files, you can mount them in PhysicsFS like regular
|
||||
* directories. You'll probably want to call
|
||||
* PHYSFS_setRoot(basedir, "/assets") after mounting to make your
|
||||
* app's actual data available directly without all the Android
|
||||
* metadata and directory offset. Note that if you passed a NULL to
|
||||
* PHYSFS_init(), you will not get the APK file here.
|
||||
*
|
||||
* \return READ ONLY string of base dir in platform-dependent notation.
|
||||
*
|
||||
* \sa PHYSFS_getPrefDir
|
||||
|
@ -2176,11 +2206,15 @@ PHYSFS_DECL int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator);
|
|||
* or each other, for example.
|
||||
*
|
||||
* The mountpoint does not need to exist prior to mounting, which is different
|
||||
* than those familiar with the Unix concept of "mounting" may not expect.
|
||||
* than those familiar with the Unix concept of "mounting" may expect.
|
||||
* As well, more than one archive can be mounted to the same mountpoint, or
|
||||
* mountpoints and archive contents can overlap...the interpolation mechanism
|
||||
* still functions as usual.
|
||||
*
|
||||
* Specifying a symbolic link to an archive or directory is allowed here,
|
||||
* regardless of the state of PHYSFS_permitSymbolicLinks(). That function
|
||||
* only deals with symlinks inside the mounted directory or archive.
|
||||
*
|
||||
* \param newDir directory or archive to add to the path, in
|
||||
* platform-dependent notation.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
|
@ -2386,7 +2420,11 @@ PHYSFS_DECL void PHYSFS_enumerateFilesCallback(const char *dir,
|
|||
* \fn void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
|
||||
* \brief Convert a UCS-4 string to a UTF-8 string.
|
||||
*
|
||||
* UCS-4 strings are 32-bits per character: \c wchar_t on Unix.
|
||||
* \warning This function will not report an error if there are invalid UCS-4
|
||||
* values in the source string. It will replace them with a '?'
|
||||
* character and continue on.
|
||||
*
|
||||
* UCS-4 (aka UTF-32) strings are 32-bits per character: \c wchar_t on Unix.
|
||||
*
|
||||
* To ensure that the destination buffer is large enough for the conversion,
|
||||
* please allocate a buffer that is the same size as the source buffer. UTF-8
|
||||
|
@ -2408,7 +2446,11 @@ PHYSFS_DECL void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst,
|
|||
* \fn void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
|
||||
* \brief Convert a UTF-8 string to a UCS-4 string.
|
||||
*
|
||||
* UCS-4 strings are 32-bits per character: \c wchar_t on Unix.
|
||||
* \warning This function will not report an error if there are invalid UTF-8
|
||||
* sequences in the source string. It will replace them with a '?'
|
||||
* character and continue on.
|
||||
*
|
||||
* UCS-4 (aka UTF-32) strings are 32-bits per character: \c wchar_t on Unix.
|
||||
*
|
||||
* To ensure that the destination buffer is large enough for the conversion,
|
||||
* please allocate a buffer that is four times the size of the source buffer.
|
||||
|
@ -2433,6 +2475,10 @@ PHYSFS_DECL void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst,
|
|||
* \warning you almost certainly should use PHYSFS_utf8FromUtf16(), which
|
||||
* became available in PhysicsFS 2.1, unless you know what you're doing.
|
||||
*
|
||||
* \warning This function will not report an error if there are invalid UCS-2
|
||||
* values in the source string. It will replace them with a '?'
|
||||
* character and continue on.
|
||||
*
|
||||
* UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building
|
||||
* with Unicode support. Please note that modern versions of Windows use
|
||||
* UTF-16, which is an extended form of UCS-2, and not UCS-2 itself. You
|
||||
|
@ -2463,6 +2509,10 @@ PHYSFS_DECL void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst,
|
|||
* \warning you almost certainly should use PHYSFS_utf8ToUtf16(), which
|
||||
* became available in PhysicsFS 2.1, unless you know what you're doing.
|
||||
*
|
||||
* \warning This function will not report an error if there are invalid UTF-8
|
||||
* sequences in the source string. It will replace them with a '?'
|
||||
* character and continue on.
|
||||
*
|
||||
* UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building
|
||||
* with Unicode support. Please note that modern versions of Windows use
|
||||
* UTF-16, which is an extended form of UCS-2, and not UCS-2 itself. You
|
||||
|
@ -2515,6 +2565,36 @@ PHYSFS_DECL void PHYSFS_utf8FromLatin1(const char *src, char *dst,
|
|||
|
||||
/* Everything above this line is part of the PhysicsFS 2.0 API. */
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_caseFold(const PHYSFS_uint32 from, PHYSFS_uint32 *to)
|
||||
* \brief "Fold" a Unicode codepoint to a lowercase equivalent.
|
||||
*
|
||||
* (This is for limited, hardcore use. If you don't immediately see a need
|
||||
* for it, you can probably ignore this forever.)
|
||||
*
|
||||
* This will convert a Unicode codepoint into its lowercase equivalent.
|
||||
* Bogus codepoints and codepoints without a lowercase equivalent will
|
||||
* be returned unconverted.
|
||||
*
|
||||
* Note that you might get multiple codepoints in return! The German Eszett,
|
||||
* for example, will fold down to two lowercase latin 's' codepoints. The
|
||||
* theory is that if you fold two strings, one with an Eszett and one with
|
||||
* "SS" down, they will match.
|
||||
*
|
||||
* \warning Anyone that is a student of Unicode knows about the "Turkish I"
|
||||
* problem. This API does not handle it. Assume this one letter
|
||||
* in all of Unicode will definitely fold sort of incorrectly. If
|
||||
* you don't know what this is about, you can probably ignore this
|
||||
* problem for most of the planet, but perfection is impossible.
|
||||
*
|
||||
* \param from The codepoint to fold.
|
||||
* \param to Buffer to store the folded codepoint values into. This should
|
||||
* point to space for at least 3 PHYSFS_uint32 slots.
|
||||
* \return The number of codepoints the folding produced. Between 1 and 3.
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_caseFold(const PHYSFS_uint32 from, PHYSFS_uint32 *to);
|
||||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_utf8stricmp(const char *str1, const char *str2)
|
||||
* \brief Case-insensitive compare of two UTF-8 strings.
|
||||
|
@ -2523,6 +2603,10 @@ PHYSFS_DECL void PHYSFS_utf8FromLatin1(const char *src, char *dst,
|
|||
* to be in UTF-8 encoding. It will do "case folding" to decide if the
|
||||
* Unicode codepoints in the strings match.
|
||||
*
|
||||
* If both strings are exclusively low-ASCII characters, this will do the
|
||||
* right thing, as that is also valid UTF-8. If there are any high-ASCII
|
||||
* chars, this will not do what you expect!
|
||||
*
|
||||
* It will report which string is "greater than" the other, but be aware that
|
||||
* this doesn't necessarily mean anything: 'a' may be "less than" 'b', but
|
||||
* a Japanese kuten has no meaningful alphabetically relationship to
|
||||
|
@ -2538,6 +2622,72 @@ PHYSFS_DECL void PHYSFS_utf8FromLatin1(const char *src, char *dst,
|
|||
*/
|
||||
PHYSFS_DECL int PHYSFS_utf8stricmp(const char *str1, const char *str2);
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_utf16stricmp(const PHYSFS_uint16 *str1, const PHYSFS_uint16 *str2)
|
||||
* \brief Case-insensitive compare of two UTF-16 strings.
|
||||
*
|
||||
* This is a strcasecmp/stricmp replacement that expects both strings
|
||||
* to be in UTF-16 encoding. It will do "case folding" to decide if the
|
||||
* Unicode codepoints in the strings match.
|
||||
*
|
||||
* It will report which string is "greater than" the other, but be aware that
|
||||
* this doesn't necessarily mean anything: 'a' may be "less than" 'b', but
|
||||
* a Japanese kuten has no meaningful alphabetically relationship to
|
||||
* a Greek lambda, but being able to assign a reliable "value" makes sorting
|
||||
* algorithms possible, if not entirely sane. Most cases should treat the
|
||||
* return value as "equal" or "not equal".
|
||||
*
|
||||
* Like stricmp, this expects both strings to be NULL-terminated.
|
||||
*
|
||||
* \param str1 First string to compare.
|
||||
* \param str2 Second string to compare.
|
||||
* \return -1 if str1 is "less than" str2, 1 if "greater than", 0 if equal.
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_utf16stricmp(const PHYSFS_uint16 *str1,
|
||||
const PHYSFS_uint16 *str2);
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_ucs4stricmp(const PHYSFS_uint32 *str1, const PHYSFS_uint32 *str2)
|
||||
* \brief Case-insensitive compare of two UCS-4 strings.
|
||||
*
|
||||
* This is a strcasecmp/stricmp replacement that expects both strings
|
||||
* to be in UCS-4 (aka UTF-32) encoding. It will do "case folding" to decide
|
||||
* if the Unicode codepoints in the strings match.
|
||||
*
|
||||
* It will report which string is "greater than" the other, but be aware that
|
||||
* this doesn't necessarily mean anything: 'a' may be "less than" 'b', but
|
||||
* a Japanese kuten has no meaningful alphabetically relationship to
|
||||
* a Greek lambda, but being able to assign a reliable "value" makes sorting
|
||||
* algorithms possible, if not entirely sane. Most cases should treat the
|
||||
* return value as "equal" or "not equal".
|
||||
*
|
||||
* Like stricmp, this expects both strings to be NULL-terminated.
|
||||
*
|
||||
* \param str1 First string to compare.
|
||||
* \param str2 Second string to compare.
|
||||
* \return -1 if str1 is "less than" str2, 1 if "greater than", 0 if equal.
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_ucs4stricmp(const PHYSFS_uint32 *str1,
|
||||
const PHYSFS_uint32 *str2);
|
||||
|
||||
|
||||
/**
|
||||
* \typedef PHYSFS_EnumerateCallback
|
||||
* \brief Possible return values from PHYSFS_EnumerateCallback.
|
||||
*
|
||||
* These values dictate if an enumeration callback should continue to fire,
|
||||
* or stop (and why it is stopping).
|
||||
*
|
||||
* \sa PHYSFS_EnumerateCallback
|
||||
* \sa PHYSFS_enumerate
|
||||
*/
|
||||
typedef enum PHYSFS_EnumerateCallbackResult
|
||||
{
|
||||
PHYSFS_ENUM_ERROR = -1, /**< Stop enumerating, report error to app. */
|
||||
PHYSFS_ENUM_STOP = 0, /**< Stop enumerating, report success to app. */
|
||||
PHYSFS_ENUM_OK = 1 /**< Keep enumerating, no problems */
|
||||
} PHYSFS_EnumerateCallbackResult;
|
||||
|
||||
/**
|
||||
* \typedef PHYSFS_EnumerateCallback
|
||||
* \brief Function signature for callbacks that enumerate and return results.
|
||||
|
@ -2559,13 +2709,14 @@ PHYSFS_DECL int PHYSFS_utf8stricmp(const char *str1, const char *str2);
|
|||
* fired, and it will not contain the full path. You can
|
||||
* recreate the fullpath with $origdir/$fname ... The file
|
||||
* can be a subdirectory, a file, a symlink, etc.
|
||||
* \return 1 to keep enumerating, 0 to stop (no error), -1 to stop (error).
|
||||
* \return A value from PHYSFS_EnumerateCallbackResult.
|
||||
* All other values are (currently) undefined; don't use them.
|
||||
*
|
||||
* \sa PHYSFS_enumerate
|
||||
* \sa PHYSFS_EnumerateCallbackResult
|
||||
*/
|
||||
typedef int (*PHYSFS_EnumerateCallback)(void *data, const char *origdir,
|
||||
const char *fname);
|
||||
typedef PHYSFS_EnumerateCallbackResult (*PHYSFS_EnumerateCallback)(void *data,
|
||||
const char *origdir, const char *fname);
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_enumerate(const char *dir, PHYSFS_EnumerateCallback c, void *d)
|
||||
|
@ -2581,10 +2732,10 @@ typedef int (*PHYSFS_EnumerateCallback)(void *data, const char *origdir,
|
|||
*
|
||||
* \code
|
||||
*
|
||||
* static int printDir(void *data, const char *origdir, const char *fname)
|
||||
* static PHYSFS_EnumerateCallbackResult printDir(void *data, const char *origdir, const char *fname)
|
||||
* {
|
||||
* printf(" * We've got [%s] in [%s].\n", fname, origdir);
|
||||
* return 1; // give me more data, please.
|
||||
* return PHYSFS_ENUM_OK; // give me more data, please.
|
||||
* }
|
||||
*
|
||||
* // ...
|
||||
|
@ -2618,8 +2769,9 @@ typedef int (*PHYSFS_EnumerateCallback)(void *data, const char *origdir,
|
|||
* \param d Application-defined data passed to callback. Can be NULL.
|
||||
* \return non-zero on success, zero on failure. Use
|
||||
* PHYSFS_getLastErrorCode() to obtain the specific error. If the
|
||||
* callback returns zero to stop early, this will be considered
|
||||
* success. Callbacks returning -1 will result in
|
||||
* callback returns PHYSFS_ENUM_STOP to stop early, this will be
|
||||
* considered success. Callbacks returning PHYSFS_ENUM_ERROR will
|
||||
* make this function return zero and set the error code to
|
||||
* PHYSFS_ERR_APP_CALLBACK.
|
||||
*
|
||||
* \sa PHYSFS_EnumerateCallback
|
||||
|
@ -2642,6 +2794,12 @@ PHYSFS_DECL int PHYSFS_enumerate(const char *dir, PHYSFS_EnumerateCallback c,
|
|||
* This call will fail (and fail to remove from the path) if the element still
|
||||
* has files open in it.
|
||||
*
|
||||
* \warning This function wants the path to the archive or directory that was
|
||||
* mounted (the same string used for the "newDir" argument of
|
||||
* PHYSFS_addToSearchPath or any of the mount functions), not the
|
||||
* path where it is mounted in the tree (the "mountPoint" argument
|
||||
* to any of the mount functions).
|
||||
*
|
||||
* \param oldDir dir/archive to remove.
|
||||
* \return nonzero on success, zero on failure. Use
|
||||
* PHYSFS_getLastErrorCode() to obtain the specific error.
|
||||
|
@ -2757,6 +2915,10 @@ PHYSFS_DECL int PHYSFS_stat(const char *fname, PHYSFS_Stat *stat);
|
|||
* \fn void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
|
||||
* \brief Convert a UTF-16 string to a UTF-8 string.
|
||||
*
|
||||
* \warning This function will not report an error if there are invalid UTF-16
|
||||
* sequences in the source string. It will replace them with a '?'
|
||||
* character and continue on.
|
||||
*
|
||||
* UTF-16 strings are 16-bits per character (except some chars, which are
|
||||
* 32-bits): \c TCHAR on Windows, when building with Unicode support. Modern
|
||||
* Windows releases use UTF-16. Windows releases before 2000 used TCHAR, but
|
||||
|
@ -2784,6 +2946,10 @@ PHYSFS_DECL void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst,
|
|||
* \fn PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
||||
* \brief Convert a UTF-8 string to a UTF-16 string.
|
||||
*
|
||||
* \warning This function will not report an error if there are invalid UTF-8
|
||||
* sequences in the source string. It will replace them with a '?'
|
||||
* character and continue on.
|
||||
*
|
||||
* UTF-16 strings are 16-bits per character (except some chars, which are
|
||||
* 32-bits): \c TCHAR on Windows, when building with Unicode support. Modern
|
||||
* Windows releases use UTF-16. Windows releases before 2000 used TCHAR, but
|
||||
|
@ -3062,7 +3228,7 @@ typedef struct PHYSFS_Io
|
|||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname, const char *mountPoint, int appendToPath)
|
||||
* \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *newDir, const char *mountPoint, int appendToPath)
|
||||
* \brief Add an archive, built on a PHYSFS_Io, to the search path.
|
||||
*
|
||||
* \warning Unless you have some special, low-level need, you should be using
|
||||
|
@ -3072,11 +3238,14 @@ typedef struct PHYSFS_Io
|
|||
* instead of a pathname. Behind the scenes, PHYSFS_mount() calls this
|
||||
* function with a physical-filesystem-based PHYSFS_Io.
|
||||
*
|
||||
* (filename) is only used here to optimize archiver selection (if you name it
|
||||
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
|
||||
* need to refer to a real file at all, and can even be NULL. If the filename
|
||||
* isn't helpful, the system will try every archiver until one works or none
|
||||
* of them do.
|
||||
* (newDir) must be a unique string to identify this archive. It is used
|
||||
* to optimize archiver selection (if you name it XXXXX.zip, we might try
|
||||
* the ZIP archiver first, for example, or directly choose an archiver that
|
||||
* can only trust the data is valid by filename extension). It doesn't
|
||||
* need to refer to a real file at all. If the filename extension isn't
|
||||
* helpful, the system will try every archiver until one works or none
|
||||
* of them do. This filename must be unique, as the system won't allow you
|
||||
* to have two archives with the same name.
|
||||
*
|
||||
* (io) must remain until the archive is unmounted. When the archive is
|
||||
* unmounted, the system will call (io)->destroy(io), which will give you
|
||||
|
@ -3085,7 +3254,7 @@ typedef struct PHYSFS_Io
|
|||
* If this function fails, (io)->destroy(io) is not called.
|
||||
*
|
||||
* \param io i/o instance for archive to add to the path.
|
||||
* \param fname Filename that can represent this stream. Can be NULL.
|
||||
* \param newDir Filename that can represent this stream.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
* will be "mounted", in platform-independent notation.
|
||||
* NULL or "" is equivalent to "/".
|
||||
|
@ -3098,12 +3267,12 @@ typedef struct PHYSFS_Io
|
|||
* \sa PHYSFS_getSearchPath
|
||||
* \sa PHYSFS_getMountPoint
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
||||
PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *newDir,
|
||||
const char *mountPoint, int appendToPath);
|
||||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_mountMemory(const void *ptr, PHYSFS_uint64 len, void (*del)(void *), const char *fname, const char *mountPoint, int appendToPath)
|
||||
* \fn int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *), const char *newDir, const char *mountPoint, int appendToPath)
|
||||
* \brief Add an archive, contained in a memory buffer, to the search path.
|
||||
*
|
||||
* \warning Unless you have some special, low-level need, you should be using
|
||||
|
@ -3113,11 +3282,14 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
* instead of a pathname. This buffer contains all the data of the archive,
|
||||
* and is used instead of a real file in the physical filesystem.
|
||||
*
|
||||
* (filename) is only used here to optimize archiver selection (if you name it
|
||||
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
|
||||
* need to refer to a real file at all, and can even be NULL. If the filename
|
||||
* isn't helpful, the system will try every archiver until one works or none
|
||||
* of them do.
|
||||
* (newDir) must be a unique string to identify this archive. It is used
|
||||
* to optimize archiver selection (if you name it XXXXX.zip, we might try
|
||||
* the ZIP archiver first, for example, or directly choose an archiver that
|
||||
* can only trust the data is valid by filename extension). It doesn't
|
||||
* need to refer to a real file at all. If the filename extension isn't
|
||||
* helpful, the system will try every archiver until one works or none
|
||||
* of them do. This filename must be unique, as the system won't allow you
|
||||
* to have two archives with the same name.
|
||||
*
|
||||
* (ptr) must remain until the archive is unmounted. When the archive is
|
||||
* unmounted, the system will call (del)(ptr), which will notify you that
|
||||
|
@ -3130,7 +3302,7 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
* \param buf Address of the memory buffer containing the archive data.
|
||||
* \param len Size of memory buffer, in bytes.
|
||||
* \param del A callback that triggers upon unmount. Can be NULL.
|
||||
* \param fname Filename that can represent this stream. Can be NULL.
|
||||
* \param newDir Filename that can represent this stream.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
* will be "mounted", in platform-independent notation.
|
||||
* NULL or "" is equivalent to "/".
|
||||
|
@ -3143,12 +3315,12 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
|
|||
* \sa PHYSFS_getMountPoint
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
||||
void (*del)(void *), const char *fname,
|
||||
void (*del)(void *), const char *newDir,
|
||||
const char *mountPoint, int appendToPath);
|
||||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname, const char *mountPoint, int appendToPath)
|
||||
* \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *newDir, const char *mountPoint, int appendToPath)
|
||||
* \brief Add an archive, contained in a PHYSFS_File handle, to the search path.
|
||||
*
|
||||
* \warning Unless you have some special, low-level need, you should be using
|
||||
|
@ -3171,11 +3343,14 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
|||
* but isn't necessarily. The most popular use for this is likely to mount
|
||||
* archives stored inside other archives.
|
||||
*
|
||||
* (filename) is only used here to optimize archiver selection (if you name it
|
||||
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
|
||||
* need to refer to a real file at all, and can even be NULL. If the filename
|
||||
* isn't helpful, the system will try every archiver until one works or none
|
||||
* of them do.
|
||||
* (newDir) must be a unique string to identify this archive. It is used
|
||||
* to optimize archiver selection (if you name it XXXXX.zip, we might try
|
||||
* the ZIP archiver first, for example, or directly choose an archiver that
|
||||
* can only trust the data is valid by filename extension). It doesn't
|
||||
* need to refer to a real file at all. If the filename extension isn't
|
||||
* helpful, the system will try every archiver until one works or none
|
||||
* of them do. This filename must be unique, as the system won't allow you
|
||||
* to have two archives with the same name.
|
||||
*
|
||||
* (file) must remain until the archive is unmounted. When the archive is
|
||||
* unmounted, the system will call PHYSFS_close(file). If you need this
|
||||
|
@ -3185,7 +3360,7 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
|||
* If this function fails, PHYSFS_close(file) is not called.
|
||||
*
|
||||
* \param file The PHYSFS_File handle containing archive data.
|
||||
* \param fname Filename that can represent this stream. Can be NULL.
|
||||
* \param newDir Filename that can represent this stream.
|
||||
* \param mountPoint Location in the interpolated tree that this archive
|
||||
* will be "mounted", in platform-independent notation.
|
||||
* NULL or "" is equivalent to "/".
|
||||
|
@ -3197,7 +3372,7 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
|
|||
* \sa PHYSFS_getSearchPath
|
||||
* \sa PHYSFS_getMountPoint
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
|
||||
PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *newDir,
|
||||
const char *mountPoint, int appendToPath);
|
||||
|
||||
|
||||
|
@ -3524,23 +3699,26 @@ typedef struct PHYSFS_Archiver
|
|||
* you can dispose of it upon return from the callback. (dirname) is in
|
||||
* platform-independent notation.
|
||||
* If you have a failure, call PHYSFS_SetErrorCode() with whatever code
|
||||
* seem appropriate and return -1.
|
||||
* If the callback returns -1, please call
|
||||
* PHYSFS_SetErrorCode(PHYSFS_ERR_APP_CALLBACK) and then return -1.
|
||||
* If the callback returns 0, stop enumerating and return 0. Don't call
|
||||
* the callback again in any circumstances. Don't set an error code in
|
||||
* this case.
|
||||
* Callbacks are (currently) only supposed to return -1, 0, or 1. Any
|
||||
* other result has undefined behavior.
|
||||
* As long as the callback returned 1 and you haven't experienced any
|
||||
* errors of your own, keep enumerating until you're done and then return
|
||||
* 1 without setting an error code.
|
||||
* seem appropriate and return PHYSFS_ENUM_ERROR.
|
||||
* If the callback returns PHYSFS_ENUM_ERROR, please call
|
||||
* PHYSFS_SetErrorCode(PHYSFS_ERR_APP_CALLBACK) and then return
|
||||
* PHYSFS_ENUM_ERROR as well. Don't call the callback again in any
|
||||
* circumstances.
|
||||
* If the callback returns PHYSFS_ENUM_STOP, stop enumerating and return
|
||||
* PHYSFS_ENUM_STOP as well. Don't call the callback again in any
|
||||
* circumstances. Don't set an error code in this case.
|
||||
* Callbacks are only supposed to return a value from
|
||||
* PHYSFS_EnumerateCallbackResult. Any other result has undefined
|
||||
* behavior.
|
||||
* As long as the callback returned PHYSFS_ENUM_OK and you haven't
|
||||
* experienced any errors of your own, keep enumerating until you're done
|
||||
* and then return PHYSFS_ENUM_OK without setting an error code.
|
||||
*
|
||||
* \warning PHYSFS_enumerate returns zero or non-zero (success or failure),
|
||||
* so be aware this function pointer returns different values!
|
||||
*/
|
||||
int (*enumerate)(void *opaque, const char *dirname,
|
||||
PHYSFS_EnumerateCallback cb,
|
||||
PHYSFS_EnumerateCallbackResult (*enumerate)(void *opaque,
|
||||
const char *dirname, PHYSFS_EnumerateCallback cb,
|
||||
const char *origdir, void *callbackdata);
|
||||
|
||||
/**
|
||||
|
@ -3696,6 +3874,46 @@ PHYSFS_DECL int PHYSFS_deregisterArchiver(const char *ext);
|
|||
|
||||
/* Everything above this line is part of the PhysicsFS 2.1 API. */
|
||||
|
||||
|
||||
/**
|
||||
* \fn int PHYSFS_setRoot(const char *archive, const char *subdir)
|
||||
* \brief Make a subdirectory of an archive its root directory.
|
||||
*
|
||||
* This lets you narrow down the accessible files in a specific archive. For
|
||||
* example, if you have x.zip with a file in y/z.txt, mounted to /a, if you
|
||||
* call PHYSFS_setRoot("x.zip", "/y"), then the call
|
||||
* PHYSFS_openRead("/a/z.txt") will succeed.
|
||||
*
|
||||
* You can change an archive's root at any time, altering the interpolated
|
||||
* file tree (depending on where paths shift, a different archive may be
|
||||
* providing various files). If you set the root to NULL or "/", the
|
||||
* archive will be treated as if no special root was set (as if the archive
|
||||
* was just mounted normally).
|
||||
*
|
||||
* Changing the root only affects future operations on pathnames; a file
|
||||
* that was opened from a path that changed due to a setRoot will not be
|
||||
* affected.
|
||||
*
|
||||
* Setting a new root is not limited to archives in the search path; you may
|
||||
* set one on the write dir, too, which might be useful if you have files
|
||||
* open for write and thus can't change the write dir at the moment.
|
||||
*
|
||||
* It is not an error to set a subdirectory that does not exist to be the
|
||||
* root of an archive; however, no files will be visible in this case. If
|
||||
* the missing directories end up getting created (a mkdir to the physical
|
||||
* filesystem, etc) then this will be reflected in the interpolated tree.
|
||||
*
|
||||
* \param archive dir/archive on which to change root.
|
||||
* \param subdir new subdirectory to make the root of this archive.
|
||||
* \return nonzero on success, zero on failure. Use
|
||||
* PHYSFS_getLastErrorCode() to obtain the specific error.
|
||||
*/
|
||||
PHYSFS_DECL int PHYSFS_setRoot(const char *archive, const char *subdir);
|
||||
|
||||
|
||||
/* Everything above this line is part of the PhysicsFS 3.1 API. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -185,7 +185,7 @@ static int szipLoadEntries(SZIPinfo *info)
|
|||
{
|
||||
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;
|
||||
PHYSFS_uint32 i;
|
||||
|
@ -203,6 +203,8 @@ static void SZIP_closeArchive(void *opaque)
|
|||
SZIPinfo *info = (SZIPinfo *) opaque;
|
||||
if (info)
|
||||
{
|
||||
if (info->io)
|
||||
info->io->destroy(info->io);
|
||||
SzArEx_Free(&info->db, &SZIP_SzAlloc);
|
||||
__PHYSFS_DirTreeDeinit(&info->tree);
|
||||
allocator.Free(info);
|
||||
|
@ -283,13 +285,16 @@ static PHYSFS_Io *SZIP_openRead(void *opaque, const char *path)
|
|||
&blockIndex, &outBuffer, &outBufferSize, &offset,
|
||||
&outSizeProcessed, alloc, alloc);
|
||||
GOTO_IF(rc != SZ_OK, szipErrorCode(rc), SZIP_openRead_failed);
|
||||
GOTO_IF(outBuffer == NULL, PHYSFS_ERR_OUT_OF_MEMORY, SZIP_openRead_failed);
|
||||
|
||||
io->destroy(io);
|
||||
io = NULL;
|
||||
|
||||
buf = allocator.Malloc(outSizeProcessed);
|
||||
GOTO_IF(rc != SZ_OK, PHYSFS_ERR_OUT_OF_MEMORY, SZIP_openRead_failed);
|
||||
memcpy(buf, outBuffer + offset, outSizeProcessed);
|
||||
buf = allocator.Malloc(outSizeProcessed ? outSizeProcessed : 1);
|
||||
GOTO_IF(buf == NULL, PHYSFS_ERR_OUT_OF_MEMORY, SZIP_openRead_failed);
|
||||
|
||||
if (outSizeProcessed > 0)
|
||||
memcpy(buf, outBuffer + offset, outSizeProcessed);
|
||||
|
||||
alloc->Free(alloc, outBuffer);
|
||||
outBuffer = NULL;
|
||||
|
|
|
@ -49,7 +49,8 @@ static void *DIR_openArchive(PHYSFS_Io *io, const char *name,
|
|||
const size_t seplen = 1;
|
||||
|
||||
assert(io == NULL); /* shouldn't create an Io for these. */
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st), NULL);
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st, 1), NULL);
|
||||
|
||||
if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
|
||||
BAIL(PHYSFS_ERR_UNSUPPORTED, NULL);
|
||||
|
||||
|
@ -70,14 +71,14 @@ static void *DIR_openArchive(PHYSFS_Io *io, const char *name,
|
|||
} /* DIR_openArchive */
|
||||
|
||||
|
||||
static int DIR_enumerate(void *opaque, const char *dname,
|
||||
PHYSFS_EnumerateCallback cb,
|
||||
static PHYSFS_EnumerateCallbackResult DIR_enumerate(void *opaque,
|
||||
const char *dname, PHYSFS_EnumerateCallback cb,
|
||||
const char *origdir, void *callbackdata)
|
||||
{
|
||||
char *d;
|
||||
int retval;
|
||||
PHYSFS_EnumerateCallbackResult retval;
|
||||
CVT_TO_DEPENDENT(d, opaque, dname);
|
||||
BAIL_IF_ERRPASS(!d, -1);
|
||||
BAIL_IF_ERRPASS(!d, PHYSFS_ENUM_ERROR);
|
||||
retval = __PHYSFS_platformEnumerate(d, cb, origdir, callbackdata);
|
||||
__PHYSFS_smallFree(d);
|
||||
return retval;
|
||||
|
@ -97,7 +98,7 @@ static PHYSFS_Io *doOpen(void *opaque, const char *name, const int mode)
|
|||
{
|
||||
const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
|
||||
PHYSFS_Stat statbuf;
|
||||
__PHYSFS_platformStat(f, &statbuf);
|
||||
__PHYSFS_platformStat(f, &statbuf, 0); /* !!! FIXME: why are we stating here? */
|
||||
PHYSFS_setErrorCode(err);
|
||||
} /* if */
|
||||
|
||||
|
@ -164,7 +165,7 @@ static int DIR_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
|
|||
|
||||
CVT_TO_DEPENDENT(d, opaque, name);
|
||||
BAIL_IF_ERRPASS(!d, 0);
|
||||
retval = __PHYSFS_platformStat(d, stat);
|
||||
retval = __PHYSFS_platformStat(d, stat, 0);
|
||||
__PHYSFS_smallFree(d);
|
||||
return retval;
|
||||
} /* DIR_stat */
|
||||
|
|
|
@ -76,7 +76,7 @@ static void *GRP_openArchive(PHYSFS_Io *io, const char *name,
|
|||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
|
||||
count = PHYSFS_swapULE32(count);
|
||||
|
||||
unpkarc = UNPK_openArchive(io);
|
||||
unpkarc = UNPK_openArchive(io, 0, 1);
|
||||
BAIL_IF_ERRPASS(!unpkarc, NULL);
|
||||
|
||||
if (!grpLoadEntries(io, count, unpkarc))
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* HOG support routines for PhysicsFS.
|
||||
*
|
||||
* This driver handles Descent I/II HOG archives.
|
||||
* This driver handles Descent I/II/III HOG archives.
|
||||
*
|
||||
* The format is very simple:
|
||||
* The Descent I/II format is very simple:
|
||||
*
|
||||
* The file always starts with the 3-byte signature "DHF" (Descent
|
||||
* HOG file). After that the files of a HOG are just attached after
|
||||
|
@ -23,10 +23,23 @@
|
|||
*
|
||||
* (That info is from http://www.descent2.com/ddn/specs/hog/)
|
||||
*
|
||||
* Descent 3 moved to HOG2 format, which starts with the chars "HOG2",
|
||||
* then 32-bits for the number of contained files, 32 bits for the offset
|
||||
* to the first file's data, then 56 bytes of 0xFF (reserved?). Then for
|
||||
* each file, there's 36 bytes for filename (null-terminated, rest of bytes
|
||||
* are garbage), 32-bits unknown/reserved (always zero?), 32-bits of length
|
||||
* of file data, 32-bits of time since Unix epoch. Then immediately following,
|
||||
* for each file is their uncompressed content, you can find its offset
|
||||
* by starting at the initial data offset and adding the filesize of each
|
||||
* prior file.
|
||||
*
|
||||
* This information was found at:
|
||||
* https://web.archive.org/web/20020213004051/http://descent-3.com/ddn/specs/hog/
|
||||
*
|
||||
*
|
||||
* Please see the file LICENSE.txt in the source's root directory.
|
||||
*
|
||||
* This file written by Bradley Bell.
|
||||
* Based on grp.c by Ryan C. Gordon.
|
||||
* This file written by Bradley Bell and Ryan C. Gordon.
|
||||
*/
|
||||
|
||||
#define __PHYSICSFS_INTERNAL__
|
||||
|
@ -34,7 +47,15 @@
|
|||
|
||||
#if PHYSFS_SUPPORTS_HOG
|
||||
|
||||
static int hogLoadEntries(PHYSFS_Io *io, void *arc)
|
||||
static int readui32(PHYSFS_Io *io, PHYSFS_uint32 *val)
|
||||
{
|
||||
PHYSFS_uint32 v;
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &v, sizeof (v)), 0);
|
||||
*val = PHYSFS_swapULE32(v);
|
||||
return 1;
|
||||
} /* readui32 */
|
||||
|
||||
static int hog1LoadEntries(PHYSFS_Io *io, void *arc)
|
||||
{
|
||||
const PHYSFS_uint64 iolen = io->length(io);
|
||||
PHYSFS_uint32 pos = 3;
|
||||
|
@ -45,11 +66,10 @@ static int hogLoadEntries(PHYSFS_Io *io, void *arc)
|
|||
char name[13];
|
||||
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 13), 0);
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0);
|
||||
BAIL_IF_ERRPASS(!readui32(io, &size), 0);
|
||||
name[12] = '\0'; /* just in case. */
|
||||
pos += 13 + 4;
|
||||
|
||||
size = PHYSFS_swapULE32(size);
|
||||
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0);
|
||||
pos += size;
|
||||
|
||||
|
@ -60,24 +80,60 @@ static int hogLoadEntries(PHYSFS_Io *io, void *arc)
|
|||
return 1;
|
||||
} /* hogLoadEntries */
|
||||
|
||||
static int hog2LoadEntries(PHYSFS_Io *io, void *arc)
|
||||
{
|
||||
PHYSFS_uint32 numfiles;
|
||||
PHYSFS_uint32 pos;
|
||||
PHYSFS_uint32 i;
|
||||
|
||||
BAIL_IF_ERRPASS(!readui32(io, &numfiles), 0);
|
||||
BAIL_IF_ERRPASS(!readui32(io, &pos), 0);
|
||||
BAIL_IF_ERRPASS(!io->seek(io, 68), 0); /* skip to end of header. */
|
||||
|
||||
for (i = 0; i < numfiles; i++) {
|
||||
char name[37];
|
||||
PHYSFS_uint32 reserved;
|
||||
PHYSFS_uint32 size;
|
||||
PHYSFS_uint32 mtime;
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 36), 0);
|
||||
BAIL_IF_ERRPASS(!readui32(io, &reserved), 0);
|
||||
BAIL_IF_ERRPASS(!readui32(io, &size), 0);
|
||||
BAIL_IF_ERRPASS(!readui32(io, &mtime), 0);
|
||||
name[36] = '\0'; /* just in case */
|
||||
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, mtime, mtime, pos, size), 0);
|
||||
pos += size;
|
||||
}
|
||||
|
||||
return 1;
|
||||
} /* hog2LoadEntries */
|
||||
|
||||
|
||||
static void *HOG_openArchive(PHYSFS_Io *io, const char *name,
|
||||
int forWriting, int *claimed)
|
||||
{
|
||||
PHYSFS_uint8 buf[3];
|
||||
void *unpkarc = NULL;
|
||||
int hog1 = 0;
|
||||
|
||||
assert(io != NULL); /* shouldn't ever happen. */
|
||||
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, buf, 3), NULL);
|
||||
BAIL_IF(memcmp(buf, "DHF", 3) != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
|
||||
|
||||
if (memcmp(buf, "DHF", 3) == 0)
|
||||
hog1 = 1; /* original HOG (Descent 1 and 2) archive */
|
||||
else
|
||||
{
|
||||
BAIL_IF(memcmp(buf, "HOG", 3) != 0, PHYSFS_ERR_UNSUPPORTED, NULL); /* Not HOG2 */
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, buf, 1), NULL);
|
||||
BAIL_IF(buf[0] != '2', PHYSFS_ERR_UNSUPPORTED, NULL); /* Not HOG2 */
|
||||
} /* else */
|
||||
|
||||
*claimed = 1;
|
||||
|
||||
unpkarc = UNPK_openArchive(io);
|
||||
unpkarc = UNPK_openArchive(io, 0, 1);
|
||||
BAIL_IF_ERRPASS(!unpkarc, NULL);
|
||||
|
||||
if (!hogLoadEntries(io, unpkarc))
|
||||
if (!(hog1 ? hog1LoadEntries(io, unpkarc) : hog2LoadEntries(io, unpkarc)))
|
||||
{
|
||||
UNPK_abandonArchive(unpkarc);
|
||||
return NULL;
|
||||
|
@ -92,7 +148,7 @@ const PHYSFS_Archiver __PHYSFS_Archiver_HOG =
|
|||
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
|
||||
{
|
||||
"HOG",
|
||||
"Descent I/II HOG file format",
|
||||
"Descent I/II/III HOG file format",
|
||||
"Bradley Bell <btb@icculus.org>",
|
||||
"https://icculus.org/physfs/",
|
||||
0, /* supportsSymlinks */
|
||||
|
|
|
@ -151,18 +151,25 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet,
|
|||
|
||||
/* recordlen = 0 -> no more entries or fill entry */
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &recordlen, 1), 0);
|
||||
if (recordlen == 0)
|
||||
if (recordlen > 0)
|
||||
readpos += recordlen; /* ready to seek to next record. */
|
||||
else
|
||||
{
|
||||
PHYSFS_uint64 nextpos;
|
||||
|
||||
/* if we are in the last sector of the directory & it's 0 -> end */
|
||||
if ((dirend - 2048) <= (readpos - 1))
|
||||
break; /* finished */
|
||||
|
||||
/* else skip to the next sector & continue; */
|
||||
readpos = (((readpos - 1) / 2048) + 1) * 2048;
|
||||
continue;
|
||||
} /* if */
|
||||
nextpos = (((readpos - 1) / 2048) + 1) * 2048;
|
||||
|
||||
readpos += recordlen; /* ready to seek to next record. */
|
||||
/* whoops, can't make forward progress! */
|
||||
BAIL_IF(nextpos == readpos, PHYSFS_ERR_CORRUPT, 0);
|
||||
|
||||
readpos = nextpos;
|
||||
continue; /* start back at upper loop. */
|
||||
} /* else */
|
||||
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &extattrlen, 1), 0);
|
||||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &extent, 4), 0);
|
||||
|
@ -203,6 +210,10 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet,
|
|||
timestamp = (PHYSFS_sint64) mktime(&t);
|
||||
|
||||
extent += extattrlen; /* skip extended attribute record. */
|
||||
|
||||
/* infinite loop, corrupt file? */
|
||||
BAIL_IF((extent * 2048) == dirstart, PHYSFS_ERR_CORRUPT, 0);
|
||||
|
||||
if (!iso9660AddEntry(io, joliet, isdir, base, fname, fnamelen,
|
||||
timestamp, extent * 2048, datalen, unpkarc))
|
||||
{
|
||||
|
@ -240,7 +251,7 @@ static int parseVolumeDescriptor(PHYSFS_Io *io, PHYSFS_uint64 *_rootpos,
|
|||
pos += 2048; /* each volume descriptor is 2048 bytes */
|
||||
|
||||
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? */
|
||||
{
|
||||
|
@ -335,7 +346,8 @@ static void *ISO9660_openArchive(PHYSFS_Io *io, const char *filename,
|
|||
if (!parseVolumeDescriptor(io, &rootpos, &len, &joliet, claimed))
|
||||
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);
|
||||
|
||||
if (!iso9660LoadEntries(io, joliet, "", rootpos, rootpos + len, unpkarc))
|
||||
|
|
|
@ -70,7 +70,7 @@ static void *MVL_openArchive(PHYSFS_Io *io, const char *name,
|
|||
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
|
||||
count = PHYSFS_swapULE32(count);
|
||||
|
||||
unpkarc = UNPK_openArchive(io);
|
||||
unpkarc = UNPK_openArchive(io, 0, 1);
|
||||
BAIL_IF_ERRPASS(!unpkarc, NULL);
|
||||
|
||||
if (!mvlLoadEntries(io, count, unpkarc))
|
||||
|
|
|
@ -86,7 +86,8 @@ static void *QPAK_openArchive(PHYSFS_Io *io, const char *name,
|
|||
|
||||
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);
|
||||
|
||||
if (!qpakLoadEntries(io, count, unpkarc))
|
||||
|
|
|
@ -36,7 +36,7 @@ static int slbLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
|
|||
BAIL_IF(backslash != '\\', PHYSFS_ERR_CORRUPT, 0);
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* convert backslashes */
|
||||
|
@ -94,7 +94,8 @@ static void *SLB_openArchive(PHYSFS_Io *io, const char *name,
|
|||
/* seek to the table of contents */
|
||||
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);
|
||||
|
||||
if (!slbLoadEntries(io, count, unpkarc))
|
||||
|
|
|
@ -285,12 +285,12 @@ void *UNPK_addEntry(void *opaque, char *name, const int isdir,
|
|||
} /* 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));
|
||||
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);
|
||||
return NULL;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define VDF_COMMENT_LENGTH 256
|
||||
#define VDF_SIGNATURE_LENGTH 16
|
||||
#define VDF_ENTRY_NAME_LENGTH 64
|
||||
#define VDF_ENTRY_DIR 0x80000000
|
||||
|
||||
static const char* VDF_SIGNATURE_G1 = "PSVDSC_V2.00\r\n\r\n";
|
||||
static const char* VDF_SIGNATURE_G2 = "PSVDSC_V2.00\n\r\n\r";
|
||||
|
@ -83,8 +84,9 @@ static int vdfLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count,
|
|||
} /* for */
|
||||
|
||||
BAIL_IF(!name[0], PHYSFS_ERR_CORRUPT, 0);
|
||||
|
||||
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, ts, ts, jump, size), 0);
|
||||
if (!(type & VDF_ENTRY_DIR)) {
|
||||
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, ts, ts, jump, size), 0);
|
||||
}
|
||||
} /* for */
|
||||
|
||||
return 1;
|
||||
|
@ -100,7 +102,7 @@ static void *VDF_openArchive(PHYSFS_Io *io, const char *name,
|
|||
void *unpkarc;
|
||||
|
||||
assert(io != NULL); /* shouldn't ever happen. */
|
||||
|
||||
|
||||
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
|
||||
|
||||
/* skip the 256-byte comment field. */
|
||||
|
@ -127,7 +129,8 @@ static void *VDF_openArchive(PHYSFS_Io *io, const char *name,
|
|||
|
||||
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);
|
||||
|
||||
if (!vdfLoadEntries(io, count, vdfDosTimeToEpoch(timestamp), unpkarc))
|
||||
|
|
|
@ -95,7 +95,7 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name,
|
|||
|
||||
BAIL_IF_ERRPASS(!io->seek(io, directoryOffset), 0);
|
||||
|
||||
unpkarc = UNPK_openArchive(io);
|
||||
unpkarc = UNPK_openArchive(io, 0, 1);
|
||||
BAIL_IF_ERRPASS(!unpkarc, NULL);
|
||||
|
||||
if (!wadLoadEntries(io, count, unpkarc))
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
#include <errno.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"
|
||||
|
||||
/*
|
||||
|
@ -455,6 +460,7 @@ static PHYSFS_Io *ZIP_duplicate(PHYSFS_Io *io)
|
|||
finfo->io = zip_get_io(origfinfo->io, NULL, finfo->entry);
|
||||
GOTO_IF_ERRPASS(!finfo->io, failed);
|
||||
|
||||
initializeZStream(&finfo->stream);
|
||||
if (finfo->entry->compression_method != COMPMETH_NONE)
|
||||
{
|
||||
finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
|
||||
|
@ -567,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))
|
||||
return -1;
|
||||
memcpy(&buf[maxread - 4], &extra, sizeof (extra));
|
||||
memcpy(&buf[maxread - 4], extra, sizeof (extra));
|
||||
totalread += maxread - 4;
|
||||
} /* if */
|
||||
else
|
||||
|
@ -577,7 +583,7 @@ static PHYSFS_sint64 zip_find_end_of_central_dir(PHYSFS_Io *io, PHYSFS_sint64 *l
|
|||
totalread += maxread;
|
||||
} /* else */
|
||||
|
||||
memcpy(&extra, buf, sizeof (extra));
|
||||
memcpy(extra, buf, sizeof (extra));
|
||||
|
||||
for (i = maxread - 4; i > 0; i--)
|
||||
{
|
||||
|
@ -832,7 +838,10 @@ static int zip_parse_local(PHYSFS_Io *io, ZIPentry *entry)
|
|||
BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
|
||||
BAIL_IF(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 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);
|
||||
BAIL_IF(ui16 != entry->compression_method, PHYSFS_ERR_CORRUPT, 0);
|
||||
|
@ -1481,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))
|
||||
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;
|
||||
|
||||
root = (ZIPentry *) info->tree.root;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#endif
|
||||
|
||||
/* Turn off MSVC warnings that are aggressively anti-portability. */
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
|||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef PHYSFS_PLATFORM_SOLARIS
|
||||
#if defined(PHYSFS_PLATFORM_SOLARIS) || defined(PHYSFS_PLATFORM_LINUX)
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
|
@ -69,7 +69,7 @@ extern "C" {
|
|||
All file-private symbols need to be marked "static".
|
||||
Everything shared between PhysicsFS sources needs to be in this
|
||||
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
|
||||
#endif
|
||||
|
||||
|
@ -95,6 +95,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
|
|||
/* a real C99-compliant snprintf() is in Visual Studio 2015,
|
||||
but just use this everywhere for binary compatibility. */
|
||||
#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_snprintf(char *outBuf, size_t size, const char *format, ...);
|
||||
#define vsnprintf __PHYSFS_msvc_vsnprintf
|
||||
|
@ -108,14 +109,24 @@ const void *__PHYSFS_winrtCalcPrefDir(void);
|
|||
#endif
|
||||
|
||||
/* atomic operations. */
|
||||
/* increment/decrement operations return the final incremented/decremented value. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
#include <intrin.h>
|
||||
__PHYSFS_COMPILE_TIME_ASSERT(LongEqualsInt, sizeof (int) == sizeof (long));
|
||||
#define __PHYSFS_ATOMIC_INCR(ptrval) _InterlockedIncrement((long*)(ptrval))
|
||||
#define __PHYSFS_ATOMIC_DECR(ptrval) _InterlockedDecrement((long*)(ptrval))
|
||||
#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
|
||||
#define PHYSFS_NEED_ATOMIC_OP_FALLBACK 1
|
||||
int __PHYSFS_ATOMIC_INCR(int *ptrval);
|
||||
|
@ -162,35 +173,44 @@ void __PHYSFS_smallFree(void *ptr);
|
|||
#define free(x) Do not use free() directly.
|
||||
/* !!! FIXME: add alloca check here. */
|
||||
|
||||
|
||||
/* by default, enable things, so builds can opt out of a few things they
|
||||
want to avoid. But you can build with this #defined to 0 if you would
|
||||
like to turn off everything except a handful of things you opt into. */
|
||||
#ifndef PHYSFS_SUPPORTS_DEFAULT
|
||||
#define PHYSFS_SUPPORTS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PHYSFS_SUPPORTS_ZIP
|
||||
#define PHYSFS_SUPPORTS_ZIP 1
|
||||
#define PHYSFS_SUPPORTS_ZIP PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_7Z
|
||||
#define PHYSFS_SUPPORTS_7Z 1
|
||||
#define PHYSFS_SUPPORTS_7Z PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_GRP
|
||||
#define PHYSFS_SUPPORTS_GRP 1
|
||||
#define PHYSFS_SUPPORTS_GRP PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_HOG
|
||||
#define PHYSFS_SUPPORTS_HOG 1
|
||||
#define PHYSFS_SUPPORTS_HOG PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_MVL
|
||||
#define PHYSFS_SUPPORTS_MVL 1
|
||||
#define PHYSFS_SUPPORTS_MVL PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_WAD
|
||||
#define PHYSFS_SUPPORTS_WAD 1
|
||||
#define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_QPAK
|
||||
#define PHYSFS_SUPPORTS_QPAK 1
|
||||
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_SLB
|
||||
#define PHYSFS_SUPPORTS_SLB 1
|
||||
#define PHYSFS_SUPPORTS_SLB PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_ISO9660
|
||||
#define PHYSFS_SUPPORTS_ISO9660 1
|
||||
#define PHYSFS_SUPPORTS_ISO9660 PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
#ifndef PHYSFS_SUPPORTS_VDF
|
||||
#define PHYSFS_SUPPORTS_VDF 1
|
||||
#define PHYSFS_SUPPORTS_VDF PHYSFS_SUPPORTS_DEFAULT
|
||||
#endif
|
||||
|
||||
#if PHYSFS_SUPPORTS_7Z
|
||||
|
@ -204,6 +224,7 @@ extern void SZIP_global_init(void);
|
|||
/* The latest supported PHYSFS_Archiver::version value. */
|
||||
#define CURRENT_PHYSFS_ARCHIVER_API_VERSION 0
|
||||
|
||||
|
||||
/* This byteorder stuff was lifted from SDL. https://www.libsdl.org/ */
|
||||
#define PHYSFS_LIL_ENDIAN 1234
|
||||
#define PHYSFS_BIG_ENDIAN 4321
|
||||
|
@ -211,11 +232,26 @@ extern void SZIP_global_init(void);
|
|||
#ifdef __linux__
|
||||
#include <endian.h>
|
||||
#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__) || \
|
||||
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__)
|
||||
#define PHYSFS_BYTEORDER PHYSFS_BIG_ENDIAN
|
||||
#else
|
||||
|
@ -303,7 +339,18 @@ char *__PHYSFS_strdup(const char *str);
|
|||
/*
|
||||
* 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);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -339,9 +386,10 @@ int __PHYSFS_readAll(PHYSFS_Io *io, void *buf, const size_t len);
|
|||
|
||||
/* 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_closeArchive(void *opaque);
|
||||
void *UNPK_openArchive(PHYSFS_Io *io);
|
||||
void *UNPK_addEntry(void *opaque, char *name, const int isdir,
|
||||
const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime,
|
||||
const PHYSFS_uint64 pos, const PHYSFS_uint64 len);
|
||||
|
@ -373,14 +421,17 @@ typedef struct __PHYSFS_DirTree
|
|||
__PHYSFS_DirTreeEntry **hash; /* all entries hashed for fast lookup. */
|
||||
size_t hashBuckets; /* number of buckets in hash. */
|
||||
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;
|
||||
|
||||
|
||||
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_DirTreeFind(__PHYSFS_DirTree *dt, const char *path);
|
||||
int __PHYSFS_DirTreeEnumerate(void *opaque, const char *dname,
|
||||
PHYSFS_EnumerateCallback cb,
|
||||
PHYSFS_EnumerateCallbackResult __PHYSFS_DirTreeEnumerate(void *opaque,
|
||||
const char *dname, PHYSFS_EnumerateCallback cb,
|
||||
const char *origdir, void *callbackdata);
|
||||
void __PHYSFS_DirTreeDeinit(__PHYSFS_DirTree *dt);
|
||||
|
||||
|
@ -549,11 +600,12 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
|
|||
*
|
||||
* This needs to fill in all the fields of (stat). For fields that might not
|
||||
* mean anything on a platform (access time, perhaps), choose a reasonable
|
||||
* default.
|
||||
* default. if (follow), we want to follow symlinks and stat what they
|
||||
* link to and not the link itself.
|
||||
*
|
||||
* Return zero on failure, non-zero on success.
|
||||
*/
|
||||
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat);
|
||||
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat, const int follow);
|
||||
|
||||
/*
|
||||
* Flush any pending writes to disk. (opaque) should be cast to whatever data
|
||||
|
@ -633,7 +685,7 @@ void *__PHYSFS_platformGetThreadID(void);
|
|||
* notation. Note that ".", "..", and other meta-entries should always
|
||||
* be ignored.
|
||||
*/
|
||||
int __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallback callback,
|
||||
const char *origdir, void *callbackdata);
|
||||
|
||||
|
@ -705,6 +757,11 @@ int __PHYSFS_platformGrabMutex(void *mutex);
|
|||
*/
|
||||
void __PHYSFS_platformReleaseMutex(void *mutex);
|
||||
|
||||
|
||||
/* !!! FIXME: move to public API? */
|
||||
PHYSFS_uint32 __PHYSFS_utf8codepoint(const char **_str);
|
||||
|
||||
|
||||
#if PHYSFS_HAVE_PRAGMA_VISIBILITY
|
||||
#pragma GCC visibility pop
|
||||
#endif
|
||||
|
|
|
@ -506,6 +506,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|
|||
#endif
|
||||
|
||||
#if defined(MY_CPU_AMD64) \
|
||||
|| defined(_M_ARM64) \
|
||||
|| defined(_M_IA64) \
|
||||
|| defined(__AARCH64EL__) \
|
||||
|| 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)
|
||||
#define MY_CPU_ARM_LE
|
||||
#elif defined(_WIN64) && defined(_M_ARM64)
|
||||
#define MY_CPU_ARM_LE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_IA64)
|
||||
|
|
|
@ -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_free_func)(void *opaque, void *address);
|
||||
|
||||
#ifndef MINIZ_LITTLE_ENDIAN /* if not defined by PHYSFS */
|
||||
#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). */
|
||||
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
|
||||
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
|
||||
#define MINIZ_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#endif /**/
|
||||
|
||||
#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) */
|
||||
|
@ -117,6 +119,8 @@ struct tinfl_decompressor_tag
|
|||
#define MZ_MAX(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_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
|
||||
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
|
||||
|
@ -166,13 +170,17 @@ struct tinfl_decompressor_tag
|
|||
if (temp >= 0) { \
|
||||
code_len = temp >> 9; \
|
||||
if ((code_len) && (num_bits >= code_len)) \
|
||||
break; \
|
||||
break; \
|
||||
} else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
|
||||
code_len = TINFL_FAST_LOOKUP_BITS; \
|
||||
do { \
|
||||
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);
|
||||
|
||||
/* 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
|
||||
{
|
||||
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;
|
||||
}
|
||||
for ( ; (int)r->m_type >= 0; r->m_type--)
|
||||
{
|
||||
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]]++;
|
||||
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)); }
|
||||
|
@ -699,3 +707,4 @@ static int mz_inflateEnd(mz_streamp pStream)
|
|||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
*/
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Android support routines for PhysicsFS.
|
||||
*
|
||||
* Please see the file LICENSE.txt in the source's root directory.
|
||||
*
|
||||
* This file written by Ryan C. Gordon.
|
||||
*/
|
||||
|
||||
#define __PHYSICSFS_INTERNAL__
|
||||
#include "physfs_platforms.h"
|
||||
|
||||
#ifdef PHYSFS_PLATFORM_ANDROID
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include "physfs_internal.h"
|
||||
|
||||
static char *prefpath = NULL;
|
||||
|
||||
|
||||
int __PHYSFS_platformInit(void)
|
||||
{
|
||||
return 1; /* always succeed. */
|
||||
} /* __PHYSFS_platformInit */
|
||||
|
||||
|
||||
void __PHYSFS_platformDeinit(void)
|
||||
{
|
||||
if (prefpath)
|
||||
{
|
||||
allocator.Free(prefpath);
|
||||
prefpath = NULL;
|
||||
} /* if */
|
||||
} /* __PHYSFS_platformDeinit */
|
||||
|
||||
|
||||
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
||||
{
|
||||
/* no-op. */
|
||||
} /* __PHYSFS_platformDetectAvailableCDs */
|
||||
|
||||
|
||||
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
||||
{
|
||||
/* as a cheat, we expect argv0 to be a PHYSFS_AndroidInit* on Android. */
|
||||
PHYSFS_AndroidInit *ainit = (PHYSFS_AndroidInit *) argv0;
|
||||
char *retval = NULL;
|
||||
JNIEnv *jenv = NULL;
|
||||
jobject jcontext;
|
||||
|
||||
if (ainit == NULL)
|
||||
return __PHYSFS_strdup("/"); /* oh well. */
|
||||
|
||||
jenv = (JNIEnv *) ainit->jnienv;
|
||||
jcontext = (jobject) ainit->context;
|
||||
|
||||
if ((*jenv)->PushLocalFrame(jenv, 16) >= 0)
|
||||
{
|
||||
jobject jfileobj = 0;
|
||||
jmethodID jmeth = 0;
|
||||
jthrowable jexception = 0;
|
||||
jstring jstr = 0;
|
||||
|
||||
jmeth = (*jenv)->GetMethodID(jenv, (*jenv)->GetObjectClass(jenv, jcontext), "getPackageResourcePath", "()Ljava/lang/String;");
|
||||
jstr = (jstring)(*jenv)->CallObjectMethod(jenv, jcontext, jmeth);
|
||||
jexception = (*jenv)->ExceptionOccurred(jenv); /* this can't throw an exception, right? Just in case. */
|
||||
if (jexception != NULL)
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
else
|
||||
{
|
||||
const char *path = (*jenv)->GetStringUTFChars(jenv, jstr, NULL);
|
||||
retval = __PHYSFS_strdup(path);
|
||||
(*jenv)->ReleaseStringUTFChars(jenv, jstr, path);
|
||||
} /* else */
|
||||
|
||||
/* We only can rely on the Activity being valid during this function call,
|
||||
so go ahead and grab the prefpath too. */
|
||||
jmeth = (*jenv)->GetMethodID(jenv, (*jenv)->GetObjectClass(jenv, jcontext), "getFilesDir", "()Ljava/io/File;");
|
||||
jfileobj = (*jenv)->CallObjectMethod(jenv, jcontext, jmeth);
|
||||
if (jfileobj)
|
||||
{
|
||||
jmeth = (*jenv)->GetMethodID(jenv, (*jenv)->GetObjectClass(jenv, jfileobj), "getCanonicalPath", "()Ljava/lang/String;");
|
||||
jstr = (jstring)(*jenv)->CallObjectMethod(jenv, jfileobj, jmeth);
|
||||
jexception = (*jenv)->ExceptionOccurred(jenv);
|
||||
if (jexception != NULL)
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
else
|
||||
{
|
||||
const char *path = (*jenv)->GetStringUTFChars(jenv, jstr, NULL);
|
||||
const size_t len = strlen(path) + 2;
|
||||
prefpath = allocator.Malloc(len);
|
||||
if (prefpath)
|
||||
snprintf(prefpath, len, "%s/", path);
|
||||
(*jenv)->ReleaseStringUTFChars(jenv, jstr, path);
|
||||
} /* else */
|
||||
} /* if */
|
||||
|
||||
(*jenv)->PopLocalFrame(jenv, NULL);
|
||||
} /* if */
|
||||
|
||||
/* we can't return NULL because then PhysicsFS will treat argv0 as a string, but it's a non-NULL jobject! */
|
||||
if (retval == NULL)
|
||||
retval = __PHYSFS_strdup("/"); /* we pray this works. */
|
||||
|
||||
return retval;
|
||||
} /* __PHYSFS_platformCalcBaseDir */
|
||||
|
||||
|
||||
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
||||
{
|
||||
return __PHYSFS_strdup(prefpath ? prefpath : "/");
|
||||
} /* __PHYSFS_platformCalcPrefDir */
|
||||
|
||||
#endif /* PHYSFS_PLATFORM_ANDROID */
|
||||
|
||||
/* end of physfs_platform_android.c ... */
|
||||
|
|
@ -7,15 +7,14 @@
|
|||
*/
|
||||
|
||||
#define __PHYSICSFS_INTERNAL__
|
||||
#include "physfs_internal.h"
|
||||
#include "physfs_platforms.h"
|
||||
|
||||
#ifdef PHYSFS_PLATFORM_APPLE
|
||||
|
||||
/* Foundation.h steps on these. :( */
|
||||
#undef malloc
|
||||
#undef free
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "physfs_internal.h"
|
||||
|
||||
int __PHYSFS_platformInit(void)
|
||||
{
|
||||
|
@ -52,7 +51,7 @@ char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
|||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
|
||||
BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL);
|
||||
NSString *path = (NSString *) paths[0];
|
||||
NSString *path = (NSString *) [paths objectAtIndex:0];
|
||||
BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
|
||||
size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
const size_t applen = strlen(app);
|
||||
|
@ -101,7 +100,7 @@ static int darwinIsWholeMedia(io_service_t service)
|
|||
} /* darwinIsWholeMedia */
|
||||
|
||||
|
||||
static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
|
||||
static int darwinIsMountedDisc(char *bsdName, mach_port_t mainPort)
|
||||
{
|
||||
int retval = 0;
|
||||
CFMutableDictionaryRef matchingDict;
|
||||
|
@ -109,10 +108,10 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
|
|||
io_iterator_t iter;
|
||||
io_service_t service;
|
||||
|
||||
if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
|
||||
if ((matchingDict = IOBSDNameMatching(mainPort, 0, bsdName)) == NULL)
|
||||
return 0;
|
||||
|
||||
rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
|
||||
rc = IOServiceGetMatchingServices(mainPort, matchingDict, &iter);
|
||||
if ((rc != KERN_SUCCESS) || (!iter))
|
||||
return 0;
|
||||
|
||||
|
@ -160,13 +159,25 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
|
|||
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
||||
{
|
||||
#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 int prefixLen = strlen(devPrefix);
|
||||
mach_port_t masterPort = 0;
|
||||
mach_port_t mainPort = 0;
|
||||
struct statfs *mntbufp;
|
||||
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*/;
|
||||
|
||||
mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
|
||||
|
@ -178,7 +189,7 @@ void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
|||
continue;
|
||||
|
||||
dev += prefixLen;
|
||||
if (darwinIsMountedDisc(dev, masterPort))
|
||||
if (darwinIsMountedDisc(dev, mainPort))
|
||||
cb(data, mnt);
|
||||
} /* for */
|
||||
#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
|
||||
|
|
|
@ -95,25 +95,42 @@ static PHYSFS_ErrorCode errcodeFromAPIRET(const APIRET rc)
|
|||
|
||||
static char *cvtUtf8ToCodepage(const char *utf8str)
|
||||
{
|
||||
if (uconvdll)
|
||||
const size_t len = strlen(utf8str) + 1;
|
||||
const size_t uc2buflen = len * sizeof (UniChar);
|
||||
UniChar *uc2ptr = (UniChar *) __PHYSFS_smallAlloc(uc2buflen);
|
||||
UniChar *uc2str = uc2ptr;
|
||||
char *cpptr = NULL;
|
||||
char *cpstr = NULL;
|
||||
size_t subs = 0;
|
||||
size_t unilen;
|
||||
|
||||
BAIL_IF(!uc2str, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||
PHYSFS_utf8ToUcs2(utf8str, (PHYSFS_uint16 *) uc2str, uc2buflen);
|
||||
for (unilen = 0; uc2str[unilen]; unilen++) { /* spin */ }
|
||||
unilen++; /* null terminator. */
|
||||
|
||||
if (!uconvdll)
|
||||
{
|
||||
/* There's really not much we can do on older OS/2s except pray this
|
||||
is latin1-compatible. */
|
||||
size_t i;
|
||||
cpptr = (char *) allocator.Malloc(unilen);
|
||||
cpstr = cpptr;
|
||||
GOTO_IF(!cpptr, PHYSFS_ERR_OUT_OF_MEMORY, failed);
|
||||
for (i = 0; i < unilen; i++)
|
||||
{
|
||||
const UniChar ch = uc2str[i];
|
||||
GOTO_IF(ch > 0xFF, PHYSFS_ERR_BAD_FILENAME, failed);
|
||||
cpptr[i] = (char) ((unsigned char) ch);
|
||||
} /* for */
|
||||
|
||||
__PHYSFS_smallFree(uc2ptr);
|
||||
return cpstr;
|
||||
} /* if */
|
||||
else
|
||||
{
|
||||
int rc;
|
||||
size_t len = strlen(utf8str) + 1;
|
||||
const size_t uc2buflen = len * sizeof (UniChar);
|
||||
UniChar *uc2ptr = (UniChar *) __PHYSFS_smallAlloc(uc2buflen);
|
||||
UniChar *uc2str = uc2ptr;
|
||||
char *cpptr = NULL;
|
||||
char *cpstr = NULL;
|
||||
size_t subs = 0;
|
||||
size_t unilen;
|
||||
size_t cplen;
|
||||
|
||||
GOTO_IF(!uc2str, PHYSFS_ERR_OUT_OF_MEMORY, failed);
|
||||
PHYSFS_utf8ToUcs2(utf8str, (PHYSFS_uint16 *) uc2str, uc2buflen);
|
||||
for (unilen = 0; uc2str[unilen]; unilen++) { /* spin */ }
|
||||
unilen++; /* null terminator. */
|
||||
|
||||
cplen = unilen * 4; /* overallocate, just in case. */
|
||||
size_t cplen = unilen * 4; /* overallocate, just in case. */
|
||||
cpptr = (char *) allocator.Malloc(cplen);
|
||||
GOTO_IF(!cpptr, PHYSFS_ERR_OUT_OF_MEMORY, failed);
|
||||
cpstr = cpptr;
|
||||
|
@ -123,23 +140,35 @@ static char *cvtUtf8ToCodepage(const char *utf8str)
|
|||
GOTO_IF(subs > 0, PHYSFS_ERR_BAD_FILENAME, failed);
|
||||
assert(unilen == 0);
|
||||
|
||||
return cpptr;
|
||||
|
||||
failed:
|
||||
__PHYSFS_smallFree(uc2ptr);
|
||||
allocator.Free(cpptr);
|
||||
} /* if */
|
||||
return cpptr;
|
||||
} /* else */
|
||||
|
||||
failed:
|
||||
__PHYSFS_smallFree(uc2ptr);
|
||||
allocator.Free(cpptr);
|
||||
|
||||
return NULL;
|
||||
} /* cvtUtf8ToCodepage */
|
||||
|
||||
static char *cvtCodepageToUtf8(const char *cpstr)
|
||||
{
|
||||
const size_t len = strlen(cpstr) + 1;
|
||||
char *retvalbuf = (char *) allocator.Malloc(len * 4);
|
||||
char *retval = NULL;
|
||||
if (uconvdll)
|
||||
|
||||
BAIL_IF(!retvalbuf, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||
|
||||
if (!uconvdll)
|
||||
{
|
||||
/* There's really not much we can do on older OS/2s except pray this
|
||||
is latin1-compatible. */
|
||||
retval = retvalbuf;
|
||||
PHYSFS_utf8FromLatin1(cpstr, retval, len * 4);
|
||||
} /* if */
|
||||
else
|
||||
{
|
||||
int rc;
|
||||
size_t len = strlen(cpstr) + 1;
|
||||
size_t cplen = len;
|
||||
size_t unilen = len;
|
||||
size_t subs = 0;
|
||||
|
@ -151,12 +180,11 @@ static char *cvtCodepageToUtf8(const char *cpstr)
|
|||
GOTO_IF(rc != ULS_SUCCESS, PHYSFS_ERR_BAD_FILENAME, done);
|
||||
GOTO_IF(subs > 0, PHYSFS_ERR_BAD_FILENAME, done);
|
||||
assert(cplen == 0);
|
||||
retval = (char *) allocator.Malloc(len * 4);
|
||||
GOTO_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, done);
|
||||
retval = retvalbuf;
|
||||
PHYSFS_utf8FromUcs2((const PHYSFS_uint16 *) uc2ptr, retval, len * 4);
|
||||
done:
|
||||
__PHYSFS_smallFree(uc2ptr);
|
||||
} /* if */
|
||||
} /* else */
|
||||
|
||||
return retval;
|
||||
} /* cvtCodepageToUtf8 */
|
||||
|
@ -194,7 +222,7 @@ static char *cvtPathToCorrectCase(char *buf)
|
|||
if (ptr != NULL) /* isolate element to find (fname is the start). */
|
||||
*ptr = '\0';
|
||||
|
||||
rc = DosFindFirst((unsigned char *) spec, &hdir, FILE_DIRECTORY,
|
||||
rc = DosFindFirst(spec, &hdir, FILE_DIRECTORY,
|
||||
&fb, sizeof (fb), &count, FIL_STANDARD);
|
||||
if (rc == NO_ERROR)
|
||||
{
|
||||
|
@ -203,7 +231,7 @@ static char *cvtPathToCorrectCase(char *buf)
|
|||
int cmp;
|
||||
char *utf8 = cvtCodepageToUtf8(fb.achName);
|
||||
if (!utf8) /* ugh, maybe we'll get lucky with the C runtime. */
|
||||
cmp = stricmp(utf8, fname);
|
||||
cmp = stricmp(fb.achName, fname);
|
||||
else
|
||||
{
|
||||
cmp = PHYSFS_utf8stricmp(utf8, fname);
|
||||
|
@ -303,7 +331,7 @@ static int isCdRomDrive(ULONG drive)
|
|||
ULONG ul1, ul2;
|
||||
APIRET rc;
|
||||
HFILE hfile = NULLHANDLE;
|
||||
unsigned char drivename[3] = { 0, ':', '\0' };
|
||||
char drivename[3] = { 0, ':', '\0' };
|
||||
|
||||
drivename[0] = 'A' + drive;
|
||||
|
||||
|
@ -390,10 +418,11 @@ char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
|||
return __PHYSFS_platformCalcBaseDir(NULL); /* !!! FIXME: ? */
|
||||
} /* __PHYSFS_platformCalcPrefDir */
|
||||
|
||||
int __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallback callback,
|
||||
const char *origdir, void *callbackdata)
|
||||
{
|
||||
PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK;
|
||||
size_t utf8len = strlen(dirname);
|
||||
char *utf8 = (char *) __PHYSFS_smallAlloc(utf8len + 5);
|
||||
char *cpspec = NULL;
|
||||
|
@ -401,9 +430,8 @@ int __PHYSFS_platformEnumerate(const char *dirname,
|
|||
HDIR hdir = HDIR_CREATE;
|
||||
ULONG count = 1;
|
||||
APIRET rc;
|
||||
int retval = 1;
|
||||
|
||||
BAIL_IF(!utf8, PHYSFS_ERR_OUT_OF_MEMORY, -1);
|
||||
BAIL_IF(!utf8, PHYSFS_ERR_OUT_OF_MEMORY, PHYSFS_ENUM_ERROR);
|
||||
|
||||
strcpy(utf8, dirname);
|
||||
if (utf8[utf8len - 1] != '\\')
|
||||
|
@ -413,15 +441,15 @@ int __PHYSFS_platformEnumerate(const char *dirname,
|
|||
|
||||
cpspec = cvtUtf8ToCodepage(utf8);
|
||||
__PHYSFS_smallFree(utf8);
|
||||
BAIL_IF_ERRPASS(!cpspec, -1);
|
||||
BAIL_IF_ERRPASS(!cpspec, PHYSFS_ENUM_ERROR);
|
||||
|
||||
rc = DosFindFirst((unsigned char *) cpspec, &hdir,
|
||||
rc = DosFindFirst(cpspec, &hdir,
|
||||
FILE_DIRECTORY | FILE_ARCHIVED |
|
||||
FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM,
|
||||
&fb, sizeof (fb), &count, FIL_STANDARD);
|
||||
allocator.Free(cpspec);
|
||||
|
||||
BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), -1);
|
||||
BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), PHYSFS_ENUM_ERROR);
|
||||
|
||||
while (count == 1)
|
||||
{
|
||||
|
@ -429,17 +457,17 @@ int __PHYSFS_platformEnumerate(const char *dirname,
|
|||
{
|
||||
utf8 = cvtCodepageToUtf8(fb.achName);
|
||||
if (!utf8)
|
||||
retval = -1;
|
||||
retval = PHYSFS_ENUM_ERROR;
|
||||
else
|
||||
{
|
||||
retval = callback(callbackdata, origdir, utf8);
|
||||
allocator.Free(utf8);
|
||||
if (retval == -1)
|
||||
if (retval == PHYSFS_ENUM_ERROR)
|
||||
PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK);
|
||||
} /* else */
|
||||
} /* if */
|
||||
|
||||
if (retval != 1)
|
||||
if (retval != PHYSFS_ENUM_OK)
|
||||
break;
|
||||
|
||||
DosFindNext(hdir, &fb, sizeof (fb), &count);
|
||||
|
@ -507,7 +535,7 @@ int __PHYSFS_platformMkDir(const char *filename)
|
|||
APIRET rc;
|
||||
char *cpstr = cvtUtf8ToCodepage(filename);
|
||||
BAIL_IF_ERRPASS(!cpstr, 0);
|
||||
rc = DosCreateDir((unsigned char *) cpstr, NULL);
|
||||
rc = DosCreateDir(cpstr, NULL);
|
||||
allocator.Free(cpstr);
|
||||
BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), 0);
|
||||
return 1;
|
||||
|
@ -693,7 +721,7 @@ PHYSFS_sint64 os2TimeToUnixTime(const FDATE *date, const FTIME *time)
|
|||
} /* os2TimeToUnixTime */
|
||||
|
||||
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *stat)
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *stat, const int follow)
|
||||
{
|
||||
char *cpfname = cvtUtf8ToCodepage(filename);
|
||||
FILESTATUS3 fs;
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
* This file written by Ryan C. Gordon.
|
||||
*/
|
||||
|
||||
/* !!! FIXME: check for EINTR? */
|
||||
|
||||
#define __PHYSICSFS_INTERNAL__
|
||||
#include "physfs_platforms.h"
|
||||
|
||||
|
@ -118,18 +116,18 @@ char *__PHYSFS_platformCalcUserDir(void)
|
|||
} /* __PHYSFS_platformCalcUserDir */
|
||||
|
||||
|
||||
int __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallback callback,
|
||||
const char *origdir, void *callbackdata)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
int retval = 1;
|
||||
PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK;
|
||||
|
||||
dir = opendir(dirname);
|
||||
BAIL_IF(dir == NULL, errcodeFromErrno(), -1);
|
||||
BAIL_IF(dir == NULL, errcodeFromErrno(), PHYSFS_ENUM_ERROR);
|
||||
|
||||
while ((retval == 1) && ((ent = readdir(dir)) != NULL))
|
||||
while ((retval == PHYSFS_ENUM_OK) && ((ent = readdir(dir)) != NULL))
|
||||
{
|
||||
const char *name = ent->d_name;
|
||||
if (name[0] == '.') /* ignore "." and ".." */
|
||||
|
@ -139,7 +137,7 @@ int __PHYSFS_platformEnumerate(const char *dirname,
|
|||
} /* if */
|
||||
|
||||
retval = callback(callbackdata, origdir, name);
|
||||
if (retval == -1)
|
||||
if (retval == PHYSFS_ENUM_ERROR)
|
||||
PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK);
|
||||
} /* while */
|
||||
|
||||
|
@ -157,19 +155,41 @@ int __PHYSFS_platformMkDir(const char *path)
|
|||
} /* __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)
|
||||
{
|
||||
const int appending = (mode & O_APPEND);
|
||||
int fd;
|
||||
int *retval;
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* O_APPEND doesn't actually behave as we'd like. */
|
||||
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);
|
||||
|
||||
#if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
|
||||
set_CLOEXEC(fd);
|
||||
#endif
|
||||
|
||||
if (appending)
|
||||
{
|
||||
if (lseek(fd, 0, SEEK_END) < 0)
|
||||
|
@ -219,7 +239,9 @@ PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
|
|||
if (!__PHYSFS_ui64FitsAddressSpace(len))
|
||||
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);
|
||||
assert(rc >= 0);
|
||||
assert(rc <= len);
|
||||
|
@ -236,7 +258,9 @@ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
|
|||
if (!__PHYSFS_ui64FitsAddressSpace(len))
|
||||
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);
|
||||
assert(rc >= 0);
|
||||
assert(rc <= len);
|
||||
|
@ -275,8 +299,13 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
|
|||
int __PHYSFS_platformFlush(void *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;
|
||||
} /* __PHYSFS_platformFlush */
|
||||
|
||||
|
@ -284,7 +313,10 @@ int __PHYSFS_platformFlush(void *opaque)
|
|||
void __PHYSFS_platformClose(void *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);
|
||||
} /* __PHYSFS_platformClose */
|
||||
|
||||
|
@ -296,11 +328,11 @@ int __PHYSFS_platformDelete(const char *path)
|
|||
} /* __PHYSFS_platformDelete */
|
||||
|
||||
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
||||
int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st, const int follow)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
BAIL_IF(lstat(filename, &statbuf) == -1, errcodeFromErrno(), 0);
|
||||
const int rc = follow ? stat(fname, &statbuf) : lstat(fname, &statbuf);
|
||||
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
|
||||
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
{
|
||||
|
@ -330,7 +362,7 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
|||
st->createtime = statbuf.st_ctime;
|
||||
st->accesstime = statbuf.st_atime;
|
||||
|
||||
st->readonly = (access(filename, W_OK) == -1);
|
||||
st->readonly = (access(fname, W_OK) == -1);
|
||||
return 1;
|
||||
} /* __PHYSFS_platformStat */
|
||||
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* QNX support routines for PhysicsFS.
|
||||
*
|
||||
* Please see the file LICENSE.txt in the source's root directory.
|
||||
*
|
||||
* This file written by Ryan C. Gordon.
|
||||
*/
|
||||
|
||||
/* This is tested against QNX 7 at the moment. */
|
||||
|
||||
#define __PHYSICSFS_INTERNAL__
|
||||
#include "physfs_platforms.h"
|
||||
|
||||
#ifdef PHYSFS_PLATFORM_QNX
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "physfs_internal.h"
|
||||
|
||||
int __PHYSFS_platformInit(void)
|
||||
{
|
||||
return 1; /* always succeed. */
|
||||
} /* __PHYSFS_platformInit */
|
||||
|
||||
|
||||
void __PHYSFS_platformDeinit(void)
|
||||
{
|
||||
/* no-op */
|
||||
} /* __PHYSFS_platformDeinit */
|
||||
|
||||
|
||||
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
||||
{
|
||||
char *retval = (char *) allocator.Malloc(PATH_MAX+1);
|
||||
if (retval == NULL)
|
||||
BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||
else
|
||||
{
|
||||
const int fd = open("/proc/self/exefile", O_RDONLY);
|
||||
const ssize_t br = (fd == -1) ? -1 : read(fd, retval, PATH_MAX);
|
||||
char *ptr;
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
if ((br < 0) || (br > PATH_MAX))
|
||||
{
|
||||
allocator.Free(retval);
|
||||
BAIL(PHYSFS_ERR_OS_ERROR, NULL);
|
||||
} /* if */
|
||||
|
||||
retval[br] = '\0';
|
||||
ptr = strrchr(retval, '/');
|
||||
if (ptr == NULL) /* uhoh! */
|
||||
{
|
||||
allocator.Free(retval);
|
||||
BAIL(PHYSFS_ERR_OS_ERROR, NULL);
|
||||
} /* if */
|
||||
|
||||
ptr[1] = '\0'; /* chop off filename, leave dirs and '/' */
|
||||
|
||||
ptr = (char *) allocator.Realloc(retval, (ptr - retval) + 2);
|
||||
if (ptr != NULL) /* just shrinking buffer; don't care if it failed. */
|
||||
retval = ptr;
|
||||
} /* else */
|
||||
|
||||
return retval;
|
||||
} /* __PHYSFS_platformCalcBaseDir */
|
||||
|
||||
|
||||
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
||||
{
|
||||
/* !!! FIXME: this might be wrong; I don't know if there's a better method
|
||||
on QNX, or if it follows XDG specs, etc. */
|
||||
char *retval = NULL;
|
||||
const char *home = __PHYSFS_getUserDir();
|
||||
if (home)
|
||||
{
|
||||
const size_t len = strlen(home) + strlen(app) + 3;
|
||||
retval = (char *) allocator.Malloc(len);
|
||||
BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||
snprintf(retval, len, "%s.%s/", home, app);
|
||||
} /* if */
|
||||
return retval;
|
||||
} /* __PHYSFS_platformCalcPrefDir */
|
||||
|
||||
|
||||
#if !PHYSFS_NO_CDROM_SUPPORT
|
||||
#include <devctl.h>
|
||||
#include <sys/dcmd_blk.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
static void checkPathForCD(const char *path, PHYSFS_StringCallback cb, void *d)
|
||||
{
|
||||
struct stat statbuf;
|
||||
int fd;
|
||||
|
||||
/* The devctl() thing is QNX-specific. In this case, we query what is
|
||||
probably the mountpoint for the device. statvfs() on that mountpoint
|
||||
will tell use its filesystem type. */
|
||||
|
||||
if ( (stat(path, &statbuf) == 0) &&
|
||||
(S_ISBLK(statbuf.st_mode)) &&
|
||||
((fd = open(path, O_RDONLY | O_NONBLOCK)) != -1) )
|
||||
{
|
||||
char mnt[256] = { 0 };
|
||||
const int rc = devctl(fd, DCMD_FSYS_MOUNTED_BY, mnt, sizeof (mnt), 0);
|
||||
close(fd);
|
||||
if ( (rc == EOK) && (mnt[0]) )
|
||||
{
|
||||
struct statvfs statvfsbuf;
|
||||
if (statvfs(mnt, &statvfsbuf) == 0)
|
||||
{
|
||||
/* I don't know if this is a complete or accurate list. */
|
||||
const char *fstype = statvfsbuf.f_basetype;
|
||||
const int iscd = ( (strcmp(fstype, "cd") == 0) ||
|
||||
(strcmp(fstype, "udf") == 0) );
|
||||
if (iscd)
|
||||
cb(d, mnt);
|
||||
} /* if */
|
||||
} /* if */
|
||||
} /* if */
|
||||
} /* checkPathForCD */
|
||||
|
||||
static void checkDevForCD(const char *dev, PHYSFS_StringCallback cb, void *d)
|
||||
{
|
||||
size_t len;
|
||||
char *path;
|
||||
|
||||
if (dev[0] == '.') /* ignore "." and ".." */
|
||||
{
|
||||
if ((dev[1] == '\0') || ((dev[1] == '.') && (dev[2] == '\0')))
|
||||
return;
|
||||
} /* if */
|
||||
|
||||
len = strlen(dev) + 6;
|
||||
path = (char *) __PHYSFS_smallAlloc(len);
|
||||
if (!path)
|
||||
return; /* oh well. */
|
||||
|
||||
snprintf(path, len, "/dev/%s", dev);
|
||||
checkPathForCD(path, cb, d);
|
||||
__PHYSFS_smallFree(path);
|
||||
} /* checkDevForCD */
|
||||
#endif /* !PHYSFS_NO_CDROM_SUPPORT */
|
||||
|
||||
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
||||
{
|
||||
#if !PHYSFS_NO_CDROM_SUPPORT
|
||||
DIR *dirp = opendir("/dev");
|
||||
if (dirp)
|
||||
{
|
||||
struct dirent *dent;
|
||||
while ((dent = readdir(dirp)) != NULL)
|
||||
checkDevForCD(dent->d_name, cb, data);
|
||||
closedir(dirp);
|
||||
} /* if */
|
||||
#endif
|
||||
} /* __PHYSFS_platformDetectAvailableCDs */
|
||||
|
||||
#endif /* PHYSFS_PLATFORM_QNX */
|
||||
|
||||
/* end of physfs_platform_qnx.c ... */
|
||||
|
|
@ -57,6 +57,7 @@
|
|||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "physfs_internal.h"
|
||||
|
||||
int __PHYSFS_platformInit(void)
|
||||
|
@ -71,7 +72,6 @@ void __PHYSFS_platformDeinit(void)
|
|||
} /* __PHYSFS_platformDeinit */
|
||||
|
||||
|
||||
/* Stub version for platforms without CD-ROM support. */
|
||||
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
||||
{
|
||||
#if (defined PHYSFS_NO_CDROM_SUPPORT)
|
||||
|
@ -261,12 +261,6 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
|||
if (sysctl(mib, 4, fullpath, &buflen, NULL, 0) != -1)
|
||||
retval = __PHYSFS_strdup(fullpath);
|
||||
}
|
||||
#elif defined(PHYSFS_PLATFORM_SOLARIS)
|
||||
{
|
||||
const char *path = getexecname();
|
||||
if ((path != NULL) && (path[0] == '/')) /* must be absolute path... */
|
||||
retval = __PHYSFS_strdup(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there's a Linux-like /proc filesystem, you can get the full path to
|
||||
|
@ -278,6 +272,7 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
|||
retval = readSymLink("/proc/self/exe");
|
||||
if (!retval) retval = readSymLink("/proc/curproc/file");
|
||||
if (!retval) retval = readSymLink("/proc/curproc/exe");
|
||||
if (!retval) retval = readSymLink("/proc/self/path/a.out");
|
||||
if (retval == NULL)
|
||||
{
|
||||
/* older kernels don't have /proc/self ... try PID version... */
|
||||
|
@ -289,6 +284,15 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
|||
} /* if */
|
||||
} /* if */
|
||||
|
||||
#if defined(PHYSFS_PLATFORM_SOLARIS)
|
||||
if (!retval) /* try getexecname() if /proc didn't pan out. This may not be an absolute path! */
|
||||
{
|
||||
const char *path = getexecname();
|
||||
if ((path != NULL) && (path[0] == '/')) /* must be absolute path... */
|
||||
retval = __PHYSFS_strdup(path);
|
||||
} /* if */
|
||||
#endif
|
||||
|
||||
if (retval != NULL) /* chop off filename. */
|
||||
{
|
||||
char *ptr = strrchr(retval, '/');
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
#define __PHYSICSFS_INTERNAL__
|
||||
#include "physfs_internal.h"
|
||||
#include "physfs_platforms.h"
|
||||
|
||||
#ifdef PHYSFS_PLATFORM_WINDOWS
|
||||
|
||||
|
@ -16,8 +16,9 @@
|
|||
#undef UNICODE
|
||||
#endif
|
||||
|
||||
/* !!! FIXME: maybe clean out the "allocator" macro, eventually. */
|
||||
#undef allocator /* apparently Windows 10 SDK conflicts here. */
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
|
@ -38,7 +39,8 @@
|
|||
#ifdef allocator /* apparently Windows 10 SDK conflicts here. */
|
||||
#undef allocator
|
||||
#endif
|
||||
#define allocator __PHYSFS_AllocatorHooks
|
||||
|
||||
#include "physfs_internal.h"
|
||||
|
||||
/*
|
||||
* Users without the platform SDK don't have this defined. The original docs
|
||||
|
@ -99,7 +101,7 @@ static char *unicodeToUtf8Heap(const WCHAR *w_str)
|
|||
|
||||
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,
|
||||
FindExSearchNameMatch, NULL, 0);
|
||||
#else
|
||||
|
@ -109,7 +111,7 @@ static inline HANDLE winFindFirstFileW(const WCHAR *path, LPWIN32_FIND_DATAW d)
|
|||
|
||||
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);
|
||||
#else
|
||||
InitializeCriticalSection(lpcs);
|
||||
|
@ -121,7 +123,7 @@ static inline HANDLE winCreateFileW(const WCHAR *wfname, const DWORD mode,
|
|||
const DWORD creation)
|
||||
{
|
||||
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);
|
||||
#else
|
||||
return CreateFileW(wfname, mode, share, NULL, creation,
|
||||
|
@ -132,7 +134,7 @@ static inline HANDLE winCreateFileW(const WCHAR *wfname, const DWORD mode,
|
|||
static BOOL winSetFilePointer(HANDLE h, const PHYSFS_sint64 pos,
|
||||
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 linewpos;
|
||||
BOOL rc;
|
||||
|
@ -156,7 +158,7 @@ static BOOL winSetFilePointer(HANDLE h, const PHYSFS_sint64 pos,
|
|||
|
||||
static PHYSFS_sint64 winGetFileSize(HANDLE h)
|
||||
{
|
||||
#ifdef PHYSFS_PLATFORM_WINRT
|
||||
#if defined(PHYSFS_PLATFORM_WINRT) || (_WIN32_WINNT >= 0x0600) // Windows Vista+
|
||||
FILE_STANDARD_INFO info;
|
||||
const BOOL rc = GetFileInformationByHandleEx(h, FileStandardInfo,
|
||||
&info, sizeof (info));
|
||||
|
@ -564,18 +566,26 @@ char *__PHYSFS_platformCalcUserDir(void)
|
|||
else
|
||||
{
|
||||
DWORD psize = 0;
|
||||
WCHAR dummy = 0;
|
||||
LPWSTR wstr = NULL;
|
||||
BOOL rc = 0;
|
||||
|
||||
/*
|
||||
* Should fail. Will write the size of the profile path in
|
||||
* psize. Also note that the second parameter can't be
|
||||
* NULL or the function fails.
|
||||
* NULL or the function fails on Windows XP, but has to be NULL on
|
||||
* Windows 10 or it will fail. :(
|
||||
*/
|
||||
rc = pGetDir(accessToken, &dummy, &psize);
|
||||
rc = pGetDir(accessToken, NULL, &psize);
|
||||
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
|
||||
|
||||
if (psize == 0) /* probably on Windows XP, try a different way. */
|
||||
{
|
||||
WCHAR x = 0;
|
||||
rc = pGetDir(accessToken, &x, &psize);
|
||||
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
|
||||
GOTO_IF(!psize, PHYSFS_ERR_OS_ERROR, done); /* Uhoh... */
|
||||
} /* if */
|
||||
|
||||
/* Allocate memory for the profile directory */
|
||||
wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR));
|
||||
if (wstr != NULL)
|
||||
|
@ -621,20 +631,20 @@ void *__PHYSFS_platformGetThreadID(void)
|
|||
} /* __PHYSFS_platformGetThreadID */
|
||||
|
||||
|
||||
int __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
|
||||
PHYSFS_EnumerateCallback callback,
|
||||
const char *origdir, void *callbackdata)
|
||||
{
|
||||
PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK;
|
||||
HANDLE dir = INVALID_HANDLE_VALUE;
|
||||
WIN32_FIND_DATAW entw;
|
||||
size_t len = strlen(dirname);
|
||||
char *searchPath = NULL;
|
||||
WCHAR *wSearchPath = NULL;
|
||||
int retval = 1;
|
||||
|
||||
/* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
|
||||
searchPath = (char *) __PHYSFS_smallAlloc(len + 3);
|
||||
BAIL_IF(!searchPath, PHYSFS_ERR_OUT_OF_MEMORY, -1);
|
||||
BAIL_IF(!searchPath, PHYSFS_ERR_OUT_OF_MEMORY, PHYSFS_ENUM_ERROR);
|
||||
|
||||
/* Copy current dirname */
|
||||
strcpy(searchPath, dirname);
|
||||
|
@ -651,11 +661,11 @@ int __PHYSFS_platformEnumerate(const char *dirname,
|
|||
|
||||
UTF8_TO_UNICODE_STACK(wSearchPath, searchPath);
|
||||
__PHYSFS_smallFree(searchPath);
|
||||
BAIL_IF_ERRPASS(!wSearchPath, -1);
|
||||
BAIL_IF_ERRPASS(!wSearchPath, PHYSFS_ENUM_ERROR);
|
||||
|
||||
dir = winFindFirstFileW(wSearchPath, &entw);
|
||||
__PHYSFS_smallFree(wSearchPath);
|
||||
BAIL_IF(dir == INVALID_HANDLE_VALUE, errcodeFromWinApi(), -1);
|
||||
BAIL_IF(dir==INVALID_HANDLE_VALUE, errcodeFromWinApi(), PHYSFS_ENUM_ERROR);
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -675,10 +685,10 @@ int __PHYSFS_platformEnumerate(const char *dirname,
|
|||
{
|
||||
retval = callback(callbackdata, origdir, utf8);
|
||||
allocator.Free(utf8);
|
||||
if (retval == -1)
|
||||
if (retval == PHYSFS_ENUM_ERROR)
|
||||
PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK);
|
||||
} /* else */
|
||||
} while ((retval == 1) && (FindNextFileW(dir, &entw) != 0));
|
||||
} while ((retval == PHYSFS_ENUM_OK) && (FindNextFileW(dir, &entw) != 0));
|
||||
|
||||
FindClose(dir);
|
||||
|
||||
|
@ -958,7 +968,7 @@ static int isSymlink(const WCHAR *wpath, const DWORD attr)
|
|||
} /* isSymlink */
|
||||
|
||||
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
||||
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st, const int follow)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA winstat;
|
||||
WCHAR *wstr = NULL;
|
||||
|
@ -973,7 +983,7 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
|
|||
if (!rc)
|
||||
err = GetLastError();
|
||||
else /* check for symlink while wstr is still available */
|
||||
issymlink = isSymlink(wstr, winstat.dwFileAttributes);
|
||||
issymlink = !follow && isSymlink(wstr, winstat.dwFileAttributes);
|
||||
|
||||
__PHYSFS_smallFree(wstr);
|
||||
BAIL_IF(!rc, errcodeFromWinApiError(err), 0);
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
#ifdef PHYSFS_PLATFORM_WINRT
|
||||
|
||||
#include "physfs_internal.h"
|
||||
|
||||
/* !!! FIXME: maybe clean out the "allocator" macro, eventually. */
|
||||
#undef allocator /* apparently Windows 10 SDK conflicts here. */
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include "physfs_internal.h"
|
||||
|
||||
const void *__PHYSFS_winrtCalcBaseDir(void)
|
||||
{
|
||||
return Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
|
||||
|
|
|
@ -40,11 +40,11 @@
|
|||
# define PHYSFS_PLATFORM_POSIX 1
|
||||
#elif defined(macintosh)
|
||||
# error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
|
||||
#elif defined(ANDROID)
|
||||
# define PHYSFS_PLATFORM_LINUX 1
|
||||
# define PHYSFS_PLATFORM_UNIX 1
|
||||
# define PHYSFS_PLATFORM_POSIX 1
|
||||
# define PHYSFS_NO_CDROM_SUPPORT 1
|
||||
#elif defined(__ANDROID__)
|
||||
# define PHYSFS_PLATFORM_LINUX 1
|
||||
# define PHYSFS_PLATFORM_ANDROID 1
|
||||
# define PHYSFS_PLATFORM_POSIX 1
|
||||
# define PHYSFS_NO_CDROM_SUPPORT 1
|
||||
#elif defined(__linux)
|
||||
# define PHYSFS_PLATFORM_LINUX 1
|
||||
# define PHYSFS_PLATFORM_UNIX 1
|
||||
|
@ -67,9 +67,7 @@
|
|||
# define PHYSFS_PLATFORM_UNIX 1
|
||||
# define PHYSFS_PLATFORM_POSIX 1
|
||||
#elif defined(__QNX__)
|
||||
# define PHYSFS_NO_CDROM_SUPPORT 1 /* !!! FIXME? */
|
||||
# define PHYSFS_PLATFORM_QNX 1
|
||||
# define PHYSFS_PLATFORM_UNIX 1
|
||||
# define PHYSFS_PLATFORM_POSIX 1
|
||||
#elif defined(unix) || defined(__unix__)
|
||||
# define PHYSFS_PLATFORM_UNIX 1
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
/*
|
||||
* 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
|
||||
* 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,
|
||||
* whereas utf8valid() will use the value to determine if a string has bad
|
||||
* bits.
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
#define UNICODE_BOGUS_CHAR_CODEPOINT '?'
|
||||
|
||||
static PHYSFS_uint32 utf8codepoint(const char **_str)
|
||||
PHYSFS_uint32 __PHYSFS_utf8codepoint(const char **_str)
|
||||
{
|
||||
const char *str = *_str;
|
||||
PHYSFS_uint32 retval = 0;
|
||||
|
@ -188,15 +188,62 @@ static PHYSFS_uint32 utf8codepoint(const char **_str)
|
|||
} /* else if */
|
||||
|
||||
return UNICODE_BOGUS_CHAR_VALUE;
|
||||
} /* __PHYSFS_utf8codepoint */
|
||||
|
||||
static inline PHYSFS_uint32 utf8codepoint(const char **_str)
|
||||
{
|
||||
return __PHYSFS_utf8codepoint(_str);
|
||||
} /* utf8codepoint */
|
||||
|
||||
static PHYSFS_uint32 utf16codepoint(const PHYSFS_uint16 **_str)
|
||||
{
|
||||
const PHYSFS_uint16 *src = *_str;
|
||||
PHYSFS_uint32 cp = (PHYSFS_uint32) *(src++);
|
||||
|
||||
if (cp == 0) /* null terminator, end of string. */
|
||||
return 0;
|
||||
/* Orphaned second half of surrogate pair? */
|
||||
else if ((cp >= 0xDC00) && (cp <= 0xDFFF))
|
||||
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||
else if ((cp >= 0xD800) && (cp <= 0xDBFF)) /* start surrogate pair! */
|
||||
{
|
||||
const PHYSFS_uint32 pair = (PHYSFS_uint32) *src;
|
||||
if (pair == 0)
|
||||
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||
else if ((pair < 0xDC00) || (pair > 0xDFFF))
|
||||
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||
else
|
||||
{
|
||||
src++; /* eat the other surrogate. */
|
||||
cp = 0x10000 + (((cp - 0xD800) << 10) | (pair - 0xDC00));
|
||||
} /* else */
|
||||
} /* else if */
|
||||
|
||||
*_str = src;
|
||||
return cp;
|
||||
} /* utf16codepoint */
|
||||
|
||||
static PHYSFS_uint32 utf32codepoint(const PHYSFS_uint32 **_str)
|
||||
{
|
||||
const PHYSFS_uint32 *src = *_str;
|
||||
PHYSFS_uint32 cp = *(src++);
|
||||
|
||||
if (cp == 0) /* null terminator, end of string. */
|
||||
return 0;
|
||||
else if (cp > 0x10FFF)
|
||||
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||
|
||||
*_str = src;
|
||||
return cp;
|
||||
} /* utf32codepoint */
|
||||
|
||||
|
||||
void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
|
||||
{
|
||||
len -= sizeof (PHYSFS_uint32); /* save room for null char. */
|
||||
while (len >= sizeof (PHYSFS_uint32))
|
||||
{
|
||||
PHYSFS_uint32 cp = utf8codepoint(&src);
|
||||
PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&src);
|
||||
if (cp == 0)
|
||||
break;
|
||||
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
|
||||
|
@ -214,7 +261,7 @@ void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
|||
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
|
||||
while (len >= sizeof (PHYSFS_uint16))
|
||||
{
|
||||
PHYSFS_uint32 cp = utf8codepoint(&src);
|
||||
PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&src);
|
||||
if (cp == 0)
|
||||
break;
|
||||
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
|
||||
|
@ -236,7 +283,7 @@ void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
|||
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
|
||||
while (len >= sizeof (PHYSFS_uint16))
|
||||
{
|
||||
PHYSFS_uint32 cp = utf8codepoint(&src);
|
||||
PHYSFS_uint32 cp = __PHYSFS_utf8codepoint(&src);
|
||||
if (cp == 0)
|
||||
break;
|
||||
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
|
||||
|
@ -378,25 +425,9 @@ void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len
|
|||
len--;
|
||||
while (len)
|
||||
{
|
||||
PHYSFS_uint32 cp = (PHYSFS_uint32) *(src++);
|
||||
if (cp == 0)
|
||||
const PHYSFS_uint32 cp = utf16codepoint(&src);
|
||||
if (!cp)
|
||||
break;
|
||||
|
||||
/* Orphaned second half of surrogate pair? */
|
||||
if ((cp >= 0xDC00) && (cp <= 0xDFFF))
|
||||
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||
else if ((cp >= 0xD800) && (cp <= 0xDBFF)) /* start surrogate pair! */
|
||||
{
|
||||
const PHYSFS_uint32 pair = (PHYSFS_uint32) *src;
|
||||
if ((pair < 0xDC00) || (pair > 0xDFFF))
|
||||
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||
else
|
||||
{
|
||||
src++; /* eat the other surrogate. */
|
||||
cp = (((cp - 0xD800) << 10) | (pair - 0xDC00));
|
||||
} /* else */
|
||||
} /* else if */
|
||||
|
||||
utf8fromcodepoint(cp, &dst, &len);
|
||||
} /* while */
|
||||
|
||||
|
@ -404,8 +435,7 @@ void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len
|
|||
} /* PHYSFS_utf8FromUtf16 */
|
||||
|
||||
|
||||
/* (to) should point to at least 3 PHYSFS_uint32 slots. */
|
||||
static int locate_casefold_mapping(const PHYSFS_uint32 from, PHYSFS_uint32 *to)
|
||||
int PHYSFS_caseFold(const PHYSFS_uint32 from, PHYSFS_uint32 *to)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -489,49 +519,54 @@ static int locate_casefold_mapping(const PHYSFS_uint32 from, PHYSFS_uint32 *to)
|
|||
/* Not found...there's no remapping for this codepoint. */
|
||||
*to = from;
|
||||
return 1;
|
||||
} /* locate_casefold_mapping */
|
||||
} /* PHYSFS_caseFold */
|
||||
|
||||
|
||||
#define UTFSTRICMP(bits) \
|
||||
PHYSFS_uint32 folded1[3], folded2[3]; \
|
||||
int head1 = 0, tail1 = 0, head2 = 0, tail2 = 0; \
|
||||
while (1) { \
|
||||
PHYSFS_uint32 cp1, cp2; \
|
||||
if (head1 != tail1) { \
|
||||
cp1 = folded1[tail1++]; \
|
||||
} else { \
|
||||
head1 = PHYSFS_caseFold(utf##bits##codepoint(&str1), folded1); \
|
||||
cp1 = folded1[0]; \
|
||||
tail1 = 1; \
|
||||
} \
|
||||
if (head2 != tail2) { \
|
||||
cp2 = folded2[tail2++]; \
|
||||
} else { \
|
||||
head2 = PHYSFS_caseFold(utf##bits##codepoint(&str2), folded2); \
|
||||
cp2 = folded2[0]; \
|
||||
tail2 = 1; \
|
||||
} \
|
||||
if (cp1 < cp2) { \
|
||||
return -1; \
|
||||
} else if (cp1 > cp2) { \
|
||||
return 1; \
|
||||
} else if (cp1 == 0) { \
|
||||
break; /* complete match. */ \
|
||||
} \
|
||||
} \
|
||||
return 0
|
||||
|
||||
int PHYSFS_utf8stricmp(const char *str1, const char *str2)
|
||||
{
|
||||
PHYSFS_uint32 folded1[3], folded2[3];
|
||||
int head1 = 0;
|
||||
int tail1 = 0;
|
||||
int head2 = 0;
|
||||
int tail2 = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
PHYSFS_uint32 cp1, cp2;
|
||||
|
||||
if (head1 != tail1)
|
||||
cp1 = folded1[tail1++];
|
||||
else
|
||||
{
|
||||
head1 = locate_casefold_mapping(utf8codepoint(&str1), folded1);
|
||||
cp1 = folded1[0];
|
||||
tail1 = 1;
|
||||
} /* else */
|
||||
|
||||
if (head2 != tail2)
|
||||
cp2 = folded2[tail2++];
|
||||
else
|
||||
{
|
||||
head2 = locate_casefold_mapping(utf8codepoint(&str2), folded2);
|
||||
cp2 = folded2[0];
|
||||
tail2 = 1;
|
||||
} /* else */
|
||||
|
||||
if (cp1 < cp2)
|
||||
return -1;
|
||||
else if (cp1 > cp2)
|
||||
return 1;
|
||||
else if (cp1 == 0)
|
||||
break; /* complete match. */
|
||||
} /* while */
|
||||
|
||||
return 0;
|
||||
UTFSTRICMP(8);
|
||||
} /* PHYSFS_utf8stricmp */
|
||||
|
||||
int PHYSFS_utf16stricmp(const PHYSFS_uint16 *str1, const PHYSFS_uint16 *str2)
|
||||
{
|
||||
UTFSTRICMP(16);
|
||||
} /* PHYSFS_utf16stricmp */
|
||||
|
||||
int PHYSFS_ucs4stricmp(const PHYSFS_uint32 *str1, const PHYSFS_uint32 *str2)
|
||||
{
|
||||
UTFSTRICMP(32);
|
||||
} /* PHYSFS_ucs4stricmp */
|
||||
|
||||
#undef UTFSTRICMP
|
||||
|
||||
/* end of physfs_unicode.c ... */
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#include "physfs.h"
|
||||
|
||||
#define TEST_VERSION_MAJOR 2
|
||||
#define TEST_VERSION_MINOR 1
|
||||
#define TEST_VERSION_MAJOR 3
|
||||
#define TEST_VERSION_MINOR 3
|
||||
#define TEST_VERSION_PATCH 0
|
||||
|
||||
static FILE *history_file = NULL;
|
||||
|
@ -288,6 +288,53 @@ static int cmd_getmountpoint(char *args)
|
|||
return 1;
|
||||
} /* cmd_getmountpoint */
|
||||
|
||||
|
||||
static int cmd_setroot(char *args)
|
||||
{
|
||||
char *archive;
|
||||
char *subdir;
|
||||
char *ptr;
|
||||
|
||||
archive = args;
|
||||
if (*archive == '\"')
|
||||
{
|
||||
archive++;
|
||||
ptr = strchr(archive, '\"');
|
||||
if (ptr == NULL)
|
||||
{
|
||||
printf("missing string terminator in argument.\n");
|
||||
return 1;
|
||||
} /* if */
|
||||
*(ptr) = '\0';
|
||||
} /* if */
|
||||
else
|
||||
{
|
||||
ptr = strchr(archive, ' ');
|
||||
*ptr = '\0';
|
||||
} /* else */
|
||||
|
||||
subdir = ptr + 1;
|
||||
if (*subdir == '\"')
|
||||
{
|
||||
subdir++;
|
||||
ptr = strchr(subdir, '\"');
|
||||
if (ptr == NULL)
|
||||
{
|
||||
printf("missing string terminator in argument.\n");
|
||||
return 1;
|
||||
} /* if */
|
||||
*(ptr) = '\0';
|
||||
} /* if */
|
||||
|
||||
if (PHYSFS_setRoot(archive, subdir))
|
||||
printf("Successful.\n");
|
||||
else
|
||||
printf("Failure. reason: %s.\n", PHYSFS_getLastError());
|
||||
|
||||
return 1;
|
||||
} /* cmd_setroot */
|
||||
|
||||
|
||||
static int cmd_removearchive(char *args)
|
||||
{
|
||||
if (*args == '\"')
|
||||
|
@ -1340,6 +1387,7 @@ static const command_info commands[] =
|
|||
{ "stressbuffer", cmd_stressbuffer, 1, "<bufferSize>" },
|
||||
{ "crc32", cmd_crc32, 1, "<fileToHash>" },
|
||||
{ "getmountpoint", cmd_getmountpoint, 1, "<dir>" },
|
||||
{ "setroot", cmd_setroot, 2, "<archiveLocation> <root>" },
|
||||
{ NULL, NULL, -1, NULL }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue