Compare commits
84 Commits
main
...
stable-1.0
Author | SHA1 | Date |
---|---|---|
Ryan C. Gordon | 15073ad63f | |
Ryan C. Gordon | c65c196152 | |
Ryan C. Gordon | 77f939cb43 | |
Ryan C. Gordon | cdbd264cb4 | |
Ryan C. Gordon | e095ee4303 | |
Ryan C. Gordon | 9977f5c9b4 | |
Ryan C. Gordon | 0ba88e4714 | |
Ryan C. Gordon | 8ae1b528a0 | |
Ryan C. Gordon | 1921be0ddf | |
Ryan C. Gordon | 08a15ea0c6 | |
Ryan C. Gordon | 5a07f78897 | |
Ryan C. Gordon | 205a7d3e63 | |
Ryan C. Gordon | ef63e223c3 | |
Ryan C. Gordon | 7888c05d4d | |
Ryan C. Gordon | 5db500ac4e | |
Ryan C. Gordon | 8ff89ca115 | |
Ryan C. Gordon | c973e5a46b | |
Ryan C. Gordon | ea1b848580 | |
Ryan C. Gordon | 6667d42c31 | |
Ryan C. Gordon | 0314ea857b | |
Ryan C. Gordon | b35a36ddaa | |
Ryan C. Gordon | 87aeb4dd16 | |
Ryan C. Gordon | 836c941bc7 | |
Ryan C. Gordon | 552769be6b | |
Ryan C. Gordon | d407ca2266 | |
Ryan C. Gordon | 2470672852 | |
Ryan C. Gordon | 42eb0768d5 | |
Ryan C. Gordon | ab4e94c49e | |
Ryan C. Gordon | f1ba7f8112 | |
Ryan C. Gordon | 27d1a25b24 | |
Ryan C. Gordon | c14984f70e | |
Ryan C. Gordon | 32fb2ab4a9 | |
Ryan C. Gordon | 0e720678af | |
Ryan C. Gordon | 81d6df6972 | |
Ryan C. Gordon | aee6bd359e | |
Ryan C. Gordon | 0abf1d7584 | |
Ryan C. Gordon | 6ec1239122 | |
Ryan C. Gordon | 9c8f5312de | |
Ryan C. Gordon | be12a5bdc5 | |
Ryan C. Gordon | 782bb8a06f | |
Ryan C. Gordon | 8d1003ce7f | |
Ryan C. Gordon | 87f7eb152a | |
Ryan C. Gordon | fc6d85b2f4 | |
Ryan C. Gordon | 625e8e8f87 | |
Ryan C. Gordon | 785d617e74 | |
Ryan C. Gordon | bc14217e36 | |
Ryan C. Gordon | 994e62e5f2 | |
Ryan C. Gordon | cbf1dc67f3 | |
Ryan C. Gordon | 0d9f7c7b8a | |
Ryan C. Gordon | c08f79715b | |
Ryan C. Gordon | cf12ff2b96 | |
Ryan C. Gordon | 57b48ae7f6 | |
Ryan C. Gordon | f71362cbb7 | |
Ryan C. Gordon | 7130cea2bf | |
Ryan C. Gordon | 33ce47743f | |
Ryan C. Gordon | 7840ae68a6 | |
Ryan C. Gordon | 69d796fc7b | |
Ryan C. Gordon | a2ca51373c | |
Ryan C. Gordon | caf1c499be | |
Ryan C. Gordon | 14993f806e | |
Ryan C. Gordon | 55c8465eeb | |
Ryan C. Gordon | 8593f1484e | |
Ryan C. Gordon | f5195696b6 | |
Ryan C. Gordon | 661a359586 | |
Ryan C. Gordon | 481f85a91c | |
Ryan C. Gordon | 5e0de7cc73 | |
Ryan C. Gordon | 1affc74230 | |
Ryan C. Gordon | 092abfdeda | |
Ryan C. Gordon | 68f832b9f7 | |
Ryan C. Gordon | 12353f5346 | |
Ryan C. Gordon | 804d364506 | |
Ryan C. Gordon | e7a9d06206 | |
Ryan C. Gordon | cd065471c8 | |
Ryan C. Gordon | ab1fd8a763 | |
Ryan C. Gordon | 73fc0593bf | |
Ryan C. Gordon | df02d9722d | |
Ryan C. Gordon | a63b842e24 | |
Ryan C. Gordon | 791d52465c | |
Ryan C. Gordon | 4b036dc0a2 | |
Ryan C. Gordon | c5bf5c15d7 | |
Ryan C. Gordon | 7521634ee6 | |
Ryan C. Gordon | 58fac19bb4 | |
Ryan C. Gordon | 969bf3d341 | |
Ryan C. Gordon | c495f050e6 |
|
@ -1,2 +0,0 @@
|
||||||
github: [icculus]
|
|
||||||
patreon: icculus
|
|
|
@ -1,30 +0,0 @@
|
||||||
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/
|
|
|
@ -1,20 +0,0 @@
|
||||||
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
|
cmake-build
|
||||||
|
|
|
@ -6,6 +6,5 @@ The changelog is no longer maintained by hand. It made sense to have a single
|
||||||
If you want a list of changes, updated in real time, just point your web
|
If you want a list of changes, updated in real time, just point your web
|
||||||
browser here:
|
browser here:
|
||||||
|
|
||||||
https://github.com/icculus/physfs/commits/
|
http://hg.icculus.org/icculus/physfs/
|
||||||
|
|
||||||
|
|
345
CMakeLists.txt
345
CMakeLists.txt
|
@ -1,345 +0,0 @@
|
||||||
# PhysicsFS; a portable, flexible file i/o abstraction.
|
|
||||||
#
|
|
||||||
# Please see the file LICENSE.txt in the source's root directory.
|
|
||||||
|
|
||||||
# The CMake project file is meant to get this compiling on all sorts of
|
|
||||||
# platforms quickly, and serve as the way Unix platforms and Linux distros
|
|
||||||
# package up official builds, but you don't _need_ to use this; we have
|
|
||||||
# built PhysicsFS to (hopefully) be able to drop into your project and
|
|
||||||
# compile, using preprocessor checks for platform-specific bits instead of
|
|
||||||
# testing in here.
|
|
||||||
|
|
||||||
set(PHYSFS_VERSION 3.3.0)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
set(PHYSFS_M_SRCS)
|
|
||||||
set(PHYSFS_CPP_SRCS)
|
|
||||||
|
|
||||||
# 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")
|
|
||||||
list(APPEND PHYSFS_M_SRCS src/physfs_platform_apple.m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "SunPro")
|
|
||||||
add_definitions(-erroff=E_EMPTY_TRANSLATION_UNIT)
|
|
||||||
add_definitions(-xldscope=hidden)
|
|
||||||
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.
|
|
||||||
list(APPEND PHYSFS_CPP_SRCS src/physfs_platform_haiku.cpp)
|
|
||||||
find_library(BE_LIBRARY be)
|
|
||||||
find_library(ROOT_LIBRARY root)
|
|
||||||
list(APPEND OPTIONAL_LIBRARY_LIBS ${BE_LIBRARY} ${ROOT_LIBRARY})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" OR CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
|
|
||||||
set(WINRT TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WINRT)
|
|
||||||
list(APPEND PHYSFS_CPP_SRCS src/physfs_platform_winrt.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
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
|
|
||||||
# code and #define the things you want.
|
|
||||||
set(PHYSFS_SRCS
|
|
||||||
src/physfs.c
|
|
||||||
src/physfs_byteorder.c
|
|
||||||
src/physfs_unicode.c
|
|
||||||
src/physfs_platform_posix.c
|
|
||||||
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
|
|
||||||
src/physfs_archiver_hog.c
|
|
||||||
src/physfs_archiver_7z.c
|
|
||||||
src/physfs_archiver_mvl.c
|
|
||||||
src/physfs_archiver_qpak.c
|
|
||||||
src/physfs_archiver_wad.c
|
|
||||||
src/physfs_archiver_zip.c
|
|
||||||
src/physfs_archiver_slb.c
|
|
||||||
src/physfs_archiver_iso9660.c
|
|
||||||
src/physfs_archiver_vdf.c
|
|
||||||
${PHYSFS_CPP_SRCS}
|
|
||||||
${PHYSFS_M_SRCS}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Archivers ...
|
|
||||||
# These are (mostly) on by default now, so these options are only useful for
|
|
||||||
# disabling them.
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_ZIP "Enable ZIP support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_ZIP)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_ZIP=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_7Z "Enable 7zip support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_7Z)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_7Z=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_GRP "Enable Build Engine GRP support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_GRP)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_GRP=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_WAD "Enable Doom WAD support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_WAD)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_WAD=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_HOG)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_HOG=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_MVL "Enable Descent I/II MVL support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_MVL)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_MVL=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_QPAK "Enable Quake I/II QPAK support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_QPAK)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_QPAK=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_SLB "Enable I-War / Independence War SLB support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_SLB)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_SLB=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_ISO9660 "Enable ISO9660 support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_ISO9660)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_ISO9660=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_ARCHIVE_VDF "Enable Gothic I/II VDF archive support" TRUE)
|
|
||||||
if(NOT PHYSFS_ARCHIVE_VDF)
|
|
||||||
add_definitions(-DPHYSFS_SUPPORTS_VDF=0)
|
|
||||||
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 MSVC)
|
|
||||||
set_target_properties(physfs-static PROPERTIES OUTPUT_NAME "physfs")
|
|
||||||
endif()
|
|
||||||
if(WINRT)
|
|
||||||
# Ignore LNK4264 warnings; we don't author any WinRT components, just consume them, so we're okay in a static library.
|
|
||||||
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)
|
|
||||||
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()
|
|
||||||
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)
|
|
||||||
list(APPEND PHYSFS_INSTALL_TARGETS "physfs")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
|
|
||||||
message(FATAL "Both shared and static libraries are disabled!")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# CMake FAQ says I need this...
|
|
||||||
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()
|
|
||||||
|
|
||||||
option(PHYSFS_BUILD_TEST "Build stdio test program." TRUE)
|
|
||||||
mark_as_advanced(PHYSFS_BUILD_TEST)
|
|
||||||
if(PHYSFS_BUILD_TEST)
|
|
||||||
find_path(READLINE_H readline/readline.h)
|
|
||||||
find_path(HISTORY_H readline/history.h)
|
|
||||||
if(READLINE_H AND HISTORY_H)
|
|
||||||
find_library(CURSES_LIBRARY NAMES curses ncurses)
|
|
||||||
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 PRIVATE ${PHYSFS_LIB_TARGET} ${TEST_PHYSFS_LIBS} ${OTHER_LDFLAGS})
|
|
||||||
list(APPEND PHYSFS_INSTALL_TARGETS test_physfs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(PHYSFS_DISABLE_INSTALL "Disable installing PhysFS" OFF)
|
|
||||||
if(NOT PHYSFS_DISABLE_INSTALL)
|
|
||||||
|
|
||||||
install(TARGETS ${PHYSFS_INSTALL_TARGETS} EXPORT PhysFSExport
|
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
||||||
install(FILES src/physfs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
||||||
|
|
||||||
install(EXPORT PhysFSExport
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PhysFS"
|
|
||||||
FILE PhysFSConfig.cmake
|
|
||||||
NAMESPACE PhysFS::
|
|
||||||
)
|
|
||||||
|
|
||||||
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.gz")
|
|
||||||
|
|
||||||
set(PHYSFS_TARGETNAME_DIST "dist" CACHE STRING "Name of 'dist' build target")
|
|
||||||
add_custom_target(
|
|
||||||
${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(
|
|
||||||
${PHYSFS_TARGETNAME_UNINSTALL}
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/extras/uninstall.sh"
|
|
||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
||||||
COMMENT "Uninstall the project..."
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
macro(message_bool_option _NAME _VALUE)
|
|
||||||
if(${_VALUE})
|
|
||||||
message(STATUS " ${_NAME}: enabled")
|
|
||||||
else()
|
|
||||||
message(STATUS " ${_NAME}: disabled")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
message(STATUS "PhysicsFS will build with the following options:")
|
|
||||||
message_bool_option("ZIP support" PHYSFS_ARCHIVE_ZIP)
|
|
||||||
message_bool_option("7zip support" PHYSFS_ARCHIVE_7Z)
|
|
||||||
message_bool_option("GRP support" PHYSFS_ARCHIVE_GRP)
|
|
||||||
message_bool_option("WAD support" PHYSFS_ARCHIVE_WAD)
|
|
||||||
message_bool_option("HOG support" PHYSFS_ARCHIVE_HOG)
|
|
||||||
message_bool_option("MVL support" PHYSFS_ARCHIVE_MVL)
|
|
||||||
message_bool_option("QPAK support" PHYSFS_ARCHIVE_QPAK)
|
|
||||||
message_bool_option("SLB support" PHYSFS_ARCHIVE_SLB)
|
|
||||||
message_bool_option("VDF support" PHYSFS_ARCHIVE_VDF)
|
|
||||||
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 ...
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
Initial API interface and implementation,
|
||||||
|
Unix support,
|
||||||
|
Win32 support,
|
||||||
|
BeOS support,
|
||||||
|
POSIX support,
|
||||||
|
OS/2 support,
|
||||||
|
GRP archiver,
|
||||||
|
DIR archiver,
|
||||||
|
ZIP archiver,
|
||||||
|
QPAK archiver,
|
||||||
|
MacOS Classic support:
|
||||||
|
Ryan C. Gordon
|
||||||
|
|
||||||
|
Tons of win32 help:
|
||||||
|
Adam Gates
|
||||||
|
|
||||||
|
More win32 hacking:
|
||||||
|
Gregory S. Read
|
||||||
|
|
||||||
|
Fixes for missing current working directories,
|
||||||
|
PHYSFS_setSaneConfig() improvements,
|
||||||
|
other bugfixes:
|
||||||
|
David Hedbor
|
||||||
|
|
||||||
|
Darwin support:
|
||||||
|
Patrick Stein
|
||||||
|
|
||||||
|
configure fixes,
|
||||||
|
RPM specfile:
|
||||||
|
Edward Rudd
|
||||||
|
|
||||||
|
GetLastModTime API,
|
||||||
|
other stuff:
|
||||||
|
John R. Hall
|
||||||
|
|
||||||
|
Various support, fixes and suggestions:
|
||||||
|
Alexander Pipelka
|
||||||
|
|
||||||
|
Russian translation,
|
||||||
|
Ruby bindings,
|
||||||
|
QPAK archiver:
|
||||||
|
Ed Sinjiashvili
|
||||||
|
|
||||||
|
French translation:
|
||||||
|
Stéphane Peter
|
||||||
|
|
||||||
|
Debian package support:
|
||||||
|
Colin Bayer
|
||||||
|
|
||||||
|
"abs-file.h" in "extras" dir:
|
||||||
|
Adam D. Moss
|
||||||
|
|
||||||
|
WinCE port and other Win32 patches:
|
||||||
|
Corona688
|
||||||
|
|
||||||
|
German translation:
|
||||||
|
Michael Renner
|
||||||
|
|
||||||
|
Apple Project Builder support,
|
||||||
|
MacOS X improvements:
|
||||||
|
Eric Wing
|
||||||
|
|
||||||
|
HOG archiver,
|
||||||
|
MVL archiver,
|
||||||
|
Bradley Bell
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
Tolga Dalman
|
||||||
|
|
||||||
|
Brazillian Portuguese translation:
|
||||||
|
Danny Angelo Carminati Grein
|
||||||
|
|
||||||
|
Spanish translation:
|
||||||
|
Pedro J. Pérez
|
||||||
|
|
||||||
|
Mingw support:
|
||||||
|
Matze Braun
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
Jörg Walter
|
||||||
|
James Haley
|
||||||
|
|
||||||
|
Windows .rc file:
|
||||||
|
Dennis Schridde
|
||||||
|
|
||||||
|
Other stuff:
|
||||||
|
Your name here! Patches go to icculus@icculus.org ...
|
||||||
|
|
||||||
|
/* end of CREDITS ... */
|
||||||
|
|
Binary file not shown.
|
@ -23,8 +23,7 @@ PROJECT_NAME = physfs
|
||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
# (CMake will set this properly at build time. --ryan.)
|
PROJECT_NUMBER = 1.0.2
|
||||||
PROJECT_NUMBER = "unknown version (build with 'make docs' next time!)"
|
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
@ -362,7 +361,7 @@ WARN_LOGFILE =
|
||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# with spaces.
|
||||||
|
|
||||||
INPUT = src/physfs.h
|
INPUT = physfs.h
|
||||||
|
|
||||||
# If the value of the INPUT tag contains directories, you can use the
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||||
|
@ -877,8 +876,7 @@ INCLUDE_FILE_PATTERNS =
|
||||||
# omitted =1 is assumed.
|
# omitted =1 is assumed.
|
||||||
|
|
||||||
PREDEFINED = DOXYGEN_SHOULD_IGNORE_THIS=1 \
|
PREDEFINED = DOXYGEN_SHOULD_IGNORE_THIS=1 \
|
||||||
PHYSFS_DECL= \
|
__EXPORT__=
|
||||||
PHYSFS_DEPRECATED=
|
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||||
# this tag can be used to specify a list of macro names that should be expanded.
|
# this tag can be used to specify a list of macro names that should be expanded.
|
|
@ -0,0 +1,133 @@
|
||||||
|
|
||||||
|
The latest PhysicsFS information and releases can be found at:
|
||||||
|
http://icculus.org/physfs/
|
||||||
|
|
||||||
|
Building is (ahem) very easy.
|
||||||
|
|
||||||
|
|
||||||
|
ALL PLATFORMS:
|
||||||
|
|
||||||
|
Please understand your rights and mine: read the text file LICENSE in the root
|
||||||
|
of the source tree. If you can't abide by it, delete this source tree now.
|
||||||
|
|
||||||
|
If you've got Doxygen (http://www.doxygen.org/) installed, you can run it
|
||||||
|
without any command line arguments in the root of the source tree to generate
|
||||||
|
the API reference. This is optional. You can browse the API docs online
|
||||||
|
here: http://icculus.org/physfs/docs/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UNIX:
|
||||||
|
(If you got this code from Mercurial, run "./bootstrap" first.)
|
||||||
|
|
||||||
|
Run ./configure --help and see what features can be optionally enabled or
|
||||||
|
disabled. "./configure" does its best to pick optimal defaults for your
|
||||||
|
platform.
|
||||||
|
|
||||||
|
Run "make".
|
||||||
|
As root, run "make install".
|
||||||
|
If you get sick of the library, run "make uninstall" as root and it will
|
||||||
|
remove all traces of the library from the system paths.
|
||||||
|
|
||||||
|
Primary Unix development is done with GNU/Linux, but PhysicsFS is known to
|
||||||
|
work out of the box with several flavors of Unix. It it doesn't work, patches
|
||||||
|
to get it running can be sent to icculus@icculus.org.
|
||||||
|
|
||||||
|
|
||||||
|
BeOS:
|
||||||
|
Use the "Unix" instructions, above.
|
||||||
|
|
||||||
|
|
||||||
|
AtheOS:
|
||||||
|
Use the "Unix" instructions, above.
|
||||||
|
|
||||||
|
|
||||||
|
WIN32:
|
||||||
|
If building with CygWin, mingw32 or something else that uses the GNU
|
||||||
|
toolchain, follow the Unix instructions, above.
|
||||||
|
|
||||||
|
If you're using Visual C++ 6, point it at "physfs.dsp" in the root of the
|
||||||
|
source tree, and build. This will produce a "physfs.dll" and "physfs.lib"
|
||||||
|
(shared library and import lib, respectively) in either a "Debug" or
|
||||||
|
"Release" directory, depending on what configuration you chose to build.
|
||||||
|
After building the lib, you can make sure it works by building the
|
||||||
|
"test_physfs.dsp" project file, which will create "test_physfs.exe" in
|
||||||
|
"Debug" or "Release". This EXE is linked against the DLL you built
|
||||||
|
previously.
|
||||||
|
|
||||||
|
If you're using Visual C++ 6 and want to generate a static LIB file, point
|
||||||
|
it at "physfs_static.dsp" in the root of the source tree and build. This
|
||||||
|
will produce a "physfs_static.lib" in either a "physfs_static_debug"
|
||||||
|
or a "physfs_static_release" directory, depending on what configuration
|
||||||
|
you chose to build. NOPE: "test_physfs.dsp" does not work with the
|
||||||
|
statically linked build.
|
||||||
|
|
||||||
|
Visual Studio.NET users should do the same thing, but use the "physfs.vcproj"
|
||||||
|
and "test_physfs.vcproj" project files instead.
|
||||||
|
|
||||||
|
NOTE: to change build options such as which drivers are loaded (ZIP, QPAK,
|
||||||
|
etc.) modify the appropriate manifest constants under the Project Settings.
|
||||||
|
By default the LIB version supports all drivers, but the DLL build does
|
||||||
|
not support MVL or HOG file formats.
|
||||||
|
|
||||||
|
If you're using another compiler, send me a patch when you get it working. :)
|
||||||
|
|
||||||
|
No one's tried building this for a WinCE (PocketPC) platform, but it may or
|
||||||
|
may not work. Patches are welcome.
|
||||||
|
|
||||||
|
If someone is willing to maintain prebuilt PhysicsFS DLLs, I'd like to hear
|
||||||
|
from you; send an email to icculus@icculus.org.
|
||||||
|
|
||||||
|
MACOS 8/9:
|
||||||
|
Double-click on "CWProjects.sit" in the root of the source tree. This will
|
||||||
|
unpack into a folder called "Mac Classic Support", which has CodeWarrior 6
|
||||||
|
project files.
|
||||||
|
|
||||||
|
Point CodeWarrior at "physfs.mcp" in that new folder, and build. This will
|
||||||
|
produce a "PhysicsFS" or "PhysicsFS Debug" shared library, depending on what
|
||||||
|
configuration you chose to build. After building the lib, you can make sure
|
||||||
|
it works by building the "test_physfs.mcp" project file, which will create
|
||||||
|
"test_physfs" or "test_physfs Debug". These binaries are linked against the
|
||||||
|
DLLs you built previously.
|
||||||
|
|
||||||
|
If someone is willing to maintain prebuilt PhysicsFS Shared Libraries for
|
||||||
|
the Mac, I'd like to hear from you; send an email to icculus@icculus.org.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MACOS X:
|
||||||
|
You (currently) need to use the freeware Apple Developer Tools, which are
|
||||||
|
based on the GNU toolchain. Fire up a terminal and run "cc"...if this reports
|
||||||
|
"no input files" then you've got the tools installed.
|
||||||
|
|
||||||
|
Follow the Unix directions, above (configure, make, make install).
|
||||||
|
|
||||||
|
If someone is willing to maintain prebuilt PhysicsFS Shared Libraries for
|
||||||
|
MacOS X, I'd like to hear from you; send an email to icculus@icculus.org.
|
||||||
|
|
||||||
|
|
||||||
|
OS/2:
|
||||||
|
You need EMX installed. I tried this on a stock Warp 4 install, no fixpaks.
|
||||||
|
I used the latest EMX and patches (which are several years old now). You need
|
||||||
|
to install link386.exe (Selective Install, "link object modules" option). Once
|
||||||
|
EMX is installed correctly, unpack the source to PhysicsFS and run the script
|
||||||
|
file "makeos2.cmd". I know this isn't ideal, but I wanted to have this build
|
||||||
|
without users having to hunt down a "make" program (While several exist, EMX
|
||||||
|
doesn't come with one). If someone wants to hack some REXX to make this a bit
|
||||||
|
more piccky about recompiling, I'll accept the patch.
|
||||||
|
|
||||||
|
If someone is willing to maintain prebuilt PhysicsFS Shared Libraries for
|
||||||
|
OS/2, I'd like to hear from you; send an email to icculus@icculus.org.
|
||||||
|
|
||||||
|
|
||||||
|
OTHER PLATFORMS:
|
||||||
|
Many Unix-like platforms might "just work" with the GNU autoconf tools. Some
|
||||||
|
of these platforms are known to have worked at one time, but have not been
|
||||||
|
heavily tested, if tested at all. PhysicsFS is, as far as we know, 64-bit and
|
||||||
|
byteorder clean, and is known to compile on several compilers across many
|
||||||
|
platforms. To implement a new platform or archiver, please read the
|
||||||
|
heavily-commented physfs_internal.h and look in the platform/ and archiver/
|
||||||
|
directories for examples.
|
||||||
|
|
||||||
|
--ryan. (icculus@icculus.org)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
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
|
||||||
|
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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Notes, separate from the license. This is not legal advice.
|
||||||
|
|
||||||
|
Versions of PhysicsFS prior to 0.1.9 are licensed under the GNU Lesser General
|
||||||
|
Public License, which restricts you significantly more. For your own safety,
|
||||||
|
please make sure you've got 0.1.9 or later if you plan to use physfs in a
|
||||||
|
commercial or closed-source project.
|
||||||
|
|
||||||
|
Optional pieces of PhysicsFS may fall under other licenses, please consult
|
||||||
|
your lawyer for legal advice, which this is not...
|
||||||
|
|
||||||
|
zlib: if you enable ZIP archive support, PhysicsFS uses zlib. Its license
|
||||||
|
requirements are identical to PhysicsFS.
|
||||||
|
Please see zlib123/README for details.
|
||||||
|
|
17
LICENSE.txt
17
LICENSE.txt
|
@ -1,17 +0,0 @@
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
lib_LTLIBRARIES = libphysfs.la
|
||||||
|
|
||||||
|
libphysfsincludedir = $(includedir)
|
||||||
|
libphysfsinclude_HEADERS = \
|
||||||
|
physfs.h
|
||||||
|
|
||||||
|
if BUILD_MACOSX
|
||||||
|
|
||||||
|
ZLIB_FILES = zlib123/adler32.c \
|
||||||
|
zlib123/compress.c \
|
||||||
|
zlib123/crc32.c \
|
||||||
|
zlib123/crc32.h \
|
||||||
|
zlib123/deflate.c \
|
||||||
|
zlib123/deflate.h \
|
||||||
|
zlib123/gzio.c \
|
||||||
|
zlib123/infback.c \
|
||||||
|
zlib123/inffast.c \
|
||||||
|
zlib123/inffast.h \
|
||||||
|
zlib123/inffixed.h \
|
||||||
|
zlib123/inflate.c \
|
||||||
|
zlib123/inflate.h \
|
||||||
|
zlib123/inftrees.c \
|
||||||
|
zlib123/inftrees.h \
|
||||||
|
zlib123/trees.c \
|
||||||
|
zlib123/trees.h \
|
||||||
|
zlib123/uncompr.c \
|
||||||
|
zlib123/zconf.h \
|
||||||
|
zlib123/zlib.h \
|
||||||
|
zlib123/zutil.c \
|
||||||
|
zlib123/zutil.h
|
||||||
|
|
||||||
|
|
||||||
|
if BUILD_ZLIB
|
||||||
|
ZLIB_SRC = $(ZLIB_FILES)
|
||||||
|
ZLIB_INC = -I$(top_srcdir)/zlib123
|
||||||
|
ZLIB_EXTRADIST =
|
||||||
|
else
|
||||||
|
ZLIB_SRC =
|
||||||
|
ZLIB_INC =
|
||||||
|
ZLIB_EXTRADIST = $(ZLIB_FILES)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libphysfs_la_SOURCES = \
|
||||||
|
physfs.c \
|
||||||
|
physfs_internal.h \
|
||||||
|
physfs_byteorder.c \
|
||||||
|
archivers/dir.c \
|
||||||
|
archivers/grp.c \
|
||||||
|
archivers/wad.c \
|
||||||
|
archivers/hog.c \
|
||||||
|
archivers/mvl.c \
|
||||||
|
archivers/zip.c \
|
||||||
|
archivers/qpak.c \
|
||||||
|
platform/unix.c \
|
||||||
|
platform/posix.c \
|
||||||
|
$(ZLIB_SRC)
|
||||||
|
|
||||||
|
libphysfs_la_INCLUDES = $(ZLIB_INC)
|
||||||
|
|
||||||
|
libphysfs_la_LDFLAGS = \
|
||||||
|
-release $(LT_RELEASE) \
|
||||||
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
||||||
|
|
||||||
|
|
||||||
|
if BUILD_TEST_PHYSFS
|
||||||
|
bin_PROGRAMS = test_physfs
|
||||||
|
test_physfs_INCLUDES = -I$(top_srcdir)
|
||||||
|
test_physfs_LDADD = $(top_srcdir)/libphysfs.la
|
||||||
|
test_physfs_SOURCES = test/test_physfs.c
|
||||||
|
TEST_EXTRADIST =
|
||||||
|
else
|
||||||
|
TEST_EXTRADIST = test/test_physfs.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
CREDITS \
|
||||||
|
LICENSE \
|
||||||
|
CHANGELOG \
|
||||||
|
INSTALL \
|
||||||
|
TODO \
|
||||||
|
Doxyfile \
|
||||||
|
CWProjects.sit \
|
||||||
|
physfs.spec \
|
||||||
|
physfs.dsp \
|
||||||
|
test_physfs.dsp \
|
||||||
|
physfs_static.dsp \
|
||||||
|
physfs.vcproj \
|
||||||
|
test_physfs.vcproj \
|
||||||
|
platform/skeleton.c \
|
||||||
|
platform/macclassic.c \
|
||||||
|
platform/win32.c \
|
||||||
|
platform/beos.cpp \
|
||||||
|
platform/os2.c \
|
||||||
|
extras/physfsrwops.h \
|
||||||
|
extras/physfsrwops.c \
|
||||||
|
extras/physfshttpd.c \
|
||||||
|
Makefile.am.oldautomake \
|
||||||
|
Makefile.am.newautomake \
|
||||||
|
zlib_license_change.txt \
|
||||||
|
makeos2.cmd \
|
||||||
|
PBProjects \
|
||||||
|
$(ZLIB_EXTRADIST) $(BEOS_EXTRADIST) $(TEST_EXTRADIST)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
SUBDIRS = platform archivers zlib123 . test extras
|
||||||
|
|
||||||
|
libphysfs_la_SOURCES = \
|
||||||
|
physfs.c \
|
||||||
|
physfs_internal.h \
|
||||||
|
physfs_byteorder.c
|
||||||
|
|
||||||
|
if BUILD_ZLIB
|
||||||
|
ZLIB_LIB = zlib123/libz.la
|
||||||
|
else
|
||||||
|
ZLIB_LIB =
|
||||||
|
endif
|
||||||
|
|
||||||
|
libphysfs_la_LDFLAGS = \
|
||||||
|
-release $(LT_RELEASE) \
|
||||||
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
||||||
|
libphysfs_la_LIBADD = \
|
||||||
|
archivers/libarchivers.la \
|
||||||
|
platform/libplatform.la \
|
||||||
|
$(ZLIB_LIB)
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
CREDITS \
|
||||||
|
LICENSE \
|
||||||
|
CHANGELOG \
|
||||||
|
INSTALL \
|
||||||
|
TODO \
|
||||||
|
Doxyfile \
|
||||||
|
PBProjects \
|
||||||
|
CWProjects.sit \
|
||||||
|
physfs.spec.in \
|
||||||
|
physfs.spec \
|
||||||
|
physfs.dsp \
|
||||||
|
test_physfs.dsp \
|
||||||
|
physfs_static.dsp \
|
||||||
|
physfs.vcproj \
|
||||||
|
test_physfs.vcproj \
|
||||||
|
zlib_license_change.txt \
|
||||||
|
makeos2.cmd
|
||||||
|
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
perl -w -pi -e 'chomp; $$_ .= "\r\n";' $(distdir)/*.dsp $(distdir)/*.vcproj
|
||||||
|
mkdir $(distdir)/docs
|
||||||
|
echo "Docs are generated with the program "Doxygen" (http://www.doxygen.org/)," >> $(distdir)/docs/README
|
||||||
|
echo " or can be read online at http://icculus.org/physfs/docs/" >> $(distdir)/docs/README
|
||||||
|
echo >> $(distdir)/docs/README
|
||||||
|
rm -rf `find $(distdir) -name "CVS" -type d`
|
||||||
|
rm -rf `find $(distdir) -name ".svn" -type d`
|
||||||
|
rm -rf $(distdir)/.hg
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
lib_LTLIBRARIES = libphysfs.la
|
||||||
|
|
||||||
|
SUBDIRS = platform archivers zlib123 . test extras
|
||||||
|
|
||||||
|
libphysfsincludedir = $(includedir)
|
||||||
|
libphysfsinclude_HEADERS = \
|
||||||
|
physfs.h
|
||||||
|
|
||||||
|
libphysfs_la_SOURCES = \
|
||||||
|
physfs.c \
|
||||||
|
physfs_internal.h \
|
||||||
|
physfs_byteorder.c
|
||||||
|
|
||||||
|
if BUILD_ZLIB
|
||||||
|
ZLIB_LIB = zlib123/libz.la
|
||||||
|
else
|
||||||
|
ZLIB_LIB =
|
||||||
|
endif
|
||||||
|
|
||||||
|
libphysfs_la_LDFLAGS = \
|
||||||
|
-release $(LT_RELEASE) \
|
||||||
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
||||||
|
libphysfs_la_LIBADD = \
|
||||||
|
archivers/libarchivers.la \
|
||||||
|
platform/libplatform.la \
|
||||||
|
$(ZLIB_LIB)
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
CREDITS \
|
||||||
|
LICENSE \
|
||||||
|
CHANGELOG \
|
||||||
|
INSTALL \
|
||||||
|
TODO \
|
||||||
|
Doxyfile \
|
||||||
|
PBProjects \
|
||||||
|
CWProjects.sit \
|
||||||
|
physfs.spec.in \
|
||||||
|
physfs.spec \
|
||||||
|
physfs.dsp \
|
||||||
|
physfs_static.dsp \
|
||||||
|
test_physfs.dsp \
|
||||||
|
physfs.vcproj \
|
||||||
|
test_physfs.vcproj \
|
||||||
|
zlib_license_change.txt \
|
||||||
|
makeos2.cmd
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
perl -w -pi -e 'chomp; $$_ .= "\r\n";' $(distdir)/*.dsp $(distdir)/*.vcproj
|
||||||
|
mkdir $(distdir)/docs
|
||||||
|
echo "Docs are generated with the program "Doxygen" (http://www.doxygen.org/)," >> $(distdir)/docs/README
|
||||||
|
echo " or can be read online at http://icculus.org/physfs/docs/" >> $(distdir)/docs/README
|
||||||
|
echo >> $(distdir)/docs/README
|
||||||
|
rm -rf `find $(distdir) -name "CVS" -type d`
|
||||||
|
rm -rf `find $(distdir) -name ".svn" -type d`
|
||||||
|
rm -rf $(distdir)/.hg
|
Binary file not shown.
|
@ -0,0 +1,25 @@
|
||||||
|
This is an unofficial OS X Project Builder environment to build a physfs Framework.
|
||||||
|
|
||||||
|
|
||||||
|
Built with:
|
||||||
|
physfs 0.1.9
|
||||||
|
Project Builder 2.0.1
|
||||||
|
OS X (10.2 Jaguar)
|
||||||
|
|
||||||
|
This project was created by brainlessly mimicking the SDL (Simple Direct Media
|
||||||
|
Layer) Project Builder projects. The scripts were also shamelessly taken from
|
||||||
|
SDL as well. There may be errors. Use at your own risk!
|
||||||
|
|
||||||
|
This project creates 2 installer packages:
|
||||||
|
|
||||||
|
- A physfs framework for development (for people who wish to link to physfs)
|
||||||
|
|
||||||
|
- A physfs framework for users (for users who run programs that used the above
|
||||||
|
package
|
||||||
|
|
||||||
|
This project also builds static libraries for physfs (to build physfs and physfsc) but
|
||||||
|
they are not installed anywhere. If you wish to use them, you will need to
|
||||||
|
copy them out of the build directory.
|
||||||
|
|
||||||
|
Eric Wing <ewing2121@yahoo.com>
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
EXPORTS = SDL_sound.x
|
||||||
|
HEADERS = \
|
||||||
|
../../SDL_sound.h
|
||||||
|
|
||||||
|
all: $(EXPORTS)
|
||||||
|
|
||||||
|
$(EXPORTS): $(HEADERS)
|
||||||
|
perl gendef.pl $(HEADERS) >$@ || rm $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXPORTS)
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
#
|
||||||
|
# Program to take a set of header files and generate DLL export definitions
|
||||||
|
|
||||||
|
while ( ($file = shift(@ARGV)) ) {
|
||||||
|
if ( ! defined(open(FILE, $file)) ) {
|
||||||
|
warn "Couldn't open $file: $!\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
$printed_header = 0;
|
||||||
|
$file =~ s,.*/,,;
|
||||||
|
while (<FILE>) {
|
||||||
|
if ( /^__EXPORT__.*\s\**([^\s\(]+)\(/ ) {
|
||||||
|
print "\t_$1\n";
|
||||||
|
} elsif ( /^__EXPORT__.*\s\**([^\s\(]+)$/ ) {
|
||||||
|
print "\t_$1\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(FILE);
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
_PHYSFS_getLinkedVersion
|
||||||
|
_PHYSFS_init
|
||||||
|
_PHYSFS_deinit
|
||||||
|
_PHYSFS_supportedArchiveTypes
|
||||||
|
_PHYSFS_freeList
|
||||||
|
_PHYSFS_getLastError
|
||||||
|
_PHYSFS_getDirSeparator
|
||||||
|
_PHYSFS_permitSymbolicLinks
|
||||||
|
_PHYSFS_getCdRomDirs
|
||||||
|
_PHYSFS_getBaseDir
|
||||||
|
_PHYSFS_getUserDir
|
||||||
|
_PHYSFS_getWriteDir
|
||||||
|
_PHYSFS_setWriteDir
|
||||||
|
_PHYSFS_addToSearchPath
|
||||||
|
_PHYSFS_removeFromSearchPath
|
||||||
|
_PHYSFS_getSearchPath
|
||||||
|
_PHYSFS_setSaneConfig
|
||||||
|
_PHYSFS_mkdir
|
||||||
|
_PHYSFS_delete
|
||||||
|
_PHYSFS_getRealDir
|
||||||
|
_PHYSFS_enumerateFiles
|
||||||
|
_PHYSFS_exists
|
||||||
|
_PHYSFS_isDirectory
|
||||||
|
_PHYSFS_isSymbolicLink
|
||||||
|
_PHYSFS_getLastModTime
|
||||||
|
_PHYSFS_openWrite
|
||||||
|
_PHYSFS_openAppend
|
||||||
|
_PHYSFS_openRead
|
||||||
|
_PHYSFS_close
|
||||||
|
_PHYSFS_read
|
||||||
|
_PHYSFS_write
|
||||||
|
_PHYSFS_eof
|
||||||
|
_PHYSFS_tell
|
||||||
|
_PHYSFS_seek
|
||||||
|
_PHYSFS_fileLength
|
||||||
|
_PHYSFS_setBuffer
|
||||||
|
_PHYSFS_flush
|
||||||
|
_PHYSFS_swapSLE16
|
||||||
|
_PHYSFS_swapULE16
|
||||||
|
_PHYSFS_swapSLE32
|
||||||
|
_PHYSFS_swapULE32
|
||||||
|
_PHYSFS_swapSLE64
|
||||||
|
_PHYSFS_swapULE64
|
||||||
|
_PHYSFS_swapSBE16
|
||||||
|
_PHYSFS_swapUBE16
|
||||||
|
_PHYSFS_swapSBE32
|
||||||
|
_PHYSFS_swapUBE32
|
||||||
|
_PHYSFS_swapSBE64
|
||||||
|
_PHYSFS_swapUBE64
|
||||||
|
_PHYSFS_readSLE16
|
||||||
|
_PHYSFS_readULE16
|
||||||
|
_PHYSFS_readSBE16
|
||||||
|
_PHYSFS_readUBE16
|
||||||
|
_PHYSFS_readSLE32
|
||||||
|
_PHYSFS_readULE32
|
||||||
|
_PHYSFS_readSBE32
|
||||||
|
_PHYSFS_readUBE32
|
||||||
|
_PHYSFS_readSLE64
|
||||||
|
_PHYSFS_readULE64
|
||||||
|
_PHYSFS_readSBE64
|
||||||
|
_PHYSFS_readUBE64
|
||||||
|
_PHYSFS_writeSLE16
|
||||||
|
_PHYSFS_writeULE16
|
||||||
|
_PHYSFS_writeSBE16
|
||||||
|
_PHYSFS_writeUBE16
|
||||||
|
_PHYSFS_writeSLE32
|
||||||
|
_PHYSFS_writeULE32
|
||||||
|
_PHYSFS_writeSBE32
|
||||||
|
_PHYSFS_writeUBE32
|
||||||
|
_PHYSFS_writeSLE64
|
||||||
|
_PHYSFS_writeULE64
|
||||||
|
_PHYSFS_writeSBE64
|
||||||
|
_PHYSFS_writeUBE64
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/csh
|
||||||
|
|
||||||
|
###
|
||||||
|
## This script creates "PBProjects.tar.gz" in the parent directory
|
||||||
|
###
|
||||||
|
|
||||||
|
# remove build products
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
|
# remove Finder info files
|
||||||
|
find . -name ".DS_Store" -exec rm "{}" ";"
|
||||||
|
|
||||||
|
# remove user project prefs
|
||||||
|
find . -name "*.pbxuser" -exec rm "{}" ";"
|
||||||
|
|
||||||
|
# create the archive
|
||||||
|
(cd .. && gnutar -zcvf PBProjects.tar.gz PBProjects)
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
||||||
|
This is an example portable filesystem.
|
||||||
|
The API can be found in the file ~/Library/Frameworks/physfs.framework/Headers/physfs.h
|
||||||
|
|
||||||
|
The source code is available from:
|
||||||
|
http://www.icculus.org/physfs/
|
||||||
|
|
||||||
|
This library is distributed under the terms of the zlib license: http://www.opensource.org/licenses/zlib-license.php
|
|
@ -0,0 +1,3 @@
|
||||||
|
This package installs the developer version of the physfs library and associated files.
|
||||||
|
|
||||||
|
The physfs Framework is installed into ~/Library/Frameworks.
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# finish up the installation
|
||||||
|
# this script should be executed using the sudo command
|
||||||
|
# this file is copied to physfs.post_install and physfs.post_upgrade
|
||||||
|
# inside the .pkg bundle
|
||||||
|
echo "Running post-install script"
|
||||||
|
umask 022
|
||||||
|
|
||||||
|
ROOT=/Developer/Documentation/SDL
|
||||||
|
|
||||||
|
echo "Moving physfs.framework to ~/Library/Frameworks"
|
||||||
|
# move SDL to its proper home, so the target stationary works
|
||||||
|
mkdir -p ~/Library/Frameworks
|
||||||
|
/Developer/Tools/CpMac -r $ROOT/physfs.framework ~/Library/Frameworks
|
||||||
|
rm -rf $ROOT/physfs.framework
|
||||||
|
|
||||||
|
echo "Precompiling Header"
|
||||||
|
# precompile header for speedier compiles
|
||||||
|
/usr/bin/cc -I $HOME/Library/Frameworks/SDL.framework/Headers -precomp ~/Library/Frameworks/physfs.framework/Headers/physfs.h -o ~/Library/Frameworks/physfs.framework/Headers/physfs.p
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Generic script to create a package with Project Builder in mind
|
||||||
|
# There should only be one version of this script for all projects!
|
||||||
|
|
||||||
|
FRAMEWORK="$1"
|
||||||
|
VARIANT="$2"
|
||||||
|
|
||||||
|
if test "$VARIANT" = "devel" ; then
|
||||||
|
PACKAGE="$FRAMEWORK-devel"
|
||||||
|
PACKAGE_RESOURCES="pkg-support/devel-resources"
|
||||||
|
else
|
||||||
|
PACKAGE="$FRAMEWORK"
|
||||||
|
PACKAGE_RESOURCES="pkg-support/resources"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Building package for $FRAMEWORK.framework"
|
||||||
|
echo "Will fetch resources from $PACKAGE_RESOURCES"
|
||||||
|
echo "Will create the package $PACKAGE.pkg"
|
||||||
|
|
||||||
|
# create a copy of the framework
|
||||||
|
mkdir -p build/pkg-tmp
|
||||||
|
/Developer/Tools/CpMac -r "build/$FRAMEWORK.framework" build/pkg-tmp/
|
||||||
|
|
||||||
|
|
||||||
|
if test "$VARIANT" = "standard" ; then
|
||||||
|
rm -rf "build/pkg-tmp/$FRAMEWORK.framework/Headers"
|
||||||
|
rm -rf "build/pkg-tmp/$FRAMEWORK.framework/Versions/Current/Headers"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf build/pkg-tmp/$FRAMEWORK.framework/Resources/pbdevelopment.plist
|
||||||
|
rm -rf $PACKAGE_RESOURCES/.DS_Store
|
||||||
|
|
||||||
|
# create the .pkg
|
||||||
|
package build/pkg-tmp "pkg-support/$PACKAGE.info" -d build -r "$PACKAGE_RESOURCES"
|
||||||
|
|
||||||
|
if test "$VARIANT" = "devel" ; then
|
||||||
|
# create install scripts
|
||||||
|
DIR="build/$PACKAGE.pkg"
|
||||||
|
cp "$DIR/install.sh" "$DIR/$PACKAGE.post_install"
|
||||||
|
mv "$DIR/install.sh" "$DIR/$PACKAGE.post_upgrade"
|
||||||
|
|
||||||
|
# add execute flag to scripts
|
||||||
|
chmod 755 "$DIR/$PACKAGE.post_install" "$DIR/$PACKAGE.post_upgrade"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# remove temporary files
|
||||||
|
rm -rf build/pkg-tmp
|
||||||
|
|
||||||
|
# compress
|
||||||
|
(cd build; tar -zcvf "$PACKAGE.pkg.tar.gz" "$PACKAGE.pkg")
|
|
@ -0,0 +1,15 @@
|
||||||
|
Title PhysFS-Devel 1.0.0
|
||||||
|
Version 1
|
||||||
|
Description PhysicsFS Library for Mac OS X (http://www.icculus.org/physfs/)
|
||||||
|
DefaultLocation /Developer/Documentation/physfs
|
||||||
|
Diskname (null)
|
||||||
|
DeleteWarning
|
||||||
|
NeedsAuthorization YES
|
||||||
|
DisableStop NO
|
||||||
|
UseUserMask YES
|
||||||
|
Application NO
|
||||||
|
Relocatable NO
|
||||||
|
Required NO
|
||||||
|
InstallOnly NO
|
||||||
|
RequiresReboot NO
|
||||||
|
InstallFat NO
|
|
@ -0,0 +1,15 @@
|
||||||
|
Title PhysFS 1.0.0
|
||||||
|
Version 1
|
||||||
|
Description PhysicsFS Library for Mac OS X (http://www.icculus.org/physfs/)
|
||||||
|
DefaultLocation /Library/Frameworks
|
||||||
|
Diskname (null)
|
||||||
|
DeleteWarning
|
||||||
|
NeedsAuthorization NO
|
||||||
|
DisableStop NO
|
||||||
|
UseUserMask NO
|
||||||
|
Application NO
|
||||||
|
Relocatable YES
|
||||||
|
Required NO
|
||||||
|
InstallOnly NO
|
||||||
|
RequiresReboot NO
|
||||||
|
InstallFat NO
|
|
@ -0,0 +1,6 @@
|
||||||
|
This is an example portable file system.
|
||||||
|
|
||||||
|
The source code is available from:
|
||||||
|
http://www.icculus.org/physfs/
|
||||||
|
|
||||||
|
This library is distributed under the terms of the zlib license: http://www.opensource.org/licenses/zlib-license.php
|
|
@ -0,0 +1,3 @@
|
||||||
|
This package installs the physfs library into /Library/Frameworks. You can also install it in
|
||||||
|
<your home directory>/Library/Frameworks if your access privileges are not high enough.
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/csh
|
||||||
|
|
||||||
|
###
|
||||||
|
## This script removes the Developer physfs package
|
||||||
|
###
|
||||||
|
|
||||||
|
setenv HOME_DIR ~
|
||||||
|
|
||||||
|
sudo -v -p "Enter administrator password to remove physfs: "
|
||||||
|
|
||||||
|
sudo rm -rf "$HOME_DIR/Library/Frameworks/physfs.framework"
|
||||||
|
|
||||||
|
# will only remove the Frameworks dir if empty (since we put it there)
|
||||||
|
sudo rmdir "$HOME_DIR/Library/Frameworks"
|
||||||
|
|
||||||
|
#sudo rm -r "$HOME_DIR/Readme physfs Developer.txt"
|
||||||
|
sudo rm -r "/Developer/Documentation/physfs"
|
||||||
|
sudo rm -r "/Developer/Documentation/ManPages/man1/physfs"*
|
||||||
|
#sudo rm -r "/Developer/ProjectBuilder Extras/Project Templates/Application/physfs Application"
|
||||||
|
#sudo rm -r "/Developer/ProjectBuilder Extras/Target Templates/physfs"
|
||||||
|
sudo rm -r "/Library/Receipts/physfs-devel.pkg"
|
||||||
|
|
||||||
|
# rebuild apropos database
|
||||||
|
sudo /usr/libexec/makewhatis
|
||||||
|
|
||||||
|
unsetenv HOME_DIR
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
PhysicsFS; a portable, flexible file i/o abstraction.
|
|
||||||
|
|
||||||
https://icculus.org/physfs/
|
|
||||||
|
|
||||||
Please see the docs directory for documentation.
|
|
||||||
|
|
||||||
Please see LICENSE.txt for licensing information.
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
Stuff that needs to be done and wishlist:
|
||||||
|
|
||||||
|
These are in no particular order.
|
||||||
|
Some might be dupes, some might be done already.
|
||||||
|
|
||||||
|
- Other archivers: perhaps tar(.gz|.bz2), RPM, ARJ, etc. These are less
|
||||||
|
important, since streaming archives aren't of much value to games (which
|
||||||
|
is why zipfiles are king: random access), but it could have uses for, say,
|
||||||
|
an installer/updater.
|
||||||
|
- Stack allocate in stripAppleBundle() (platform/unix.c) instead of calloc().
|
||||||
|
- Reduce malloc() pressure all over the place. We fragment memory like mad.
|
||||||
|
- macclassic.c :
|
||||||
|
"/* (Hmm. Default behaviour is broken in the base library. :) ) */"
|
||||||
|
- Platforms to port to: Amiga (needs platform driver), DOS4GW (platform driver).
|
||||||
|
- profile string list interpolation.
|
||||||
|
- We have two different ways to find dir entries in zip.c.
|
||||||
|
- Do symlinks in zip archiver work when they point to dirs?
|
||||||
|
- Enable more warnings?
|
||||||
|
- Use __cdecl in physfs.h?
|
||||||
|
- Look for FIXMEs (many marked with "!!!" in comments).
|
||||||
|
- Probably other stuff. Requests and recommendations are welcome.
|
||||||
|
|
||||||
|
// end of TODO ...
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
#undef DEBUG
|
||||||
|
#undef DEBUG_CHATTER
|
||||||
|
#undef NDEBUG
|
||||||
|
#undef PHYSFS_SUPPORTS_ZIP
|
||||||
|
#undef PHYSFS_SUPPORTS_GRP
|
||||||
|
#undef PHYSFS_SUPPORTS_HOG
|
||||||
|
#undef PHYSFS_SUPPORTS_MVL
|
||||||
|
#undef PHYSFS_HAVE_READLINE
|
||||||
|
#undef PHYSFS_HAVE_LLSEEK
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
noinst_LTLIBRARIES = libarchivers.la
|
||||||
|
|
||||||
|
if BUILD_ZLIB
|
||||||
|
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/zlib123
|
||||||
|
else
|
||||||
|
INCLUDES = -I$(top_srcdir)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libarchivers_la_SOURCES = \
|
||||||
|
dir.c \
|
||||||
|
grp.c \
|
||||||
|
wad.c \
|
||||||
|
hog.c \
|
||||||
|
mvl.c \
|
||||||
|
zip.c \
|
||||||
|
qpak.c
|
||||||
|
|
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
* Standard directory I/O support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static int DIR_eof(FileHandle *handle);
|
||||||
|
static PHYSFS_sint64 DIR_tell(FileHandle *handle);
|
||||||
|
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset);
|
||||||
|
static PHYSFS_sint64 DIR_fileLength(FileHandle *handle);
|
||||||
|
static int DIR_fileClose(FileHandle *handle);
|
||||||
|
static int DIR_isArchive(const char *filename, int forWriting);
|
||||||
|
static DirHandle *DIR_openArchive(const char *name, int forWriting);
|
||||||
|
static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dname,
|
||||||
|
int omitSymLinks);
|
||||||
|
static int DIR_exists(DirHandle *h, const char *name);
|
||||||
|
static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist);
|
||||||
|
static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h, const char *f, int *e);
|
||||||
|
static FileHandle *DIR_openWrite(DirHandle *h, const char *filename);
|
||||||
|
static FileHandle *DIR_openAppend(DirHandle *h, const char *filename);
|
||||||
|
static int DIR_remove(DirHandle *h, const char *name);
|
||||||
|
static int DIR_mkdir(DirHandle *h, const char *name);
|
||||||
|
static void DIR_dirClose(DirHandle *h);
|
||||||
|
|
||||||
|
|
||||||
|
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
DIR_ARCHIVE_DESCRIPTION,
|
||||||
|
"Ryan C. Gordon <icculus@icculus.org>",
|
||||||
|
"http://icculus.org/physfs/",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_DIR =
|
||||||
|
{
|
||||||
|
DIR_read, /* read() method */
|
||||||
|
DIR_dummyWrite, /* write() method */
|
||||||
|
DIR_eof, /* eof() method */
|
||||||
|
DIR_tell, /* tell() method */
|
||||||
|
DIR_seek, /* seek() method */
|
||||||
|
DIR_fileLength, /* fileLength() method */
|
||||||
|
DIR_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_DIRW =
|
||||||
|
{
|
||||||
|
DIR_dummyRead, /* read() method */
|
||||||
|
DIR_write, /* write() method */
|
||||||
|
DIR_eof, /* eof() method */
|
||||||
|
DIR_tell, /* tell() method */
|
||||||
|
DIR_seek, /* seek() method */
|
||||||
|
DIR_fileLength, /* fileLength() method */
|
||||||
|
DIR_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_DIR =
|
||||||
|
{
|
||||||
|
&__PHYSFS_ArchiveInfo_DIR,
|
||||||
|
DIR_isArchive, /* isArchive() method */
|
||||||
|
DIR_openArchive, /* openArchive() method */
|
||||||
|
DIR_enumerateFiles, /* enumerateFiles() method */
|
||||||
|
DIR_exists, /* exists() method */
|
||||||
|
DIR_isDirectory, /* isDirectory() method */
|
||||||
|
DIR_isSymLink, /* isSymLink() method */
|
||||||
|
DIR_getLastModTime, /* getLastModTime() method */
|
||||||
|
DIR_openRead, /* openRead() method */
|
||||||
|
DIR_openWrite, /* openWrite() method */
|
||||||
|
DIR_openAppend, /* openAppend() method */
|
||||||
|
DIR_remove, /* remove() method */
|
||||||
|
DIR_mkdir, /* mkdir() method */
|
||||||
|
DIR_dirClose /* dirClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
PHYSFS_sint64 retval;
|
||||||
|
retval = __PHYSFS_platformRead(handle->opaque, buffer, objSize, objCount);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
PHYSFS_sint64 retval;
|
||||||
|
retval = __PHYSFS_platformWrite(handle->opaque, buffer, objSize, objCount);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_write */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_dummyRead(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* DIR_dummyRead */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_dummyWrite(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* DIR_dummyWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_eof(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(__PHYSFS_platformEOF(handle->opaque));
|
||||||
|
} /* DIR_eof */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_tell(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(__PHYSFS_platformTell(handle->opaque));
|
||||||
|
} /* DIR_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_seek(FileHandle *handle, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
return(__PHYSFS_platformSeek(handle->opaque, offset));
|
||||||
|
} /* DIR_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_fileLength(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(__PHYSFS_platformFileLength(handle->opaque));
|
||||||
|
} /* DIR_fileLength */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_fileClose(FileHandle *handle)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* we manually flush the buffer, since that's the place a close will
|
||||||
|
* most likely fail, but that will leave the file handle in an undefined
|
||||||
|
* state if it fails. Flush failures we can recover from.
|
||||||
|
*/
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformFlush(handle->opaque), NULL, 0);
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformClose(handle->opaque), NULL, 0);
|
||||||
|
free(handle);
|
||||||
|
return(1);
|
||||||
|
} /* DIR_fileClose */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_isArchive(const char *filename, int forWriting)
|
||||||
|
{
|
||||||
|
/* directories ARE archives in this driver... */
|
||||||
|
return(__PHYSFS_platformIsDirectory(filename));
|
||||||
|
} /* DIR_isArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static DirHandle *DIR_openArchive(const char *name, int forWriting)
|
||||||
|
{
|
||||||
|
const char *dirsep = PHYSFS_getDirSeparator();
|
||||||
|
DirHandle *retval = NULL;
|
||||||
|
size_t namelen = strlen(name);
|
||||||
|
size_t seplen = strlen(dirsep);
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(!DIR_isArchive(name, forWriting),
|
||||||
|
ERR_UNSUPPORTED_ARCHIVE, NULL);
|
||||||
|
|
||||||
|
retval = (DirHandle *) malloc(sizeof (DirHandle));
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
retval->opaque = malloc(namelen + seplen + 1);
|
||||||
|
if (retval->opaque == NULL)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* make sure there's a dir separator at the end of the string */
|
||||||
|
strcpy((char *) (retval->opaque), name);
|
||||||
|
if (strcmp((name + namelen) - seplen, dirsep) != 0)
|
||||||
|
strcat((char *) (retval->opaque), dirsep);
|
||||||
|
|
||||||
|
retval->funcs = &__PHYSFS_DirFunctions_DIR;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static LinkedStringList *DIR_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dname,
|
||||||
|
int omitSymLinks)
|
||||||
|
{
|
||||||
|
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque),dname,NULL);
|
||||||
|
LinkedStringList *retval;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(d == NULL, NULL, NULL);
|
||||||
|
retval = __PHYSFS_platformEnumerateFiles(d, omitSymLinks);
|
||||||
|
free(d);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_exists(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(f == NULL, NULL, 0);
|
||||||
|
retval = __PHYSFS_platformExists(f);
|
||||||
|
free(f);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_exists */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_isDirectory(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(d == NULL, NULL, 0);
|
||||||
|
*fileExists = __PHYSFS_platformExists(d);
|
||||||
|
if (*fileExists)
|
||||||
|
retval = __PHYSFS_platformIsDirectory(d);
|
||||||
|
free(d);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_isDirectory */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_isSymLink(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(f == NULL, NULL, 0);
|
||||||
|
*fileExists = __PHYSFS_platformExists(f);
|
||||||
|
if (*fileExists)
|
||||||
|
retval = __PHYSFS_platformIsSymLink(f);
|
||||||
|
free(f);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_isSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 DIR_getLastModTime(DirHandle *h,
|
||||||
|
const char *name,
|
||||||
|
int *fileExists)
|
||||||
|
{
|
||||||
|
char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
PHYSFS_sint64 retval = -1;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(d == NULL, NULL, 0);
|
||||||
|
*fileExists = __PHYSFS_platformExists(d);
|
||||||
|
if (*fileExists)
|
||||||
|
retval = __PHYSFS_platformGetLastModTime(d);
|
||||||
|
free(d);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_getLastModTime */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *doOpen(DirHandle *h, const char *name,
|
||||||
|
void *(*openFunc)(const char *filename),
|
||||||
|
int *fileExists, const FileFunctions *fileFuncs)
|
||||||
|
{
|
||||||
|
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
void *rc;
|
||||||
|
FileHandle *retval;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(f == NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (fileExists != NULL)
|
||||||
|
{
|
||||||
|
*fileExists = __PHYSFS_platformExists(f);
|
||||||
|
if (!(*fileExists))
|
||||||
|
{
|
||||||
|
free(f);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
retval = (FileHandle *) malloc(sizeof (FileHandle));
|
||||||
|
if (!retval)
|
||||||
|
{
|
||||||
|
free(f);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
rc = openFunc(f);
|
||||||
|
free(f);
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
retval->opaque = (void *) rc;
|
||||||
|
retval->dirHandle = h;
|
||||||
|
retval->funcs = fileFuncs;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* doOpen */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *DIR_openRead(DirHandle *h, const char *fnm, int *exist)
|
||||||
|
{
|
||||||
|
return(doOpen(h, fnm, __PHYSFS_platformOpenRead, exist,
|
||||||
|
&__PHYSFS_FileFunctions_DIR));
|
||||||
|
} /* DIR_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *DIR_openWrite(DirHandle *h, const char *filename)
|
||||||
|
{
|
||||||
|
return(doOpen(h, filename, __PHYSFS_platformOpenWrite, NULL,
|
||||||
|
&__PHYSFS_FileFunctions_DIRW));
|
||||||
|
} /* DIR_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *DIR_openAppend(DirHandle *h, const char *filename)
|
||||||
|
{
|
||||||
|
return(doOpen(h, filename, __PHYSFS_platformOpenAppend, NULL,
|
||||||
|
&__PHYSFS_FileFunctions_DIRW));
|
||||||
|
} /* DIR_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_remove(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(f == NULL, NULL, 0);
|
||||||
|
retval = __PHYSFS_platformDelete(f);
|
||||||
|
free(f);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_mkdir(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
char *f = __PHYSFS_platformCvtToDependent((char *)(h->opaque), name, NULL);
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(f == NULL, NULL, 0);
|
||||||
|
retval = __PHYSFS_platformMkDir(f);
|
||||||
|
free(f);
|
||||||
|
return(retval);
|
||||||
|
} /* DIR_mkdir */
|
||||||
|
|
||||||
|
|
||||||
|
static void DIR_dirClose(DirHandle *h)
|
||||||
|
{
|
||||||
|
free(h->opaque);
|
||||||
|
free(h);
|
||||||
|
} /* DIR_dirClose */
|
||||||
|
|
||||||
|
/* end of dir.c ... */
|
||||||
|
|
|
@ -0,0 +1,541 @@
|
||||||
|
/*
|
||||||
|
* GRP support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* This driver handles BUILD engine archives ("groupfiles"). This format
|
||||||
|
* (but not this driver) was put together by Ken Silverman.
|
||||||
|
*
|
||||||
|
* The format is simple enough. In Ken's words:
|
||||||
|
*
|
||||||
|
* What's the .GRP file format?
|
||||||
|
*
|
||||||
|
* The ".grp" file format is just a collection of a lot of files stored
|
||||||
|
* into 1 big one. I tried to make the format as simple as possible: The
|
||||||
|
* first 12 bytes contains my name, "KenSilverman". The next 4 bytes is
|
||||||
|
* the number of files that were compacted into the group file. Then for
|
||||||
|
* each file, there is a 16 byte structure, where the first 12 bytes are
|
||||||
|
* the filename, and the last 4 bytes are the file's size. The rest of
|
||||||
|
* the group file is just the raw data packed one after the other in the
|
||||||
|
* same order as the list of files.
|
||||||
|
*
|
||||||
|
* (That info is from http://www.advsys.net/ken/build.htm ...)
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined PHYSFS_SUPPORTS_GRP)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[13];
|
||||||
|
PHYSFS_uint32 startPos;
|
||||||
|
PHYSFS_uint32 size;
|
||||||
|
} GRPentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
PHYSFS_sint64 last_mod_time;
|
||||||
|
PHYSFS_uint32 entryCount;
|
||||||
|
GRPentry *entries;
|
||||||
|
} GRPinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
GRPentry *entry;
|
||||||
|
PHYSFS_uint32 curPos;
|
||||||
|
} GRPfileinfo;
|
||||||
|
|
||||||
|
|
||||||
|
static void GRP_dirClose(DirHandle *h);
|
||||||
|
static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 GRP_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static int GRP_eof(FileHandle *handle);
|
||||||
|
static PHYSFS_sint64 GRP_tell(FileHandle *handle);
|
||||||
|
static int GRP_seek(FileHandle *handle, PHYSFS_uint64 offset);
|
||||||
|
static PHYSFS_sint64 GRP_fileLength(FileHandle *handle);
|
||||||
|
static int GRP_fileClose(FileHandle *handle);
|
||||||
|
static int GRP_isArchive(const char *filename, int forWriting);
|
||||||
|
static DirHandle *GRP_openArchive(const char *name, int forWriting);
|
||||||
|
static LinkedStringList *GRP_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks);
|
||||||
|
static int GRP_exists(DirHandle *h, const char *name);
|
||||||
|
static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h, const char *n, int *e);
|
||||||
|
static FileHandle *GRP_openRead(DirHandle *h, const char *name, int *exist);
|
||||||
|
static FileHandle *GRP_openWrite(DirHandle *h, const char *name);
|
||||||
|
static FileHandle *GRP_openAppend(DirHandle *h, const char *name);
|
||||||
|
static int GRP_remove(DirHandle *h, const char *name);
|
||||||
|
static int GRP_mkdir(DirHandle *h, const char *name);
|
||||||
|
|
||||||
|
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP =
|
||||||
|
{
|
||||||
|
"GRP",
|
||||||
|
GRP_ARCHIVE_DESCRIPTION,
|
||||||
|
"Ryan C. Gordon <icculus@icculus.org>",
|
||||||
|
"http://icculus.org/physfs/",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_GRP =
|
||||||
|
{
|
||||||
|
GRP_read, /* read() method */
|
||||||
|
GRP_write, /* write() method */
|
||||||
|
GRP_eof, /* eof() method */
|
||||||
|
GRP_tell, /* tell() method */
|
||||||
|
GRP_seek, /* seek() method */
|
||||||
|
GRP_fileLength, /* fileLength() method */
|
||||||
|
GRP_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_GRP =
|
||||||
|
{
|
||||||
|
&__PHYSFS_ArchiveInfo_GRP,
|
||||||
|
GRP_isArchive, /* isArchive() method */
|
||||||
|
GRP_openArchive, /* openArchive() method */
|
||||||
|
GRP_enumerateFiles, /* enumerateFiles() method */
|
||||||
|
GRP_exists, /* exists() method */
|
||||||
|
GRP_isDirectory, /* isDirectory() method */
|
||||||
|
GRP_isSymLink, /* isSymLink() method */
|
||||||
|
GRP_getLastModTime, /* getLastModTime() method */
|
||||||
|
GRP_openRead, /* openRead() method */
|
||||||
|
GRP_openWrite, /* openWrite() method */
|
||||||
|
GRP_openAppend, /* openAppend() method */
|
||||||
|
GRP_remove, /* remove() method */
|
||||||
|
GRP_mkdir, /* mkdir() method */
|
||||||
|
GRP_dirClose /* dirClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void GRP_dirClose(DirHandle *h)
|
||||||
|
{
|
||||||
|
GRPinfo *info = ((GRPinfo *) h->opaque);
|
||||||
|
free(info->filename);
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
free(h);
|
||||||
|
} /* GRP_dirClose */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 GRP_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
|
||||||
|
GRPentry *entry = finfo->entry;
|
||||||
|
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
|
||||||
|
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
|
||||||
|
PHYSFS_sint64 rc;
|
||||||
|
|
||||||
|
if (objsLeft < objCount)
|
||||||
|
objCount = objsLeft;
|
||||||
|
|
||||||
|
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
|
||||||
|
if (rc > 0)
|
||||||
|
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* GRP_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 GRP_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* GRP_write */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_eof(FileHandle *handle)
|
||||||
|
{
|
||||||
|
GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
|
||||||
|
GRPentry *entry = finfo->entry;
|
||||||
|
return(finfo->curPos >= entry->size);
|
||||||
|
} /* GRP_eof */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 GRP_tell(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(((GRPfileinfo *) (handle->opaque))->curPos);
|
||||||
|
} /* GRP_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_seek(FileHandle *handle, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque);
|
||||||
|
GRPentry *entry = finfo->entry;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
|
||||||
|
rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
|
||||||
|
if (rc)
|
||||||
|
finfo->curPos = (PHYSFS_uint32) offset;
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* GRP_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 GRP_fileLength(FileHandle *handle)
|
||||||
|
{
|
||||||
|
GRPfileinfo *finfo = ((GRPfileinfo *) handle->opaque);
|
||||||
|
return((PHYSFS_sint64) finfo->entry->size);
|
||||||
|
} /* GRP_fileLength */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_fileClose(FileHandle *handle)
|
||||||
|
{
|
||||||
|
GRPfileinfo *finfo = ((GRPfileinfo *) handle->opaque);
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
|
||||||
|
free(finfo);
|
||||||
|
free(handle);
|
||||||
|
return(1);
|
||||||
|
} /* GRP_fileClose */
|
||||||
|
|
||||||
|
|
||||||
|
static int grp_open(const char *filename, int forWriting,
|
||||||
|
void **fh, PHYSFS_uint32 *count)
|
||||||
|
{
|
||||||
|
PHYSFS_uint8 buf[12];
|
||||||
|
|
||||||
|
*fh = NULL;
|
||||||
|
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
|
||||||
|
|
||||||
|
*fh = __PHYSFS_platformOpenRead(filename);
|
||||||
|
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, buf, 12, 1) != 1)
|
||||||
|
goto openGrp_failed;
|
||||||
|
|
||||||
|
if (memcmp(buf, "KenSilverman", 12) != 0)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
|
||||||
|
goto openGrp_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openGrp_failed;
|
||||||
|
|
||||||
|
*count = PHYSFS_swapULE32(*count);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
openGrp_failed:
|
||||||
|
if (*fh != NULL)
|
||||||
|
__PHYSFS_platformClose(*fh);
|
||||||
|
|
||||||
|
*count = -1;
|
||||||
|
*fh = NULL;
|
||||||
|
return(0);
|
||||||
|
} /* grp_open */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_isArchive(const char *filename, int forWriting)
|
||||||
|
{
|
||||||
|
void *fh;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
int retval = grp_open(filename, forWriting, &fh, &fileCount);
|
||||||
|
|
||||||
|
if (fh != NULL)
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* GRP_isArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static int grp_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
const GRPentry *a = (const GRPentry *) _a;
|
||||||
|
return(strcmp(a[one].name, a[two].name));
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* grp_entry_cmp */
|
||||||
|
|
||||||
|
|
||||||
|
static void grp_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
GRPentry tmp;
|
||||||
|
GRPentry *first = &(((GRPentry *) _a)[one]);
|
||||||
|
GRPentry *second = &(((GRPentry *) _a)[two]);
|
||||||
|
memcpy(&tmp, first, sizeof (GRPentry));
|
||||||
|
memcpy(first, second, sizeof (GRPentry));
|
||||||
|
memcpy(second, &tmp, sizeof (GRPentry));
|
||||||
|
} /* if */
|
||||||
|
} /* grp_entry_swap */
|
||||||
|
|
||||||
|
|
||||||
|
static int grp_load_entries(const char *name, int forWriting, GRPinfo *info)
|
||||||
|
{
|
||||||
|
void *fh = NULL;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
PHYSFS_uint32 location = 16; /* sizeof sig. */
|
||||||
|
GRPentry *entry;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(!grp_open(name, forWriting, &fh, &fileCount), NULL, 0);
|
||||||
|
info->entryCount = fileCount;
|
||||||
|
info->entries = (GRPentry *) malloc(sizeof (GRPentry) * fileCount);
|
||||||
|
if (info->entries == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
location += (16 * fileCount);
|
||||||
|
|
||||||
|
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
|
||||||
|
{
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->name, 12, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
entry->name[12] = '\0'; /* name isn't null-terminated in file. */
|
||||||
|
if ((ptr = strchr(entry->name, ' ')) != NULL)
|
||||||
|
*ptr = '\0'; /* trim extra spaces. */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
entry->size = PHYSFS_swapULE32(entry->size);
|
||||||
|
entry->startPos = location;
|
||||||
|
location += entry->size;
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
__PHYSFS_sort(info->entries, info->entryCount,
|
||||||
|
grp_entry_cmp, grp_entry_swap);
|
||||||
|
return(1);
|
||||||
|
} /* grp_load_entries */
|
||||||
|
|
||||||
|
|
||||||
|
static DirHandle *GRP_openArchive(const char *name, int forWriting)
|
||||||
|
{
|
||||||
|
GRPinfo *info;
|
||||||
|
DirHandle *retval = malloc(sizeof (DirHandle));
|
||||||
|
PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
info = retval->opaque = malloc(sizeof (GRPinfo));
|
||||||
|
if (info == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto GRP_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
memset(info, '\0', sizeof (GRPinfo));
|
||||||
|
|
||||||
|
info->filename = (char *) malloc(strlen(name) + 1);
|
||||||
|
if (info->filename == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto GRP_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!grp_load_entries(name, forWriting, info))
|
||||||
|
goto GRP_openArchive_failed;
|
||||||
|
|
||||||
|
strcpy(info->filename, name);
|
||||||
|
info->last_mod_time = modtime;
|
||||||
|
retval->funcs = &__PHYSFS_DirFunctions_GRP;
|
||||||
|
return(retval);
|
||||||
|
|
||||||
|
GRP_openArchive_failed:
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
if (retval->opaque != NULL)
|
||||||
|
{
|
||||||
|
if (info->filename != NULL)
|
||||||
|
free(info->filename);
|
||||||
|
if (info->entries != NULL)
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
} /* if */
|
||||||
|
free(retval);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
} /* GRP_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static LinkedStringList *GRP_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks)
|
||||||
|
{
|
||||||
|
GRPinfo *info = ((GRPinfo *) h->opaque);
|
||||||
|
GRPentry *entry = info->entries;
|
||||||
|
LinkedStringList *retval = NULL, *p = NULL;
|
||||||
|
PHYSFS_uint32 max = info->entryCount;
|
||||||
|
PHYSFS_uint32 i;
|
||||||
|
|
||||||
|
/* no directories in GRP files. */
|
||||||
|
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < max; i++, entry++)
|
||||||
|
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* GRP_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
static GRPentry *grp_find_entry(GRPinfo *info, const char *name)
|
||||||
|
{
|
||||||
|
char *ptr = strchr(name, '.');
|
||||||
|
GRPentry *a = info->entries;
|
||||||
|
PHYSFS_sint32 lo = 0;
|
||||||
|
PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
|
||||||
|
PHYSFS_sint32 middle;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rule out filenames to avoid unneeded processing...no dirs,
|
||||||
|
* big filenames, or extensions > 3 chars.
|
||||||
|
*/
|
||||||
|
BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
|
{
|
||||||
|
middle = lo + ((hi - lo) / 2);
|
||||||
|
rc = strcmp(name, a[middle].name);
|
||||||
|
if (rc == 0) /* found it! */
|
||||||
|
return(&a[middle]);
|
||||||
|
else if (rc > 0)
|
||||||
|
lo = middle + 1;
|
||||||
|
else
|
||||||
|
hi = middle - 1;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
|
||||||
|
} /* grp_find_entry */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_exists(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
return(grp_find_entry(((GRPinfo *) h->opaque), name) != NULL);
|
||||||
|
} /* GRP_exists */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_isDirectory(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = GRP_exists(h, name);
|
||||||
|
return(0); /* never directories in a groupfile. */
|
||||||
|
} /* GRP_isDirectory */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_isSymLink(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = GRP_exists(h, name);
|
||||||
|
return(0); /* never symlinks in a groupfile. */
|
||||||
|
} /* GRP_isSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 GRP_getLastModTime(DirHandle *h,
|
||||||
|
const char *name,
|
||||||
|
int *fileExists)
|
||||||
|
{
|
||||||
|
GRPinfo *info = ((GRPinfo *) h->opaque);
|
||||||
|
PHYSFS_sint64 retval = -1;
|
||||||
|
|
||||||
|
*fileExists = (grp_find_entry(info, name) != NULL);
|
||||||
|
if (*fileExists) /* use time of GRP itself in the physical filesystem. */
|
||||||
|
retval = ((GRPinfo *) h->opaque)->last_mod_time;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* GRP_getLastModTime */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *GRP_openRead(DirHandle *h, const char *fnm, int *fileExists)
|
||||||
|
{
|
||||||
|
GRPinfo *info = ((GRPinfo *) h->opaque);
|
||||||
|
FileHandle *retval;
|
||||||
|
GRPfileinfo *finfo;
|
||||||
|
GRPentry *entry;
|
||||||
|
|
||||||
|
entry = grp_find_entry(info, fnm);
|
||||||
|
*fileExists = (entry != NULL);
|
||||||
|
BAIL_IF_MACRO(entry == NULL, NULL, NULL);
|
||||||
|
|
||||||
|
retval = (FileHandle *) malloc(sizeof (FileHandle));
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
finfo = (GRPfileinfo *) malloc(sizeof (GRPfileinfo));
|
||||||
|
if (finfo == NULL)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->handle = __PHYSFS_platformOpenRead(info->filename);
|
||||||
|
if ( (finfo->handle == NULL) ||
|
||||||
|
(!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
|
||||||
|
{
|
||||||
|
free(finfo);
|
||||||
|
free(retval);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->curPos = 0;
|
||||||
|
finfo->entry = entry;
|
||||||
|
retval->opaque = (void *) finfo;
|
||||||
|
retval->funcs = &__PHYSFS_FileFunctions_GRP;
|
||||||
|
retval->dirHandle = h;
|
||||||
|
return(retval);
|
||||||
|
} /* GRP_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *GRP_openWrite(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* GRP_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *GRP_openAppend(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* GRP_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_remove(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* GRP_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int GRP_mkdir(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* GRP_mkdir */
|
||||||
|
|
||||||
|
#endif /* defined PHYSFS_SUPPORTS_GRP */
|
||||||
|
|
||||||
|
/* end of grp.c ... */
|
||||||
|
|
|
@ -0,0 +1,581 @@
|
||||||
|
/*
|
||||||
|
* HOG support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* This driver handles Descent I/II HOG archives.
|
||||||
|
*
|
||||||
|
* The 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
|
||||||
|
* another, divided by a 17 bytes header, which specifies the name
|
||||||
|
* and length (in bytes) of the forthcoming file! So you just read
|
||||||
|
* the header with its information of how big the following file is,
|
||||||
|
* and then skip exact that number of bytes to get to the next file
|
||||||
|
* in that HOG.
|
||||||
|
*
|
||||||
|
* char sig[3] = {'D', 'H', 'F'}; // "DHF"=Descent HOG File
|
||||||
|
*
|
||||||
|
* struct {
|
||||||
|
* char file_name[13]; // Filename, padded to 13 bytes with 0s
|
||||||
|
* int file_size; // filesize in bytes
|
||||||
|
* char data[file_size]; // The file data
|
||||||
|
* } FILE_STRUCT; // Repeated until the end of the file.
|
||||||
|
*
|
||||||
|
* (That info is from http://www.descent2.com/ddn/specs/hog/)
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Bradley Bell.
|
||||||
|
* Based on grp.c by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined PHYSFS_SUPPORTS_HOG)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One HOGentry is kept for each file in an open HOG archive.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[13];
|
||||||
|
PHYSFS_uint32 startPos;
|
||||||
|
PHYSFS_uint32 size;
|
||||||
|
} HOGentry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One HOGinfo is kept for each open HOG archive.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
PHYSFS_sint64 last_mod_time;
|
||||||
|
PHYSFS_uint32 entryCount;
|
||||||
|
HOGentry *entries;
|
||||||
|
} HOGinfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One HOGfileinfo is kept for each open file in a HOG archive.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
HOGentry *entry;
|
||||||
|
PHYSFS_uint32 curPos;
|
||||||
|
} HOGfileinfo;
|
||||||
|
|
||||||
|
|
||||||
|
static void HOG_dirClose(DirHandle *h);
|
||||||
|
static PHYSFS_sint64 HOG_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 HOG_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static int HOG_eof(FileHandle *handle);
|
||||||
|
static PHYSFS_sint64 HOG_tell(FileHandle *handle);
|
||||||
|
static int HOG_seek(FileHandle *handle, PHYSFS_uint64 offset);
|
||||||
|
static PHYSFS_sint64 HOG_fileLength(FileHandle *handle);
|
||||||
|
static int HOG_fileClose(FileHandle *handle);
|
||||||
|
static int HOG_isArchive(const char *filename, int forWriting);
|
||||||
|
static DirHandle *HOG_openArchive(const char *name, int forWriting);
|
||||||
|
static LinkedStringList *HOG_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks);
|
||||||
|
static int HOG_exists(DirHandle *h, const char *name);
|
||||||
|
static int HOG_isDirectory(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static int HOG_isSymLink(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static PHYSFS_sint64 HOG_getLastModTime(DirHandle *h, const char *n, int *e);
|
||||||
|
static FileHandle *HOG_openRead(DirHandle *h, const char *name, int *exist);
|
||||||
|
static FileHandle *HOG_openWrite(DirHandle *h, const char *name);
|
||||||
|
static FileHandle *HOG_openAppend(DirHandle *h, const char *name);
|
||||||
|
static int HOG_remove(DirHandle *h, const char *name);
|
||||||
|
static int HOG_mkdir(DirHandle *h, const char *name);
|
||||||
|
|
||||||
|
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_HOG =
|
||||||
|
{
|
||||||
|
"HOG",
|
||||||
|
HOG_ARCHIVE_DESCRIPTION,
|
||||||
|
"Bradley Bell <btb@icculus.org>",
|
||||||
|
"http://icculus.org/physfs/",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_HOG =
|
||||||
|
{
|
||||||
|
HOG_read, /* read() method */
|
||||||
|
HOG_write, /* write() method */
|
||||||
|
HOG_eof, /* eof() method */
|
||||||
|
HOG_tell, /* tell() method */
|
||||||
|
HOG_seek, /* seek() method */
|
||||||
|
HOG_fileLength, /* fileLength() method */
|
||||||
|
HOG_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_HOG =
|
||||||
|
{
|
||||||
|
&__PHYSFS_ArchiveInfo_HOG,
|
||||||
|
HOG_isArchive, /* isArchive() method */
|
||||||
|
HOG_openArchive, /* openArchive() method */
|
||||||
|
HOG_enumerateFiles, /* enumerateFiles() method */
|
||||||
|
HOG_exists, /* exists() method */
|
||||||
|
HOG_isDirectory, /* isDirectory() method */
|
||||||
|
HOG_isSymLink, /* isSymLink() method */
|
||||||
|
HOG_getLastModTime, /* getLastModTime() method */
|
||||||
|
HOG_openRead, /* openRead() method */
|
||||||
|
HOG_openWrite, /* openWrite() method */
|
||||||
|
HOG_openAppend, /* openAppend() method */
|
||||||
|
HOG_remove, /* remove() method */
|
||||||
|
HOG_mkdir, /* mkdir() method */
|
||||||
|
HOG_dirClose /* dirClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void HOG_dirClose(DirHandle *h)
|
||||||
|
{
|
||||||
|
HOGinfo *info = ((HOGinfo *) h->opaque);
|
||||||
|
free(info->filename);
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
free(h);
|
||||||
|
} /* HOG_dirClose */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 HOG_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque);
|
||||||
|
HOGentry *entry = finfo->entry;
|
||||||
|
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
|
||||||
|
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
|
||||||
|
PHYSFS_sint64 rc;
|
||||||
|
|
||||||
|
if (objsLeft < objCount)
|
||||||
|
objCount = objsLeft;
|
||||||
|
|
||||||
|
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
|
||||||
|
if (rc > 0)
|
||||||
|
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* HOG_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 HOG_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* HOG_write */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_eof(FileHandle *handle)
|
||||||
|
{
|
||||||
|
HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque);
|
||||||
|
HOGentry *entry = finfo->entry;
|
||||||
|
return(finfo->curPos >= entry->size);
|
||||||
|
} /* HOG_eof */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 HOG_tell(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(((HOGfileinfo *) (handle->opaque))->curPos);
|
||||||
|
} /* HOG_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_seek(FileHandle *handle, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque);
|
||||||
|
HOGentry *entry = finfo->entry;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
|
||||||
|
rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
|
||||||
|
if (rc)
|
||||||
|
finfo->curPos = (PHYSFS_uint32) offset;
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* HOG_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 HOG_fileLength(FileHandle *handle)
|
||||||
|
{
|
||||||
|
HOGfileinfo *finfo = ((HOGfileinfo *) handle->opaque);
|
||||||
|
return((PHYSFS_sint64) finfo->entry->size);
|
||||||
|
} /* HOG_fileLength */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_fileClose(FileHandle *handle)
|
||||||
|
{
|
||||||
|
HOGfileinfo *finfo = ((HOGfileinfo *) handle->opaque);
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
|
||||||
|
free(finfo);
|
||||||
|
free(handle);
|
||||||
|
return(1);
|
||||||
|
} /* HOG_fileClose */
|
||||||
|
|
||||||
|
|
||||||
|
static int hog_open(const char *filename, int forWriting,
|
||||||
|
void **fh, PHYSFS_uint32 *count)
|
||||||
|
{
|
||||||
|
PHYSFS_uint8 buf[13];
|
||||||
|
PHYSFS_uint32 size;
|
||||||
|
PHYSFS_sint64 pos;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
*fh = NULL;
|
||||||
|
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
|
||||||
|
|
||||||
|
*fh = __PHYSFS_platformOpenRead(filename);
|
||||||
|
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, buf, 3, 1) != 1)
|
||||||
|
goto openHog_failed;
|
||||||
|
|
||||||
|
if (memcmp(buf, "DHF", 3) != 0)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
|
||||||
|
goto openHog_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (__PHYSFS_platformRead(*fh, buf, 13, 1) != 1)
|
||||||
|
break; /* eof here is ok */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, &size, 4, 1) != 1)
|
||||||
|
goto openHog_failed;
|
||||||
|
|
||||||
|
size = PHYSFS_swapULE32(size);
|
||||||
|
|
||||||
|
(*count)++;
|
||||||
|
|
||||||
|
/* Skip over entry... */
|
||||||
|
pos = __PHYSFS_platformTell(*fh);
|
||||||
|
if (pos == -1)
|
||||||
|
goto openHog_failed;
|
||||||
|
if (!__PHYSFS_platformSeek(*fh, pos + size))
|
||||||
|
goto openHog_failed;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
/* Rewind to start of entries... */
|
||||||
|
if (!__PHYSFS_platformSeek(*fh, 3))
|
||||||
|
goto openHog_failed;
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
openHog_failed:
|
||||||
|
if (*fh != NULL)
|
||||||
|
__PHYSFS_platformClose(*fh);
|
||||||
|
|
||||||
|
*count = -1;
|
||||||
|
*fh = NULL;
|
||||||
|
return(0);
|
||||||
|
} /* hog_open */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_isArchive(const char *filename, int forWriting)
|
||||||
|
{
|
||||||
|
void *fh;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
int retval = hog_open(filename, forWriting, &fh, &fileCount);
|
||||||
|
|
||||||
|
if (fh != NULL)
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* HOG_isArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static int hog_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
const HOGentry *a = (const HOGentry *) _a;
|
||||||
|
return(__PHYSFS_platformStricmp(a[one].name, a[two].name));
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* hog_entry_cmp */
|
||||||
|
|
||||||
|
|
||||||
|
static void hog_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
HOGentry tmp;
|
||||||
|
HOGentry *first = &(((HOGentry *) _a)[one]);
|
||||||
|
HOGentry *second = &(((HOGentry *) _a)[two]);
|
||||||
|
memcpy(&tmp, first, sizeof (HOGentry));
|
||||||
|
memcpy(first, second, sizeof (HOGentry));
|
||||||
|
memcpy(second, &tmp, sizeof (HOGentry));
|
||||||
|
} /* if */
|
||||||
|
} /* hog_entry_swap */
|
||||||
|
|
||||||
|
|
||||||
|
static int hog_load_entries(const char *name, int forWriting, HOGinfo *info)
|
||||||
|
{
|
||||||
|
void *fh = NULL;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
HOGentry *entry;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(!hog_open(name, forWriting, &fh, &fileCount), NULL, 0);
|
||||||
|
info->entryCount = fileCount;
|
||||||
|
info->entries = (HOGentry *) malloc(sizeof (HOGentry) * fileCount);
|
||||||
|
if (info->entries == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
|
||||||
|
{
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
entry->size = PHYSFS_swapULE32(entry->size);
|
||||||
|
entry->startPos = (unsigned int) __PHYSFS_platformTell(fh);
|
||||||
|
if (entry->startPos == -1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip over entry */
|
||||||
|
if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size))
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
__PHYSFS_sort(info->entries, info->entryCount,
|
||||||
|
hog_entry_cmp, hog_entry_swap);
|
||||||
|
return(1);
|
||||||
|
} /* hog_load_entries */
|
||||||
|
|
||||||
|
|
||||||
|
static DirHandle *HOG_openArchive(const char *name, int forWriting)
|
||||||
|
{
|
||||||
|
HOGinfo *info;
|
||||||
|
DirHandle *retval = malloc(sizeof (DirHandle));
|
||||||
|
PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
info = retval->opaque = malloc(sizeof (HOGinfo));
|
||||||
|
if (info == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto HOG_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
memset(info, '\0', sizeof (HOGinfo));
|
||||||
|
|
||||||
|
info->filename = (char *) malloc(strlen(name) + 1);
|
||||||
|
if (info->filename == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto HOG_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!hog_load_entries(name, forWriting, info))
|
||||||
|
goto HOG_openArchive_failed;
|
||||||
|
|
||||||
|
strcpy(info->filename, name);
|
||||||
|
info->last_mod_time = modtime;
|
||||||
|
retval->funcs = &__PHYSFS_DirFunctions_HOG;
|
||||||
|
return(retval);
|
||||||
|
|
||||||
|
HOG_openArchive_failed:
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
if (retval->opaque != NULL)
|
||||||
|
{
|
||||||
|
if (info->filename != NULL)
|
||||||
|
free(info->filename);
|
||||||
|
if (info->entries != NULL)
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
} /* if */
|
||||||
|
free(retval);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
} /* HOG_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static LinkedStringList *HOG_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks)
|
||||||
|
{
|
||||||
|
HOGinfo *info = ((HOGinfo *) h->opaque);
|
||||||
|
HOGentry *entry = info->entries;
|
||||||
|
LinkedStringList *retval = NULL, *p = NULL;
|
||||||
|
PHYSFS_uint32 max = info->entryCount;
|
||||||
|
PHYSFS_uint32 i;
|
||||||
|
|
||||||
|
/* no directories in HOG files. */
|
||||||
|
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < max; i++, entry++)
|
||||||
|
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* HOG_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
static HOGentry *hog_find_entry(HOGinfo *info, const char *name)
|
||||||
|
{
|
||||||
|
char *ptr = strchr(name, '.');
|
||||||
|
HOGentry *a = info->entries;
|
||||||
|
PHYSFS_sint32 lo = 0;
|
||||||
|
PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
|
||||||
|
PHYSFS_sint32 middle;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rule out filenames to avoid unneeded processing...no dirs,
|
||||||
|
* big filenames, or extensions > 3 chars.
|
||||||
|
*/
|
||||||
|
BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
|
{
|
||||||
|
middle = lo + ((hi - lo) / 2);
|
||||||
|
rc = __PHYSFS_platformStricmp(name, a[middle].name);
|
||||||
|
if (rc == 0) /* found it! */
|
||||||
|
return(&a[middle]);
|
||||||
|
else if (rc > 0)
|
||||||
|
lo = middle + 1;
|
||||||
|
else
|
||||||
|
hi = middle - 1;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
|
||||||
|
} /* hog_find_entry */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_exists(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
return(hog_find_entry(((HOGinfo *) h->opaque), name) != NULL);
|
||||||
|
} /* HOG_exists */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_isDirectory(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = HOG_exists(h, name);
|
||||||
|
return(0); /* never directories in a groupfile. */
|
||||||
|
} /* HOG_isDirectory */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_isSymLink(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = HOG_exists(h, name);
|
||||||
|
return(0); /* never symlinks in a groupfile. */
|
||||||
|
} /* HOG_isSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 HOG_getLastModTime(DirHandle *h,
|
||||||
|
const char *name,
|
||||||
|
int *fileExists)
|
||||||
|
{
|
||||||
|
HOGinfo *info = ((HOGinfo *) h->opaque);
|
||||||
|
PHYSFS_sint64 retval = -1;
|
||||||
|
|
||||||
|
*fileExists = (hog_find_entry(info, name) != NULL);
|
||||||
|
if (*fileExists) /* use time of HOG itself in the physical filesystem. */
|
||||||
|
retval = ((HOGinfo *) h->opaque)->last_mod_time;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* HOG_getLastModTime */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *HOG_openRead(DirHandle *h, const char *fnm, int *fileExists)
|
||||||
|
{
|
||||||
|
HOGinfo *info = ((HOGinfo *) h->opaque);
|
||||||
|
FileHandle *retval;
|
||||||
|
HOGfileinfo *finfo;
|
||||||
|
HOGentry *entry;
|
||||||
|
|
||||||
|
entry = hog_find_entry(info, fnm);
|
||||||
|
*fileExists = (entry != NULL);
|
||||||
|
BAIL_IF_MACRO(entry == NULL, NULL, NULL);
|
||||||
|
|
||||||
|
retval = (FileHandle *) malloc(sizeof (FileHandle));
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
finfo = (HOGfileinfo *) malloc(sizeof (HOGfileinfo));
|
||||||
|
if (finfo == NULL)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->handle = __PHYSFS_platformOpenRead(info->filename);
|
||||||
|
if ( (finfo->handle == NULL) ||
|
||||||
|
(!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
|
||||||
|
{
|
||||||
|
free(finfo);
|
||||||
|
free(retval);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->curPos = 0;
|
||||||
|
finfo->entry = entry;
|
||||||
|
retval->opaque = (void *) finfo;
|
||||||
|
retval->funcs = &__PHYSFS_FileFunctions_HOG;
|
||||||
|
retval->dirHandle = h;
|
||||||
|
return(retval);
|
||||||
|
} /* HOG_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *HOG_openWrite(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* HOG_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *HOG_openAppend(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* HOG_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_remove(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* HOG_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int HOG_mkdir(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* HOG_mkdir */
|
||||||
|
|
||||||
|
#endif /* defined PHYSFS_SUPPORTS_HOG */
|
||||||
|
|
||||||
|
/* end of hog.c ... */
|
||||||
|
|
|
@ -0,0 +1,539 @@
|
||||||
|
/*
|
||||||
|
* MVL support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* This driver handles Descent II Movielib archives.
|
||||||
|
*
|
||||||
|
* The file format of MVL is quite easy...
|
||||||
|
*
|
||||||
|
* //MVL File format - Written by Heiko Herrmann
|
||||||
|
* char sig[4] = {'D','M', 'V', 'L'}; // "DMVL"=Descent MoVie Library
|
||||||
|
*
|
||||||
|
* int num_files; // the number of files in this MVL
|
||||||
|
*
|
||||||
|
* struct {
|
||||||
|
* char file_name[13]; // Filename, padded to 13 bytes with 0s
|
||||||
|
* int file_size; // filesize in bytes
|
||||||
|
* }DIR_STRUCT[num_files];
|
||||||
|
*
|
||||||
|
* struct {
|
||||||
|
* char data[file_size]; // The file data
|
||||||
|
* }FILE_STRUCT[num_files];
|
||||||
|
*
|
||||||
|
* (That info is from http://www.descent2.com/ddn/specs/mvl/)
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Bradley Bell.
|
||||||
|
* Based on grp.c by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined PHYSFS_SUPPORTS_MVL)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[13];
|
||||||
|
PHYSFS_uint32 startPos;
|
||||||
|
PHYSFS_uint32 size;
|
||||||
|
} MVLentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
PHYSFS_sint64 last_mod_time;
|
||||||
|
PHYSFS_uint32 entryCount;
|
||||||
|
MVLentry *entries;
|
||||||
|
} MVLinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
MVLentry *entry;
|
||||||
|
PHYSFS_uint32 curPos;
|
||||||
|
} MVLfileinfo;
|
||||||
|
|
||||||
|
|
||||||
|
static void MVL_dirClose(DirHandle *h);
|
||||||
|
static PHYSFS_sint64 MVL_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 MVL_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static int MVL_eof(FileHandle *handle);
|
||||||
|
static PHYSFS_sint64 MVL_tell(FileHandle *handle);
|
||||||
|
static int MVL_seek(FileHandle *handle, PHYSFS_uint64 offset);
|
||||||
|
static PHYSFS_sint64 MVL_fileLength(FileHandle *handle);
|
||||||
|
static int MVL_fileClose(FileHandle *handle);
|
||||||
|
static int MVL_isArchive(const char *filename, int forWriting);
|
||||||
|
static DirHandle *MVL_openArchive(const char *name, int forWriting);
|
||||||
|
static LinkedStringList *MVL_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks);
|
||||||
|
static int MVL_exists(DirHandle *h, const char *name);
|
||||||
|
static int MVL_isDirectory(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static int MVL_isSymLink(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static PHYSFS_sint64 MVL_getLastModTime(DirHandle *h, const char *n, int *e);
|
||||||
|
static FileHandle *MVL_openRead(DirHandle *h, const char *name, int *exist);
|
||||||
|
static FileHandle *MVL_openWrite(DirHandle *h, const char *name);
|
||||||
|
static FileHandle *MVL_openAppend(DirHandle *h, const char *name);
|
||||||
|
static int MVL_remove(DirHandle *h, const char *name);
|
||||||
|
static int MVL_mkdir(DirHandle *h, const char *name);
|
||||||
|
|
||||||
|
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_MVL =
|
||||||
|
{
|
||||||
|
"MVL",
|
||||||
|
MVL_ARCHIVE_DESCRIPTION,
|
||||||
|
"Bradley Bell <btb@icculus.org>",
|
||||||
|
"http://icculus.org/physfs/",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_MVL =
|
||||||
|
{
|
||||||
|
MVL_read, /* read() method */
|
||||||
|
MVL_write, /* write() method */
|
||||||
|
MVL_eof, /* eof() method */
|
||||||
|
MVL_tell, /* tell() method */
|
||||||
|
MVL_seek, /* seek() method */
|
||||||
|
MVL_fileLength, /* fileLength() method */
|
||||||
|
MVL_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_MVL =
|
||||||
|
{
|
||||||
|
&__PHYSFS_ArchiveInfo_MVL,
|
||||||
|
MVL_isArchive, /* isArchive() method */
|
||||||
|
MVL_openArchive, /* openArchive() method */
|
||||||
|
MVL_enumerateFiles, /* enumerateFiles() method */
|
||||||
|
MVL_exists, /* exists() method */
|
||||||
|
MVL_isDirectory, /* isDirectory() method */
|
||||||
|
MVL_isSymLink, /* isSymLink() method */
|
||||||
|
MVL_getLastModTime, /* getLastModTime() method */
|
||||||
|
MVL_openRead, /* openRead() method */
|
||||||
|
MVL_openWrite, /* openWrite() method */
|
||||||
|
MVL_openAppend, /* openAppend() method */
|
||||||
|
MVL_remove, /* remove() method */
|
||||||
|
MVL_mkdir, /* mkdir() method */
|
||||||
|
MVL_dirClose /* dirClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void MVL_dirClose(DirHandle *h)
|
||||||
|
{
|
||||||
|
MVLinfo *info = ((MVLinfo *) h->opaque);
|
||||||
|
free(info->filename);
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
free(h);
|
||||||
|
} /* MVL_dirClose */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 MVL_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
MVLfileinfo *finfo = (MVLfileinfo *) (handle->opaque);
|
||||||
|
MVLentry *entry = finfo->entry;
|
||||||
|
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
|
||||||
|
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
|
||||||
|
PHYSFS_sint64 rc;
|
||||||
|
|
||||||
|
if (objsLeft < objCount)
|
||||||
|
objCount = objsLeft;
|
||||||
|
|
||||||
|
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
|
||||||
|
if (rc > 0)
|
||||||
|
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* MVL_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 MVL_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* MVL_write */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_eof(FileHandle *handle)
|
||||||
|
{
|
||||||
|
MVLfileinfo *finfo = (MVLfileinfo *) (handle->opaque);
|
||||||
|
MVLentry *entry = finfo->entry;
|
||||||
|
return(finfo->curPos >= entry->size);
|
||||||
|
} /* MVL_eof */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 MVL_tell(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(((MVLfileinfo *) (handle->opaque))->curPos);
|
||||||
|
} /* MVL_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_seek(FileHandle *handle, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
MVLfileinfo *finfo = (MVLfileinfo *) (handle->opaque);
|
||||||
|
MVLentry *entry = finfo->entry;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
|
||||||
|
rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
|
||||||
|
if (rc)
|
||||||
|
finfo->curPos = (PHYSFS_uint32) offset;
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* MVL_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 MVL_fileLength(FileHandle *handle)
|
||||||
|
{
|
||||||
|
MVLfileinfo *finfo = ((MVLfileinfo *) handle->opaque);
|
||||||
|
return((PHYSFS_sint64) finfo->entry->size);
|
||||||
|
} /* MVL_fileLength */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_fileClose(FileHandle *handle)
|
||||||
|
{
|
||||||
|
MVLfileinfo *finfo = ((MVLfileinfo *) handle->opaque);
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
|
||||||
|
free(finfo);
|
||||||
|
free(handle);
|
||||||
|
return(1);
|
||||||
|
} /* MVL_fileClose */
|
||||||
|
|
||||||
|
|
||||||
|
static int mvl_open(const char *filename, int forWriting,
|
||||||
|
void **fh, PHYSFS_uint32 *count)
|
||||||
|
{
|
||||||
|
PHYSFS_uint8 buf[4];
|
||||||
|
|
||||||
|
*fh = NULL;
|
||||||
|
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
|
||||||
|
|
||||||
|
*fh = __PHYSFS_platformOpenRead(filename);
|
||||||
|
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
|
||||||
|
goto openMvl_failed;
|
||||||
|
|
||||||
|
if (memcmp(buf, "DMVL", 4) != 0)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
|
||||||
|
goto openMvl_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openMvl_failed;
|
||||||
|
|
||||||
|
*count = PHYSFS_swapULE32(*count);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
openMvl_failed:
|
||||||
|
if (*fh != NULL)
|
||||||
|
__PHYSFS_platformClose(*fh);
|
||||||
|
|
||||||
|
*count = -1;
|
||||||
|
*fh = NULL;
|
||||||
|
return(0);
|
||||||
|
} /* mvl_open */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_isArchive(const char *filename, int forWriting)
|
||||||
|
{
|
||||||
|
void *fh;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
int retval = mvl_open(filename, forWriting, &fh, &fileCount);
|
||||||
|
|
||||||
|
if (fh != NULL)
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* MVL_isArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static int mvl_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
const MVLentry *a = (const MVLentry *) _a;
|
||||||
|
return(strcmp(a[one].name, a[two].name));
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* mvl_entry_cmp */
|
||||||
|
|
||||||
|
|
||||||
|
static void mvl_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
MVLentry tmp;
|
||||||
|
MVLentry *first = &(((MVLentry *) _a)[one]);
|
||||||
|
MVLentry *second = &(((MVLentry *) _a)[two]);
|
||||||
|
memcpy(&tmp, first, sizeof (MVLentry));
|
||||||
|
memcpy(first, second, sizeof (MVLentry));
|
||||||
|
memcpy(second, &tmp, sizeof (MVLentry));
|
||||||
|
} /* if */
|
||||||
|
} /* mvl_entry_swap */
|
||||||
|
|
||||||
|
|
||||||
|
static int mvl_load_entries(const char *name, int forWriting, MVLinfo *info)
|
||||||
|
{
|
||||||
|
void *fh = NULL;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
PHYSFS_uint32 location = 8; /* sizeof sig. */
|
||||||
|
MVLentry *entry;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(!mvl_open(name, forWriting, &fh, &fileCount), NULL, 0);
|
||||||
|
info->entryCount = fileCount;
|
||||||
|
info->entries = (MVLentry *) malloc(sizeof (MVLentry) * fileCount);
|
||||||
|
if (info->entries == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
location += (17 * fileCount);
|
||||||
|
|
||||||
|
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
|
||||||
|
{
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
entry->size = PHYSFS_swapULE32(entry->size);
|
||||||
|
entry->startPos = location;
|
||||||
|
location += entry->size;
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
__PHYSFS_sort(info->entries, info->entryCount,
|
||||||
|
mvl_entry_cmp, mvl_entry_swap);
|
||||||
|
return(1);
|
||||||
|
} /* mvl_load_entries */
|
||||||
|
|
||||||
|
|
||||||
|
static DirHandle *MVL_openArchive(const char *name, int forWriting)
|
||||||
|
{
|
||||||
|
MVLinfo *info;
|
||||||
|
DirHandle *retval = malloc(sizeof (DirHandle));
|
||||||
|
PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
info = retval->opaque = malloc(sizeof (MVLinfo));
|
||||||
|
if (info == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto MVL_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
memset(info, '\0', sizeof (MVLinfo));
|
||||||
|
|
||||||
|
info->filename = (char *) malloc(strlen(name) + 1);
|
||||||
|
if (info->filename == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto MVL_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!mvl_load_entries(name, forWriting, info))
|
||||||
|
goto MVL_openArchive_failed;
|
||||||
|
|
||||||
|
strcpy(info->filename, name);
|
||||||
|
info->last_mod_time = modtime;
|
||||||
|
retval->funcs = &__PHYSFS_DirFunctions_MVL;
|
||||||
|
return(retval);
|
||||||
|
|
||||||
|
MVL_openArchive_failed:
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
if (retval->opaque != NULL)
|
||||||
|
{
|
||||||
|
if (info->filename != NULL)
|
||||||
|
free(info->filename);
|
||||||
|
if (info->entries != NULL)
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
} /* if */
|
||||||
|
free(retval);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
} /* MVL_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static LinkedStringList *MVL_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks)
|
||||||
|
{
|
||||||
|
MVLinfo *info = ((MVLinfo *) h->opaque);
|
||||||
|
MVLentry *entry = info->entries;
|
||||||
|
LinkedStringList *retval = NULL, *p = NULL;
|
||||||
|
PHYSFS_uint32 max = info->entryCount;
|
||||||
|
PHYSFS_uint32 i;
|
||||||
|
|
||||||
|
/* no directories in MVL files. */
|
||||||
|
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < max; i++, entry++)
|
||||||
|
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* MVL_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
static MVLentry *mvl_find_entry(MVLinfo *info, const char *name)
|
||||||
|
{
|
||||||
|
char *ptr = strchr(name, '.');
|
||||||
|
MVLentry *a = info->entries;
|
||||||
|
PHYSFS_sint32 lo = 0;
|
||||||
|
PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
|
||||||
|
PHYSFS_sint32 middle;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rule out filenames to avoid unneeded processing...no dirs,
|
||||||
|
* big filenames, or extensions > 3 chars.
|
||||||
|
*/
|
||||||
|
BAIL_IF_MACRO((ptr) && (strlen(ptr) > 4), ERR_NO_SUCH_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(strlen(name) > 12, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(strchr(name, '/') != NULL, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
|
{
|
||||||
|
middle = lo + ((hi - lo) / 2);
|
||||||
|
rc = __PHYSFS_platformStricmp(name, a[middle].name);
|
||||||
|
if (rc == 0) /* found it! */
|
||||||
|
return(&a[middle]);
|
||||||
|
else if (rc > 0)
|
||||||
|
lo = middle + 1;
|
||||||
|
else
|
||||||
|
hi = middle - 1;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
|
||||||
|
} /* mvl_find_entry */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_exists(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
return(mvl_find_entry(((MVLinfo *) h->opaque), name) != NULL);
|
||||||
|
} /* MVL_exists */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_isDirectory(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = MVL_exists(h, name);
|
||||||
|
return(0); /* never directories in a groupfile. */
|
||||||
|
} /* MVL_isDirectory */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_isSymLink(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = MVL_exists(h, name);
|
||||||
|
return(0); /* never symlinks in a groupfile. */
|
||||||
|
} /* MVL_isSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 MVL_getLastModTime(DirHandle *h,
|
||||||
|
const char *name,
|
||||||
|
int *fileExists)
|
||||||
|
{
|
||||||
|
MVLinfo *info = ((MVLinfo *) h->opaque);
|
||||||
|
PHYSFS_sint64 retval = -1;
|
||||||
|
|
||||||
|
*fileExists = (mvl_find_entry(info, name) != NULL);
|
||||||
|
if (*fileExists) /* use time of MVL itself in the physical filesystem. */
|
||||||
|
retval = ((MVLinfo *) h->opaque)->last_mod_time;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* MVL_getLastModTime */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *MVL_openRead(DirHandle *h, const char *fnm, int *fileExists)
|
||||||
|
{
|
||||||
|
MVLinfo *info = ((MVLinfo *) h->opaque);
|
||||||
|
FileHandle *retval;
|
||||||
|
MVLfileinfo *finfo;
|
||||||
|
MVLentry *entry;
|
||||||
|
|
||||||
|
entry = mvl_find_entry(info, fnm);
|
||||||
|
*fileExists = (entry != NULL);
|
||||||
|
BAIL_IF_MACRO(entry == NULL, NULL, NULL);
|
||||||
|
|
||||||
|
retval = (FileHandle *) malloc(sizeof (FileHandle));
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
finfo = (MVLfileinfo *) malloc(sizeof (MVLfileinfo));
|
||||||
|
if (finfo == NULL)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->handle = __PHYSFS_platformOpenRead(info->filename);
|
||||||
|
if ( (finfo->handle == NULL) ||
|
||||||
|
(!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
|
||||||
|
{
|
||||||
|
free(finfo);
|
||||||
|
free(retval);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->curPos = 0;
|
||||||
|
finfo->entry = entry;
|
||||||
|
retval->opaque = (void *) finfo;
|
||||||
|
retval->funcs = &__PHYSFS_FileFunctions_MVL;
|
||||||
|
retval->dirHandle = h;
|
||||||
|
return(retval);
|
||||||
|
} /* MVL_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *MVL_openWrite(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* MVL_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *MVL_openAppend(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* MVL_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_remove(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* MVL_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int MVL_mkdir(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* MVL_mkdir */
|
||||||
|
|
||||||
|
#endif /* defined PHYSFS_SUPPORTS_MVL */
|
||||||
|
|
||||||
|
/* end of mvl.c ... */
|
||||||
|
|
|
@ -0,0 +1,685 @@
|
||||||
|
/*
|
||||||
|
* QPAK support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* This archiver handles the archive format utilized by Quake 1 and 2.
|
||||||
|
* Quake3-based games use the PkZip/Info-Zip format (which our zip.c
|
||||||
|
* archiver handles).
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* This format info (in more detail) comes from:
|
||||||
|
* http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/pak.txt
|
||||||
|
*
|
||||||
|
* Quake PAK Format
|
||||||
|
*
|
||||||
|
* Header
|
||||||
|
* (4 bytes) signature = 'PACK'
|
||||||
|
* (4 bytes) directory offset
|
||||||
|
* (4 bytes) directory length
|
||||||
|
*
|
||||||
|
* Directory
|
||||||
|
* (56 bytes) file name
|
||||||
|
* (4 bytes) file position
|
||||||
|
* (4 bytes) file length
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined PHYSFS_SUPPORTS_QPAK)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
#if 1 /* Make this case insensitive? */
|
||||||
|
#define QPAK_strcmp(x, y) __PHYSFS_platformStricmp(x, y)
|
||||||
|
#define QPAK_strncmp(x, y, z) __PHYSFS_platformStrnicmp(x, y, z)
|
||||||
|
#else
|
||||||
|
#define QPAK_strcmp(x, y) strcmp(x, y)
|
||||||
|
#define QPAK_strncmp(x, y, z) strncmp(x, y, z)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[56];
|
||||||
|
PHYSFS_uint32 startPos;
|
||||||
|
PHYSFS_uint32 size;
|
||||||
|
} QPAKentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
PHYSFS_sint64 last_mod_time;
|
||||||
|
PHYSFS_uint32 entryCount;
|
||||||
|
QPAKentry *entries;
|
||||||
|
} QPAKinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
QPAKentry *entry;
|
||||||
|
PHYSFS_uint32 curPos;
|
||||||
|
} QPAKfileinfo;
|
||||||
|
|
||||||
|
/* Magic numbers... */
|
||||||
|
#define QPAK_SIGNATURE 0x4b434150 /* "PACK" in ASCII. */
|
||||||
|
|
||||||
|
|
||||||
|
static void QPAK_dirClose(DirHandle *h);
|
||||||
|
static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static int QPAK_eof(FileHandle *handle);
|
||||||
|
static PHYSFS_sint64 QPAK_tell(FileHandle *handle);
|
||||||
|
static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset);
|
||||||
|
static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle);
|
||||||
|
static int QPAK_fileClose(FileHandle *handle);
|
||||||
|
static int QPAK_isArchive(const char *filename, int forWriting);
|
||||||
|
static DirHandle *QPAK_openArchive(const char *name, int forWriting);
|
||||||
|
static LinkedStringList *QPAK_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks);
|
||||||
|
static int QPAK_exists(DirHandle *h, const char *name);
|
||||||
|
static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *n, int *e);
|
||||||
|
static FileHandle *QPAK_openRead(DirHandle *h, const char *name, int *exist);
|
||||||
|
static FileHandle *QPAK_openWrite(DirHandle *h, const char *name);
|
||||||
|
static FileHandle *QPAK_openAppend(DirHandle *h, const char *name);
|
||||||
|
static int QPAK_remove(DirHandle *h, const char *name);
|
||||||
|
static int QPAK_mkdir(DirHandle *h, const char *name);
|
||||||
|
|
||||||
|
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK =
|
||||||
|
{
|
||||||
|
"PAK",
|
||||||
|
QPAK_ARCHIVE_DESCRIPTION,
|
||||||
|
"Ryan C. Gordon <icculus@icculus.org>",
|
||||||
|
"http://icculus.org/physfs/",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_QPAK =
|
||||||
|
{
|
||||||
|
QPAK_read, /* read() method */
|
||||||
|
QPAK_write, /* write() method */
|
||||||
|
QPAK_eof, /* eof() method */
|
||||||
|
QPAK_tell, /* tell() method */
|
||||||
|
QPAK_seek, /* seek() method */
|
||||||
|
QPAK_fileLength, /* fileLength() method */
|
||||||
|
QPAK_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_QPAK =
|
||||||
|
{
|
||||||
|
&__PHYSFS_ArchiveInfo_QPAK,
|
||||||
|
QPAK_isArchive, /* isArchive() method */
|
||||||
|
QPAK_openArchive, /* openArchive() method */
|
||||||
|
QPAK_enumerateFiles, /* enumerateFiles() method */
|
||||||
|
QPAK_exists, /* exists() method */
|
||||||
|
QPAK_isDirectory, /* isDirectory() method */
|
||||||
|
QPAK_isSymLink, /* isSymLink() method */
|
||||||
|
QPAK_getLastModTime, /* getLastModTime() method */
|
||||||
|
QPAK_openRead, /* openRead() method */
|
||||||
|
QPAK_openWrite, /* openWrite() method */
|
||||||
|
QPAK_openAppend, /* openAppend() method */
|
||||||
|
QPAK_remove, /* remove() method */
|
||||||
|
QPAK_mkdir, /* mkdir() method */
|
||||||
|
QPAK_dirClose /* dirClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void QPAK_dirClose(DirHandle *h)
|
||||||
|
{
|
||||||
|
QPAKinfo *info = ((QPAKinfo *) h->opaque);
|
||||||
|
free(info->filename);
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
free(h);
|
||||||
|
} /* QPAK_dirClose */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque);
|
||||||
|
QPAKentry *entry = finfo->entry;
|
||||||
|
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
|
||||||
|
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
|
||||||
|
PHYSFS_sint64 rc;
|
||||||
|
|
||||||
|
if (objsLeft < objCount)
|
||||||
|
objCount = objsLeft;
|
||||||
|
|
||||||
|
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
|
||||||
|
if (rc > 0)
|
||||||
|
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* QPAK_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* QPAK_write */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_eof(FileHandle *handle)
|
||||||
|
{
|
||||||
|
QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque);
|
||||||
|
QPAKentry *entry = finfo->entry;
|
||||||
|
return(finfo->curPos >= entry->size);
|
||||||
|
} /* QPAK_eof */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 QPAK_tell(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(((QPAKfileinfo *) (handle->opaque))->curPos);
|
||||||
|
} /* QPAK_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque);
|
||||||
|
QPAKentry *entry = finfo->entry;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
|
||||||
|
rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
|
||||||
|
if (rc)
|
||||||
|
finfo->curPos = (PHYSFS_uint32) offset;
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* QPAK_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle)
|
||||||
|
{
|
||||||
|
QPAKfileinfo *finfo = ((QPAKfileinfo *) handle->opaque);
|
||||||
|
return((PHYSFS_sint64) finfo->entry->size);
|
||||||
|
} /* QPAK_fileLength */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_fileClose(FileHandle *handle)
|
||||||
|
{
|
||||||
|
QPAKfileinfo *finfo = ((QPAKfileinfo *) handle->opaque);
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
|
||||||
|
free(finfo);
|
||||||
|
free(handle);
|
||||||
|
return(1);
|
||||||
|
} /* QPAK_fileClose */
|
||||||
|
|
||||||
|
|
||||||
|
static int qpak_open(const char *filename, int forWriting,
|
||||||
|
void **fh, PHYSFS_uint32 *count)
|
||||||
|
{
|
||||||
|
PHYSFS_uint32 buf;
|
||||||
|
|
||||||
|
*fh = NULL;
|
||||||
|
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
|
||||||
|
|
||||||
|
*fh = __PHYSFS_platformOpenRead(filename);
|
||||||
|
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, &buf, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openQpak_failed;
|
||||||
|
|
||||||
|
buf = PHYSFS_swapULE32(buf);
|
||||||
|
if (buf != QPAK_SIGNATURE)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
|
||||||
|
goto openQpak_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, &buf, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openQpak_failed;
|
||||||
|
|
||||||
|
buf = PHYSFS_swapULE32(buf); /* directory table offset. */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openQpak_failed;
|
||||||
|
|
||||||
|
*count = PHYSFS_swapULE32(*count);
|
||||||
|
|
||||||
|
if ((*count % 64) != 0) /* corrupted archive? */
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_CORRUPTED);
|
||||||
|
goto openQpak_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!__PHYSFS_platformSeek(*fh, buf))
|
||||||
|
goto openQpak_failed;
|
||||||
|
|
||||||
|
*count /= 64;
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
openQpak_failed:
|
||||||
|
if (*fh != NULL)
|
||||||
|
__PHYSFS_platformClose(*fh);
|
||||||
|
|
||||||
|
*count = -1;
|
||||||
|
*fh = NULL;
|
||||||
|
return(0);
|
||||||
|
} /* qpak_open */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_isArchive(const char *filename, int forWriting)
|
||||||
|
{
|
||||||
|
void *fh;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
int retval = qpak_open(filename, forWriting, &fh, &fileCount);
|
||||||
|
|
||||||
|
if (fh != NULL)
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* QPAK_isArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static int qpak_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
const QPAKentry *a = (const QPAKentry *) _a;
|
||||||
|
return(QPAK_strcmp(a[one].name, a[two].name));
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* qpak_entry_cmp */
|
||||||
|
|
||||||
|
|
||||||
|
static void qpak_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
QPAKentry tmp;
|
||||||
|
QPAKentry *first = &(((QPAKentry *) _a)[one]);
|
||||||
|
QPAKentry *second = &(((QPAKentry *) _a)[two]);
|
||||||
|
memcpy(&tmp, first, sizeof (QPAKentry));
|
||||||
|
memcpy(first, second, sizeof (QPAKentry));
|
||||||
|
memcpy(second, &tmp, sizeof (QPAKentry));
|
||||||
|
} /* if */
|
||||||
|
} /* qpak_entry_swap */
|
||||||
|
|
||||||
|
|
||||||
|
static int qpak_load_entries(const char *name, int forWriting, QPAKinfo *info)
|
||||||
|
{
|
||||||
|
void *fh = NULL;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
QPAKentry *entry;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(!qpak_open(name, forWriting, &fh, &fileCount), NULL, 0);
|
||||||
|
info->entryCount = fileCount;
|
||||||
|
info->entries = (QPAKentry *) malloc(sizeof (QPAKentry) * fileCount);
|
||||||
|
if (info->entries == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
|
||||||
|
{
|
||||||
|
PHYSFS_uint32 loc;
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh,&entry->name,sizeof(entry->name),1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh,&loc,sizeof(loc),1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh,&entry->size,sizeof(entry->size),1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
entry->size = PHYSFS_swapULE32(entry->size);
|
||||||
|
entry->startPos = PHYSFS_swapULE32(loc);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
__PHYSFS_sort(info->entries, info->entryCount,
|
||||||
|
qpak_entry_cmp, qpak_entry_swap);
|
||||||
|
return(1);
|
||||||
|
} /* qpak_load_entries */
|
||||||
|
|
||||||
|
|
||||||
|
static DirHandle *QPAK_openArchive(const char *name, int forWriting)
|
||||||
|
{
|
||||||
|
QPAKinfo *info;
|
||||||
|
DirHandle *retval = malloc(sizeof (DirHandle));
|
||||||
|
PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
info = retval->opaque = malloc(sizeof (QPAKinfo));
|
||||||
|
if (info == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto QPAK_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
memset(info, '\0', sizeof (QPAKinfo));
|
||||||
|
|
||||||
|
info->filename = (char *) malloc(strlen(name) + 1);
|
||||||
|
if (info->filename == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto QPAK_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!qpak_load_entries(name, forWriting, info))
|
||||||
|
goto QPAK_openArchive_failed;
|
||||||
|
|
||||||
|
strcpy(info->filename, name);
|
||||||
|
info->last_mod_time = modtime;
|
||||||
|
retval->funcs = &__PHYSFS_DirFunctions_QPAK;
|
||||||
|
return(retval);
|
||||||
|
|
||||||
|
QPAK_openArchive_failed:
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
if (retval->opaque != NULL)
|
||||||
|
{
|
||||||
|
if (info->filename != NULL)
|
||||||
|
free(info->filename);
|
||||||
|
if (info->entries != NULL)
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
} /* if */
|
||||||
|
free(retval);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
} /* QPAK_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint32 qpak_find_start_of_dir(QPAKinfo *info, const char *path,
|
||||||
|
int stop_on_first_find)
|
||||||
|
{
|
||||||
|
PHYSFS_sint32 lo = 0;
|
||||||
|
PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
|
||||||
|
PHYSFS_sint32 middle;
|
||||||
|
PHYSFS_uint32 dlen = strlen(path);
|
||||||
|
PHYSFS_sint32 retval = -1;
|
||||||
|
const char *name;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (*path == '\0') /* root dir? */
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
|
||||||
|
dlen--;
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
|
{
|
||||||
|
middle = lo + ((hi - lo) / 2);
|
||||||
|
name = info->entries[middle].name;
|
||||||
|
rc = QPAK_strncmp(path, name, dlen);
|
||||||
|
if (rc == 0)
|
||||||
|
{
|
||||||
|
char ch = name[dlen];
|
||||||
|
if (ch < '/') /* make sure this isn't just a substr match. */
|
||||||
|
rc = -1;
|
||||||
|
else if (ch > '/')
|
||||||
|
rc = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (stop_on_first_find) /* Just checking dir's existance? */
|
||||||
|
return(middle);
|
||||||
|
|
||||||
|
if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
|
||||||
|
return(middle + 1);
|
||||||
|
|
||||||
|
/* there might be more entries earlier in the list. */
|
||||||
|
retval = middle;
|
||||||
|
hi = middle - 1;
|
||||||
|
} /* else */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (rc > 0)
|
||||||
|
lo = middle + 1;
|
||||||
|
else
|
||||||
|
hi = middle - 1;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* qpak_find_start_of_dir */
|
||||||
|
|
||||||
|
|
||||||
|
static LinkedStringList *QPAK_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks)
|
||||||
|
{
|
||||||
|
QPAKinfo *info = ((QPAKinfo *) h->opaque);
|
||||||
|
LinkedStringList *retval = NULL, *p = NULL;
|
||||||
|
PHYSFS_sint32 dlen, dlen_inc, max, i;
|
||||||
|
|
||||||
|
i = qpak_find_start_of_dir(info, dirname, 0);
|
||||||
|
BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
|
||||||
|
dlen = strlen(dirname);
|
||||||
|
if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */
|
||||||
|
dlen--;
|
||||||
|
|
||||||
|
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
|
||||||
|
max = (PHYSFS_sint32) info->entryCount;
|
||||||
|
while (i < max)
|
||||||
|
{
|
||||||
|
char *add;
|
||||||
|
char *ptr;
|
||||||
|
PHYSFS_sint32 ln;
|
||||||
|
char *e = info->entries[i].name;
|
||||||
|
if ((dlen) && ((QPAK_strncmp(e, dirname, dlen)) || (e[dlen] != '/')))
|
||||||
|
break; /* past end of this dir; we're done. */
|
||||||
|
|
||||||
|
add = e + dlen_inc;
|
||||||
|
ptr = strchr(add, '/');
|
||||||
|
ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
|
||||||
|
retval = __PHYSFS_addToLinkedStringList(retval, &p, add, ln);
|
||||||
|
ln += dlen_inc; /* point past entry to children... */
|
||||||
|
|
||||||
|
/* increment counter and skip children of subdirs... */
|
||||||
|
while ((++i < max) && (ptr != NULL))
|
||||||
|
{
|
||||||
|
char *e_new = info->entries[i].name;
|
||||||
|
if ((QPAK_strncmp(e, e_new, ln) != 0) || (e_new[ln] != '/'))
|
||||||
|
break;
|
||||||
|
} /* while */
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* QPAK_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This will find the QPAKentry associated with a path in platform-independent
|
||||||
|
* notation. Directories don't have QPAKentries associated with them, but
|
||||||
|
* (*isDir) will be set to non-zero if a dir was hit.
|
||||||
|
*/
|
||||||
|
static QPAKentry *qpak_find_entry(QPAKinfo *info, const char *path, int *isDir)
|
||||||
|
{
|
||||||
|
QPAKentry *a = info->entries;
|
||||||
|
PHYSFS_sint32 pathlen = strlen(path);
|
||||||
|
PHYSFS_sint32 lo = 0;
|
||||||
|
PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
|
||||||
|
PHYSFS_sint32 middle;
|
||||||
|
const char *thispath = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
|
{
|
||||||
|
middle = lo + ((hi - lo) / 2);
|
||||||
|
thispath = a[middle].name;
|
||||||
|
rc = QPAK_strncmp(path, thispath, pathlen);
|
||||||
|
|
||||||
|
if (rc > 0)
|
||||||
|
lo = middle + 1;
|
||||||
|
|
||||||
|
else if (rc < 0)
|
||||||
|
hi = middle - 1;
|
||||||
|
|
||||||
|
else /* substring match...might be dir or entry or nothing. */
|
||||||
|
{
|
||||||
|
if (isDir != NULL)
|
||||||
|
{
|
||||||
|
*isDir = (thispath[pathlen] == '/');
|
||||||
|
if (*isDir)
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (thispath[pathlen] == '\0') /* found entry? */
|
||||||
|
return(&a[middle]);
|
||||||
|
/* adjust search params, try again. */
|
||||||
|
else if (thispath[pathlen] > '/')
|
||||||
|
hi = middle - 1;
|
||||||
|
else
|
||||||
|
lo = middle + 1;
|
||||||
|
} /* if */
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
if (isDir != NULL)
|
||||||
|
*isDir = 0;
|
||||||
|
|
||||||
|
BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
|
||||||
|
} /* qpak_find_entry */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_exists(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
int isDir;
|
||||||
|
QPAKinfo *info = (QPAKinfo *) h->opaque;
|
||||||
|
QPAKentry *entry = qpak_find_entry(info, name, &isDir);
|
||||||
|
return((entry != NULL) || (isDir));
|
||||||
|
} /* QPAK_exists */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
QPAKinfo *info = (QPAKinfo *) h->opaque;
|
||||||
|
int isDir;
|
||||||
|
QPAKentry *entry = qpak_find_entry(info, name, &isDir);
|
||||||
|
|
||||||
|
*fileExists = ((isDir) || (entry != NULL));
|
||||||
|
if (isDir)
|
||||||
|
return(1); /* definitely a dir. */
|
||||||
|
|
||||||
|
BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
|
||||||
|
} /* QPAK_isDirectory */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = QPAK_exists(h, name);
|
||||||
|
return(0); /* never symlinks in a quake pak. */
|
||||||
|
} /* QPAK_isSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h,
|
||||||
|
const char *name,
|
||||||
|
int *fileExists)
|
||||||
|
{
|
||||||
|
int isDir;
|
||||||
|
QPAKinfo *info = ((QPAKinfo *) h->opaque);
|
||||||
|
PHYSFS_sint64 retval = -1;
|
||||||
|
QPAKentry *entry = qpak_find_entry(info, name, &isDir);
|
||||||
|
|
||||||
|
*fileExists = ((isDir) || (entry != NULL));
|
||||||
|
if (*fileExists) /* use time of QPAK itself in the physical filesystem. */
|
||||||
|
retval = info->last_mod_time;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* QPAK_getLastModTime */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *QPAK_openRead(DirHandle *h, const char *fnm, int *fileExists)
|
||||||
|
{
|
||||||
|
QPAKinfo *info = ((QPAKinfo *) h->opaque);
|
||||||
|
FileHandle *retval;
|
||||||
|
QPAKfileinfo *finfo;
|
||||||
|
QPAKentry *entry;
|
||||||
|
int isDir;
|
||||||
|
|
||||||
|
entry = qpak_find_entry(info, fnm, &isDir);
|
||||||
|
*fileExists = ((entry != NULL) || (isDir));
|
||||||
|
BAIL_IF_MACRO(isDir, ERR_NOT_A_FILE, NULL);
|
||||||
|
BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, NULL);
|
||||||
|
|
||||||
|
retval = (FileHandle *) malloc(sizeof (FileHandle));
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
finfo = (QPAKfileinfo *) malloc(sizeof (QPAKfileinfo));
|
||||||
|
if (finfo == NULL)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->handle = __PHYSFS_platformOpenRead(info->filename);
|
||||||
|
if ( (finfo->handle == NULL) ||
|
||||||
|
(!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
|
||||||
|
{
|
||||||
|
free(finfo);
|
||||||
|
free(retval);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->curPos = 0;
|
||||||
|
finfo->entry = entry;
|
||||||
|
retval->opaque = (void *) finfo;
|
||||||
|
retval->funcs = &__PHYSFS_FileFunctions_QPAK;
|
||||||
|
retval->dirHandle = h;
|
||||||
|
return(retval);
|
||||||
|
} /* QPAK_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *QPAK_openWrite(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* QPAK_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *QPAK_openAppend(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* QPAK_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_remove(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* QPAK_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int QPAK_mkdir(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* QPAK_mkdir */
|
||||||
|
|
||||||
|
#endif /* defined PHYSFS_SUPPORTS_QPAK */
|
||||||
|
|
||||||
|
/* end of qpak.c ... */
|
||||||
|
|
|
@ -0,0 +1,605 @@
|
||||||
|
/*
|
||||||
|
* WAD support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* This driver handles DOOM engine archives ("wads").
|
||||||
|
* This format (but not this driver) was designed by id Software for use
|
||||||
|
* with the DOOM engine.
|
||||||
|
* The specs of the format are from the unofficial doom specs v1.666
|
||||||
|
* found here: http://www.gamers.org/dhs/helpdocs/dmsp1666.html
|
||||||
|
* The format of the archive: (from the specs)
|
||||||
|
*
|
||||||
|
* A WAD file has three parts:
|
||||||
|
* (1) a twelve-byte header
|
||||||
|
* (2) one or more "lumps"
|
||||||
|
* (3) a directory or "info table" that contains the names, offsets, and
|
||||||
|
* sizes of all the lumps in the WAD
|
||||||
|
*
|
||||||
|
* The header consists of three four-byte parts:
|
||||||
|
* (a) an ASCII string which must be either "IWAD" or "PWAD"
|
||||||
|
* (b) a 4-byte (long) integer which is the number of lumps in the wad
|
||||||
|
* (c) a long integer which is the file offset to the start of
|
||||||
|
* the directory
|
||||||
|
*
|
||||||
|
* The directory has one 16-byte entry for every lump. Each entry consists
|
||||||
|
* of three parts:
|
||||||
|
*
|
||||||
|
* (a) a long integer, the file offset to the start of the lump
|
||||||
|
* (b) a long integer, the size of the lump in bytes
|
||||||
|
* (c) an 8-byte ASCII string, the name of the lump, padded with zeros.
|
||||||
|
* For example, the "DEMO1" entry in hexadecimal would be
|
||||||
|
* (44 45 4D 4F 31 00 00 00)
|
||||||
|
*
|
||||||
|
* Note that there is no way to tell if an opened WAD archive is a
|
||||||
|
* IWAD or PWAD with this archiver.
|
||||||
|
* I couldn't think of a way to provide that information, without being too
|
||||||
|
* hacky.
|
||||||
|
* I don't think it's really that important though.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Travis Wells, based on the GRP archiver by
|
||||||
|
* Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined PHYSFS_SUPPORTS_WAD)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[18];
|
||||||
|
PHYSFS_uint32 startPos;
|
||||||
|
PHYSFS_uint32 size;
|
||||||
|
} WADentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
PHYSFS_sint64 last_mod_time;
|
||||||
|
PHYSFS_uint32 entryCount;
|
||||||
|
PHYSFS_uint32 entryOffset;
|
||||||
|
WADentry *entries;
|
||||||
|
} WADinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *handle;
|
||||||
|
WADentry *entry;
|
||||||
|
PHYSFS_uint32 curPos;
|
||||||
|
} WADfileinfo;
|
||||||
|
|
||||||
|
|
||||||
|
static void WAD_dirClose(DirHandle *h);
|
||||||
|
static PHYSFS_sint64 WAD_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static PHYSFS_sint64 WAD_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
|
||||||
|
static int WAD_eof(FileHandle *handle);
|
||||||
|
static PHYSFS_sint64 WAD_tell(FileHandle *handle);
|
||||||
|
static int WAD_seek(FileHandle *handle, PHYSFS_uint64 offset);
|
||||||
|
static PHYSFS_sint64 WAD_fileLength(FileHandle *handle);
|
||||||
|
static int WAD_fileClose(FileHandle *handle);
|
||||||
|
static int WAD_isArchive(const char *filename, int forWriting);
|
||||||
|
static DirHandle *WAD_openArchive(const char *name, int forWriting);
|
||||||
|
static LinkedStringList *WAD_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks);
|
||||||
|
static int WAD_exists(DirHandle *h, const char *name);
|
||||||
|
static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static int WAD_isSymLink(DirHandle *h, const char *name, int *fileExists);
|
||||||
|
static PHYSFS_sint64 WAD_getLastModTime(DirHandle *h, const char *n, int *e);
|
||||||
|
static FileHandle *WAD_openRead(DirHandle *h, const char *name, int *exist);
|
||||||
|
static FileHandle *WAD_openWrite(DirHandle *h, const char *name);
|
||||||
|
static FileHandle *WAD_openAppend(DirHandle *h, const char *name);
|
||||||
|
static int WAD_remove(DirHandle *h, const char *name);
|
||||||
|
static int WAD_mkdir(DirHandle *h, const char *name);
|
||||||
|
|
||||||
|
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_WAD =
|
||||||
|
{
|
||||||
|
"WAD",
|
||||||
|
WAD_ARCHIVE_DESCRIPTION,
|
||||||
|
"Travis Wells <traviswells@mchsi.com>",
|
||||||
|
"http://www.3dmm2.com/doom/",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileFunctions_WAD =
|
||||||
|
{
|
||||||
|
WAD_read, /* read() method */
|
||||||
|
WAD_write, /* write() method */
|
||||||
|
WAD_eof, /* eof() method */
|
||||||
|
WAD_tell, /* tell() method */
|
||||||
|
WAD_seek, /* seek() method */
|
||||||
|
WAD_fileLength, /* fileLength() method */
|
||||||
|
WAD_fileClose /* fileClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_WAD =
|
||||||
|
{
|
||||||
|
&__PHYSFS_ArchiveInfo_WAD,
|
||||||
|
WAD_isArchive, /* isArchive() method */
|
||||||
|
WAD_openArchive, /* openArchive() method */
|
||||||
|
WAD_enumerateFiles, /* enumerateFiles() method */
|
||||||
|
WAD_exists, /* exists() method */
|
||||||
|
WAD_isDirectory, /* isDirectory() method */
|
||||||
|
WAD_isSymLink, /* isSymLink() method */
|
||||||
|
WAD_getLastModTime, /* getLastModTime() method */
|
||||||
|
WAD_openRead, /* openRead() method */
|
||||||
|
WAD_openWrite, /* openWrite() method */
|
||||||
|
WAD_openAppend, /* openAppend() method */
|
||||||
|
WAD_remove, /* remove() method */
|
||||||
|
WAD_mkdir, /* mkdir() method */
|
||||||
|
WAD_dirClose /* dirClose() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void WAD_dirClose(DirHandle *h)
|
||||||
|
{
|
||||||
|
WADinfo *info = ((WADinfo *) h->opaque);
|
||||||
|
free(info->filename);
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
free(h);
|
||||||
|
} /* WAD_dirClose */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 WAD_read(FileHandle *handle, void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
WADfileinfo *finfo = (WADfileinfo *) (handle->opaque);
|
||||||
|
WADentry *entry = finfo->entry;
|
||||||
|
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
|
||||||
|
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
|
||||||
|
PHYSFS_sint64 rc;
|
||||||
|
|
||||||
|
if (objsLeft < objCount)
|
||||||
|
objCount = objsLeft;
|
||||||
|
|
||||||
|
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
|
||||||
|
if (rc > 0)
|
||||||
|
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* WAD_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 WAD_write(FileHandle *handle, const void *buffer,
|
||||||
|
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
|
||||||
|
} /* WAD_write */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_eof(FileHandle *handle)
|
||||||
|
{
|
||||||
|
WADfileinfo *finfo = (WADfileinfo *) (handle->opaque);
|
||||||
|
WADentry *entry = finfo->entry;
|
||||||
|
return(finfo->curPos >= entry->size);
|
||||||
|
} /* WAD_eof */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 WAD_tell(FileHandle *handle)
|
||||||
|
{
|
||||||
|
return(((WADfileinfo *) (handle->opaque))->curPos);
|
||||||
|
} /* WAD_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_seek(FileHandle *handle, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
WADfileinfo *finfo = (WADfileinfo *) (handle->opaque);
|
||||||
|
WADentry *entry = finfo->entry;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
BAIL_IF_MACRO(offset >= entry->size, ERR_PAST_EOF, 0);
|
||||||
|
rc = __PHYSFS_platformSeek(finfo->handle, entry->startPos + offset);
|
||||||
|
if (rc)
|
||||||
|
finfo->curPos = (PHYSFS_uint32) offset;
|
||||||
|
|
||||||
|
return(rc);
|
||||||
|
} /* WAD_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 WAD_fileLength(FileHandle *handle)
|
||||||
|
{
|
||||||
|
WADfileinfo *finfo = ((WADfileinfo *) handle->opaque);
|
||||||
|
return((PHYSFS_sint64) finfo->entry->size);
|
||||||
|
} /* WAD_fileLength */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_fileClose(FileHandle *handle)
|
||||||
|
{
|
||||||
|
WADfileinfo *finfo = ((WADfileinfo *) handle->opaque);
|
||||||
|
BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0);
|
||||||
|
free(finfo);
|
||||||
|
free(handle);
|
||||||
|
return(1);
|
||||||
|
} /* WAD_fileClose */
|
||||||
|
|
||||||
|
|
||||||
|
static int wad_open(const char *filename, int forWriting,
|
||||||
|
void **fh, PHYSFS_uint32 *count,PHYSFS_uint32 *offset)
|
||||||
|
{
|
||||||
|
PHYSFS_uint8 buf[4];
|
||||||
|
|
||||||
|
*fh = NULL;
|
||||||
|
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
|
||||||
|
|
||||||
|
*fh = __PHYSFS_platformOpenRead(filename);
|
||||||
|
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
|
||||||
|
goto openWad_failed;
|
||||||
|
|
||||||
|
if (memcmp(buf, "IWAD", 4) != 0 && memcmp(buf, "PWAD", 4) != 0)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
|
||||||
|
goto openWad_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openWad_failed;
|
||||||
|
|
||||||
|
*count = PHYSFS_swapULE32(*count);
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(*fh, offset, sizeof (PHYSFS_uint32), 1) != 1)
|
||||||
|
goto openWad_failed;
|
||||||
|
|
||||||
|
*offset = PHYSFS_swapULE32(*offset);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
openWad_failed:
|
||||||
|
if (*fh != NULL)
|
||||||
|
__PHYSFS_platformClose(*fh);
|
||||||
|
|
||||||
|
*count = -1;
|
||||||
|
*fh = NULL;
|
||||||
|
return(0);
|
||||||
|
} /* wad_open */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_isArchive(const char *filename, int forWriting)
|
||||||
|
{
|
||||||
|
void *fh;
|
||||||
|
PHYSFS_uint32 fileCount,offset;
|
||||||
|
int retval = wad_open(filename, forWriting, &fh, &fileCount,&offset);
|
||||||
|
|
||||||
|
if (fh != NULL)
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* WAD_isArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static int wad_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
const WADentry *a = (const WADentry *) _a;
|
||||||
|
return(strcmp(a[one].name, a[two].name));
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} /* wad_entry_cmp */
|
||||||
|
|
||||||
|
|
||||||
|
static void wad_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two)
|
||||||
|
{
|
||||||
|
if (one != two)
|
||||||
|
{
|
||||||
|
WADentry tmp;
|
||||||
|
WADentry *first = &(((WADentry *) _a)[one]);
|
||||||
|
WADentry *second = &(((WADentry *) _a)[two]);
|
||||||
|
memcpy(&tmp, first, sizeof (WADentry));
|
||||||
|
memcpy(first, second, sizeof (WADentry));
|
||||||
|
memcpy(second, &tmp, sizeof (WADentry));
|
||||||
|
} /* if */
|
||||||
|
} /* wad_entry_swap */
|
||||||
|
|
||||||
|
|
||||||
|
static int wad_load_entries(const char *name, int forWriting, WADinfo *info)
|
||||||
|
{
|
||||||
|
void *fh = NULL;
|
||||||
|
PHYSFS_uint32 fileCount;
|
||||||
|
PHYSFS_uint32 directoryOffset;
|
||||||
|
WADentry *entry;
|
||||||
|
char lastDirectory[9];
|
||||||
|
|
||||||
|
lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0);
|
||||||
|
info->entryCount = fileCount;
|
||||||
|
info->entries = (WADentry *) malloc(sizeof (WADentry) * fileCount);
|
||||||
|
if (info->entries == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
__PHYSFS_platformSeek(fh,directoryOffset);
|
||||||
|
|
||||||
|
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
|
||||||
|
{
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->startPos, 4, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (__PHYSFS_platformRead(fh, &entry->name, 8, 1) != 1)
|
||||||
|
{
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
entry->name[8] = '\0'; /* name might not be null-terminated in file. */
|
||||||
|
entry->size = PHYSFS_swapULE32(entry->size);
|
||||||
|
entry->startPos = PHYSFS_swapULE32(entry->startPos);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
__PHYSFS_platformClose(fh);
|
||||||
|
|
||||||
|
__PHYSFS_sort(info->entries, info->entryCount,
|
||||||
|
wad_entry_cmp, wad_entry_swap);
|
||||||
|
return(1);
|
||||||
|
} /* wad_load_entries */
|
||||||
|
|
||||||
|
|
||||||
|
static DirHandle *WAD_openArchive(const char *name, int forWriting)
|
||||||
|
{
|
||||||
|
WADinfo *info;
|
||||||
|
DirHandle *retval = malloc(sizeof (DirHandle));
|
||||||
|
PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name);
|
||||||
|
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
info = retval->opaque = malloc(sizeof (WADinfo));
|
||||||
|
if (info == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto WAD_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
memset(info, '\0', sizeof (WADinfo));
|
||||||
|
|
||||||
|
info->filename = (char *) malloc(strlen(name) + 1);
|
||||||
|
if (info->filename == NULL)
|
||||||
|
{
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
goto WAD_openArchive_failed;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!wad_load_entries(name, forWriting, info))
|
||||||
|
goto WAD_openArchive_failed;
|
||||||
|
|
||||||
|
strcpy(info->filename, name);
|
||||||
|
info->last_mod_time = modtime;
|
||||||
|
retval->funcs = &__PHYSFS_DirFunctions_WAD;
|
||||||
|
return(retval);
|
||||||
|
|
||||||
|
WAD_openArchive_failed:
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
if (retval->opaque != NULL)
|
||||||
|
{
|
||||||
|
if (info->filename != NULL)
|
||||||
|
free(info->filename);
|
||||||
|
if (info->entries != NULL)
|
||||||
|
free(info->entries);
|
||||||
|
free(info);
|
||||||
|
} /* if */
|
||||||
|
free(retval);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
} /* WAD_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static LinkedStringList *WAD_enumerateFiles(DirHandle *h,
|
||||||
|
const char *dirname,
|
||||||
|
int omitSymLinks)
|
||||||
|
{
|
||||||
|
WADinfo *info = ((WADinfo *) h->opaque);
|
||||||
|
WADentry *entry = info->entries;
|
||||||
|
LinkedStringList *retval = NULL, *p = NULL;
|
||||||
|
PHYSFS_uint32 max = info->entryCount;
|
||||||
|
PHYSFS_uint32 i;
|
||||||
|
char *sep;
|
||||||
|
|
||||||
|
if (dirname[0] == 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < max; i++, entry++)
|
||||||
|
{
|
||||||
|
if (strchr(entry->name, '/') == NULL)
|
||||||
|
{
|
||||||
|
retval = __PHYSFS_addToLinkedStringList(retval, &p,
|
||||||
|
entry->name, -1);
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
} /* if */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < max; i++, entry++)
|
||||||
|
{
|
||||||
|
sep = strchr(entry->name, '/');
|
||||||
|
if (sep != NULL)
|
||||||
|
{
|
||||||
|
if (strncmp(dirname, entry->name, (sep-entry->name)) == 0)
|
||||||
|
{
|
||||||
|
retval = __PHYSFS_addToLinkedStringList(retval, &p,
|
||||||
|
sep + 1, -1);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* WAD_enumerateFiles */
|
||||||
|
|
||||||
|
|
||||||
|
static WADentry *wad_find_entry(WADinfo *info, const char *name)
|
||||||
|
{
|
||||||
|
WADentry *a = info->entries;
|
||||||
|
PHYSFS_sint32 lo = 0;
|
||||||
|
PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
|
||||||
|
PHYSFS_sint32 middle;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
|
{
|
||||||
|
middle = lo + ((hi - lo) / 2);
|
||||||
|
rc = strcmp(name, a[middle].name);
|
||||||
|
if (rc == 0) /* found it! */
|
||||||
|
return(&a[middle]);
|
||||||
|
else if (rc > 0)
|
||||||
|
lo = middle + 1;
|
||||||
|
else
|
||||||
|
hi = middle - 1;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
|
||||||
|
} /* wad_find_entry */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_exists(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
return(wad_find_entry(((WADinfo *) h->opaque), name) != NULL);
|
||||||
|
} /* WAD_exists */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_isDirectory(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
WADentry *entry = wad_find_entry(((WADinfo *) h->opaque), name);
|
||||||
|
if (entry != NULL)
|
||||||
|
{
|
||||||
|
char *n;
|
||||||
|
|
||||||
|
*fileExists = 1;
|
||||||
|
|
||||||
|
/* Can't be a directory if it's a subdirectory. */
|
||||||
|
if (strchr(entry->name, '/') != NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/* Check if it matches "MAP??" or "E?M?" ... */
|
||||||
|
n = entry->name;
|
||||||
|
if ((n[0] == 'E' && n[2] == 'M') ||
|
||||||
|
(n[0] == 'M' && n[1] == 'A' && n[2] == 'P' && n[6] == 0))
|
||||||
|
{
|
||||||
|
return(1);
|
||||||
|
} /* if */
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*fileExists = 0;
|
||||||
|
return(0);
|
||||||
|
} /* else */
|
||||||
|
} /* WAD_isDirectory */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_isSymLink(DirHandle *h, const char *name, int *fileExists)
|
||||||
|
{
|
||||||
|
*fileExists = WAD_exists(h, name);
|
||||||
|
return(0); /* never symlinks in a wad. */
|
||||||
|
} /* WAD_isSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 WAD_getLastModTime(DirHandle *h,
|
||||||
|
const char *name,
|
||||||
|
int *fileExists)
|
||||||
|
{
|
||||||
|
WADinfo *info = ((WADinfo *) h->opaque);
|
||||||
|
PHYSFS_sint64 retval = -1;
|
||||||
|
|
||||||
|
*fileExists = (wad_find_entry(info, name) != NULL);
|
||||||
|
if (*fileExists) /* use time of WAD itself in the physical filesystem. */
|
||||||
|
retval = ((WADinfo *) h->opaque)->last_mod_time;
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* WAD_getLastModTime */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *WAD_openRead(DirHandle *h, const char *fnm, int *fileExists)
|
||||||
|
{
|
||||||
|
WADinfo *info = ((WADinfo *) h->opaque);
|
||||||
|
FileHandle *retval;
|
||||||
|
WADfileinfo *finfo;
|
||||||
|
WADentry *entry;
|
||||||
|
|
||||||
|
entry = wad_find_entry(info, fnm);
|
||||||
|
*fileExists = (entry != NULL);
|
||||||
|
BAIL_IF_MACRO(entry == NULL, NULL, NULL);
|
||||||
|
|
||||||
|
retval = (FileHandle *) malloc(sizeof (FileHandle));
|
||||||
|
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
finfo = (WADfileinfo *) malloc(sizeof (WADfileinfo));
|
||||||
|
if (finfo == NULL)
|
||||||
|
{
|
||||||
|
free(retval);
|
||||||
|
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->handle = __PHYSFS_platformOpenRead(info->filename);
|
||||||
|
if ( (finfo->handle == NULL) ||
|
||||||
|
(!__PHYSFS_platformSeek(finfo->handle, entry->startPos)) )
|
||||||
|
{
|
||||||
|
free(finfo);
|
||||||
|
free(retval);
|
||||||
|
return(NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
finfo->curPos = 0;
|
||||||
|
finfo->entry = entry;
|
||||||
|
retval->opaque = (void *) finfo;
|
||||||
|
retval->funcs = &__PHYSFS_FileFunctions_WAD;
|
||||||
|
retval->dirHandle = h;
|
||||||
|
return(retval);
|
||||||
|
} /* WAD_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *WAD_openWrite(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* WAD_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static FileHandle *WAD_openAppend(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);
|
||||||
|
} /* WAD_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_remove(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* WAD_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int WAD_mkdir(DirHandle *h, const char *name)
|
||||||
|
{
|
||||||
|
BAIL_MACRO(ERR_NOT_SUPPORTED, 0);
|
||||||
|
} /* WAD_mkdir */
|
||||||
|
|
||||||
|
#endif /* defined PHYSFS_SUPPORTS_WAD */
|
||||||
|
|
||||||
|
/* end of wad.c ... */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
echo "Initial preparation...this can take awhile, so sit tight..."
|
||||||
|
rm -f Makefile.am
|
||||||
|
perl -w -e 'use File::Copy; exit 0 if (-f "Makefile.am"); my $x = `automake --version |head -n 1`; chomp($x); $x = 0.0 if ($x !~ s/\A.*?(\d+\.\d+).*\Z/$1/); if ($x < 1.5) { copy("./Makefile.am.oldautomake", "./Makefile.am"); } else { copy("./Makefile.am.newautomake", "./Makefile.am"); }'
|
||||||
|
aclocal
|
||||||
|
|
||||||
|
# MacOS X renames GNU libtool to "glibtool", since they have something
|
||||||
|
# else called "libtool" already...
|
||||||
|
if [ -x /usr/bin/glibtoolize ]; then
|
||||||
|
glibtoolize --automake --copy --force
|
||||||
|
else
|
||||||
|
libtoolize --automake --copy --force
|
||||||
|
fi
|
||||||
|
|
||||||
|
autoheader
|
||||||
|
automake --foreign --add-missing --copy
|
||||||
|
autoconf
|
||||||
|
|
||||||
|
echo "You are now ready to run ./configure ..."
|
||||||
|
|
|
@ -0,0 +1,567 @@
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
AC_INIT(physfs.c)
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl System/version info
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Making releases:
|
||||||
|
# MICRO_VERSION += 1;
|
||||||
|
# INTERFACE_AGE += 1;
|
||||||
|
# BINARY_AGE += 1;
|
||||||
|
# if any functions have been added, set INTERFACE_AGE to 0.
|
||||||
|
# if backwards compatibility has been broken,
|
||||||
|
# set BINARY_AGE and INTERFACE_AGE to 0.
|
||||||
|
|
||||||
|
MAJOR_VERSION=1
|
||||||
|
MINOR_VERSION=0
|
||||||
|
MICRO_VERSION=2
|
||||||
|
INTERFACE_AGE=2
|
||||||
|
BINARY_AGE=2
|
||||||
|
VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
|
||||||
|
|
||||||
|
AC_SUBST(MAJOR_VERSION)
|
||||||
|
AC_SUBST(MINOR_VERSION)
|
||||||
|
AC_SUBST(MICRO_VERSION)
|
||||||
|
AC_SUBST(INTERFACE_AGE)
|
||||||
|
AC_SUBST(BINARY_AGE)
|
||||||
|
AC_SUBST(VERSION)
|
||||||
|
|
||||||
|
# libtool versioning
|
||||||
|
LT_RELEASE=$MAJOR_VERSION.$MINOR_VERSION
|
||||||
|
LT_CURRENT=`expr $MICRO_VERSION - $INTERFACE_AGE`
|
||||||
|
LT_REVISION=$INTERFACE_AGE
|
||||||
|
LT_AGE=`expr $BINARY_AGE - $INTERFACE_AGE`
|
||||||
|
|
||||||
|
AC_SUBST(LT_RELEASE)
|
||||||
|
AC_SUBST(LT_CURRENT)
|
||||||
|
AC_SUBST(LT_REVISION)
|
||||||
|
AC_SUBST(LT_AGE)
|
||||||
|
|
||||||
|
dnl Detect the canonical host and target build environment
|
||||||
|
AC_CANONICAL_SYSTEM
|
||||||
|
|
||||||
|
dnl Setup for automake
|
||||||
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
AM_INIT_AUTOMAKE(physfs, $VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl Compilers and other tools
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_LN_S
|
||||||
|
AC_LIBTOOL_WIN32_DLL
|
||||||
|
LIBTOOL="libtool"
|
||||||
|
AM_PROG_LIBTOOL
|
||||||
|
AC_CHECK_PROG(we_have_sed, sed, yes, no)
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl Debug mode?
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
[ --enable-debug enable debug mode [default=no]],
|
||||||
|
, enable_debug=no)
|
||||||
|
if test x$enable_debug = xyes; then
|
||||||
|
if test x$ac_cv_prog_cc_g = xyes; then
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -g -O0"
|
||||||
|
else
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -O0"
|
||||||
|
fi
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -Werror -Wall"
|
||||||
|
AC_DEFINE([DEBUG], 1, [define if debug build is enabled])
|
||||||
|
AC_DEFINE([DEBUG_CHATTER], 1, [define if debug chatter is enabled])
|
||||||
|
else
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -O2"
|
||||||
|
AC_DEFINE([NDEBUG], 1, [define if debug build is disabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl Have GCC's -fvisibility option?
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
AC_MSG_CHECKING(for GCC -fvisibility=hidden option)
|
||||||
|
have_gcc_fvisibility=no
|
||||||
|
visibility_CFLAGS="-fvisibility=hidden"
|
||||||
|
save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$save_CFLAGS $visibility_CFLAGS"
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
int placeholder = 1;
|
||||||
|
],[
|
||||||
|
],[
|
||||||
|
have_gcc_fvisibility=yes
|
||||||
|
])
|
||||||
|
AC_MSG_RESULT($have_gcc_fvisibility)
|
||||||
|
CFLAGS="$save_CFLAGS"
|
||||||
|
|
||||||
|
if test x$have_gcc_fvisibility = xyes; then
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS $visibility_CFLAGS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl Profile sorts, etc?
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(profiling,
|
||||||
|
[ --enable-profiling do algorithm profiling [default=no]],
|
||||||
|
, enable_profiling=no)
|
||||||
|
if test x$enable_profiling = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_PROFILING], 1, [define to profile sorting, etc algorithms])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl Build test program?
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(testprog,
|
||||||
|
[ --enable-testprog build test program [default=yes]],
|
||||||
|
, enable_testprog=yes)
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
dnl Checks for libraries.
|
||||||
|
dnl ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
require_zlib="no"
|
||||||
|
|
||||||
|
dnl Check for zip archiver inclusion...
|
||||||
|
AC_ARG_ENABLE(zip,
|
||||||
|
[ --enable-zip enable ZIP support [default=yes]],
|
||||||
|
, enable_zip=yes)
|
||||||
|
if test x$enable_zip = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_SUPPORTS_ZIP], 1, [define if zip support is enabled])
|
||||||
|
require_zlib="yes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl Check for grp archiver inclusion...
|
||||||
|
AC_ARG_ENABLE(grp,
|
||||||
|
[ --enable-grp enable Build Engine GRP support [default=yes]],
|
||||||
|
, enable_grp=yes)
|
||||||
|
if test x$enable_grp = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_SUPPORTS_GRP], 1, [define if grp support is enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Check for wad archiver inclusion...
|
||||||
|
AC_ARG_ENABLE(wad,
|
||||||
|
[ --enable-wad enable Doom WAD support [default=yes]],
|
||||||
|
, enable_wad=yes)
|
||||||
|
if test x$enable_wad = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_SUPPORTS_WAD], 1, [define if wad support is enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Check for hog archiver inclusion...
|
||||||
|
AC_ARG_ENABLE(hog,
|
||||||
|
[ --enable-hog enable Descent I/II HOG support [default=yes]],
|
||||||
|
, enable_hog=yes)
|
||||||
|
if test x$enable_hog = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_SUPPORTS_HOG], 1, [define if hog support is enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl Check for mvl archiver inclusion...
|
||||||
|
AC_ARG_ENABLE(mvl,
|
||||||
|
[ --enable-mvl enable Descent II MVL support [default=yes]],
|
||||||
|
, enable_mvl=yes)
|
||||||
|
if test x$enable_mvl = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_SUPPORTS_MVL], 1, [define if mvl support is enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl Check for qpak archiver inclusion...
|
||||||
|
AC_ARG_ENABLE(qpak,
|
||||||
|
[ --enable-qpak enable Quake PAK support [default=yes]],
|
||||||
|
, enable_qpak=yes)
|
||||||
|
if test x$enable_qpak = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_SUPPORTS_QPAK], 1, [define if qpak support is enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Check if we should statically link the included zlib...
|
||||||
|
AC_ARG_ENABLE(internal-zlib,
|
||||||
|
[ --enable-internal-zlib use included zlib [default=only if needed]],
|
||||||
|
, enable_internal_zlib=maybe)
|
||||||
|
|
||||||
|
dnl Check for zlib if needed.
|
||||||
|
have_external_zlib="no"
|
||||||
|
if test x$enable_internal_zlib != xyes; then
|
||||||
|
if test x$require_zlib = xyes; then
|
||||||
|
AC_CHECK_HEADER(zlib.h, have_zlib_hdr=yes)
|
||||||
|
AC_CHECK_LIB(z, zlibVersion, have_zlib_lib=yes)
|
||||||
|
if test x$have_zlib_hdr = xyes -a x$have_zlib_lib = xyes; then
|
||||||
|
have_external_zlib="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([what zlib to use])
|
||||||
|
|
||||||
|
dnl no zlib is needed at all if we aren't supporting ZIP files.
|
||||||
|
if test x$require_zlib = xno; then
|
||||||
|
enable_internal_zlib="no"
|
||||||
|
enable_external_zlib="no"
|
||||||
|
AC_MSG_RESULT([no zlib needed])
|
||||||
|
else
|
||||||
|
|
||||||
|
if test x$enable_internal_zlib = xmaybe; then
|
||||||
|
if test x$have_external_zlib = xyes; then
|
||||||
|
enable_internal_zlib="no"
|
||||||
|
enable_external_zlib="yes"
|
||||||
|
else
|
||||||
|
enable_internal_zlib="yes"
|
||||||
|
enable_external_zlib="no"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if test x$enable_internal_zlib = xno -a x$have_external_zlib = xyes; then
|
||||||
|
enable_internal_zlib="no"
|
||||||
|
enable_external_zlib="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$enable_internal_zlib = xyes; then
|
||||||
|
AC_MSG_RESULT([internal zlib])
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -DZ_PREFIX"
|
||||||
|
else
|
||||||
|
if test x$enable_external_zlib = xyes; then
|
||||||
|
AC_MSG_RESULT([external zlib])
|
||||||
|
LIBS="$LIBS -lz"
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([Need zlib, but you disabled our copy and have no system lib])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl determine if we should include readline support...
|
||||||
|
AC_ARG_ENABLE(readline,
|
||||||
|
[ --enable-readline use GNU readline in test program [default=yes]],
|
||||||
|
, enable_readline=yes)
|
||||||
|
|
||||||
|
if test x$enable_readline = xyes; then
|
||||||
|
AC_CHECK_HEADER(readline/readline.h, have_readline_hdr=yes)
|
||||||
|
AC_CHECK_LIB(readline, readline, have_readline_lib=yes, , -lcurses)
|
||||||
|
AC_CHECK_HEADER(readline/history.h, have_history_hdr=yes)
|
||||||
|
AC_CHECK_LIB(readline, add_history, have_history_lib=yes, , -lcurses)
|
||||||
|
if test x$have_readline_hdr = xyes -a x$have_readline_lib = xyes; then
|
||||||
|
if test x$have_history_hdr = xyes -a x$have_history_lib = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_HAVE_READLINE], 1, [define if we have readline])
|
||||||
|
have_readline="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl !!! FIXME: Not sure how to detect this...
|
||||||
|
dnl check for 64-bit llseek()...
|
||||||
|
dnl AC_CHECK_LIB(c, llseek, have_llseek=yes)
|
||||||
|
if test x$have_llseek = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_HAVE_LLSEEK], 1, [define if we have llseek])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl determine if we should use the stubbed pthread code.
|
||||||
|
AC_ARG_ENABLE(pthreads,
|
||||||
|
[ --enable-pthreads include POSIX threads support [default=yes]],
|
||||||
|
, enable_pthreads=yes)
|
||||||
|
if test x$enable_pthreads = xyes; then
|
||||||
|
AC_CHECK_HEADER(pthread.h, have_pthread_hdr=yes)
|
||||||
|
if test x$have_pthread_hdr != xyes; then
|
||||||
|
enable_pthreads=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl determine if we should use the stubbed CD-ROM detection code.
|
||||||
|
AC_ARG_ENABLE(cdrom,
|
||||||
|
[ --enable-cdrom include CD-ROM support [default=yes]],
|
||||||
|
, enable_cdrom=yes)
|
||||||
|
|
||||||
|
if test x$enable_cdrom = xyes; then
|
||||||
|
dnl reset this and let header detection reenable...
|
||||||
|
enable_cdrom=no
|
||||||
|
|
||||||
|
dnl BSD systems use sys/ucred.h for getting mounted volumes.
|
||||||
|
dnl Linux and others use mntent.h.
|
||||||
|
AC_CHECK_HEADER(sys/ucred.h, have_ucred_hdr=yes)
|
||||||
|
if test x$have_ucred_hdr = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_HAVE_SYS_UCRED_H], 1, [define if we have sys/ucred.h])
|
||||||
|
enable_cdrom=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_HEADER(mntent.h, have_mntent_hdr=yes)
|
||||||
|
if test x$have_mntent_hdr = xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_HAVE_MNTENT_H], 1, [define if we have mntent.h])
|
||||||
|
enable_cdrom=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl determine language.
|
||||||
|
AC_ARG_ENABLE(language,
|
||||||
|
[ --enable-language=lang Select natural language. [default=english]],
|
||||||
|
physfslang=`echo $enable_language |tr A-Z a-z`, physfslang=english)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if language choice is supported])
|
||||||
|
physfs_valid_lang=no
|
||||||
|
|
||||||
|
if test x$physfslang = xenglish; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_ENGLISH, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xgerman; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_GERMAN, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xfrench; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_FRENCH, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xspanish; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_SPANISH, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xportuguese-br; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_PORTUGUESE_BR, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xrussian-koi8-r; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_RUSSIAN_KOI8_R, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xrussian-cp1251; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_RUSSIAN_CP866, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xrussian-cp866; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_RUSSIAN_CP866, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$physfslang = xrussian-iso-8859-5; then
|
||||||
|
physfs_valid_lang=yes
|
||||||
|
AC_DEFINE([PHYSFS_LANG], PHYSFS_LANG_RUSSIAN_ISO_8859_5, [define desired natural language])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Add other language checks here...
|
||||||
|
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$physfs_valid_lang])
|
||||||
|
if test x$physfs_valid_lang = xno; then
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
AC_MSG_WARN([*** You've asked for "$physfslang" language support...])
|
||||||
|
AC_MSG_WARN([*** ...but we don't support that.])
|
||||||
|
AC_MSG_WARN([*** You could choose another language,])
|
||||||
|
AC_MSG_WARN([*** but is this what you REALLY wanted?])
|
||||||
|
AC_MSG_WARN([*** Please see the LANG section of physfs_internal.h])
|
||||||
|
AC_MSG_WARN([*** for info on writing a translation.])
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
AC_MSG_WARN([*** Currently known languages:])
|
||||||
|
AC_MSG_WARN([*** --enable-language=english])
|
||||||
|
AC_MSG_WARN([*** --enable-language=german])
|
||||||
|
AC_MSG_WARN([*** --enable-language=french])
|
||||||
|
AC_MSG_WARN([*** --enable-language=spanish])
|
||||||
|
AC_MSG_WARN([*** --enable-language=portuguese-br])
|
||||||
|
AC_MSG_WARN([*** --enable-language=russian-koi8-r])
|
||||||
|
AC_MSG_WARN([*** --enable-language=russian-cp1251])
|
||||||
|
AC_MSG_WARN([*** --enable-language=russian-cp866])
|
||||||
|
AC_MSG_WARN([*** --enable-language=russian-iso-8859-5])
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
AC_MSG_ERROR([*** unsupported language. stop.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
have_non_posix_threads=no
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if this is BeOS])
|
||||||
|
if test x$target_os = xbeos; then
|
||||||
|
this_is_beos=yes
|
||||||
|
have_non_posix_threads=yes
|
||||||
|
enable_cdrom=yes
|
||||||
|
enable_pthreads=no
|
||||||
|
LIBS="$LIBS -lroot -lbe"
|
||||||
|
else
|
||||||
|
this_is_beos=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_beos])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if this is Cygwin])
|
||||||
|
if test x$target_os = xcygwin; then
|
||||||
|
this_is_cygwin=yes
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -DWIN32"
|
||||||
|
enable_cdrom=yes
|
||||||
|
enable_pthreads=no
|
||||||
|
have_non_posix_threads=yes
|
||||||
|
else
|
||||||
|
this_is_cygwin=no
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([$this_is_cygwin])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if this is mingw])
|
||||||
|
if test x$target_os = xmingw32; then
|
||||||
|
this_is_mingw=yes
|
||||||
|
fi
|
||||||
|
if test x$target_os = xmingw32msvc; then
|
||||||
|
this_is_mingw=yes
|
||||||
|
fi
|
||||||
|
if test x$this_is_mingw = xyes; then
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -DWIN32"
|
||||||
|
enable_cdrom=yes
|
||||||
|
enable_pthreads=no
|
||||||
|
have_non_posix_threads=yes
|
||||||
|
else
|
||||||
|
this_is_mingw=no
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([$this_is_mingw])
|
||||||
|
|
||||||
|
this_is_macosx=no
|
||||||
|
if test x$we_have_sed = xyes; then
|
||||||
|
AC_MSG_CHECKING([if this is MacOS X])
|
||||||
|
x=`echo $target_os |sed "s/darwin.*/darwin/"`
|
||||||
|
if test x$x = xdarwin -a x$target_vendor = xapple; then
|
||||||
|
this_is_macosx=yes
|
||||||
|
PHYSFSLDFLAGS="$PHYSFSLDFLAGS -Wl,-framework -Wl,Carbon -Wl,-framework -Wl,IOKit"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_macosx])
|
||||||
|
fi
|
||||||
|
|
||||||
|
this_is_freebsd=no
|
||||||
|
if test x$we_have_sed = xyes; then
|
||||||
|
AC_MSG_CHECKING([if this is FreeBSD])
|
||||||
|
x=`echo $target_os |tr A-Z a-z |sed "s/.*freebsd.*/freebsd/"`
|
||||||
|
if test x$x = xfreebsd; then
|
||||||
|
this_is_freebsd=yes
|
||||||
|
PHYSFSLDFLAGS="$PHYSFSLDFLAGS -pthread"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_freebsd])
|
||||||
|
fi
|
||||||
|
|
||||||
|
this_is_openbsd=no
|
||||||
|
if test x$we_have_sed = xyes; then
|
||||||
|
AC_MSG_CHECKING([if this is OpenBSD])
|
||||||
|
x=`echo $target_os |tr A-Z a-z |sed "s/.*openbsd.*/openbsd/"`
|
||||||
|
if test x$x = xopenbsd; then
|
||||||
|
this_is_openbsd=yes
|
||||||
|
PHYSFSLDFLAGS="$PHYSFSLDFLAGS -pthread"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_openbsd])
|
||||||
|
fi
|
||||||
|
|
||||||
|
this_is_atheos=no
|
||||||
|
if test x$we_have_sed = xyes; then
|
||||||
|
AC_MSG_CHECKING([if this is AtheOS])
|
||||||
|
x=`echo $target_os |tr A-Z a-z |sed "s/.*atheos.*/atheos/"`
|
||||||
|
if test x$x = xatheos; then
|
||||||
|
this_is_atheos=yes
|
||||||
|
enable_cdrom=no
|
||||||
|
enable_pthreads=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_atheos])
|
||||||
|
fi
|
||||||
|
|
||||||
|
this_is_os2=no
|
||||||
|
if test x$we_have_sed = xyes; then
|
||||||
|
AC_MSG_CHECKING([if this is OS/2])
|
||||||
|
x=`echo $target_os |tr A-Z a-z |sed "s/.*os2.*/os2/"`
|
||||||
|
if test x$x = xos2; then
|
||||||
|
this_is_os2=yes
|
||||||
|
have_non_posix_threads=yes
|
||||||
|
enable_cdrom=yes
|
||||||
|
enable_pthreads=no
|
||||||
|
PHYSFSCFLAGS="$PHYSFSCFLAGS -DOS2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_os2])
|
||||||
|
fi
|
||||||
|
|
||||||
|
this_is_mint=no
|
||||||
|
if test x$we_have_sed = xyes; then
|
||||||
|
AC_MSG_CHECKING([if this is MiNT])
|
||||||
|
x=`echo $target_os |tr A-Z a-z |sed "s/.*mint.*/mint/"`
|
||||||
|
if test x$x = xmint; then
|
||||||
|
this_is_mint=yes
|
||||||
|
enable_cdrom=no
|
||||||
|
enable_pthreads=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT([$this_is_mint])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl Some platform might disable this, so check this down here...
|
||||||
|
if test x$enable_cdrom != xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_NO_CDROM_SUPPORT], 1, [define if we have no CD support])
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
AC_MSG_WARN([*** There is no CD-ROM support in this build!])
|
||||||
|
AC_MSG_WARN([*** PhysicsFS will just pretend there are no discs.])
|
||||||
|
AC_MSG_WARN([*** This may be fine, depending on how PhysicsFS is used,])
|
||||||
|
AC_MSG_WARN([*** but is this what you REALLY wanted?])
|
||||||
|
AC_MSG_WARN([*** (Maybe fix configure.in, or write a platform driver?)])
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$enable_pthreads != xyes; then
|
||||||
|
AC_DEFINE([PHYSFS_NO_PTHREADS_SUPPORT], 1, [define if we have no POSIX threads support])
|
||||||
|
if test x$have_non_posix_threads != xyes; then
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
AC_MSG_WARN([*** There is no thread support in this build!])
|
||||||
|
AC_MSG_WARN([*** PhysicsFS will NOT be reentrant!])
|
||||||
|
AC_MSG_WARN([*** This may be fine, depending on how PhysicsFS is used,])
|
||||||
|
AC_MSG_WARN([*** but is this what you REALLY wanted?])
|
||||||
|
AC_MSG_WARN([*** (Maybe fix configure.in, or write a platform driver?)])
|
||||||
|
AC_MSG_WARN([***])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS([stdlib.h string.h assert.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
dnl AC_C_CONST
|
||||||
|
dnl AC_TYPE_SIZE_T
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
|
||||||
|
# This is only in the bleeding edge autoconf distro...
|
||||||
|
#AC_FUNC_MALLOC
|
||||||
|
|
||||||
|
AC_FUNC_MEMCMP
|
||||||
|
AC_CHECK_FUNCS([memset strrchr])
|
||||||
|
|
||||||
|
AC_CHECK_SIZEOF(int, 4)
|
||||||
|
|
||||||
|
CFLAGS="$PHYSFSCFLAGS $CFLAGS -D_REENTRANT -D_THREAD_SAFE"
|
||||||
|
LDFLAGS="$LDFLAGS $PHYSFSLDFLAGS -no-undefined"
|
||||||
|
|
||||||
|
dnl Add Makefile conditionals
|
||||||
|
AM_CONDITIONAL(BUILD_ZLIB, test x$enable_internal_zlib = xyes)
|
||||||
|
AM_CONDITIONAL(BUILD_TEST_PHYSFS, test x$enable_testprog = xyes)
|
||||||
|
AM_CONDITIONAL(BUILD_MACOSX, test x$this_is_macosx = xyes)
|
||||||
|
AM_CONDITIONAL(BUILD_BEOS, test x$this_is_beos = xyes)
|
||||||
|
AM_CONDITIONAL(BUILD_CYGWIN, test x$this_is_cygwin = xyes)
|
||||||
|
AM_CONDITIONAL(BUILD_READLINE, test x$have_readline = xyes)
|
||||||
|
|
||||||
|
AC_OUTPUT([
|
||||||
|
Makefile
|
||||||
|
archivers/Makefile
|
||||||
|
platform/Makefile
|
||||||
|
zlib123/Makefile
|
||||||
|
test/Makefile
|
||||||
|
extras/Makefile
|
||||||
|
physfs.spec
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl end of configure.in ...
|
||||||
|
|
174
docs/CREDITS.txt
174
docs/CREDITS.txt
|
@ -1,174 +0,0 @@
|
||||||
Maintainer and general codemonkey:
|
|
||||||
Ryan C. Gordon
|
|
||||||
|
|
||||||
Tons of win32 help:
|
|
||||||
Adam Gates
|
|
||||||
|
|
||||||
More win32 hacking:
|
|
||||||
Gregory S. Read
|
|
||||||
|
|
||||||
Fixes for missing current working directories,
|
|
||||||
PHYSFS_setSaneConfig() improvements,
|
|
||||||
other bugfixes:
|
|
||||||
David Hedbor
|
|
||||||
|
|
||||||
Darwin support:
|
|
||||||
Patrick Stein
|
|
||||||
|
|
||||||
configure fixes,
|
|
||||||
RPM specfile:
|
|
||||||
Edward Rudd
|
|
||||||
|
|
||||||
GetLastModTime API,
|
|
||||||
other stuff:
|
|
||||||
John R. Hall
|
|
||||||
|
|
||||||
Various support, fixes and suggestions:
|
|
||||||
Alexander Pipelka
|
|
||||||
|
|
||||||
Russian translation,
|
|
||||||
QPAK archiver:
|
|
||||||
Ed Sinjiashvili
|
|
||||||
|
|
||||||
French translation:
|
|
||||||
Stéphane Peter
|
|
||||||
|
|
||||||
Debian package support:
|
|
||||||
Colin Bayer
|
|
||||||
|
|
||||||
"abs-file.h" in "extras" dir:
|
|
||||||
Adam D. Moss
|
|
||||||
|
|
||||||
WinCE port and other Win32 patches:
|
|
||||||
Corona688
|
|
||||||
|
|
||||||
German translation:
|
|
||||||
Michael Renner
|
|
||||||
|
|
||||||
Apple Project Builder support,
|
|
||||||
Mac OS X improvements:
|
|
||||||
Eric Wing
|
|
||||||
|
|
||||||
iPhone support:
|
|
||||||
Christian Gmeiner
|
|
||||||
|
|
||||||
WinRT support:
|
|
||||||
Martin Ahrnbom
|
|
||||||
|
|
||||||
HOG archiver,
|
|
||||||
MVL archiver:
|
|
||||||
Bradley Bell
|
|
||||||
|
|
||||||
MIX archiver:
|
|
||||||
Sebastian Steinhauer
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Tolga Dalman
|
|
||||||
|
|
||||||
Initial PHYSFS_mount() work:
|
|
||||||
Philip D. Bober
|
|
||||||
|
|
||||||
Brazillian Portuguese translation:
|
|
||||||
Danny Angelo Carminati Grein
|
|
||||||
|
|
||||||
Spanish translation:
|
|
||||||
Pedro J. Pérez
|
|
||||||
|
|
||||||
MacOS Classic fixes,
|
|
||||||
MPW support,
|
|
||||||
bug fixes:
|
|
||||||
Chris Taylor
|
|
||||||
|
|
||||||
Mingw support,
|
|
||||||
General bug fixes:
|
|
||||||
Matze Braun
|
|
||||||
|
|
||||||
Haiku support:
|
|
||||||
scott mc
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Jörg Walter
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Olivier Boudeville
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Henk Boom
|
|
||||||
|
|
||||||
Build system fixes:
|
|
||||||
Marc Kleine-Budde
|
|
||||||
|
|
||||||
Windows .rc file,
|
|
||||||
7zip/lzma archiver:
|
|
||||||
Dennis Schridde
|
|
||||||
|
|
||||||
OS/2 updates:
|
|
||||||
Dave Yeo
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Patrice Mandin
|
|
||||||
|
|
||||||
PHYSFS_stat() API:
|
|
||||||
Christoph Nelles
|
|
||||||
Indy Sams
|
|
||||||
|
|
||||||
ISO9660 archiver:
|
|
||||||
Christoph Nelles
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Steven Fuller
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Tolga Dalman
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Frank Becker
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Norfanin
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Evgeny Podjachev
|
|
||||||
|
|
||||||
Haiku fixes:
|
|
||||||
Chris Roberts
|
|
||||||
|
|
||||||
SLB archiver:
|
|
||||||
Aleksi Nurmi
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Dmitry Marakasov
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Andreas Karlsson
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Michael Bacon
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Xian Nox
|
|
||||||
|
|
||||||
Bug fixes:
|
|
||||||
Reto Schneider
|
|
||||||
|
|
||||||
pkg-config support:
|
|
||||||
Jonas Kulla
|
|
||||||
|
|
||||||
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 ...
|
|
||||||
|
|
||||||
/* end of CREDITS.txt ... */
|
|
||||||
|
|
173
docs/INSTALL.txt
173
docs/INSTALL.txt
|
@ -1,173 +0,0 @@
|
||||||
|
|
||||||
The latest PhysicsFS information and releases can be found at:
|
|
||||||
https://icculus.org/physfs/
|
|
||||||
|
|
||||||
Building is (ahem) very easy.
|
|
||||||
|
|
||||||
|
|
||||||
ALL PLATFORMS:
|
|
||||||
|
|
||||||
Please read the text file LICENSE.txt in the root of the source tree.
|
|
||||||
The license is extremely liberal, even to closed-source, commercial
|
|
||||||
applications.
|
|
||||||
|
|
||||||
If you've got Doxygen (http://www.doxygen.org/) installed, you can run it
|
|
||||||
without any command line arguments in the root of the source tree to generate
|
|
||||||
the API reference (or build the "docs" target from your build system). This
|
|
||||||
is optional. You can browse the API docs online here:
|
|
||||||
|
|
||||||
https://icculus.org/physfs/docs/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BUILD IT WITH YOUR OWN PROGRAM:
|
|
||||||
|
|
||||||
If you don't care about formal packaging: just add everything in the "src"
|
|
||||||
directory to whatever you use to build your program and compile it along with
|
|
||||||
everything else, and you're done. It should compile with any reasonable
|
|
||||||
ANSI C compiler, should build cleanly even with excessive compiler warnings
|
|
||||||
enabled, needs no extra configuration, and allows static linking.
|
|
||||||
WinRT and Haiku need C++ compilers for their system APIs, but if you aren't on
|
|
||||||
these platforms and don't have a C++ compiler, don't build the .cpp files.
|
|
||||||
Likewise: Apple platforms (macOS, iOS, etc) need an Objective-C compiler, but
|
|
||||||
if you aren't on these platforms and don't have a Objective-C compiler, don't
|
|
||||||
build the .m file. Everything you need is in the .c sources.
|
|
||||||
|
|
||||||
If this all worked for your specific project, you can stop reading now.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Unix:
|
|
||||||
|
|
||||||
You will need CMake (https://www.cmake.org/) 2.4 or later installed.
|
|
||||||
|
|
||||||
Make a directory, wherever you like. This will be your build directory.
|
|
||||||
|
|
||||||
Chdir to your build directory. Run "cmake /where/i/unpacked/physfs" to
|
|
||||||
generate Makefiles. You can then run "ccmake ." and customize the build,
|
|
||||||
but the defaults are probably okay. You can have CMake generate KDevelop
|
|
||||||
or Ninja project files or whatever, if you prefer these.
|
|
||||||
|
|
||||||
Run "make". PhysicsFS will now build.
|
|
||||||
|
|
||||||
As root, run "make install".
|
|
||||||
If you get sick of the library, run "make uninstall" as root
|
|
||||||
and it will remove all traces of the library from the system paths.
|
|
||||||
|
|
||||||
Once you are satisfied, you can delete the build directory.
|
|
||||||
|
|
||||||
Primary Unix development is done with GNU/Linux, but PhysicsFS is known to
|
|
||||||
work out of the box with several flavors of Unix. It it doesn't work, patches
|
|
||||||
to get it running can be sent to icculus@icculus.org.
|
|
||||||
|
|
||||||
|
|
||||||
Windows:
|
|
||||||
|
|
||||||
If building with Cygwin, mingw32, MSYS, or something else that uses the GNU
|
|
||||||
toolchain, follow the Unix instructions, above.
|
|
||||||
|
|
||||||
If you want to use Visual Studio, nmake, or the Platform SDK, you will need
|
|
||||||
CMake (https://www.cmake.org/) 2.4 or later installed. Point CMake at the
|
|
||||||
CMakeLists.txt file in the root of the source directory and hit the
|
|
||||||
"Configure" button. After telling it what type of compiler you are targeting
|
|
||||||
(Borland, Visual Studio, etc), CMake will process for while and then give you
|
|
||||||
a list of options you can change (what archivers you want to support, etc).
|
|
||||||
If you aren't sure, the defaults are probably fine. Hit the "Configure"
|
|
||||||
button again, then "OK" once configuration has completed with options that
|
|
||||||
match your liking. Now project files for your favorite programming
|
|
||||||
environment will be generated for you in the directory you specified.
|
|
||||||
Go there and use them to build PhysicsFS.
|
|
||||||
|
|
||||||
PhysicsFS will only link directly against system libraries that have existed
|
|
||||||
since Windows NT 3.51. If there's a newer API we want to use, we try to
|
|
||||||
dynamically load it at runtime and fallback to a reasonable behaviour when
|
|
||||||
we can't find it. Note that Windows 98 and later _should_
|
|
||||||
work if you use the Microsoft Layer for Unicode (UNICOWS.DLL) to provide
|
|
||||||
some missing system APIs, but this is no longer tested as of PhysicsFS 2.1.0.
|
|
||||||
PhysicsFS 2.0.x is known to work with Windows 95 without UNICOWS.DLL.
|
|
||||||
|
|
||||||
PhysicsFS works on 32-bit and 64-bit Windows. There is no 16-bit Windows
|
|
||||||
support at all. Windows RT is covered below.
|
|
||||||
|
|
||||||
|
|
||||||
Windows RT:
|
|
||||||
|
|
||||||
Windows RT (Windows Phone, Windows Store, UWP) 8.0 and later are supported.
|
|
||||||
Make sure you include both physfs_platform_windows.c _and_
|
|
||||||
physfs_platform_winrt.cpp in your build, and that the C++ file has
|
|
||||||
"Consume Windows Runtime Extension" set to "Yes" in its Visual Studio
|
|
||||||
properties (from the command line, you want to compile this file with the
|
|
||||||
"/ZW" compiler switch). CMake can, in theory, generate a project file for
|
|
||||||
WinRT if you pick a recent Visual Studio target, choose manual cross-compile
|
|
||||||
options, and set the system name to "WindowsPhone" or "WindowsStore" and the
|
|
||||||
correct OS version (8.0 or later).
|
|
||||||
|
|
||||||
|
|
||||||
PocketPC/WindowsCE:
|
|
||||||
|
|
||||||
Support for PocketPC was removed in PhysicsFS 2.1.0. This was known to work
|
|
||||||
in the 1.0 releases, but wasn't tested in 2.0 and later. PhysicsFS should
|
|
||||||
work on modern Windows Phones (see "Windows RT" section).
|
|
||||||
|
|
||||||
|
|
||||||
macOS:
|
|
||||||
|
|
||||||
You will need CMake (https://www.cmake.org/) 2.4 or later installed.
|
|
||||||
|
|
||||||
You can either generate a Unix makefile with CMake, or generate an Xcode
|
|
||||||
project, whichever makes you more comfortable.
|
|
||||||
|
|
||||||
PowerPC and Intel Macs should both be supported.
|
|
||||||
|
|
||||||
|
|
||||||
MAC OS 8/9 ("Mac OS Classic"):
|
|
||||||
|
|
||||||
Classic Mac OS support has been dropped in PhysicsFS 2.0. Apple hasn't updated
|
|
||||||
pre-OSX versions in more than a decade at this point, none of the hardware
|
|
||||||
they've shipped will boot it for almost as many years, and finding
|
|
||||||
developer tools for it is becoming almost impossible. As the switch to Intel
|
|
||||||
hardware has removed the "Classic" emulation environment, it was time to
|
|
||||||
remove support from PhysicsFS. That being said, the PhysicsFS 1.0 branch can
|
|
||||||
still target back to Mac OS 8.5, so you can use that if you need support for
|
|
||||||
this legacy OS. We still very much support modern macOS, though: see above.
|
|
||||||
|
|
||||||
|
|
||||||
Emscripten:
|
|
||||||
|
|
||||||
Use the "Unix" instructions, above. You can install the Emscripten SDK and use
|
|
||||||
the extras/buildbot-emscripten.sh script to automate this for you.
|
|
||||||
|
|
||||||
|
|
||||||
BeOS, Zeta, YellowTab:
|
|
||||||
|
|
||||||
BeOS support was dropped in PhysicsFS 2.1.0. Consider installing Haiku, which
|
|
||||||
we still support.
|
|
||||||
|
|
||||||
|
|
||||||
Haiku:
|
|
||||||
|
|
||||||
Use the "Unix" instructions, above.
|
|
||||||
|
|
||||||
|
|
||||||
OS/2:
|
|
||||||
|
|
||||||
OS/2 is known to work with OpenWatcom and GCC-based compilers. I couldn't get
|
|
||||||
an OS/2 port of CMake to generate OpenWatcom project files (although it should
|
|
||||||
be able to do that in theory), it should be able to do Unix Makefiles with
|
|
||||||
GCC. It might be easier to just compile PhysicsFS along with the rest of
|
|
||||||
your project on this platform.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OTHER PLATFORMS:
|
|
||||||
|
|
||||||
Many Unix-like platforms might "just work" with CMake. Some of these platforms
|
|
||||||
are known to have worked at one time, but have not been heavily tested, if
|
|
||||||
tested at all. PhysicsFS is, as far as we know, 64-bit and byteorder clean,
|
|
||||||
and is known to compile on several compilers across many platforms. To
|
|
||||||
implement a new platform or archiver, please read the heavily-commented
|
|
||||||
physfs_internal.h and look at the physfs_platform_* and physfs_archiver_*
|
|
||||||
source files for examples.
|
|
||||||
|
|
||||||
--ryan. (icculus@icculus.org)
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
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,62 +0,0 @@
|
||||||
Stuff that needs to be done and wishlist:
|
|
||||||
|
|
||||||
These are in no particular order.
|
|
||||||
Some might be dupes, some might be done already, some might be bad ideas.
|
|
||||||
|
|
||||||
|
|
||||||
From https://icculus.org/pipermail/physfs/2009-March/000698.html ...
|
|
||||||
|
|
||||||
- Write support for various archives. I haven't decided how to do this yet,
|
|
||||||
but I'd like to.
|
|
||||||
- Add an API to expose a file's extended attributes to the application?
|
|
||||||
- Deprecate PHYSFS_setSaneConfig(). It really should have been in the extras
|
|
||||||
directory.
|
|
||||||
- Clean up the sources to match my ever-changing coding style. :)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
From https://icculus.org/pipermail/physfs/2010-January/000826.html ...
|
|
||||||
|
|
||||||
- Lua bindings
|
|
||||||
|
|
||||||
|
|
||||||
From https://icculus.org/pipermail/physfs/2010-January/000833.html ...
|
|
||||||
|
|
||||||
- SWIG bindings
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
From old TODO.txt...
|
|
||||||
|
|
||||||
- Other archivers: perhaps tar(.gz|.bz2), RPM, ARJ, etc. These are less
|
|
||||||
important, since streaming archives aren't of much value to games (which
|
|
||||||
is why zipfiles are king: random access), but it could have uses for, say,
|
|
||||||
an installer/updater.
|
|
||||||
- Do symlinks in zip archiver work when they point to dirs?
|
|
||||||
- Enable more warnings?
|
|
||||||
- Use __cdecl in physfs.h?
|
|
||||||
- Look for FIXMEs (many marked with "!!!" in comments).
|
|
||||||
- fscanf and fprintf support in extras dir.
|
|
||||||
- Sanity check byte order at runtime.
|
|
||||||
- Memory locking?
|
|
||||||
- General code audit.
|
|
||||||
- Multiple write dirs with mount points?
|
|
||||||
|
|
||||||
|
|
||||||
Other stuff I thought of...
|
|
||||||
- moar asserts!
|
|
||||||
- constify!
|
|
||||||
- Does iPhone work?
|
|
||||||
- Fix CMake vs Doxygen.
|
|
||||||
- Doxygen replacement? (manpages suck.)
|
|
||||||
- Fix coding standards to match.
|
|
||||||
- See if we can ditch some #include lines...
|
|
||||||
- LZMA support in zip archiver?
|
|
||||||
- bzip2 support in zip archiver?
|
|
||||||
- Reduce the BAIL and GOTO macro use. A lot of these don't add anything.
|
|
||||||
- Change the term "search path" to something less confusing.
|
|
||||||
|
|
||||||
Probably other stuff. Requests and recommendations are welcome.
|
|
||||||
|
|
||||||
// end of TODO.txt ...
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
EXTRA_DIST = \
|
||||||
|
physfsrwops.c \
|
||||||
|
physfsrwops.h \
|
||||||
|
abs-file.h \
|
||||||
|
physfshttpd.c \
|
||||||
|
globbing.h \
|
||||||
|
globbing.c \
|
||||||
|
ignorecase.c \
|
||||||
|
ignorecase.h \
|
||||||
|
PhysFS.NET \
|
||||||
|
physfs_rb
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
//
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
//
|
||||||
|
[assembly: AssemblyTitle("PhysFS.NET")]
|
||||||
|
[assembly: AssemblyDescription("PhysFS Bindings for .NET")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("PhysFS.NET")]
|
||||||
|
[assembly: AssemblyCopyright("(c)2003 Gregory S. Read")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion("1.0.*")]
|
||||||
|
|
||||||
|
//
|
||||||
|
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||||
|
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||||
|
//
|
||||||
|
// Use the attributes below to control which key is used for signing.
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// (*) If no key is specified, the assembly is not signed.
|
||||||
|
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||||
|
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||||
|
// a key.
|
||||||
|
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||||
|
// following processing occurs:
|
||||||
|
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||||
|
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||||
|
// in the KeyFile is installed into the CSP and used.
|
||||||
|
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||||
|
// When specifying the KeyFile, the location of the KeyFile should be
|
||||||
|
// relative to the project output directory which is
|
||||||
|
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||||
|
// located in the project directory, you would specify the AssemblyKeyFile
|
||||||
|
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||||
|
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||||
|
// documentation for more information on this.
|
||||||
|
//
|
||||||
|
[assembly: AssemblyDelaySign(false)]
|
||||||
|
[assembly: AssemblyKeyFile("")]
|
||||||
|
[assembly: AssemblyKeyName("")]
|
|
@ -0,0 +1,113 @@
|
||||||
|
<VisualStudioProject>
|
||||||
|
<CSHARP
|
||||||
|
ProjectType = "Local"
|
||||||
|
ProductVersion = "7.0.9466"
|
||||||
|
SchemaVersion = "1.0"
|
||||||
|
ProjectGuid = "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
|
||||||
|
>
|
||||||
|
<Build>
|
||||||
|
<Settings
|
||||||
|
ApplicationIcon = ""
|
||||||
|
AssemblyKeyContainerName = ""
|
||||||
|
AssemblyName = "PhysFS.NET"
|
||||||
|
AssemblyOriginatorKeyFile = ""
|
||||||
|
DefaultClientScript = "JScript"
|
||||||
|
DefaultHTMLPageLayout = "Grid"
|
||||||
|
DefaultTargetSchema = "IE50"
|
||||||
|
DelaySign = "false"
|
||||||
|
OutputType = "Library"
|
||||||
|
RootNamespace = "PhysFS.NET"
|
||||||
|
StartupObject = ""
|
||||||
|
>
|
||||||
|
<Config
|
||||||
|
Name = "Debug"
|
||||||
|
AllowUnsafeBlocks = "true"
|
||||||
|
BaseAddress = "285212672"
|
||||||
|
CheckForOverflowUnderflow = "false"
|
||||||
|
ConfigurationOverrideFile = ""
|
||||||
|
DefineConstants = "DEBUG;TRACE"
|
||||||
|
DocumentationFile = ""
|
||||||
|
DebugSymbols = "true"
|
||||||
|
FileAlignment = "4096"
|
||||||
|
IncrementalBuild = "true"
|
||||||
|
Optimize = "false"
|
||||||
|
OutputPath = "bin\Debug\"
|
||||||
|
RegisterForComInterop = "false"
|
||||||
|
RemoveIntegerChecks = "false"
|
||||||
|
TreatWarningsAsErrors = "false"
|
||||||
|
WarningLevel = "4"
|
||||||
|
/>
|
||||||
|
<Config
|
||||||
|
Name = "Release"
|
||||||
|
AllowUnsafeBlocks = "true"
|
||||||
|
BaseAddress = "285212672"
|
||||||
|
CheckForOverflowUnderflow = "false"
|
||||||
|
ConfigurationOverrideFile = ""
|
||||||
|
DefineConstants = "TRACE"
|
||||||
|
DocumentationFile = ""
|
||||||
|
DebugSymbols = "false"
|
||||||
|
FileAlignment = "4096"
|
||||||
|
IncrementalBuild = "false"
|
||||||
|
Optimize = "true"
|
||||||
|
OutputPath = "bin\Release\"
|
||||||
|
RegisterForComInterop = "false"
|
||||||
|
RemoveIntegerChecks = "false"
|
||||||
|
TreatWarningsAsErrors = "false"
|
||||||
|
WarningLevel = "4"
|
||||||
|
/>
|
||||||
|
</Settings>
|
||||||
|
<References>
|
||||||
|
<Reference
|
||||||
|
Name = "System"
|
||||||
|
AssemblyName = "System"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.Data"
|
||||||
|
AssemblyName = "System.Data"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.XML"
|
||||||
|
AssemblyName = "System.Xml"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.Drawing"
|
||||||
|
AssemblyName = "System.Drawing"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.Windows.Forms"
|
||||||
|
AssemblyName = "System.Windows.Forms"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
|
||||||
|
/>
|
||||||
|
</References>
|
||||||
|
</Build>
|
||||||
|
<Files>
|
||||||
|
<Include>
|
||||||
|
<File
|
||||||
|
RelPath = "AssemblyInfo.cs"
|
||||||
|
SubType = "Code"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "PhysFS.cs"
|
||||||
|
SubType = "Code"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "PhysFS_DLL.cs"
|
||||||
|
SubType = "Code"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "PhysFSFileStream.cs"
|
||||||
|
SubType = "Code"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
|
</Include>
|
||||||
|
</Files>
|
||||||
|
</CSHARP>
|
||||||
|
</VisualStudioProject>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 7.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhysFS.NET", "PhysFS.NET.csproj", "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
ConfigName.0 = Debug
|
||||||
|
ConfigName.1 = Release
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectDependencies) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.ActiveCfg = Debug|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.Build.0 = Debug|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.ActiveCfg = Release|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.Build.0 = Release|.NET
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,189 @@
|
||||||
|
/* PhysFS.cs - (c)2003 Gregory S. Read
|
||||||
|
* Provides access to PhysFS API calls not specific to file handle access.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace PhysFS_NET
|
||||||
|
{
|
||||||
|
public class PhysFS
|
||||||
|
{
|
||||||
|
/* Initialize
|
||||||
|
* Inits the PhysFS API. This normally does not need to be called unless
|
||||||
|
* the API has been manually deinitialized since the PhysFS_DLL class
|
||||||
|
* initializes just before the first call is made into the DLL.
|
||||||
|
* Parameters
|
||||||
|
* none
|
||||||
|
* Returns
|
||||||
|
* none
|
||||||
|
* Exceptions
|
||||||
|
* PhysFSException - An error occured in the PhysFS API
|
||||||
|
*/
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
// Initialize the physfs library, raise an exception if error
|
||||||
|
if(PhysFS_DLL.PHYSFS_init("") == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deinitialize
|
||||||
|
* Deinits the PhysFS API. It is recommended that this method be called
|
||||||
|
* by the application before exiting in order to gracefully deallocate
|
||||||
|
* resources and close all filehandles, etc.
|
||||||
|
* Parameters
|
||||||
|
* none
|
||||||
|
* Returns
|
||||||
|
* none
|
||||||
|
* Exceptions
|
||||||
|
* PhysFSException - An error occured in the PhysFS API
|
||||||
|
*/
|
||||||
|
public static void Deinitialize()
|
||||||
|
{
|
||||||
|
// Deinit, raise an exception if an error occured
|
||||||
|
if(PhysFS_DLL.PHYSFS_deinit() == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BaseDir
|
||||||
|
* Gets the base directory configured for PhysFS. See the PhysFS API
|
||||||
|
* documentation for more information.
|
||||||
|
* Parameters
|
||||||
|
* none
|
||||||
|
* Returns
|
||||||
|
* A string value representing the Base Directory
|
||||||
|
* Exceptions
|
||||||
|
* none
|
||||||
|
*/
|
||||||
|
public static string BaseDir
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Return the current base directory
|
||||||
|
return PhysFS_DLL.PHYSFS_getBaseDir();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WriteDir
|
||||||
|
* Gets or sets the write directory configured for PhysFS. See the PhysFS API
|
||||||
|
* documentation for more information.
|
||||||
|
* Parameters
|
||||||
|
* set - Path to set the WriteDir property to
|
||||||
|
* Returns
|
||||||
|
* A string value representing the Write Directory
|
||||||
|
* Exceptions
|
||||||
|
* PhysFSException - An error occured in the PhysFS API when
|
||||||
|
* settings the write directory.
|
||||||
|
*/
|
||||||
|
public static string WriteDir
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Return the current write directory
|
||||||
|
return PhysFS_DLL.PHYSFS_getWriteDir();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Set the write directory and raise an exception if an error occured
|
||||||
|
if(PhysFS_DLL.PHYSFS_setWriteDir(value) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UserDir
|
||||||
|
* Gets or sets the write directory configured for PhysFS. See the PhysFS API
|
||||||
|
* documentation for more information.
|
||||||
|
* Parameters
|
||||||
|
* set - Path to set the WriteDir property to
|
||||||
|
* Returns
|
||||||
|
* A string value representing the Write Directory
|
||||||
|
* Exceptions
|
||||||
|
* PhysFSException - An error occured in the PhysFS API when
|
||||||
|
* settings the write directory.
|
||||||
|
*/
|
||||||
|
public static string UserDir
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Return the current user directory
|
||||||
|
return PhysFS_DLL.PHYSFS_getUserDir();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void AddToSearchPath(string NewDir, bool Append)
|
||||||
|
{
|
||||||
|
if(PhysFS_DLL.PHYSFS_addToSearchPath(NewDir, Append?1:0) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
public static void RemoveFromSearchPath(string OldDir)
|
||||||
|
{
|
||||||
|
if(PhysFS_DLL.PHYSFS_removeFromSearchPath(OldDir) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
public unsafe static string[] GetSearchPath()
|
||||||
|
{
|
||||||
|
byte** p; // Searchpath list from PhysFS dll
|
||||||
|
string[] pathlist; // List converted to an array
|
||||||
|
|
||||||
|
// Get the CDROM drive listing
|
||||||
|
p = PhysFS_DLL.PHYSFS_getSearchPath();
|
||||||
|
// Convert the C-style array to a .NET style array
|
||||||
|
pathlist = PhysFS_DLL.BytePPToArray(p);
|
||||||
|
// Free the original list since we're done with it
|
||||||
|
PhysFS_DLL.PHYSFS_freeList(p);
|
||||||
|
|
||||||
|
return pathlist;
|
||||||
|
}
|
||||||
|
public unsafe static string[] GetCDROMDrives()
|
||||||
|
{
|
||||||
|
byte** p; // CDROM list from PhysFS dll
|
||||||
|
string[] cdromlist; // List converted to an array
|
||||||
|
|
||||||
|
// Get the CDROM drive listing
|
||||||
|
p = PhysFS_DLL.PHYSFS_getCdRomDirs();
|
||||||
|
// Convert the C-style array to a .NET style array
|
||||||
|
cdromlist = PhysFS_DLL.BytePPToArray(p);
|
||||||
|
// Free the original list since we're done with it
|
||||||
|
PhysFS_DLL.PHYSFS_freeList(p);
|
||||||
|
|
||||||
|
return cdromlist;
|
||||||
|
}
|
||||||
|
public static void MkDir(string Dirname)
|
||||||
|
{
|
||||||
|
if(PhysFS_DLL.PHYSFS_mkdir(Dirname) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
public static void Delete(string Filename)
|
||||||
|
{
|
||||||
|
if(PhysFS_DLL.PHYSFS_delete(Filename) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
public static string GetRealDir(string Filename)
|
||||||
|
{
|
||||||
|
string RetValue;
|
||||||
|
|
||||||
|
RetValue = PhysFS_DLL.PHYSFS_getRealDir(Filename);
|
||||||
|
if(RetValue == null)
|
||||||
|
throw new PhysFSException("File not found in search path.");
|
||||||
|
|
||||||
|
// Return the real file path of the specified filename
|
||||||
|
return RetValue;
|
||||||
|
}
|
||||||
|
public unsafe static string[] EnumerateFiles(string Dirname)
|
||||||
|
{
|
||||||
|
byte** p; // File list from PhysFS dll
|
||||||
|
string[] filelist; // List converted to an array
|
||||||
|
|
||||||
|
// Get the CDROM drive listing
|
||||||
|
p = PhysFS_DLL.PHYSFS_enumerateFiles(Dirname);
|
||||||
|
// Convert the C-style array to a .NET style array
|
||||||
|
filelist = PhysFS_DLL.BytePPToArray(p);
|
||||||
|
// Free the original list since we're done with it
|
||||||
|
PhysFS_DLL.PHYSFS_freeList(p);
|
||||||
|
|
||||||
|
return filelist;
|
||||||
|
}
|
||||||
|
public static bool IsDirectory(string Filename)
|
||||||
|
{
|
||||||
|
// Return true if non-zero, otherwise return false
|
||||||
|
return (PhysFS_DLL.PHYSFS_isDirectory(Filename) == 0)?false:true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/* PhysFSFileStream.cs - (c)2003 Gregory S. Read */
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace PhysFS_NET
|
||||||
|
{
|
||||||
|
public enum PhysFSFileMode {Read, Write, Append};
|
||||||
|
|
||||||
|
// Our exception class we'll use for throwing all PhysFS API related exception
|
||||||
|
public class PhysFSException : IOException
|
||||||
|
{
|
||||||
|
public PhysFSException(string Message) : base(Message) {}
|
||||||
|
public PhysFSException() : base(PhysFS_DLL.PHYSFS_getLastError()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe class PhysFSFileStream : Stream
|
||||||
|
{
|
||||||
|
// ***Public properties***
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Reading is supported
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanSeek
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Seek is supported
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Writing is supported
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Length
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
long TempLength;
|
||||||
|
TempLength = PhysFS_DLL.PHYSFS_fileLength(pHandle);
|
||||||
|
|
||||||
|
// If call returned an error, throw an exception
|
||||||
|
if(TempLength == -1)
|
||||||
|
throw new PhysFSException();
|
||||||
|
|
||||||
|
return TempLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
long TempPosition;
|
||||||
|
TempPosition = PhysFS_DLL.PHYSFS_tell(pHandle);
|
||||||
|
|
||||||
|
// If call returned an error, throw an exception
|
||||||
|
if(TempPosition == -1)
|
||||||
|
throw new PhysFSException();
|
||||||
|
|
||||||
|
return TempPosition;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Seek from beginning of file using the position value
|
||||||
|
Seek(value, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***Public methods***
|
||||||
|
public PhysFSFileStream(string FileName, PhysFSFileMode FileMode, ulong BufferSize)
|
||||||
|
{
|
||||||
|
// Open the specified file with the appropriate file access
|
||||||
|
switch(FileMode)
|
||||||
|
{
|
||||||
|
case PhysFSFileMode.Read:
|
||||||
|
pHandle = PhysFS_DLL.PHYSFS_openRead(FileName);
|
||||||
|
break;
|
||||||
|
case PhysFSFileMode.Write:
|
||||||
|
pHandle = PhysFS_DLL.PHYSFS_openWrite(FileName);
|
||||||
|
break;
|
||||||
|
case PhysFSFileMode.Append:
|
||||||
|
pHandle = PhysFS_DLL.PHYSFS_openAppend(FileName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new PhysFSException("Invalid FileMode specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If handle is null, an error occured, so raise an exception
|
||||||
|
//!!! Does object get created if exception is thrown?
|
||||||
|
if(pHandle == null)
|
||||||
|
throw new PhysFSException();
|
||||||
|
|
||||||
|
// Set buffer size, raise an exception if an error occured
|
||||||
|
if(PhysFS_DLL.PHYSFS_setBuffer(pHandle, BufferSize) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This constructor sets the buffer size to 0 if not specified
|
||||||
|
public PhysFSFileStream(string FileName, PhysFSFileMode FileMode) : this(FileName, FileMode, 0) {}
|
||||||
|
|
||||||
|
~PhysFSFileStream()
|
||||||
|
{
|
||||||
|
// Don't close the handle if they've specifically closed it already
|
||||||
|
if(!Closed)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
if(PhysFS_DLL.PHYSFS_flush(pHandle) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
long RetValue;
|
||||||
|
|
||||||
|
fixed(byte *pbytes = &buffer[offset])
|
||||||
|
{
|
||||||
|
// Read into our allocated pointer
|
||||||
|
RetValue = PhysFS_DLL.PHYSFS_read(pHandle, pbytes, sizeof(byte), (uint)count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(RetValue == -1)
|
||||||
|
throw new PhysFSException();
|
||||||
|
|
||||||
|
// Return number of bytes read
|
||||||
|
// Note: This cast should be safe since we are only reading 'count' items, which
|
||||||
|
// is of type 'int'.
|
||||||
|
return (int)RetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
long RetValue;
|
||||||
|
|
||||||
|
fixed(byte* pbytes = &buffer[offset])
|
||||||
|
{
|
||||||
|
// Write buffer
|
||||||
|
RetValue = PhysFS_DLL.PHYSFS_write(pHandle, pbytes, sizeof(byte), (uint)count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(RetValue == -1)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
// Only seeking from beginning is supported by PhysFS API
|
||||||
|
if(origin != SeekOrigin.Begin)
|
||||||
|
throw new PhysFSException("Only seek origin of \"Begin\" is supported");
|
||||||
|
|
||||||
|
// Seek to specified offset, raise an exception if error occured
|
||||||
|
if(PhysFS_DLL.PHYSFS_seek(pHandle, (ulong)offset) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
|
||||||
|
// Since we always seek from beginning, the offset is always
|
||||||
|
// the absolute position.
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("SetLength method not supported in PhysFSFileStream objects.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
// Close the handle
|
||||||
|
if(PhysFS_DLL.PHYSFS_close(pHandle) == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
|
||||||
|
// File has been closed. Rock.
|
||||||
|
Closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***Private variables***
|
||||||
|
private void *pHandle;
|
||||||
|
private bool Closed = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* PhysFS_DLL - (c)2003 Gregory S. Read
|
||||||
|
* Internal class that provides direct access to the PhysFS DLL. It is
|
||||||
|
* not accessible outside of the PhysFS.NET assembly.
|
||||||
|
*/
|
||||||
|
using System.Collections;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace PhysFS_NET
|
||||||
|
{
|
||||||
|
internal class PhysFS_DLL
|
||||||
|
{
|
||||||
|
/* Static constructor
|
||||||
|
* Initializes the PhysFS API before any method is called in this class. This
|
||||||
|
* relieves the user from having to explicitly initialize the API.
|
||||||
|
* Parameters
|
||||||
|
* none
|
||||||
|
* Returns
|
||||||
|
* none
|
||||||
|
* Exceptions
|
||||||
|
* PhysFSException - An error occured in the PhysFS API
|
||||||
|
*/
|
||||||
|
static PhysFS_DLL()
|
||||||
|
{
|
||||||
|
if(PHYSFS_init("") == 0)
|
||||||
|
throw new PhysFSException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BytePPToArray
|
||||||
|
* Converts a C-style string array into a .NET managed string array
|
||||||
|
* Parameters
|
||||||
|
* C-style string array pointer returned from PhysFS
|
||||||
|
* Returns
|
||||||
|
* .NET managed string array
|
||||||
|
* Exceptions
|
||||||
|
* none
|
||||||
|
*/
|
||||||
|
public unsafe static string[] BytePPToArray(byte **bytearray)
|
||||||
|
{
|
||||||
|
byte** ptr;
|
||||||
|
byte* c;
|
||||||
|
string tempstr;
|
||||||
|
ArrayList MyArrayList = new ArrayList();
|
||||||
|
string[] RetArray;
|
||||||
|
|
||||||
|
for(ptr = bytearray; *ptr != null; ptr++)
|
||||||
|
{
|
||||||
|
tempstr = "";
|
||||||
|
for(c = *ptr; *c != 0; c++)
|
||||||
|
{
|
||||||
|
tempstr += (char)*c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add string to our list
|
||||||
|
MyArrayList.Add(tempstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a normal array of the list
|
||||||
|
RetArray = new string[MyArrayList.Count];
|
||||||
|
MyArrayList.CopyTo(RetArray, 0);
|
||||||
|
return RetArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name of DLL to import
|
||||||
|
private const string PHYSFS_DLLNAME = "physfs.dll";
|
||||||
|
|
||||||
|
// DLL import declarations
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_init(string argv0);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_deinit();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe void PHYSFS_freeList(void *listVar);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getLastError();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getDirSeparator();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern void PHYSFS_permitSymbolicLinks(int allow);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe byte** PHYSFS_getCdRomDirs();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getBaseDir();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getUserDir();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getWriteDir();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_setWriteDir(string newDir);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_addToSearchPath(string newDir, int appendToPath);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_removeFromSearchPath(string oldDir);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe byte** PHYSFS_getSearchPath();
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_setSaneConfig(string organization,
|
||||||
|
string appName,
|
||||||
|
string archiveExt,
|
||||||
|
int includeCdRoms,
|
||||||
|
int archivesFirst);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_mkdir(string dirName);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_delete(string filename);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern string PHYSFS_getRealDir(string filename);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe byte** PHYSFS_enumerateFiles(string dir);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_exists(string fname);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_isDirectory(string fname);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern int PHYSFS_isSymbolicLink(string fname);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe void* PHYSFS_openWrite(string filename);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe void* PHYSFS_openAppend(string filename);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe void* PHYSFS_openRead(string filename);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_close(void* handle);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_getLastModTime(string filename);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_read(void* handle,
|
||||||
|
void *buffer,
|
||||||
|
uint objSize,
|
||||||
|
uint objCount);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_write(void* handle,
|
||||||
|
void *buffer,
|
||||||
|
uint objSize,
|
||||||
|
uint objCount);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_eof(void* handle);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_tell(void* handle);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_seek(void* handle, ulong pos);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe long PHYSFS_fileLength(void* handle);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_setBuffer(void* handle, ulong bufsize);
|
||||||
|
[DllImport(PHYSFS_DLLNAME)] public static extern unsafe int PHYSFS_flush(void* handle);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
PhysFS.NET is a library that encapsulates the PhysFS API into a .NET assembly.
|
||||||
|
|
||||||
|
There are two class objects that are exposed in the assembly:
|
||||||
|
PhysFS.cs
|
||||||
|
This class exposes any non-filehandle specific functionality contained in
|
||||||
|
the PhysFS library.
|
||||||
|
PhysFSFileStream.cs
|
||||||
|
A System.IO.Stream derived class which provides file access via the
|
||||||
|
PhysFS API. Usage of this object is identical to a standard stream
|
||||||
|
object.
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,58 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
//
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
//
|
||||||
|
[assembly: AssemblyTitle("")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("")]
|
||||||
|
[assembly: AssemblyCopyright("")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion("1.0.*")]
|
||||||
|
|
||||||
|
//
|
||||||
|
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||||
|
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||||
|
//
|
||||||
|
// Use the attributes below to control which key is used for signing.
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// (*) If no key is specified, the assembly is not signed.
|
||||||
|
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||||
|
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||||
|
// a key.
|
||||||
|
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||||
|
// following processing occurs:
|
||||||
|
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||||
|
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||||
|
// in the KeyFile is installed into the CSP and used.
|
||||||
|
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||||
|
// When specifying the KeyFile, the location of the KeyFile should be
|
||||||
|
// relative to the project output directory which is
|
||||||
|
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||||
|
// located in the project directory, you would specify the AssemblyKeyFile
|
||||||
|
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||||
|
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||||
|
// documentation for more information on this.
|
||||||
|
//
|
||||||
|
[assembly: AssemblyDelaySign(false)]
|
||||||
|
[assembly: AssemblyKeyFile("")]
|
||||||
|
[assembly: AssemblyKeyName("")]
|
|
@ -0,0 +1,116 @@
|
||||||
|
<VisualStudioProject>
|
||||||
|
<CSHARP
|
||||||
|
ProjectType = "Local"
|
||||||
|
ProductVersion = "7.0.9466"
|
||||||
|
SchemaVersion = "1.0"
|
||||||
|
ProjectGuid = "{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}"
|
||||||
|
>
|
||||||
|
<Build>
|
||||||
|
<Settings
|
||||||
|
ApplicationIcon = "App.ico"
|
||||||
|
AssemblyKeyContainerName = ""
|
||||||
|
AssemblyName = "TestApp"
|
||||||
|
AssemblyOriginatorKeyFile = ""
|
||||||
|
DefaultClientScript = "JScript"
|
||||||
|
DefaultHTMLPageLayout = "Grid"
|
||||||
|
DefaultTargetSchema = "IE50"
|
||||||
|
DelaySign = "false"
|
||||||
|
OutputType = "WinExe"
|
||||||
|
RootNamespace = "TestApp"
|
||||||
|
StartupObject = ""
|
||||||
|
>
|
||||||
|
<Config
|
||||||
|
Name = "Debug"
|
||||||
|
AllowUnsafeBlocks = "false"
|
||||||
|
BaseAddress = "285212672"
|
||||||
|
CheckForOverflowUnderflow = "false"
|
||||||
|
ConfigurationOverrideFile = ""
|
||||||
|
DefineConstants = "DEBUG;TRACE"
|
||||||
|
DocumentationFile = ""
|
||||||
|
DebugSymbols = "true"
|
||||||
|
FileAlignment = "4096"
|
||||||
|
IncrementalBuild = "true"
|
||||||
|
Optimize = "false"
|
||||||
|
OutputPath = "bin\Debug\"
|
||||||
|
RegisterForComInterop = "false"
|
||||||
|
RemoveIntegerChecks = "false"
|
||||||
|
TreatWarningsAsErrors = "false"
|
||||||
|
WarningLevel = "4"
|
||||||
|
/>
|
||||||
|
<Config
|
||||||
|
Name = "Release"
|
||||||
|
AllowUnsafeBlocks = "false"
|
||||||
|
BaseAddress = "285212672"
|
||||||
|
CheckForOverflowUnderflow = "false"
|
||||||
|
ConfigurationOverrideFile = ""
|
||||||
|
DefineConstants = "TRACE"
|
||||||
|
DocumentationFile = ""
|
||||||
|
DebugSymbols = "false"
|
||||||
|
FileAlignment = "4096"
|
||||||
|
IncrementalBuild = "false"
|
||||||
|
Optimize = "true"
|
||||||
|
OutputPath = "bin\Release\"
|
||||||
|
RegisterForComInterop = "false"
|
||||||
|
RemoveIntegerChecks = "false"
|
||||||
|
TreatWarningsAsErrors = "false"
|
||||||
|
WarningLevel = "4"
|
||||||
|
/>
|
||||||
|
</Settings>
|
||||||
|
<References>
|
||||||
|
<Reference
|
||||||
|
Name = "System"
|
||||||
|
AssemblyName = "System"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.Data"
|
||||||
|
AssemblyName = "System.Data"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.Drawing"
|
||||||
|
AssemblyName = "System.Drawing"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Drawing.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.Windows.Forms"
|
||||||
|
AssemblyName = "System.Windows.Forms"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "System.XML"
|
||||||
|
AssemblyName = "System.Xml"
|
||||||
|
HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
|
||||||
|
/>
|
||||||
|
<Reference
|
||||||
|
Name = "PhysFS.NET"
|
||||||
|
Project = "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
|
||||||
|
Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
|
||||||
|
/>
|
||||||
|
</References>
|
||||||
|
</Build>
|
||||||
|
<Files>
|
||||||
|
<Include>
|
||||||
|
<File
|
||||||
|
RelPath = "App.ico"
|
||||||
|
BuildAction = "Content"
|
||||||
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "AssemblyInfo.cs"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "TestAppForm.cs"
|
||||||
|
SubType = "Form"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "TestAppForm.resx"
|
||||||
|
DependentUpon = "TestAppForm.cs"
|
||||||
|
BuildAction = "EmbeddedResource"
|
||||||
|
/>
|
||||||
|
</Include>
|
||||||
|
</Files>
|
||||||
|
</CSHARP>
|
||||||
|
</VisualStudioProject>
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 7.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "TestApp.csproj", "{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhysFS.NET", "..\PhysFS.NET.csproj", "{C6205A43-3D4D-41E6-872C-96CD7BE55230}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
ConfigName.0 = Debug
|
||||||
|
ConfigName.1 = Release
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectDependencies) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Debug.ActiveCfg = Debug|.NET
|
||||||
|
{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Debug.Build.0 = Debug|.NET
|
||||||
|
{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Release.ActiveCfg = Release|.NET
|
||||||
|
{9C1ECC6B-16C7-42B3-BF7C-8BA8D81BA980}.Release.Build.0 = Release|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.ActiveCfg = Debug|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Debug.Build.0 = Debug|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.ActiveCfg = Release|.NET
|
||||||
|
{C6205A43-3D4D-41E6-872C-96CD7BE55230}.Release.Build.0 = Release|.NET
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,274 @@
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Collections;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Data;
|
||||||
|
using System.IO;
|
||||||
|
using PhysFS_NET;
|
||||||
|
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for Form1.
|
||||||
|
/// </summary>
|
||||||
|
public class TestAppForm : System.Windows.Forms.Form
|
||||||
|
{
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.Button RefreshCDsButton;
|
||||||
|
private System.Windows.Forms.ListBox CDDrivesList;
|
||||||
|
private System.Windows.Forms.ListBox SearchPathList;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.TextBox EnumFilesPath;
|
||||||
|
private System.Windows.Forms.ListBox EnumList;
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.TextBox NewSearchPathText;
|
||||||
|
private System.Windows.Forms.Button AddSearchPathButton;
|
||||||
|
private System.Windows.Forms.Button RemovePathButton;
|
||||||
|
private System.Windows.Forms.Button RefreshEnumList;
|
||||||
|
private System.Windows.Forms.Button RefreshSearchPathButton;
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.Container components = null;
|
||||||
|
|
||||||
|
public TestAppForm()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Required for Windows Form Designer support
|
||||||
|
//
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Add any constructor code after InitializeComponent call
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
protected override void Dispose( bool disposing )
|
||||||
|
{
|
||||||
|
if( disposing )
|
||||||
|
{
|
||||||
|
if (components != null)
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.Dispose( disposing );
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.RefreshCDsButton = new System.Windows.Forms.Button();
|
||||||
|
this.CDDrivesList = new System.Windows.Forms.ListBox();
|
||||||
|
this.SearchPathList = new System.Windows.Forms.ListBox();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.EnumFilesPath = new System.Windows.Forms.TextBox();
|
||||||
|
this.EnumList = new System.Windows.Forms.ListBox();
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.RefreshEnumList = new System.Windows.Forms.Button();
|
||||||
|
this.NewSearchPathText = new System.Windows.Forms.TextBox();
|
||||||
|
this.AddSearchPathButton = new System.Windows.Forms.Button();
|
||||||
|
this.RemovePathButton = new System.Windows.Forms.Button();
|
||||||
|
this.RefreshSearchPathButton = new System.Windows.Forms.Button();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.Location = new System.Drawing.Point(8, 8);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(136, 16);
|
||||||
|
this.label2.TabIndex = 2;
|
||||||
|
this.label2.Text = "Available CD-ROM Drives";
|
||||||
|
//
|
||||||
|
// RefreshCDsButton
|
||||||
|
//
|
||||||
|
this.RefreshCDsButton.Location = new System.Drawing.Point(8, 152);
|
||||||
|
this.RefreshCDsButton.Name = "RefreshCDsButton";
|
||||||
|
this.RefreshCDsButton.Size = new System.Drawing.Size(72, 24);
|
||||||
|
this.RefreshCDsButton.TabIndex = 4;
|
||||||
|
this.RefreshCDsButton.Text = "Refresh";
|
||||||
|
this.RefreshCDsButton.Click += new System.EventHandler(this.RefreshCDsButton_Click);
|
||||||
|
//
|
||||||
|
// CDDrivesList
|
||||||
|
//
|
||||||
|
this.CDDrivesList.Location = new System.Drawing.Point(8, 24);
|
||||||
|
this.CDDrivesList.Name = "CDDrivesList";
|
||||||
|
this.CDDrivesList.Size = new System.Drawing.Size(136, 121);
|
||||||
|
this.CDDrivesList.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// SearchPathList
|
||||||
|
//
|
||||||
|
this.SearchPathList.Location = new System.Drawing.Point(152, 24);
|
||||||
|
this.SearchPathList.Name = "SearchPathList";
|
||||||
|
this.SearchPathList.Size = new System.Drawing.Size(248, 95);
|
||||||
|
this.SearchPathList.TabIndex = 8;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.Location = new System.Drawing.Point(152, 8);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(136, 16);
|
||||||
|
this.label1.TabIndex = 10;
|
||||||
|
this.label1.Text = "Search Path";
|
||||||
|
//
|
||||||
|
// EnumFilesPath
|
||||||
|
//
|
||||||
|
this.EnumFilesPath.Location = new System.Drawing.Point(408, 128);
|
||||||
|
this.EnumFilesPath.Name = "EnumFilesPath";
|
||||||
|
this.EnumFilesPath.Size = new System.Drawing.Size(208, 20);
|
||||||
|
this.EnumFilesPath.TabIndex = 11;
|
||||||
|
this.EnumFilesPath.Text = "";
|
||||||
|
//
|
||||||
|
// EnumList
|
||||||
|
//
|
||||||
|
this.EnumList.Location = new System.Drawing.Point(408, 24);
|
||||||
|
this.EnumList.Name = "EnumList";
|
||||||
|
this.EnumList.Size = new System.Drawing.Size(208, 95);
|
||||||
|
this.EnumList.TabIndex = 12;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.Location = new System.Drawing.Point(408, 8);
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(136, 16);
|
||||||
|
this.label3.TabIndex = 13;
|
||||||
|
this.label3.Text = "Enumerate Files";
|
||||||
|
//
|
||||||
|
// RefreshEnumList
|
||||||
|
//
|
||||||
|
this.RefreshEnumList.Location = new System.Drawing.Point(544, 152);
|
||||||
|
this.RefreshEnumList.Name = "RefreshEnumList";
|
||||||
|
this.RefreshEnumList.Size = new System.Drawing.Size(72, 24);
|
||||||
|
this.RefreshEnumList.TabIndex = 14;
|
||||||
|
this.RefreshEnumList.Text = "Refresh";
|
||||||
|
this.RefreshEnumList.Click += new System.EventHandler(this.RefreshEnumList_Click);
|
||||||
|
//
|
||||||
|
// NewSearchPathText
|
||||||
|
//
|
||||||
|
this.NewSearchPathText.Location = new System.Drawing.Point(152, 128);
|
||||||
|
this.NewSearchPathText.Name = "NewSearchPathText";
|
||||||
|
this.NewSearchPathText.Size = new System.Drawing.Size(248, 20);
|
||||||
|
this.NewSearchPathText.TabIndex = 15;
|
||||||
|
this.NewSearchPathText.Text = "";
|
||||||
|
//
|
||||||
|
// AddSearchPathButton
|
||||||
|
//
|
||||||
|
this.AddSearchPathButton.Location = new System.Drawing.Point(152, 152);
|
||||||
|
this.AddSearchPathButton.Name = "AddSearchPathButton";
|
||||||
|
this.AddSearchPathButton.Size = new System.Drawing.Size(72, 24);
|
||||||
|
this.AddSearchPathButton.TabIndex = 9;
|
||||||
|
this.AddSearchPathButton.Text = "Add Path";
|
||||||
|
this.AddSearchPathButton.Click += new System.EventHandler(this.AddSearchPathButton_Click);
|
||||||
|
//
|
||||||
|
// RemovePathButton
|
||||||
|
//
|
||||||
|
this.RemovePathButton.Location = new System.Drawing.Point(232, 152);
|
||||||
|
this.RemovePathButton.Name = "RemovePathButton";
|
||||||
|
this.RemovePathButton.Size = new System.Drawing.Size(88, 24);
|
||||||
|
this.RemovePathButton.TabIndex = 16;
|
||||||
|
this.RemovePathButton.Text = "Remove Path";
|
||||||
|
this.RemovePathButton.Click += new System.EventHandler(this.RemovePathButton_Click);
|
||||||
|
//
|
||||||
|
// RefreshSearchPathButton
|
||||||
|
//
|
||||||
|
this.RefreshSearchPathButton.Location = new System.Drawing.Point(328, 152);
|
||||||
|
this.RefreshSearchPathButton.Name = "RefreshSearchPathButton";
|
||||||
|
this.RefreshSearchPathButton.Size = new System.Drawing.Size(72, 24);
|
||||||
|
this.RefreshSearchPathButton.TabIndex = 17;
|
||||||
|
this.RefreshSearchPathButton.Text = "Refresh";
|
||||||
|
this.RefreshSearchPathButton.Click += new System.EventHandler(this.RefreshSearchPathButton_Click);
|
||||||
|
//
|
||||||
|
// TestAppForm
|
||||||
|
//
|
||||||
|
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||||
|
this.ClientSize = new System.Drawing.Size(624, 309);
|
||||||
|
this.Controls.AddRange(new System.Windows.Forms.Control[] {
|
||||||
|
this.RefreshSearchPathButton,
|
||||||
|
this.RemovePathButton,
|
||||||
|
this.NewSearchPathText,
|
||||||
|
this.RefreshEnumList,
|
||||||
|
this.label3,
|
||||||
|
this.EnumList,
|
||||||
|
this.EnumFilesPath,
|
||||||
|
this.label1,
|
||||||
|
this.SearchPathList,
|
||||||
|
this.CDDrivesList,
|
||||||
|
this.RefreshCDsButton,
|
||||||
|
this.label2,
|
||||||
|
this.AddSearchPathButton});
|
||||||
|
this.Name = "TestAppForm";
|
||||||
|
this.Text = "PhysFS Test Application";
|
||||||
|
this.Load += new System.EventHandler(this.TestAppForm_Load);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Application.Run(new TestAppForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestAppForm_Load(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshCDsButton_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
// Clear ths listbox if it contains any items
|
||||||
|
CDDrivesList.Items.Clear();
|
||||||
|
// Add the items to the list
|
||||||
|
CDDrivesList.Items.AddRange(PhysFS.GetCDROMDrives());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshSearchPathButton_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
// Clear ths listbox if it contains any items
|
||||||
|
SearchPathList.Items.Clear();
|
||||||
|
// Add the items to the list
|
||||||
|
SearchPathList.Items.AddRange(PhysFS.GetSearchPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddSearchPathButton_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
// Add search path
|
||||||
|
PhysFS.AddToSearchPath(NewSearchPathText.Text, false);
|
||||||
|
// Clear ths listbox if it contains any items
|
||||||
|
SearchPathList.Items.Clear();
|
||||||
|
// Add the items to the list
|
||||||
|
SearchPathList.Items.AddRange(PhysFS.GetSearchPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemovePathButton_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
if(SearchPathList.SelectedItem != null)
|
||||||
|
{
|
||||||
|
PhysFS.RemoveFromSearchPath(SearchPathList.SelectedItem.ToString());
|
||||||
|
// Clear ths listbox if it contains any items
|
||||||
|
SearchPathList.Items.Clear();
|
||||||
|
// Add the items to the list
|
||||||
|
SearchPathList.Items.AddRange(PhysFS.GetSearchPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshEnumList_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
EnumList.Items.Clear();
|
||||||
|
EnumList.Items.AddRange(PhysFS.EnumerateFiles(EnumFilesPath.Text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 1.3
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">1.3</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1">this is my long string</data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
[base64 mime encoded serialized .NET Framework object]
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>1.3</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="$this.Name">
|
||||||
|
<value>TestAppForm</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
|
@ -1,11 +0,0 @@
|
||||||
There used to be C# bindings in this directory, but they have been
|
|
||||||
unmaintained for many years.
|
|
||||||
|
|
||||||
Instead, there is a more modern PhysicsFS wrapper for .NET available.
|
|
||||||
|
|
||||||
You can find it at https://github.com/frabert/SharpPhysFS
|
|
||||||
|
|
||||||
Thanks to Francesco Bertolaccini for his efforts on that project!
|
|
||||||
|
|
||||||
--ryan.
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ from the Author.
|
||||||
#ifdef USE_PHYSFS
|
#ifdef USE_PHYSFS
|
||||||
|
|
||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
#define MY_FILETYPE PHYSFS_File
|
#define MY_FILETYPE PHYSFS_file
|
||||||
#define MY_SETBUFFER(fp,size) PHYSFS_setBuffer(fp,size)
|
#define MY_SETBUFFER(fp,size) PHYSFS_setBuffer(fp,size)
|
||||||
#define MY_READ(p,s,n,fp) PHYSFS_read(fp,p,s,n)
|
#define MY_READ(p,s,n,fp) PHYSFS_read(fp,p,s,n)
|
||||||
#if PHYSFS_DEFAULT_READ_BUFFER
|
#if PHYSFS_DEFAULT_READ_BUFFER
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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), Make sure "scan-build" is in your $PATH.
|
|
||||||
|
|
||||||
FINALDIR="$1"
|
|
||||||
|
|
||||||
set -x
|
|
||||||
set -e
|
|
||||||
|
|
||||||
cd `dirname "$0"`
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
rm -rf checker-buildbot analysis
|
|
||||||
if [ ! -z "$FINALDIR" ]; then
|
|
||||||
rm -rf "$FINALDIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir checker-buildbot
|
|
||||||
cd checker-buildbot
|
|
||||||
|
|
||||||
# We turn off deprecated declarations, because we don't care about these warnings during static analysis.
|
|
||||||
# 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...
|
|
||||||
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
|
|
||||||
scan-build -o analysis cmake --build . --config Debug
|
|
||||||
|
|
||||||
if [ `ls -A analysis |wc -l` == 0 ] ; then
|
|
||||||
mkdir analysis/zarro
|
|
||||||
echo '<html><head><title>Zarro boogs</title></head><body>Static analysis: no issues to report.</body></html>' >analysis/zarro/index.html
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv analysis/* ../analysis
|
|
||||||
rmdir analysis # Make sure this is empty.
|
|
||||||
cd ..
|
|
||||||
chmod -R a+r analysis
|
|
||||||
chmod -R go-w analysis
|
|
||||||
find analysis -type d -exec chmod a+x {} \;
|
|
||||||
if [ -x /usr/bin/xattr ]; then find analysis -exec /usr/bin/xattr -d com.apple.quarantine {} \; 2>/dev/null ; fi
|
|
||||||
|
|
||||||
if [ ! -z "$FINALDIR" ]; then
|
|
||||||
mv analysis "$FINALDIR"
|
|
||||||
else
|
|
||||||
FINALDIR=analysis
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf checker-buildbot
|
|
||||||
|
|
||||||
echo "Done. Final output is in '$FINALDIR' ..."
|
|
||||||
|
|
||||||
# end of checker-buildbot.sh ...
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ -z "$SDKDIR" ]; then
|
|
||||||
SDKDIR="/emsdk"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ENVSCRIPT="$SDKDIR/emsdk_env.sh"
|
|
||||||
if [ ! -f "$ENVSCRIPT" ]; then
|
|
||||||
echo "ERROR: This script expects the Emscripten SDK to be in '$SDKDIR'." 1>&2
|
|
||||||
echo "ERROR: Set the \$SDKDIR environment variable to override this." 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TARBALL="$1"
|
|
||||||
if [ -z $1 ]; then
|
|
||||||
TARBALL=physfs-emscripten.tar.xz
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd `dirname "$0"`
|
|
||||||
cd ..
|
|
||||||
PHYSFSBASE=`pwd`
|
|
||||||
|
|
||||||
echo "Setting up Emscripten SDK environment..."
|
|
||||||
source "$ENVSCRIPT"
|
|
||||||
|
|
||||||
echo "Setting up..."
|
|
||||||
cd "$PHYSFSBASE"
|
|
||||||
rm -rf buildbot
|
|
||||||
mkdir buildbot
|
|
||||||
cd buildbot
|
|
||||||
|
|
||||||
echo "Configuring..."
|
|
||||||
emcmake cmake -G "Ninja" -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=MinSizeRel .. || exit $?
|
|
||||||
|
|
||||||
echo "Building..."
|
|
||||||
emmake cmake --build . --config MinSizeRel || exit $?
|
|
||||||
|
|
||||||
set -e
|
|
||||||
rm -rf "$TARBALL" physfs-emscripten
|
|
||||||
mkdir -p physfs-emscripten
|
|
||||||
echo "Archiving to '$TARBALL' ..."
|
|
||||||
cp ../src/physfs.h libphysfs.a physfs-emscripten
|
|
||||||
chmod -R a+r physfs-emscripten
|
|
||||||
chmod a+x physfs-emscripten
|
|
||||||
chmod -R go-w physfs-emscripten
|
|
||||||
tar -cJvvf "$TARBALL" physfs-emscripten
|
|
||||||
echo "Done."
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
# end of emscripten-buildbot.sh ...
|
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# This is used by the buildbot to cross-compile for OS/2 from Linux, using
|
|
||||||
# OpenWatcom. In an ideal world, we wouldn't need this, but we need a few
|
|
||||||
# things to do this "properly" ...
|
|
||||||
#
|
|
||||||
# - OS/2 running as a VMware guest on the build machine
|
|
||||||
# - Buildbot-worker running on that OS/2 guest
|
|
||||||
# - CMake for OS/2 that...
|
|
||||||
# - ... has Open Watcom compiler support and...
|
|
||||||
# - ... a Watcom WMake project generator.
|
|
||||||
#
|
|
||||||
# Some of these things are doable (there is a CMake port for OS/2, you can
|
|
||||||
# use GCC with it), but since OpenWatcom will just target OS/2 on Linux just
|
|
||||||
# like it could on OS/2, it's easier and more efficient to just have a
|
|
||||||
# buildbot script compile it here.
|
|
||||||
#
|
|
||||||
# Note that we just blast all the C files through the wcc386 compiler and
|
|
||||||
# skip CMake entirely. We should fix this at some point.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
ZIPFILE="$1"
|
|
||||||
if [ -z $ZIPFILE ]; then
|
|
||||||
ZIPFILE=physfs-os2.zip
|
|
||||||
fi
|
|
||||||
|
|
||||||
export WATCOM="/usr/local/share/watcom"
|
|
||||||
export PATH="$PATH:$WATCOM/binl"
|
|
||||||
|
|
||||||
CFLAGS="-i=\"$WATCOM/h;$WATCOM/h/os2;../src\" -wx -d0 -otexan -6r -zq -bt=os2 -fo=.obj -mf"
|
|
||||||
WLIBFLAGS="-b -c -n -q -p=512"
|
|
||||||
|
|
||||||
cd `dirname "$0"`
|
|
||||||
cd ..
|
|
||||||
mkdir -p buildbot
|
|
||||||
cd buildbot
|
|
||||||
|
|
||||||
rm -f test_physfs.obj
|
|
||||||
|
|
||||||
OKAY="1"
|
|
||||||
for src in ../src/*.c ; do
|
|
||||||
echo wcc386 $src $CFLAGS
|
|
||||||
wcc386 $src $CFLAGS || OKAY="0"
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$OKAY" == "1" ]; then
|
|
||||||
echo wlib $WLIBFLAGS physfs.lib *.obj
|
|
||||||
wlib $WLIBFLAGS physfs.lib *.obj || OKAY="0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo wcc386 ../test/test_physfs.c $CFLAGS
|
|
||||||
wcc386 ../test/test_physfs.c $CFLAGS || OKAY="0"
|
|
||||||
|
|
||||||
if [ "$OKAY" == "1" ]; then
|
|
||||||
LDFLAGS="name test_physfs d all sys os2v2 op m libr physfs op q op symf FIL test_physfs.obj"
|
|
||||||
echo wlink $LDFLAGS
|
|
||||||
wlink $LDFLAGS || OKAY="0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$OKAY" == "1" ]; then
|
|
||||||
F=`file test_physfs.exe`
|
|
||||||
echo "$F"
|
|
||||||
if [ "$F" != 'test_physfs.exe: MS-DOS executable, LX for OS/2 (console) i80386' ]; then
|
|
||||||
echo 1>&2 "ERROR: final binary doesn't appear to be OS/2 executable."
|
|
||||||
OKAY=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$OKAY" == "1" ]; then
|
|
||||||
echo 1>&2 "Build succeeded."
|
|
||||||
set -e
|
|
||||||
rm -rf "$ZIPFILE" physfs-os2
|
|
||||||
mkdir -p physfs-os2
|
|
||||||
echo "Zipping to '$ZIPFILE' ..."
|
|
||||||
cp ../src/physfs.h physfs.lib physfs-os2
|
|
||||||
chmod -R a+r physfs-os2
|
|
||||||
chmod a+x physfs-os2
|
|
||||||
chmod -R go-w physfs-os2
|
|
||||||
zip -9r "$ZIPFILE" physfs-os2
|
|
||||||
echo "Done."
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo 1>&2 "Build failed."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# This is the script physfs-buildbot.icculus.org uses to cross-compile
|
|
||||||
# PhysicsFS from x86 Linux to Raspberry Pi. This script was originally from
|
|
||||||
# Simple Directmedia Layer ( https://www.libsdl.org/ ).
|
|
||||||
|
|
||||||
# The final tarball can be unpacked in the root directory of a RPi,
|
|
||||||
# so the PhysicsFS install lands in /usr/local. Run ldconfig, and then
|
|
||||||
# you should be able to build and run PhysicsFS-based software on your
|
|
||||||
# Pi. Standard configure scripts should be able to find PhysicsFS and
|
|
||||||
# build against it.
|
|
||||||
|
|
||||||
TARBALL="$1"
|
|
||||||
if [ -z $1 ]; then
|
|
||||||
TARBALL=physfs-raspberrypi.tar.xz
|
|
||||||
fi
|
|
||||||
|
|
||||||
BUILDBOTDIR="buildbot"
|
|
||||||
PARENTDIR="$PWD"
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
rm -f $TARBALL
|
|
||||||
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 "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" \
|
|
||||||
-DCMAKE_FIND_ROOT_PATH="$SYSROOT" \
|
|
||||||
-DCMAKE_SYSTEM_NAME="Linux" \
|
|
||||||
-DCMAKE_SYSTEM_VERSION=1 \
|
|
||||||
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
|
|
||||||
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
|
|
||||||
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
|
|
||||||
..
|
|
||||||
|
|
||||||
cmake --build . --config MinSizeRel
|
|
||||||
|
|
||||||
rm -rf "$TARBALL" physfs-raspberrypi
|
|
||||||
mkdir -p physfs-raspberrypi
|
|
||||||
echo "Archiving to '$TARBALL' ..."
|
|
||||||
cp -a ../src/physfs.h libphysfs.a libphysfs.so* physfs-raspberrypi
|
|
||||||
chmod -R a+r physfs-raspberrypi
|
|
||||||
chmod a+x physfs-raspberrypi physfs-raspberrypi/*.so*
|
|
||||||
chmod -R go-w physfs-raspberrypi
|
|
||||||
tar -cJvvf "$TARBALL" physfs-raspberrypi
|
|
||||||
|
|
||||||
set +x
|
|
||||||
echo "Done."
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,8 +4,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
#include "physfs.h"
|
||||||
#include "globbing.h"
|
#include "globbing.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see the file LICENSE.txt in the source's root directory.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* \author Ryan C. Gordon.
|
* \author Ryan C. Gordon.
|
||||||
*/
|
*/
|
||||||
|
@ -77,118 +77,38 @@ static int matchesPattern(const char *fname, const char *wildcard,
|
||||||
fnameptr++;
|
fnameptr++;
|
||||||
|
|
||||||
if (x != y)
|
if (x != y)
|
||||||
return 0;
|
return(0);
|
||||||
} /* else */
|
} /* else */
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
while (*wildptr == '*')
|
while (*wildptr == '*')
|
||||||
wildptr++;
|
wildptr++;
|
||||||
|
|
||||||
return (*fnameptr == *wildptr);
|
return(*fnameptr == *wildptr);
|
||||||
} /* matchesPattern */
|
} /* matchesPattern */
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
const PHYSFS_Allocator *allocator;
|
|
||||||
const char *wildcard;
|
|
||||||
int caseSensitive;
|
|
||||||
PHYSFS_EnumFilesCallback callback;
|
|
||||||
void *origData;
|
|
||||||
} WildcardCallbackData;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This callback sits between the enumerator and the enduser callback,
|
|
||||||
* filtering out files that don't match the wildcard pattern.
|
|
||||||
*/
|
|
||||||
static void wildcardCallback(void *_d, const char *origdir, const char *fname)
|
|
||||||
{
|
|
||||||
const WildcardCallbackData *data = (const WildcardCallbackData *) _d;
|
|
||||||
if (matchesPattern(fname, data->wildcard, data->caseSensitive))
|
|
||||||
data->callback(data->origData, origdir, fname);
|
|
||||||
} /* wildcardCallback */
|
|
||||||
|
|
||||||
|
|
||||||
void PHYSFSEXT_enumerateFilesCallbackWildcard(const char *dir,
|
|
||||||
const char *wildcard,
|
|
||||||
int caseSensitive,
|
|
||||||
PHYSFS_EnumFilesCallback c,
|
|
||||||
void *d)
|
|
||||||
{
|
|
||||||
WildcardCallbackData data;
|
|
||||||
data.allocator = PHYSFS_getAllocator();
|
|
||||||
data.wildcard = wildcard;
|
|
||||||
data.caseSensitive = caseSensitive;
|
|
||||||
data.callback = c;
|
|
||||||
data.origData = d;
|
|
||||||
PHYSFS_enumerateFilesCallback(dir, wildcardCallback, &data);
|
|
||||||
} /* PHYSFSEXT_enumerateFilesCallbackWildcard */
|
|
||||||
|
|
||||||
|
|
||||||
void PHYSFSEXT_freeEnumeration(char **list)
|
|
||||||
{
|
|
||||||
const PHYSFS_Allocator *allocator = PHYSFS_getAllocator();
|
|
||||||
int i;
|
|
||||||
if (list != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; list[i] != NULL; i++)
|
|
||||||
allocator->Free(list[i]);
|
|
||||||
allocator->Free(list);
|
|
||||||
} /* if */
|
|
||||||
} /* PHYSFSEXT_freeEnumeration */
|
|
||||||
|
|
||||||
|
|
||||||
char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, const char *wildcard,
|
char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, const char *wildcard,
|
||||||
int caseSensitive)
|
int caseSensitive)
|
||||||
{
|
{
|
||||||
const PHYSFS_Allocator *allocator = PHYSFS_getAllocator();
|
char **rc = PHYSFS_enumerateFiles(dir);
|
||||||
char **list = PHYSFS_enumerateFiles(dir);
|
char **i = rc;
|
||||||
char **retval = NULL;
|
char **j;
|
||||||
int totalmatches = 0;
|
|
||||||
int matches = 0;
|
|
||||||
char **i;
|
|
||||||
|
|
||||||
for (i = list; *i != NULL; i++)
|
while (*i != NULL)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
printf("matchesPattern: '%s' vs '%s' (%s) ... %s\n", *i, wildcard,
|
|
||||||
caseSensitive ? "case" : "nocase",
|
|
||||||
matchesPattern(*i, wildcard, caseSensitive) ? "true" : "false");
|
|
||||||
#endif
|
|
||||||
if (matchesPattern(*i, wildcard, caseSensitive))
|
if (matchesPattern(*i, wildcard, caseSensitive))
|
||||||
totalmatches++;
|
i++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: This counts on physfs's allocation method not changing! */
|
||||||
|
free(*i);
|
||||||
|
for (j = i; *j != NULL; j++)
|
||||||
|
j[0] = j[1];
|
||||||
|
} /* else */
|
||||||
} /* for */
|
} /* for */
|
||||||
|
|
||||||
retval = (char **) allocator->Malloc(sizeof (char *) * (totalmatches+1));
|
return(rc);
|
||||||
if (retval != NULL)
|
|
||||||
{
|
|
||||||
for (i = list; ((matches < totalmatches) && (*i != NULL)); i++)
|
|
||||||
{
|
|
||||||
if (matchesPattern(*i, wildcard, caseSensitive))
|
|
||||||
{
|
|
||||||
retval[matches] = (char *) allocator->Malloc(strlen(*i) + 1);
|
|
||||||
if (retval[matches] == NULL)
|
|
||||||
{
|
|
||||||
while (matches--)
|
|
||||||
allocator->Free(retval[matches]);
|
|
||||||
allocator->Free(retval);
|
|
||||||
retval = NULL;
|
|
||||||
break;
|
|
||||||
} /* if */
|
|
||||||
strcpy(retval[matches], *i);
|
|
||||||
matches++;
|
|
||||||
} /* if */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
if (retval != NULL)
|
|
||||||
{
|
|
||||||
assert(totalmatches == matches);
|
|
||||||
retval[matches] = NULL;
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
PHYSFS_freeList(list);
|
|
||||||
return retval;
|
|
||||||
} /* PHYSFSEXT_enumerateFilesWildcard */
|
} /* PHYSFSEXT_enumerateFilesWildcard */
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,20 +123,20 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("USAGE: %s <pattern> <caseSen>\n"
|
printf("USAGE: %s <pattern> <caseSen>\n"
|
||||||
" where <caseSen> is 1 or 0.\n", argv[0]);
|
" where <caseSen> is 1 or 0.\n", argv[0]);
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_init(argv[0]))
|
if (!PHYSFS_init(argv[0]))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_addToSearchPath(".", 1))
|
if (!PHYSFS_addToSearchPath(".", 1))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
flist = PHYSFSEXT_enumerateFilesWildcard("/", argv[1], atoi(argv[2]));
|
flist = PHYSFSEXT_enumerateFilesWildcard("/", argv[1], atoi(argv[2]));
|
||||||
|
@ -228,10 +148,10 @@ int main(int argc, char **argv)
|
||||||
} /* for */
|
} /* for */
|
||||||
printf("\n total %d files.\n\n", rc);
|
printf("\n total %d files.\n\n", rc);
|
||||||
|
|
||||||
PHYSFSEXT_freeEnumeration(flist);
|
PHYSFS_freeList(flist);
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
|
|
||||||
return 0;
|
return(0);
|
||||||
} /* main */
|
} /* main */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
/** \file globbing.h */
|
/** \file globbing.h */
|
||||||
|
|
||||||
#include "physfs.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \mainpage PhysicsFS globbing
|
* \mainpage PhysicsFS globbing
|
||||||
*
|
*
|
||||||
|
@ -14,10 +12,10 @@
|
||||||
* locating matching entries.
|
* locating matching entries.
|
||||||
*
|
*
|
||||||
* Usage: Set up PhysicsFS as you normally would, then use
|
* Usage: Set up PhysicsFS as you normally would, then use
|
||||||
* PHYSFSEXT_enumerateFilesWildcard() when enumerating files. This is just
|
* PHYSFSEXT_enumerateFilesPattern() when enumerating files. This is just
|
||||||
* like PHYSFS_enumerateFiles(), but it returns a subset that matches your
|
* like PHYSFS_enumerateFiles(), but it returns a subset that matches your
|
||||||
* wildcard pattern. You must call PHYSFSEXT_freeEnumeration() on the results,
|
* wildcard pattern. You must call PHYSFS_freeList() on the results, just
|
||||||
* just PHYSFS_enumerateFiles() would do with PHYSFS_freeList().
|
* like you would with PHYSFS_enumerateFiles().
|
||||||
*
|
*
|
||||||
* License: this code is public domain. I make no warranty that it is useful,
|
* License: this code is public domain. I make no warranty that it is useful,
|
||||||
* correct, harmless, or environmentally safe.
|
* correct, harmless, or environmentally safe.
|
||||||
|
@ -30,7 +28,7 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see LICENSE.txt in the source's "docs" directory.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* \author Ryan C. Gordon.
|
* \author Ryan C. Gordon.
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +39,7 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn char **PHYSFS_enumerateFilesWildcard(const char *dir, const char *wildcard, int caseSensitive)
|
* \fn char **PHYSFS_enumerateFilesWildcard(const char *dir, const char *wildcard, int caseSensitive)
|
||||||
* \brief Get a file listing of a search path's directory, filtered with a wildcard pattern.
|
* \brief Get a file listing of a search path's directory.
|
||||||
*
|
*
|
||||||
* Matching directories are interpolated. That is, if "C:\mydir" is in the
|
* Matching directories are interpolated. That is, if "C:\mydir" is in the
|
||||||
* search path and contains a directory "savegames" that contains "x.sav",
|
* search path and contains a directory "savegames" that contains "x.sav",
|
||||||
|
@ -71,90 +69,16 @@ extern "C" {
|
||||||
* Wildcard strings can use the '*' and '?' characters, currently.
|
* Wildcard strings can use the '*' and '?' characters, currently.
|
||||||
* Matches can be case-insensitive if you pass a zero for argument 3.
|
* Matches can be case-insensitive if you pass a zero for argument 3.
|
||||||
*
|
*
|
||||||
* Don't forget to call PHYSFSEXT_freeEnumerator() with the return value from
|
* Don't forget to call PHYSFS_freeList() with the return value from this
|
||||||
* this function when you are done with it. As we use PhysicsFS's allocator
|
* function when you are done with it.
|
||||||
* for this list, you must free it before calling PHYSFS_deinit().
|
|
||||||
* Do not use PHYSFS_freeList() on the returned value!
|
|
||||||
*
|
*
|
||||||
* \param dir directory in platform-independent notation to enumerate.
|
* \param dir directory in platform-independent notation to enumerate.
|
||||||
* \param wildcard Wildcard pattern to use for filtering.
|
|
||||||
* \param caseSensitive Zero for case-insensitive matching,
|
|
||||||
* non-zero for case-sensitive.
|
|
||||||
* \return Null-terminated array of null-terminated strings.
|
* \return Null-terminated array of null-terminated strings.
|
||||||
*
|
|
||||||
* \sa PHYSFSEXT_freeEnumeration
|
|
||||||
*/
|
*/
|
||||||
PHYSFS_DECL char **PHYSFSEXT_enumerateFilesWildcard(const char *dir,
|
__EXPORT__ char **PHYSFSEXT_enumerateFilesWildcard(const char *dir,
|
||||||
const char *wildcard,
|
const char *wildcard,
|
||||||
int caseSensitive);
|
int caseSensitive);
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn void PHYSFSEXT_freeEnumeration(char **list)
|
|
||||||
* \brief Free data returned by PHYSFSEXT_enumerateFilesWildcard
|
|
||||||
*
|
|
||||||
* Conceptually, this works like PHYSFS_freeList(), but is used with data
|
|
||||||
* returned by PHYSFSEXT_enumerateFilesWildcard() only. Be sure to call this
|
|
||||||
* on any returned data from that function before
|
|
||||||
*
|
|
||||||
* \param list Pointer previously returned by
|
|
||||||
* PHYSFSEXT_enumerateFilesWildcard(). It is safe to pass a
|
|
||||||
* NULL here.
|
|
||||||
*
|
|
||||||
* \sa PHYSFSEXT_enumerateFilesWildcard
|
|
||||||
*/
|
|
||||||
PHYSFS_DECL void PHYSFSEXT_freeEnumeration(char **list);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \fn void PHYSFSEXT_enumerateFilesCallbackWildcard(const char *dir, const char *wildcard, int caseSensitive, PHYSFS_EnumFilesCallback c, void *d);
|
|
||||||
* \brief Get a file listing of a search path's directory, filtered with a wildcard pattern, using an application-defined callback.
|
|
||||||
*
|
|
||||||
* This function is equivalent to PHYSFSEXT_enumerateFilesWildcard(). It
|
|
||||||
* reports file listings, filtered by a wildcard pattern.
|
|
||||||
*
|
|
||||||
* Unlike PHYSFS_enumerateFiles(), this function does not return an array.
|
|
||||||
* Rather, it calls a function specified by the application once per
|
|
||||||
* element of the search path:
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
*
|
|
||||||
* static void printDir(void *data, const char *origdir, const char *fname)
|
|
||||||
* {
|
|
||||||
* printf(" * We've got [%s] in [%s].\n", fname, origdir);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // ...
|
|
||||||
* PHYSFS_enumerateFilesCallbackWildcard("savegames","*.sav",0,printDir,NULL);
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* Items sent to the callback are not guaranteed to be in any order whatsoever.
|
|
||||||
* There is no sorting done at this level, and if you need that, you should
|
|
||||||
* probably use PHYSFS_enumerateFilesWildcard() instead, which guarantees
|
|
||||||
* alphabetical sorting. This form reports whatever is discovered in each
|
|
||||||
* archive before moving on to the next. Even within one archive, we can't
|
|
||||||
* guarantee what order it will discover data. <em>Any sorting you find in
|
|
||||||
* these callbacks is just pure luck. Do not rely on it.</em> As this walks
|
|
||||||
* the entire list of archives, you may receive duplicate filenames.
|
|
||||||
*
|
|
||||||
* Wildcard strings can use the '*' and '?' characters, currently.
|
|
||||||
* Matches can be case-insensitive if you pass a zero for argument 3.
|
|
||||||
*
|
|
||||||
* \param dir Directory, in platform-independent notation, to enumerate.
|
|
||||||
* \param wildcard Wildcard pattern to use for filtering.
|
|
||||||
* \param caseSensitive Zero for case-insensitive matching,
|
|
||||||
* non-zero for case-sensitive.
|
|
||||||
* \param c Callback function to notify about search path elements.
|
|
||||||
* \param d Application-defined data passed to callback. Can be NULL.
|
|
||||||
*
|
|
||||||
* \sa PHYSFS_EnumFilesCallback
|
|
||||||
* \sa PHYSFS_enumerateFiles
|
|
||||||
*/
|
|
||||||
PHYSFS_DECL void PHYSFSEXT_enumerateFilesCallbackWildcard(const char *dir,
|
|
||||||
const char *wildcard,
|
|
||||||
int caseSensitive,
|
|
||||||
PHYSFS_EnumFilesCallback c,
|
|
||||||
void *d);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,11 +22,29 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see LICENSE.txt in the root of the source tree.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* \author Ryan C. Gordon.
|
* \author Ryan C. Gordon.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* I'm not screwing around with stricmp vs. strcasecmp... */
|
||||||
|
static int caseInsensitiveStringCompare(const char *x, const char *y)
|
||||||
|
{
|
||||||
|
int ux, uy;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ux = toupper((int) *x);
|
||||||
|
uy = toupper((int) *y);
|
||||||
|
if (ux != uy)
|
||||||
|
return((ux > uy) ? 1 : -1);
|
||||||
|
x++;
|
||||||
|
y++;
|
||||||
|
} while ((ux) && (uy));
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
} /* caseInsensitiveStringCompare */
|
||||||
|
|
||||||
|
|
||||||
static int locateOneElement(char *buf)
|
static int locateOneElement(char *buf)
|
||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
@ -34,7 +52,7 @@ static int locateOneElement(char *buf)
|
||||||
char **i;
|
char **i;
|
||||||
|
|
||||||
if (PHYSFS_exists(buf))
|
if (PHYSFS_exists(buf))
|
||||||
return 1; /* quick rejection: exists in current case. */
|
return(1); /* quick rejection: exists in current case. */
|
||||||
|
|
||||||
ptr = strrchr(buf, '/'); /* find entry at end of path. */
|
ptr = strrchr(buf, '/'); /* find entry at end of path. */
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
|
@ -50,23 +68,19 @@ static int locateOneElement(char *buf)
|
||||||
ptr++; /* point past dirsep to entry itself. */
|
ptr++; /* point past dirsep to entry itself. */
|
||||||
} /* else */
|
} /* else */
|
||||||
|
|
||||||
if (rc != NULL)
|
for (i = rc; *i != NULL; i++)
|
||||||
{
|
{
|
||||||
for (i = rc; *i != NULL; i++)
|
if (caseInsensitiveStringCompare(*i, ptr) == 0)
|
||||||
{
|
{
|
||||||
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
|
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
||||||
{
|
PHYSFS_freeList(rc);
|
||||||
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
return(1);
|
||||||
PHYSFS_freeList(rc);
|
} /* if */
|
||||||
return 1;
|
} /* for */
|
||||||
} /* if */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
PHYSFS_freeList(rc);
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
/* no match at all... */
|
/* no match at all... */
|
||||||
return 0;
|
PHYSFS_freeList(rc);
|
||||||
|
return(0);
|
||||||
} /* locateOneElement */
|
} /* locateOneElement */
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,25 +88,26 @@ int PHYSFSEXT_locateCorrectCase(char *buf)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
char *prevptr;
|
||||||
|
|
||||||
while (*buf == '/') /* skip any '/' at start of string... */
|
while (*buf == '/') /* skip any '/' at start of string... */
|
||||||
buf++;
|
buf++;
|
||||||
|
|
||||||
ptr = buf;
|
ptr = prevptr = buf;
|
||||||
if (*ptr == '\0')
|
if (*ptr == '\0')
|
||||||
return 0; /* Uh...I guess that's success. */
|
return(0); /* Uh...I guess that's success. */
|
||||||
|
|
||||||
while ( (ptr = strchr(ptr + 1, '/')) != NULL )
|
while (ptr = strchr(ptr + 1, '/'))
|
||||||
{
|
{
|
||||||
*ptr = '\0'; /* block this path section off */
|
*ptr = '\0'; /* block this path section off */
|
||||||
rc = locateOneElement(buf);
|
rc = locateOneElement(buf);
|
||||||
*ptr = '/'; /* restore path separator */
|
*ptr = '/'; /* restore path separator */
|
||||||
if (!rc)
|
if (!rc)
|
||||||
return -2; /* missing element in path. */
|
return(-2); /* missing element in path. */
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
/* check final element... */
|
/* check final element... */
|
||||||
return locateOneElement(buf) ? 0 : -1;
|
return(locateOneElement(buf) ? 0 : -1);
|
||||||
} /* PHYSFSEXT_locateCorrectCase */
|
} /* PHYSFSEXT_locateCorrectCase */
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,58 +116,58 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
PHYSFS_File *f;
|
PHYSFS_file *f;
|
||||||
|
|
||||||
if (!PHYSFS_init(argv[0]))
|
if (!PHYSFS_init(argv[0]))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_addToSearchPath(".", 1))
|
if (!PHYSFS_addToSearchPath(".", 1))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_setWriteDir("."))
|
if (!PHYSFS_setWriteDir("."))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_mkdir("/a/b/c"))
|
if (!PHYSFS_mkdir("/a/b/c"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_mkdir("/a/b/C"))
|
if (!PHYSFS_mkdir("/a/b/C"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
f = PHYSFS_openWrite("/a/b/c/x.txt");
|
f = PHYSFS_openWrite("/a/b/c/x.txt");
|
||||||
PHYSFS_close(f);
|
PHYSFS_close(f);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
f = PHYSFS_openWrite("/a/b/C/X.txt");
|
f = PHYSFS_openWrite("/a/b/C/X.txt");
|
||||||
PHYSFS_close(f);
|
PHYSFS_close(f);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 1;
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
strcpy(buf, "/a/b/c/x.txt");
|
strcpy(buf, "/a/b/c/x.txt");
|
||||||
|
@ -195,7 +210,7 @@ int main(int argc, char **argv)
|
||||||
PHYSFS_delete("/a/b");
|
PHYSFS_delete("/a/b");
|
||||||
PHYSFS_delete("/a");
|
PHYSFS_delete("/a");
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
return 0;
|
return(0);
|
||||||
} /* main */
|
} /* main */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
* or file (which brings security considerations and potential bugs). This
|
* or file (which brings security considerations and potential bugs). This
|
||||||
* code favours exact case matches, but you will lose access to otherwise
|
* code favours exact case matches, but you will lose access to otherwise
|
||||||
* duplicate filenames, or you might go down a wrong directory tree, etc.
|
* duplicate filenames, or you might go down a wrong directory tree, etc.
|
||||||
* In practice, this is rarely a problem, but you need to be aware of it.
|
* In practive, this is rarely a problem, but you need to be aware of it.
|
||||||
* - This doesn't do _anything_ with the write directory; you're on your
|
* - This doesn't do _anything_ with the write directory; you're on your
|
||||||
* own for opening the right files for writing. You can sort of get around
|
* own for opening the right files for writing. You can sort of get around
|
||||||
* this by adding your write directory to the search path, but then the
|
* this by adding your write directory to the search path, but then the
|
||||||
* interpolated directory tree can screw you up even more.
|
* interpolated directory tree can screw you up even more.
|
||||||
*
|
*
|
||||||
* This code should be considered an aid for legacy code. New development
|
* This code should be considered an aid for legacy code. New development
|
||||||
* shouldn't do things that require this aid in the first place. :)
|
* shouldn't do dumbass things that require this aid in the first place. :)
|
||||||
*
|
*
|
||||||
* Usage: Set up PhysicsFS as you normally would, then use
|
* Usage: Set up PhysicsFS as you normally would, then use
|
||||||
* PHYSFSEXT_locateCorrectCase() to get a "correct" pathname to pass to
|
* PHYSFSEXT_locateCorrectCase() to get a "correct" pathname to pass to
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see LICENSE.txt in the root of the source tree.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* \author Ryan C. Gordon.
|
* \author Ryan C. Gordon.
|
||||||
*/
|
*/
|
||||||
|
@ -67,7 +67,8 @@ extern "C" {
|
||||||
* existing match. If there is no match, the search aborts and reports an
|
* existing match. If there is no match, the search aborts and reports an
|
||||||
* error. Exact matches are favored over case-insensitive matches.
|
* error. Exact matches are favored over case-insensitive matches.
|
||||||
*
|
*
|
||||||
* THIS IS RISKY. Please do not use this function for anything but legacy code.
|
* THIS IS RISKY. Please do not use this function for anything but crappy
|
||||||
|
* legacy code.
|
||||||
*
|
*
|
||||||
* \param buf Buffer with null-terminated string of path/file to locate.
|
* \param buf Buffer with null-terminated string of path/file to locate.
|
||||||
* This buffer will be modified by this function.
|
* This buffer will be modified by this function.
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
use warnings;
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
my $HASHBUCKETS1_16 = 256;
|
|
||||||
my $HASHBUCKETS1_32 = 16;
|
|
||||||
my $HASHBUCKETS2_16 = 16;
|
|
||||||
my $HASHBUCKETS3_16 = 4;
|
|
||||||
|
|
||||||
print <<__EOF__;
|
|
||||||
/*
|
|
||||||
* This file is part of PhysicsFS (https://icculus.org/physfs/)
|
|
||||||
*
|
|
||||||
* This data generated by physfs/extras/makecasefoldhashtable.pl ...
|
|
||||||
* Do not manually edit this file!
|
|
||||||
*
|
|
||||||
* Please see the file LICENSE.txt in the source's root directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _INCLUDE_PHYSFS_CASEFOLDING_H_
|
|
||||||
#define _INCLUDE_PHYSFS_CASEFOLDING_H_
|
|
||||||
|
|
||||||
#ifndef __PHYSICSFS_INTERNAL__
|
|
||||||
#error Do not include this header from your applications.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We build three simple hashmaps here: one that maps Unicode codepoints to
|
|
||||||
a one, two, or three lowercase codepoints. To retrieve this info: look at
|
|
||||||
case_fold_hashX, where X is 1, 2, or 3. Most foldable codepoints fold to one,
|
|
||||||
a few dozen fold to two, and a handful fold to three. If the codepoint isn't
|
|
||||||
in any of these hashes, it doesn't fold (no separate upper and lowercase).
|
|
||||||
|
|
||||||
Almost all these codepoints fit into 16 bits, so we hash them as such to save
|
|
||||||
memory. If a codepoint is > 0xFFFF, we have separate hashes for them,
|
|
||||||
since there are (currently) only about 120 of them and (currently) all of them
|
|
||||||
map to a single lowercase codepoint. */
|
|
||||||
|
|
||||||
typedef struct CaseFoldMapping1_32
|
|
||||||
{
|
|
||||||
PHYSFS_uint32 from;
|
|
||||||
PHYSFS_uint32 to0;
|
|
||||||
} CaseFoldMapping1_32;
|
|
||||||
|
|
||||||
typedef struct CaseFoldMapping1_16
|
|
||||||
{
|
|
||||||
PHYSFS_uint16 from;
|
|
||||||
PHYSFS_uint16 to0;
|
|
||||||
} CaseFoldMapping1_16;
|
|
||||||
|
|
||||||
typedef struct CaseFoldMapping2_16
|
|
||||||
{
|
|
||||||
PHYSFS_uint16 from;
|
|
||||||
PHYSFS_uint16 to0;
|
|
||||||
PHYSFS_uint16 to1;
|
|
||||||
} CaseFoldMapping2_16;
|
|
||||||
|
|
||||||
typedef struct CaseFoldMapping3_16
|
|
||||||
{
|
|
||||||
PHYSFS_uint16 from;
|
|
||||||
PHYSFS_uint16 to0;
|
|
||||||
PHYSFS_uint16 to1;
|
|
||||||
PHYSFS_uint16 to2;
|
|
||||||
} CaseFoldMapping3_16;
|
|
||||||
|
|
||||||
typedef struct CaseFoldHashBucket1_16
|
|
||||||
{
|
|
||||||
const CaseFoldMapping1_16 *list;
|
|
||||||
const PHYSFS_uint8 count;
|
|
||||||
} CaseFoldHashBucket1_16;
|
|
||||||
|
|
||||||
typedef struct CaseFoldHashBucket1_32
|
|
||||||
{
|
|
||||||
const CaseFoldMapping1_32 *list;
|
|
||||||
const PHYSFS_uint8 count;
|
|
||||||
} CaseFoldHashBucket1_32;
|
|
||||||
|
|
||||||
typedef struct CaseFoldHashBucket2_16
|
|
||||||
{
|
|
||||||
const CaseFoldMapping2_16 *list;
|
|
||||||
const PHYSFS_uint8 count;
|
|
||||||
} CaseFoldHashBucket2_16;
|
|
||||||
|
|
||||||
typedef struct CaseFoldHashBucket3_16
|
|
||||||
{
|
|
||||||
const CaseFoldMapping3_16 *list;
|
|
||||||
const PHYSFS_uint8 count;
|
|
||||||
} CaseFoldHashBucket3_16;
|
|
||||||
|
|
||||||
__EOF__
|
|
||||||
|
|
||||||
|
|
||||||
my @foldPairs1_16;
|
|
||||||
my @foldPairs2_16;
|
|
||||||
my @foldPairs3_16;
|
|
||||||
my @foldPairs1_32;
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) {
|
|
||||||
$foldPairs1_16[$i] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) {
|
|
||||||
$foldPairs1_32[$i] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) {
|
|
||||||
$foldPairs2_16[$i] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) {
|
|
||||||
$foldPairs3_16[$i] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
open(FH,'<','casefolding.txt') or die("failed to open casefolding.txt: $!\n");
|
|
||||||
while (<FH>) {
|
|
||||||
chomp;
|
|
||||||
# strip comments from textfile...
|
|
||||||
s/\#.*\Z//;
|
|
||||||
|
|
||||||
# strip whitespace...
|
|
||||||
s/\A\s+//;
|
|
||||||
s/\s+\Z//;
|
|
||||||
|
|
||||||
next if not /\A([a-fA-F0-9]+)\;\s*(.)\;\s*(.+)\;/;
|
|
||||||
my ($code, $status, $mapping) = ($1, $2, $3);
|
|
||||||
|
|
||||||
my $hexxed = hex($code);
|
|
||||||
#print("// code '$code' status '$status' mapping '$mapping'\n");
|
|
||||||
|
|
||||||
if (($status eq 'C') or ($status eq 'F')) {
|
|
||||||
my ($map1, $map2, $map3) = (undef, undef, undef);
|
|
||||||
$map1 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
|
|
||||||
$map2 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
|
|
||||||
$map3 = $1 if $mapping =~ s/\A([a-fA-F0-9]+)(\s*|\Z)//;
|
|
||||||
die("mapping space too small for '$code'\n") if ($mapping ne '');
|
|
||||||
die("problem parsing mapping for '$code'\n") if (not defined($map1));
|
|
||||||
|
|
||||||
if ($hexxed < 128) {
|
|
||||||
# Just ignore these, we'll handle the low-ASCII ones ourselves.
|
|
||||||
} elsif ($hexxed > 0xFFFF) {
|
|
||||||
# We just need to add the 32-bit 2 and/or 3 codepoint maps if this die()'s here.
|
|
||||||
die("Uhoh, a codepoint > 0xFFFF that folds to multiple codepoints! Fixme.") if defined($map2);
|
|
||||||
my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS1_32-1));
|
|
||||||
#print("// hexxed '$hexxed' hashed1 '$hashed'\n");
|
|
||||||
$foldPairs1_32[$hashed] .= " { 0x$code, 0x$map1 },\n";
|
|
||||||
} elsif (not defined($map2)) {
|
|
||||||
my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS1_16-1));
|
|
||||||
#print("// hexxed '$hexxed' hashed1 '$hashed'\n");
|
|
||||||
$foldPairs1_16[$hashed] .= " { 0x$code, 0x$map1 },\n";
|
|
||||||
} elsif (not defined($map3)) {
|
|
||||||
my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS2_16-1));
|
|
||||||
#print("// hexxed '$hexxed' hashed2 '$hashed'\n");
|
|
||||||
$foldPairs2_16[$hashed] .= " { 0x$code, 0x$map1, 0x$map2 },\n";
|
|
||||||
} else {
|
|
||||||
my $hashed = (($hexxed ^ ($hexxed >> 8)) & ($HASHBUCKETS3_16-1));
|
|
||||||
#print("// hexxed '$hexxed' hashed3 '$hashed'\n");
|
|
||||||
$foldPairs3_16[$hashed] .= " { 0x$code, 0x$map1, 0x$map2, 0x$map3 },\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(FH);
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) {
|
|
||||||
$foldPairs1_16[$i] =~ s/,\n\Z//;
|
|
||||||
my $str = $foldPairs1_16[$i];
|
|
||||||
next if $str eq '';
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold1_16_${num}";
|
|
||||||
print("static const CaseFoldMapping1_16 ${sym}[] = {\n$str\n};\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) {
|
|
||||||
$foldPairs1_32[$i] =~ s/,\n\Z//;
|
|
||||||
my $str = $foldPairs1_32[$i];
|
|
||||||
next if $str eq '';
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold1_32_${num}";
|
|
||||||
print("static const CaseFoldMapping1_32 ${sym}[] = {\n$str\n};\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) {
|
|
||||||
$foldPairs2_16[$i] =~ s/,\n\Z//;
|
|
||||||
my $str = $foldPairs2_16[$i];
|
|
||||||
next if $str eq '';
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold2_16_${num}";
|
|
||||||
print("static const CaseFoldMapping2_16 ${sym}[] = {\n$str\n};\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) {
|
|
||||||
$foldPairs3_16[$i] =~ s/,\n\Z//;
|
|
||||||
my $str = $foldPairs3_16[$i];
|
|
||||||
next if $str eq '';
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold3_16_${num}";
|
|
||||||
print("static const CaseFoldMapping3_16 ${sym}[] = {\n$str\n};\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
print("static const CaseFoldHashBucket1_16 case_fold_hash1_16[] = {\n");
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS1_16; $i++) {
|
|
||||||
my $str = $foldPairs1_16[$i];
|
|
||||||
if ($str eq '') {
|
|
||||||
print(" { NULL, 0 },\n");
|
|
||||||
} else {
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold1_16_${num}";
|
|
||||||
print(" { $sym, __PHYSFS_ARRAYLEN($sym) },\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print("};\n\n");
|
|
||||||
|
|
||||||
|
|
||||||
print("static const CaseFoldHashBucket1_32 case_fold_hash1_32[] = {\n");
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS1_32; $i++) {
|
|
||||||
my $str = $foldPairs1_32[$i];
|
|
||||||
if ($str eq '') {
|
|
||||||
print(" { NULL, 0 },\n");
|
|
||||||
} else {
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold1_32_${num}";
|
|
||||||
print(" { $sym, __PHYSFS_ARRAYLEN($sym) },\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print("};\n\n");
|
|
||||||
|
|
||||||
|
|
||||||
print("static const CaseFoldHashBucket2_16 case_fold_hash2_16[] = {\n");
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS2_16; $i++) {
|
|
||||||
my $str = $foldPairs2_16[$i];
|
|
||||||
if ($str eq '') {
|
|
||||||
print(" { NULL, 0 },\n");
|
|
||||||
} else {
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold2_16_${num}";
|
|
||||||
print(" { $sym, __PHYSFS_ARRAYLEN($sym) },\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print("};\n\n");
|
|
||||||
|
|
||||||
print("static const CaseFoldHashBucket3_16 case_fold_hash3_16[] = {\n");
|
|
||||||
|
|
||||||
for (my $i = 0; $i < $HASHBUCKETS3_16; $i++) {
|
|
||||||
my $str = $foldPairs3_16[$i];
|
|
||||||
if ($str eq '') {
|
|
||||||
print(" { NULL, 0 },\n");
|
|
||||||
} else {
|
|
||||||
my $num = '000' . $i;
|
|
||||||
$num =~ s/\A.*?(\d\d\d)\Z/$1/;
|
|
||||||
my $sym = "case_fold3_16_${num}";
|
|
||||||
print(" { $sym, __PHYSFS_ARRAYLEN($sym) },\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print("};\n\n");
|
|
||||||
|
|
||||||
print <<__EOF__;
|
|
||||||
|
|
||||||
#endif /* _INCLUDE_PHYSFS_CASEFOLDING_H_ */
|
|
||||||
|
|
||||||
/* end of physfs_casefolding.h ... */
|
|
||||||
|
|
||||||
__EOF__
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
|
|
||||||
# end of makecashfoldhashtable.pl ...
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
|
||||||
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.
|
|
||||||
URL: https://icculus.org/physfs/
|
|
||||||
Version: @PHYSFS_VERSION@
|
|
||||||
Libs: -L${libdir} -lphysfs
|
|
||||||
Cflags: -I${includedir}
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
# $Id: installer.rb,v 1.3 2003/07/21 03:46:50 icculus Exp $
|
||||||
|
|
||||||
|
require 'rbconfig'
|
||||||
|
require 'find'
|
||||||
|
require 'ftools'
|
||||||
|
|
||||||
|
include Config
|
||||||
|
|
||||||
|
module Slimb
|
||||||
|
class Installer
|
||||||
|
def initialize target_dir = "", &user_skip
|
||||||
|
@user_skip = user_skip or proc {|f| false}
|
||||||
|
|
||||||
|
@version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
|
||||||
|
@libdir = File.join(CONFIG["libdir"], "ruby", @version)
|
||||||
|
@sitedir = CONFIG["sitedir"] || File.join(@libdir, "site_ruby")
|
||||||
|
@dest = File.join @sitedir, target_dir
|
||||||
|
|
||||||
|
File::makedirs @dest
|
||||||
|
File::chmod 0755, @dest, true
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip? file
|
||||||
|
@user_skip[file] or
|
||||||
|
file[0] == ?. or file[-1] == ?~ or file[-1] == ?#
|
||||||
|
end
|
||||||
|
|
||||||
|
def install_dir dir
|
||||||
|
File::makedirs(File.join(@dest, dir))
|
||||||
|
File::chmod(0755, File.join(@dest, dir), true)
|
||||||
|
Dir.foreach(dir) {|file|
|
||||||
|
next if skip? file
|
||||||
|
|
||||||
|
if File.ftype(File.join(dir, file)) == "directory"
|
||||||
|
install_dir File.join(dir, file)
|
||||||
|
else
|
||||||
|
install_file File.join(dir, file)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def install_file file
|
||||||
|
if file =~ /\.so$/
|
||||||
|
install_so file
|
||||||
|
else
|
||||||
|
File::install file, File.join(@dest, file), 0644, true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def install_so file
|
||||||
|
File::install file, File.join(CONFIG["sitearchdir"], file), 0644, true
|
||||||
|
end
|
||||||
|
|
||||||
|
def uninstall_so file
|
||||||
|
file = File.join(CONFIG["sitearchdir"], file)
|
||||||
|
File::safe_unlink file
|
||||||
|
end
|
||||||
|
|
||||||
|
def install something
|
||||||
|
case something
|
||||||
|
when Array
|
||||||
|
something.each {|x|
|
||||||
|
install x if x.is_a? String
|
||||||
|
}
|
||||||
|
when String
|
||||||
|
if File.ftype(something) == "directory"
|
||||||
|
install_dir something
|
||||||
|
else
|
||||||
|
install_file something
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def uninstall what = "*"
|
||||||
|
case what
|
||||||
|
when Array
|
||||||
|
files = what.map {|x| File.join(@dest, x)}
|
||||||
|
when String
|
||||||
|
files = Dir[File.join(@dest, what)]
|
||||||
|
end
|
||||||
|
|
||||||
|
files.each {|x|
|
||||||
|
# FIXME: recursive uninstall is a must
|
||||||
|
next if FileTest.directory? x
|
||||||
|
File::safe_unlink x
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def run files, argv
|
||||||
|
if !argv.grep(/--uninstall/).empty?
|
||||||
|
uninstall files
|
||||||
|
else
|
||||||
|
install files
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# self-installation
|
||||||
|
if $0 == __FILE__
|
||||||
|
$stderr.puts "Installing slimb installer..."
|
||||||
|
Slimb::Installer.new("slimb").install File.basename(__FILE__)
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
require 'mkmf'
|
||||||
|
|
||||||
|
$CFLAGS += `sdl-config --cflags`.chomp
|
||||||
|
$LDFLAGS += `sdl-config --libs`.chomp
|
||||||
|
|
||||||
|
have_library "physfs", "PHYSFS_init"
|
||||||
|
have_library "SDL", "SDL_AllocRW"
|
||||||
|
|
||||||
|
create_makefile "physfs_so"
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/local/bin/ruby
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
require 'slimb/installer'
|
||||||
|
files = ["physfs.rb", "physfs_so.so"]
|
||||||
|
installer = Slimb::Installer.new.run files, ARGV
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
ruby extconf.rb
|
||||||
|
make
|
||||||
|
cd ..
|
||||||
|
ruby installer.rb
|
||||||
|
cd physfs
|
||||||
|
ruby install.rb
|
||||||
|
cd test
|
||||||
|
ruby test_physfs.rb
|
|
@ -0,0 +1,121 @@
|
||||||
|
#
|
||||||
|
# PhysicsFS - ruby interface
|
||||||
|
#
|
||||||
|
# Author: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
# License: LGPL
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'physfs_so'
|
||||||
|
|
||||||
|
module PhysicsFS
|
||||||
|
|
||||||
|
class Version
|
||||||
|
def initialize major, minor, patch
|
||||||
|
@major = major
|
||||||
|
@minor = minor
|
||||||
|
@patch = patch
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :major, :minor, :patch
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#@major.#@minor.#@patch"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ArchiveInfo
|
||||||
|
def initialize ext, desc, author, url
|
||||||
|
@extension = ext
|
||||||
|
@description = desc
|
||||||
|
@author = author
|
||||||
|
@url = url
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :extension, :description
|
||||||
|
attr_reader :author, :url
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
" * #@extension: #@description\n Written by #@author.\n #@url\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# convenience methods
|
||||||
|
#
|
||||||
|
class << self
|
||||||
|
|
||||||
|
def init argv0 = $0
|
||||||
|
init_internal argv0
|
||||||
|
end
|
||||||
|
|
||||||
|
def append_search_path str
|
||||||
|
add_to_search_path str, 1
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepend_search_path str
|
||||||
|
add_to_search_path str, 0
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :<<, :append_search_path
|
||||||
|
alias_method :push, :append_search_path
|
||||||
|
alias_method :unshift, :prepend_search_path
|
||||||
|
|
||||||
|
def ls path = ""
|
||||||
|
enumerate path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# File - PhysicsFS abstract file - can be drawn from various sources
|
||||||
|
#
|
||||||
|
class File
|
||||||
|
def write_str str
|
||||||
|
write str, 1, str.length
|
||||||
|
end
|
||||||
|
|
||||||
|
def cat
|
||||||
|
prev_pos = tell
|
||||||
|
seek 0
|
||||||
|
r = read length, 1
|
||||||
|
seek prev_pos
|
||||||
|
r
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :size, :length
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# RWops - general stdio like operations on file-like creatures
|
||||||
|
#
|
||||||
|
class RWops
|
||||||
|
SEEK_SET = 0
|
||||||
|
SEEK_CUR = 1
|
||||||
|
SEEK_END = 2
|
||||||
|
|
||||||
|
# tell current position of RWopted entity
|
||||||
|
def tell
|
||||||
|
seek 0, SEEK_CUR
|
||||||
|
end
|
||||||
|
|
||||||
|
# length of RWops abstracted entity
|
||||||
|
def length
|
||||||
|
cur = tell
|
||||||
|
r = seek 0, SEEK_END
|
||||||
|
seek cur, SEEK_SET
|
||||||
|
r
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :size, :length
|
||||||
|
|
||||||
|
#
|
||||||
|
# create rwops from PhysicsFS file object
|
||||||
|
#
|
||||||
|
def self.from_physfs file
|
||||||
|
file.to_rwops
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# physfs.rb ends here #
|
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* This code provides a glue layer between PhysicsFS and Simple Directmedia
|
||||||
|
* Layer's (SDL) RWops i/o abstraction.
|
||||||
|
*
|
||||||
|
* License: this code is public domain. I make no warranty that it is useful,
|
||||||
|
* correct, harmless, or environmentally safe.
|
||||||
|
*
|
||||||
|
* This particular file may be used however you like, including copying it
|
||||||
|
* verbatim into a closed-source project, exploiting it commercially, and
|
||||||
|
* removing any trace of my name from the source (although I hope you won't
|
||||||
|
* do that). I welcome enhancements and corrections to this file, but I do
|
||||||
|
* not require you to send me patches if you make changes.
|
||||||
|
*
|
||||||
|
* Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
|
||||||
|
* General Public License: http://www.gnu.org/licenses/lgpl.txt
|
||||||
|
*
|
||||||
|
* SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/
|
||||||
|
*
|
||||||
|
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
|
||||||
|
#include "physfsrwops.h"
|
||||||
|
|
||||||
|
static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
|
||||||
|
{
|
||||||
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
if (whence == SEEK_SET)
|
||||||
|
{
|
||||||
|
pos = offset;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
else if (whence == SEEK_CUR)
|
||||||
|
{
|
||||||
|
PHYSFS_sint64 current = PHYSFS_tell(handle);
|
||||||
|
if (current == -1)
|
||||||
|
{
|
||||||
|
SDL_SetError("Can't find position in file: %s",
|
||||||
|
PHYSFS_getLastError());
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
pos = (int) current;
|
||||||
|
if ( ((PHYSFS_sint64) pos) != current )
|
||||||
|
{
|
||||||
|
SDL_SetError("Can't fit current file position in an int!");
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (offset == 0) /* this is a "tell" call. We're done. */
|
||||||
|
return(pos);
|
||||||
|
|
||||||
|
pos += offset;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if (whence == SEEK_END)
|
||||||
|
{
|
||||||
|
PHYSFS_sint64 len = PHYSFS_fileLength(handle);
|
||||||
|
if (len == -1)
|
||||||
|
{
|
||||||
|
SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
pos = (int) len;
|
||||||
|
if ( ((PHYSFS_sint64) pos) != len )
|
||||||
|
{
|
||||||
|
SDL_SetError("Can't fit end-of-file position in an int!");
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
pos += offset;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_SetError("Invalid 'whence' parameter.");
|
||||||
|
return(-1);
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
if ( pos < 0 )
|
||||||
|
{
|
||||||
|
SDL_SetError("Attempt to seek past start of file.");
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
|
||||||
|
{
|
||||||
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return(pos);
|
||||||
|
} /* physfsrwops_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
|
||||||
|
{
|
||||||
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
|
PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum);
|
||||||
|
if (rc != maxnum)
|
||||||
|
{
|
||||||
|
if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
|
||||||
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return((int) rc);
|
||||||
|
} /* physfsrwops_read */
|
||||||
|
|
||||||
|
|
||||||
|
static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
|
||||||
|
{
|
||||||
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
|
PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num);
|
||||||
|
if (rc != num)
|
||||||
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
|
|
||||||
|
return((int) rc);
|
||||||
|
} /* physfsrwops_write */
|
||||||
|
|
||||||
|
|
||||||
|
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());
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
SDL_FreeRW(rw);
|
||||||
|
return(0);
|
||||||
|
} /* physfsrwops_close */
|
||||||
|
|
||||||
|
|
||||||
|
static SDL_RWops *create_rwops(PHYSFS_file *handle)
|
||||||
|
{
|
||||||
|
SDL_RWops *retval = NULL;
|
||||||
|
|
||||||
|
if (handle == NULL)
|
||||||
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retval = SDL_AllocRW();
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
retval->seek = physfsrwops_seek;
|
||||||
|
retval->read = physfsrwops_read;
|
||||||
|
retval->write = physfsrwops_write;
|
||||||
|
retval->close = physfsrwops_close;
|
||||||
|
retval->hidden.unknown.data1 = handle;
|
||||||
|
} /* if */
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* create_rwops */
|
||||||
|
|
||||||
|
|
||||||
|
SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle)
|
||||||
|
{
|
||||||
|
SDL_RWops *retval = NULL;
|
||||||
|
if (handle == NULL)
|
||||||
|
SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops().");
|
||||||
|
else
|
||||||
|
retval = create_rwops(handle);
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* PHYSFSRWOPS_makeRWops */
|
||||||
|
|
||||||
|
|
||||||
|
SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
|
||||||
|
{
|
||||||
|
return(create_rwops(PHYSFS_openRead(fname)));
|
||||||
|
} /* PHYSFSRWOPS_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
|
||||||
|
{
|
||||||
|
return(create_rwops(PHYSFS_openWrite(fname)));
|
||||||
|
} /* PHYSFSRWOPS_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
|
||||||
|
{
|
||||||
|
return(create_rwops(PHYSFS_openAppend(fname)));
|
||||||
|
} /* PHYSFSRWOPS_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
/* end of physfsrwops.c ... */
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* This code provides a glue layer between PhysicsFS and Simple Directmedia
|
||||||
|
* Layer's (SDL) RWops i/o abstraction.
|
||||||
|
*
|
||||||
|
* License: this code is public domain. I make no warranty that it is useful,
|
||||||
|
* correct, harmless, or environmentally safe.
|
||||||
|
*
|
||||||
|
* This particular file may be used however you like, including copying it
|
||||||
|
* verbatim into a closed-source project, exploiting it commercially, and
|
||||||
|
* removing any trace of my name from the source (although I hope you won't
|
||||||
|
* do that). I welcome enhancements and corrections to this file, but I do
|
||||||
|
* not require you to send me patches if you make changes.
|
||||||
|
*
|
||||||
|
* Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser
|
||||||
|
* General Public License: http://www.gnu.org/licenses/lgpl.txt
|
||||||
|
*
|
||||||
|
* SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/
|
||||||
|
*
|
||||||
|
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_PHYSFSRWOPS_H_
|
||||||
|
#define _INCLUDE_PHYSFSRWOPS_H_
|
||||||
|
|
||||||
|
#include "physfs.h"
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a platform-independent filename for reading, and make it accessible
|
||||||
|
* via an SDL_RWops structure. The file will be closed in PhysicsFS when the
|
||||||
|
* RWops is closed. PhysicsFS should be configured to your liking before
|
||||||
|
* opening files through this method.
|
||||||
|
*
|
||||||
|
* @param filename File to open in platform-independent notation.
|
||||||
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
|
*/
|
||||||
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a platform-independent filename for writing, and make it accessible
|
||||||
|
* via an SDL_RWops structure. The file will be closed in PhysicsFS when the
|
||||||
|
* RWops is closed. PhysicsFS should be configured to your liking before
|
||||||
|
* opening files through this method.
|
||||||
|
*
|
||||||
|
* @param filename File to open in platform-independent notation.
|
||||||
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
|
*/
|
||||||
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a platform-independent filename for appending, and make it accessible
|
||||||
|
* via an SDL_RWops structure. The file will be closed in PhysicsFS when the
|
||||||
|
* RWops is closed. PhysicsFS should be configured to your liking before
|
||||||
|
* opening files through this method.
|
||||||
|
*
|
||||||
|
* @param filename File to open in platform-independent notation.
|
||||||
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
|
*/
|
||||||
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a SDL_RWops from an existing PhysicsFS file handle. You should
|
||||||
|
* dispose of any references to the handle after successful creation of
|
||||||
|
* the RWops. The actual PhysicsFS handle will be destroyed when the
|
||||||
|
* RWops is closed.
|
||||||
|
*
|
||||||
|
* @param handle a valid PhysicsFS file handle.
|
||||||
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
|
*/
|
||||||
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* include-once blocker */
|
||||||
|
|
||||||
|
/* end of physfsrwops.h ... */
|
||||||
|
|
|
@ -0,0 +1,462 @@
|
||||||
|
/*
|
||||||
|
* PhysicsFS - ruby interface
|
||||||
|
*
|
||||||
|
* Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
* License:: LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "physfs.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
|
||||||
|
#include "rb_physfs.h"
|
||||||
|
#include "rb_physfs_file.h"
|
||||||
|
|
||||||
|
VALUE modulePhysfs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::init str
|
||||||
|
*
|
||||||
|
* initialize PhysicsFS
|
||||||
|
*/
|
||||||
|
VALUE physfs_init (VALUE self, VALUE str)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_init (STR2CSTR(str));
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::deinit
|
||||||
|
*/
|
||||||
|
VALUE physfs_deinit (VALUE self)
|
||||||
|
{
|
||||||
|
if (PHYSFS_deinit ())
|
||||||
|
return Qtrue;
|
||||||
|
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::version
|
||||||
|
*
|
||||||
|
* return PhysicsFS::Version object
|
||||||
|
*/
|
||||||
|
VALUE physfs_version (VALUE self)
|
||||||
|
{
|
||||||
|
char evalStr[200];
|
||||||
|
PHYSFS_Version ver;
|
||||||
|
|
||||||
|
PHYSFS_getLinkedVersion (&ver);
|
||||||
|
|
||||||
|
sprintf (evalStr, "PhysicsFS::Version.new %d, %d, %d",
|
||||||
|
ver.major, ver.minor, ver.patch);
|
||||||
|
return rb_eval_string (evalStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::supported_archives
|
||||||
|
*
|
||||||
|
* return Array of PhysicsFS::ArchiveInfo objects
|
||||||
|
*/
|
||||||
|
VALUE physfs_supported_archives (VALUE self)
|
||||||
|
{
|
||||||
|
const PHYSFS_ArchiveInfo **info = PHYSFS_supportedArchiveTypes();
|
||||||
|
VALUE klass = rb_const_get (modulePhysfs, rb_intern ("ArchiveInfo"));
|
||||||
|
VALUE ary = rb_ary_new ();
|
||||||
|
VALUE params[4];
|
||||||
|
|
||||||
|
while ( *info != 0 )
|
||||||
|
{
|
||||||
|
params[0] = rb_str_new2 ((*info)->extension);
|
||||||
|
params[1] = rb_str_new2 ((*info)->description);
|
||||||
|
params[2] = rb_str_new2 ((*info)->author);
|
||||||
|
params[3] = rb_str_new2 ((*info)->url);
|
||||||
|
|
||||||
|
rb_ary_push (ary, rb_class_new_instance (4, params, klass));
|
||||||
|
info++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::last_error
|
||||||
|
*
|
||||||
|
* return string representation of last PhysicsFS error
|
||||||
|
*/
|
||||||
|
VALUE physfs_last_error (VALUE self)
|
||||||
|
{
|
||||||
|
const char *last_error = PHYSFS_getLastError ();
|
||||||
|
|
||||||
|
if (last_error == 0)
|
||||||
|
last_error = "";
|
||||||
|
|
||||||
|
return rb_str_new2 (last_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::dir_separator
|
||||||
|
*
|
||||||
|
* return platform directory separator
|
||||||
|
*/
|
||||||
|
VALUE physfs_dir_separator (VALUE self)
|
||||||
|
{
|
||||||
|
return rb_str_new2 (PHYSFS_getDirSeparator ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::permit_symlinks boolValue
|
||||||
|
*
|
||||||
|
* turn symlinks support on/off
|
||||||
|
*/
|
||||||
|
VALUE physfs_permit_symlinks (VALUE self, VALUE allow)
|
||||||
|
{
|
||||||
|
int p = 1;
|
||||||
|
|
||||||
|
if (allow == Qfalse || allow == Qnil)
|
||||||
|
p = 0;
|
||||||
|
|
||||||
|
PHYSFS_permitSymbolicLinks (p);
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::cdrom_dirs
|
||||||
|
*
|
||||||
|
* return Array of strings containing available CDs
|
||||||
|
*/
|
||||||
|
VALUE physfs_cdrom_dirs (VALUE self)
|
||||||
|
{
|
||||||
|
char **cds = PHYSFS_getCdRomDirs();
|
||||||
|
char **i;
|
||||||
|
VALUE ary = rb_ary_new ();
|
||||||
|
|
||||||
|
for (i = cds; *i != 0; i++)
|
||||||
|
rb_ary_push (ary, rb_str_new2 (*i));
|
||||||
|
|
||||||
|
PHYSFS_freeList (cds);
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::base_dir
|
||||||
|
*
|
||||||
|
* return base directory
|
||||||
|
*/
|
||||||
|
VALUE physfs_base_dir (VALUE self)
|
||||||
|
{
|
||||||
|
const char *base_dir = PHYSFS_getBaseDir ();
|
||||||
|
if (base_dir == 0)
|
||||||
|
base_dir = "";
|
||||||
|
|
||||||
|
return rb_str_new2 (base_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::user_dir
|
||||||
|
*
|
||||||
|
* return user directory
|
||||||
|
*/
|
||||||
|
VALUE physfs_user_dir (VALUE self)
|
||||||
|
{
|
||||||
|
const char *user_dir = PHYSFS_getBaseDir ();
|
||||||
|
if (user_dir == 0)
|
||||||
|
user_dir = "";
|
||||||
|
|
||||||
|
return rb_str_new2 (user_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::write_dir
|
||||||
|
*
|
||||||
|
* return write directory
|
||||||
|
*/
|
||||||
|
VALUE physfs_write_dir (VALUE self)
|
||||||
|
{
|
||||||
|
const char *write_dir = PHYSFS_getWriteDir ();
|
||||||
|
if (write_dir == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return rb_str_new2 (write_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::write_dir= str
|
||||||
|
*
|
||||||
|
* set write directory to *str*
|
||||||
|
*/
|
||||||
|
VALUE physfs_set_write_dir (VALUE self, VALUE str)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_setWriteDir (STR2CSTR(str));
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::add_to_search_path str, append
|
||||||
|
*
|
||||||
|
* if append > 0 - append str to search path, otherwise prepend it
|
||||||
|
*/
|
||||||
|
VALUE physfs_add_search_path (VALUE self, VALUE str, VALUE append)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_addToSearchPath (STR2CSTR(str), FIX2INT(append));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::remove_from_search_path str
|
||||||
|
*
|
||||||
|
* removes str from search path
|
||||||
|
*/
|
||||||
|
VALUE physfs_remove_search_path (VALUE self, VALUE str)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_removeFromSearchPath (STR2CSTR(str));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::search_path
|
||||||
|
*
|
||||||
|
* return current search_path - as array of strings
|
||||||
|
*/
|
||||||
|
VALUE physfs_search_path (VALUE self)
|
||||||
|
{
|
||||||
|
char **path = PHYSFS_getSearchPath ();
|
||||||
|
char **i;
|
||||||
|
VALUE ary = rb_ary_new ();
|
||||||
|
|
||||||
|
for (i = path ; *i != 0; i++)
|
||||||
|
rb_ary_push (ary, rb_str_new2 (*i));
|
||||||
|
|
||||||
|
PHYSFS_freeList (path);
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
VALUE physfs_setSaneConfig(VALUE self, VALUE org, VALUE app, VALUE ext,
|
||||||
|
VALUE includeCdroms, VALUE archivesFirst)
|
||||||
|
{
|
||||||
|
int res = PHYSFS_setSaneConfig (STR2CSTR(org), STR2CSTR(app), STR2CSTR(ext),
|
||||||
|
RTEST(includeCdroms), RTEST(archivesFirst));
|
||||||
|
if (res)
|
||||||
|
return Qtrue;
|
||||||
|
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::mkdir newdir
|
||||||
|
*
|
||||||
|
* create new directory
|
||||||
|
*/
|
||||||
|
VALUE physfs_mkdir (VALUE self, VALUE newdir)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_mkdir (STR2CSTR(newdir));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::delete name
|
||||||
|
*
|
||||||
|
* delete file with name
|
||||||
|
*/
|
||||||
|
VALUE physfs_delete (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_delete (STR2CSTR(name));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::real_dir name
|
||||||
|
*
|
||||||
|
* return real directory (in search path) of a name
|
||||||
|
*/
|
||||||
|
VALUE physfs_real_dir (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
const char *path = PHYSFS_getRealDir (STR2CSTR(name));
|
||||||
|
if (path == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return rb_str_new2 (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::enumerate dir
|
||||||
|
*
|
||||||
|
* list a dir from a search path
|
||||||
|
*/
|
||||||
|
VALUE physfs_enumerate (VALUE self, VALUE dir)
|
||||||
|
{
|
||||||
|
char **files = PHYSFS_enumerateFiles (STR2CSTR(dir));
|
||||||
|
char **i;
|
||||||
|
VALUE ary = rb_ary_new ();
|
||||||
|
|
||||||
|
for (i = files; *i != 0; i++)
|
||||||
|
rb_ary_push (ary, rb_str_new2 (*i));
|
||||||
|
|
||||||
|
PHYSFS_freeList (files);
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::exists? name
|
||||||
|
*
|
||||||
|
* does a file with name exist?
|
||||||
|
*/
|
||||||
|
VALUE physfs_exists (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_exists (STR2CSTR(name));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::is_directory? name
|
||||||
|
*
|
||||||
|
* return true if name is directory
|
||||||
|
*/
|
||||||
|
VALUE physfs_is_directory (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_isDirectory (STR2CSTR(name));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::is_symlink? name
|
||||||
|
*
|
||||||
|
* return true if name is symlink
|
||||||
|
*/
|
||||||
|
VALUE physfs_is_symlink (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_isSymbolicLink (STR2CSTR(name));
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::last_mod_time name
|
||||||
|
*
|
||||||
|
* return last modification time of a file
|
||||||
|
*/
|
||||||
|
VALUE physfs_last_mod_time (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
int result = PHYSFS_getLastModTime (STR2CSTR(name));
|
||||||
|
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::open_read name
|
||||||
|
*
|
||||||
|
* return +PhysicsFS::File+ ready for reading
|
||||||
|
*/
|
||||||
|
VALUE physfs_open_read (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
PHYSFS_file *file = PHYSFS_openRead (STR2CSTR(name));
|
||||||
|
return physfs_file_new (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::open_write name
|
||||||
|
*
|
||||||
|
* return PhysicsFS::File ready for writing
|
||||||
|
*/
|
||||||
|
VALUE physfs_open_write (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
PHYSFS_file *file = PHYSFS_openWrite (STR2CSTR(name));
|
||||||
|
return physfs_file_new (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::open_append name
|
||||||
|
*
|
||||||
|
* return PhysicsFS::File ready for appending
|
||||||
|
*/
|
||||||
|
VALUE physfs_open_append (VALUE self, VALUE name)
|
||||||
|
{
|
||||||
|
PHYSFS_file *file = PHYSFS_openAppend (STR2CSTR(name));
|
||||||
|
return physfs_file_new (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init_physfs_so (void)
|
||||||
|
{
|
||||||
|
modulePhysfs = rb_define_module ("PhysicsFS");
|
||||||
|
|
||||||
|
rb_define_singleton_method (modulePhysfs, "init_internal", physfs_init, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "deinit", physfs_deinit, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "version", physfs_version, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "supported_archives",
|
||||||
|
physfs_supported_archives, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "last_error",
|
||||||
|
physfs_last_error, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "dir_separator",
|
||||||
|
physfs_dir_separator, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "permit_symlinks",
|
||||||
|
physfs_permit_symlinks, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "cdrom_dirs",
|
||||||
|
physfs_cdrom_dirs, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "base_dir", physfs_base_dir, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "user_dir", physfs_user_dir, 0);
|
||||||
|
|
||||||
|
rb_define_singleton_method (modulePhysfs, "write_dir", physfs_write_dir, 0);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "write_dir=",
|
||||||
|
physfs_set_write_dir, 1);
|
||||||
|
|
||||||
|
rb_define_singleton_method (modulePhysfs, "add_to_search_path",
|
||||||
|
physfs_add_search_path, 2);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "remove_from_search_path",
|
||||||
|
physfs_remove_search_path, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "search_path",
|
||||||
|
physfs_search_path, 0);
|
||||||
|
|
||||||
|
rb_define_singleton_method (modulePhysfs, "set_sane_config",
|
||||||
|
physfs_setSaneConfig, 5);
|
||||||
|
|
||||||
|
rb_define_singleton_method (modulePhysfs, "mkdir", physfs_mkdir, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "delete", physfs_delete, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "real_dir",
|
||||||
|
physfs_real_dir, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "enumerate", physfs_enumerate, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "exists?", physfs_exists, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "is_directory?",
|
||||||
|
physfs_is_directory, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "is_symlink?",
|
||||||
|
physfs_is_symlink, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "last_mod_time",
|
||||||
|
physfs_last_mod_time, 1);
|
||||||
|
|
||||||
|
rb_define_singleton_method (modulePhysfs, "open_read",
|
||||||
|
physfs_open_read, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "open_write",
|
||||||
|
physfs_open_write, 1);
|
||||||
|
rb_define_singleton_method (modulePhysfs, "open_append",
|
||||||
|
physfs_open_append, 1);
|
||||||
|
|
||||||
|
init_physfs_file ();
|
||||||
|
init_sdl_rwops ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Local Variables:
|
||||||
|
// mode: C
|
||||||
|
// c-indentation-style: "stroustrup"
|
||||||
|
// indent-tabs-mode: nil
|
||||||
|
// End:
|
||||||
|
*/
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* PhysicsFS - ruby interface
|
||||||
|
*
|
||||||
|
* Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
* License:: LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RB__PHYSFS__H__
|
||||||
|
#define __RB__PHYSFS__H__
|
||||||
|
|
||||||
|
extern VALUE modulePhysfs;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* PhysicsFS File abstraction - ruby interface
|
||||||
|
*
|
||||||
|
* Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
* License:: LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "physfs.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
|
||||||
|
#include "rb_physfs.h"
|
||||||
|
#include "rb_physfs_file.h"
|
||||||
|
#include "physfsrwops.h"
|
||||||
|
|
||||||
|
VALUE classPhysfsFile;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* construct new PhysicsFS::File object
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_new (PHYSFS_file *file)
|
||||||
|
{
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return Data_Wrap_Struct (classPhysfsFile, 0, 0, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#close
|
||||||
|
*
|
||||||
|
* Close the file. It's illegal to use the object after its closure.
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_close (VALUE self)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
|
||||||
|
if (file == 0)
|
||||||
|
return Qfalse;
|
||||||
|
|
||||||
|
result = PHYSFS_close (file);
|
||||||
|
DATA_PTR(self) = 0;
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#read obj_size, num_objects
|
||||||
|
*
|
||||||
|
* Read *objCount* objects which are *objSize* each.
|
||||||
|
* return String instance containing raw data or nil if failure.
|
||||||
|
* #length of string will reflect real number of objects read.
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount)
|
||||||
|
{
|
||||||
|
int objRead;
|
||||||
|
void *buffer;
|
||||||
|
VALUE result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil; //wasted file - no read possible
|
||||||
|
|
||||||
|
buffer = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
|
||||||
|
if (buffer == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
objRead = PHYSFS_read (file, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
|
||||||
|
if (objRead == -1)
|
||||||
|
{
|
||||||
|
free (buffer);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
|
||||||
|
free (buffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#write buffer, obj_size, num_objects
|
||||||
|
*
|
||||||
|
* return nil on failure or number of objects written.
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = PHYSFS_write (file, STR2CSTR(buf),
|
||||||
|
FIX2UINT(objSize), FIX2UINT(objCount));
|
||||||
|
if (result == -1)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#eof?
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_eof (VALUE self)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = PHYSFS_eof (file);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#tell
|
||||||
|
*
|
||||||
|
* tells current position in file
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_tell (VALUE self)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = PHYSFS_tell (file);
|
||||||
|
|
||||||
|
if (result == -1)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#seek pos
|
||||||
|
*
|
||||||
|
* seek to pos in file
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_seek (VALUE self, VALUE pos)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = PHYSFS_seek (file, FIX2LONG(pos));
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
return Qtrue;
|
||||||
|
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#length
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_length (VALUE self)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
PHYSFS_file *file;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = PHYSFS_fileLength (file);
|
||||||
|
|
||||||
|
if (result == -1)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::File#to_rwops
|
||||||
|
*
|
||||||
|
* File object is converted to RWops object.
|
||||||
|
* File object becomes unusable after that - every operation
|
||||||
|
* should be done through new-born RWops object.
|
||||||
|
*/
|
||||||
|
VALUE physfs_file_to_rwops (VALUE self)
|
||||||
|
{
|
||||||
|
PHYSFS_file *file;
|
||||||
|
SDL_RWops *rwops;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, PHYSFS_file, file);
|
||||||
|
if (file == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
rwops = PHYSFSRWOPS_makeRWops (file);
|
||||||
|
if (rwops == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
DATA_PTR(self) = 0; // oh, gosh, we've sacrificed ourselves!
|
||||||
|
return sdl_rwops_new (rwops);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_physfs_file (void)
|
||||||
|
{
|
||||||
|
classPhysfsFile = rb_define_class_under (modulePhysfs, "File", rb_cObject);
|
||||||
|
|
||||||
|
rb_define_method (classPhysfsFile, "close", physfs_file_close, 0);
|
||||||
|
rb_define_method (classPhysfsFile, "eof?", physfs_file_eof, 0);
|
||||||
|
rb_define_method (classPhysfsFile, "tell", physfs_file_tell, 0);
|
||||||
|
rb_define_method (classPhysfsFile, "seek", physfs_file_seek, 1);
|
||||||
|
rb_define_method (classPhysfsFile, "length", physfs_file_length, 0);
|
||||||
|
rb_define_method (classPhysfsFile, "read", physfs_file_read, 2);
|
||||||
|
rb_define_method (classPhysfsFile, "write", physfs_file_write, 3);
|
||||||
|
rb_define_method (classPhysfsFile, "to_rwops", physfs_file_to_rwops, 0);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* PhysicsFS File abstraction - ruby interface
|
||||||
|
*
|
||||||
|
* Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
* License:: LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RB__PHYSFS__FILE__H__
|
||||||
|
#define __RB__PHYSFS__FILE__H__
|
||||||
|
|
||||||
|
extern VALUE classPhysfsFile;
|
||||||
|
|
||||||
|
VALUE physfs_file_new (PHYSFS_file *file);
|
||||||
|
VALUE physfs_file_close (VALUE self);
|
||||||
|
VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount);
|
||||||
|
VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount);
|
||||||
|
VALUE physfs_file_eof (VALUE self);
|
||||||
|
VALUE physfs_file_tell (VALUE self);
|
||||||
|
VALUE physfs_file_seek (VALUE self, VALUE pos);
|
||||||
|
VALUE physfs_file_length (VALUE self);
|
||||||
|
|
||||||
|
void init_physfs_file (void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* SDL_RWops - ruby interface
|
||||||
|
*
|
||||||
|
* Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
* License:: LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SDL_rwops.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
|
||||||
|
#include "rb_physfs.h"
|
||||||
|
#include "rb_sdl_rwops.h"
|
||||||
|
|
||||||
|
VALUE classRWops;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RWops constructor
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_new (SDL_RWops *ops)
|
||||||
|
{
|
||||||
|
VALUE result;
|
||||||
|
|
||||||
|
if (ops == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = Data_Wrap_Struct (classRWops, 0, SDL_FreeRW, ops);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::RWops::from_file name, mode
|
||||||
|
*
|
||||||
|
* create RWops object from file
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_from_file (VALUE self, VALUE name, VALUE mode)
|
||||||
|
{
|
||||||
|
SDL_RWops *ops = SDL_RWFromFile(STR2CSTR(name), STR2CSTR(mode));
|
||||||
|
return sdl_rwops_new (ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::RWops::from_memory string
|
||||||
|
*
|
||||||
|
* create RWops object from memory
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_from_mem (VALUE self, VALUE str)
|
||||||
|
{
|
||||||
|
int len = RSTRING(str)->len;
|
||||||
|
void *mem = STR2CSTR(str);
|
||||||
|
SDL_RWops *ops = SDL_RWFromMem(mem, len);
|
||||||
|
|
||||||
|
return sdl_rwops_new (ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::RWops#seek offset, whence
|
||||||
|
*
|
||||||
|
* position RWops object
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_seek (VALUE self, VALUE offset, VALUE whence)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
SDL_RWops *ops;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, SDL_RWops, ops);
|
||||||
|
if (ops == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = SDL_RWseek(ops, FIX2INT(offset), FIX2INT(whence));
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::RWops#close
|
||||||
|
*
|
||||||
|
* close RWops. No use of the object is possible after that.
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_close (VALUE self)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
SDL_RWops *ops;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, SDL_RWops, ops);
|
||||||
|
if (ops == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = SDL_RWclose (ops);
|
||||||
|
DATA_PTR(self) = 0;
|
||||||
|
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::RWops#read
|
||||||
|
*
|
||||||
|
* read from RWops object objCount objSize'd entities.
|
||||||
|
* return string containing raw data or nil
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_read (VALUE self, VALUE objSize, VALUE objCount)
|
||||||
|
{
|
||||||
|
int objRead;
|
||||||
|
void *buffer;
|
||||||
|
VALUE result;
|
||||||
|
SDL_RWops *ops;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, SDL_RWops, ops);
|
||||||
|
if (ops == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
buffer = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
|
||||||
|
if (buffer == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
objRead = SDL_RWread (ops, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
|
||||||
|
if (objRead == -1)
|
||||||
|
{
|
||||||
|
free (buffer);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
|
||||||
|
free (buffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PhysicsFS::RWops#write buffer, size, n
|
||||||
|
*
|
||||||
|
* write raw string containing n objects size length each.
|
||||||
|
* return number of objects written or nil
|
||||||
|
*/
|
||||||
|
VALUE sdl_rwops_write (VALUE self, VALUE buffer, VALUE size, VALUE n)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
SDL_RWops *ops;
|
||||||
|
|
||||||
|
Data_Get_Struct (self, SDL_RWops, ops);
|
||||||
|
if (ops == 0)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
result = SDL_RWwrite (ops, STR2CSTR(buffer), FIX2INT(size), FIX2INT(n));
|
||||||
|
|
||||||
|
if (result == -1)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
return INT2FIX(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_sdl_rwops (void)
|
||||||
|
{
|
||||||
|
classRWops = rb_define_class_under (modulePhysfs, "RWops", rb_cObject);
|
||||||
|
|
||||||
|
rb_define_method (classRWops, "seek", sdl_rwops_seek, 2);
|
||||||
|
rb_define_method (classRWops, "read", sdl_rwops_read, 2);
|
||||||
|
rb_define_method (classRWops, "write", sdl_rwops_write, 3);
|
||||||
|
rb_define_method (classRWops, "close", sdl_rwops_close, 0);
|
||||||
|
|
||||||
|
rb_define_singleton_method (classRWops, "from_file",
|
||||||
|
sdl_rwops_from_file, 2);
|
||||||
|
rb_define_singleton_method (classRWops, "from_memory",
|
||||||
|
sdl_rwops_from_mem, 1);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* SDL_RWops - ruby interface
|
||||||
|
*
|
||||||
|
* Author:: Ed Sinjiashvili (slimb@vlinkmail.com)
|
||||||
|
* License:: LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RB__SDL__RWOPS__H__
|
||||||
|
#define __RB__SDL__RWOPS__H__
|
||||||
|
|
||||||
|
extern VALUE classRWops;
|
||||||
|
|
||||||
|
VALUE sdl_rwops_new (SDL_RWops *ops);
|
||||||
|
void init_sdl_rwops (void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,358 @@
|
||||||
|
#
|
||||||
|
# PhysicsFS test program - mimics real physfs_test
|
||||||
|
#
|
||||||
|
require 'readline'
|
||||||
|
require 'physfs'
|
||||||
|
|
||||||
|
def die msg
|
||||||
|
puts "#{msg} - reason: #{PhysicsFS.last_error}"
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# parse line to command and args
|
||||||
|
#
|
||||||
|
def parse line
|
||||||
|
return false if line.nil?
|
||||||
|
|
||||||
|
if line.strip =~ /^(.*?) (?: (?:\s+(.*)) | $)/x
|
||||||
|
run $1, $2
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# parse command args
|
||||||
|
#
|
||||||
|
def parse_args args
|
||||||
|
args.strip!
|
||||||
|
|
||||||
|
dquoted = /^ " (.*?) "/x
|
||||||
|
squoted = /^ ' (.*?) '/x
|
||||||
|
unquoted = /^([^\s\'\"]+)/
|
||||||
|
|
||||||
|
regexps = [dquoted, squoted, unquoted]
|
||||||
|
|
||||||
|
result = []
|
||||||
|
while args != ""
|
||||||
|
regexps.each do |r|
|
||||||
|
if args =~ r
|
||||||
|
result << $1
|
||||||
|
args.sub! r, ""
|
||||||
|
args.sub!(/\s+/, "")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def usage cmd, prefix = "usage: "
|
||||||
|
print prefix
|
||||||
|
args = Commands::HELP[cmd]
|
||||||
|
if args
|
||||||
|
print cmd
|
||||||
|
args.scan(/\w+/).each {|x|
|
||||||
|
print " <#{x}>"
|
||||||
|
}
|
||||||
|
puts
|
||||||
|
else
|
||||||
|
puts %|#{cmd} (no arguments)|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# commands go below
|
||||||
|
module Commands
|
||||||
|
HELP = {
|
||||||
|
"init" => "argv0",
|
||||||
|
"addarchive" => "archiveLocation append",
|
||||||
|
"removearchive" => "archiveLocation",
|
||||||
|
"enumerate" => "dirToEnumerate",
|
||||||
|
"ls" => "dirToEnumerate",
|
||||||
|
"setwritedir" => "newWriteDir",
|
||||||
|
"permitsymlinks" => "1or0",
|
||||||
|
"setsaneconfig" => "org appName arcExt includeCdRoms archivesFirst",
|
||||||
|
"mkdir" => "dirToMk",
|
||||||
|
"delete" => "dirToDelete",
|
||||||
|
"getrealdir" => "fileToFind",
|
||||||
|
"exists" => "fileToCheck",
|
||||||
|
"isdir" => "fileToCheck",
|
||||||
|
"issymlink" => "fileToCheck",
|
||||||
|
"cat" => "fileToCat",
|
||||||
|
"filelength" => "fileToCheck",
|
||||||
|
"append" => "fileToAppend",
|
||||||
|
"write" => "fileToCreateOrTrash",
|
||||||
|
"getlastmodtime" => "fileToExamine"
|
||||||
|
}
|
||||||
|
|
||||||
|
def quit_cmd
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
alias q_cmd quit_cmd
|
||||||
|
|
||||||
|
def help_cmd
|
||||||
|
commands = ::Commands.instance_methods.grep(/_cmd$/).sort
|
||||||
|
puts "Commands:"
|
||||||
|
commands.each do |c|
|
||||||
|
usage c.sub("_cmd", ""), " - "
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def e val
|
||||||
|
if val
|
||||||
|
puts "Successful."
|
||||||
|
else
|
||||||
|
puts "Failure. reason: #{PhysicsFS.last_error}"
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def init_cmd arg
|
||||||
|
e PhysicsFS.init(arg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def deinit_cmd
|
||||||
|
e PhysicsFS.deinit
|
||||||
|
end
|
||||||
|
|
||||||
|
def addarchive_cmd archive, append
|
||||||
|
e PhysicsFS.add_to_search_path(archive, append)
|
||||||
|
end
|
||||||
|
|
||||||
|
def removearchive_cmd archive
|
||||||
|
e PhysicsFS.remove_from_search_path archive
|
||||||
|
end
|
||||||
|
|
||||||
|
def enumerate_cmd path
|
||||||
|
entries = PhysicsFS.enumerate(path)
|
||||||
|
entries.each {|x|
|
||||||
|
puts x
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
alias ls_cmd enumerate_cmd
|
||||||
|
|
||||||
|
def getlasterror_cmd
|
||||||
|
puts "Last error is [#{PhysicsFS.last_error}]"
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getdirsep_cmd
|
||||||
|
puts "Directory separator is [#{PhysicsFS.dir_separator}]"
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getcdromdirs_cmd
|
||||||
|
dirs = PhysicsFS.cdrom_dirs
|
||||||
|
dirs.each {|x|
|
||||||
|
puts x
|
||||||
|
}
|
||||||
|
puts " total [#{dirs.length}] drives."
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getsearchpath_cmd
|
||||||
|
spath = PhysicsFS.search_path
|
||||||
|
spath.each {|x|
|
||||||
|
puts x
|
||||||
|
}
|
||||||
|
puts "total [#{spath.length}] directories."
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getbasedir_cmd
|
||||||
|
dir = PhysicsFS.base_dir
|
||||||
|
puts dir if dir
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getuserdir_cmd
|
||||||
|
puts PhysicsFS.user_dir
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getwritedir_cmd
|
||||||
|
dir = PhysicsFS.write_dir
|
||||||
|
if dir
|
||||||
|
puts "Write directory is [#{dir}]."
|
||||||
|
else
|
||||||
|
puts "No write directory defined."
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def setwritedir_cmd dir
|
||||||
|
e(PhysicsFS.write_dir = dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def permitsymlinks_cmd val
|
||||||
|
if val.to_i == 1
|
||||||
|
PhysicsFS.permit_symlinks true
|
||||||
|
puts "Symlinks are now permitted"
|
||||||
|
else
|
||||||
|
PhysicsFS.permit_symlinks false
|
||||||
|
puts "Symlinks are now forbidden"
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def setsaneconfig_cmd org, appname, ext, includeCdroms, archivesFirst
|
||||||
|
includeCdroms = includeCdroms.to_i == 1
|
||||||
|
archiveFirst = archivesFirst == 1
|
||||||
|
e PhysicsFS.set_sane_config(org, appname, ext, includeCdroms, archivesFirst)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mkdir_cmd dir
|
||||||
|
e PhysicsFS.mkdir(dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_cmd dir
|
||||||
|
e PhysicsFS.delete(dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def getrealdir_cmd file
|
||||||
|
dir = PhysicsFS.real_dir file
|
||||||
|
if dir
|
||||||
|
puts "Found at [#{dir}]"
|
||||||
|
else
|
||||||
|
puts "Not found."
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def exists_cmd file
|
||||||
|
if PhysicsFS.exists? file
|
||||||
|
puts "File exists"
|
||||||
|
else
|
||||||
|
puts "File does not exist"
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def isdir_cmd file
|
||||||
|
if PhysicsFS.is_directory? file
|
||||||
|
puts "File is a directory"
|
||||||
|
else
|
||||||
|
puts "File is NOT a directory"
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def issymlink_cmd file
|
||||||
|
if PhysicsFS.is_symlink? file
|
||||||
|
puts "File is a symlink"
|
||||||
|
else
|
||||||
|
puts "File is NOT a symlink"
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def cat_cmd filename
|
||||||
|
file = PhysicsFS.open_read filename
|
||||||
|
if file.nil?
|
||||||
|
puts "failed to open. reason: #{PhysicsFS.last_error}"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
puts file.cat
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def filelength_cmd filename
|
||||||
|
file = PhysicsFS.open_read filename
|
||||||
|
if file.nil?
|
||||||
|
puts "failed to open. reason: #{PhysicsFS.last_error}"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
puts file.length
|
||||||
|
file.close
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
WRITE_STR = "Rubyfied PhysicsFS works just fine.\n\n"
|
||||||
|
|
||||||
|
def append_cmd filename
|
||||||
|
file = PhysicsFS.open_append filename
|
||||||
|
if file.nil?
|
||||||
|
puts "failed to open. reason: #{PhysicsFS.last_error}"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
file.write WRITE_STR, 1, WRITE_STR.length
|
||||||
|
file.close
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_cmd filename
|
||||||
|
file = PhysicsFS.open_write filename
|
||||||
|
if file.nil?
|
||||||
|
puts "failed to open. reason: #{PhysicsFS.last_error}"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
file.write_str WRITE_STR
|
||||||
|
file.close
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def getlastmodtime_cmd filename
|
||||||
|
t = PhysicsFS.last_mod_time filename
|
||||||
|
if t == -1
|
||||||
|
puts "failed to determin. reason: #{PhysicsFS.last_error}"
|
||||||
|
else
|
||||||
|
puts "Last modified: #{Time.at(t)}"
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
include Commands
|
||||||
|
|
||||||
|
def run command, args
|
||||||
|
if args
|
||||||
|
args = parse_args args
|
||||||
|
else
|
||||||
|
args = []
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
cmd = method "#{command}_cmd"
|
||||||
|
if args.length == cmd.arity
|
||||||
|
return cmd.call *args
|
||||||
|
else
|
||||||
|
usage command
|
||||||
|
true
|
||||||
|
end
|
||||||
|
rescue NameError
|
||||||
|
puts 'Unknown command. Enter "help" for instructions.'
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
|
||||||
|
PhysicsFS.init($0) or die "PhysicsFS init failed"
|
||||||
|
|
||||||
|
puts "PhysicsFS version: #{PhysicsFS.version}"
|
||||||
|
puts
|
||||||
|
|
||||||
|
puts "Supported archives: "
|
||||||
|
puts PhysicsFS.supported_archives
|
||||||
|
puts
|
||||||
|
|
||||||
|
puts 'Enter commands. Enter "help" for instructions.'
|
||||||
|
|
||||||
|
loop {
|
||||||
|
line = Readline::readline "physfs_rb> ", true
|
||||||
|
break unless parse line
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* ./physfshttpd archive1.zip archive2.zip /path/to/a/real/dir etc...
|
* ./physfshttpd archive1.zip archive2.zip /path/to/a/real/dir etc...
|
||||||
*
|
*
|
||||||
* The files are appended in order to the PhysicsFS search path, and when
|
* The files are appended in order to the PhysicsFS search path, and when
|
||||||
* a client request comes in, it looks for the file in said search path.
|
* a client request comes it, it looks for the file in said search path.
|
||||||
*
|
*
|
||||||
* My goal was to make this work in less than 300 lines of C, so again, it's
|
* My goal was to make this work in less than 300 lines of C, so again, it's
|
||||||
* not to be used for any serious purpose. Patches to make this application
|
* not to be used for any serious purpose. Patches to make this application
|
||||||
|
@ -27,14 +27,13 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see LICENSE.txt in the root of the source tree.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -55,7 +54,7 @@
|
||||||
#include "physfs.h"
|
#include "physfs.h"
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_PORTNUM 8080
|
#define DEFAULT_PORTNUM 6667
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -65,153 +64,45 @@ typedef struct
|
||||||
} http_args;
|
} http_args;
|
||||||
|
|
||||||
|
|
||||||
#define txt404 \
|
static char *txt404 =
|
||||||
"HTTP/1.0 404 Not Found\n" \
|
"HTTP/1.0 404 Not Found\n"
|
||||||
"Connection: close\n" \
|
"Connection: close\n"
|
||||||
"Content-Type: text/html; charset=utf-8\n" \
|
"Content-type: text/html; charset=utf-8\n"
|
||||||
"\n" \
|
"\n"
|
||||||
"<html><head><title>404 Not Found</title></head>\n" \
|
"<html><head><title>404 Not Found</title></head>\n"
|
||||||
"<body>Can't find '%s'.</body></html>\n\n" \
|
"<body>Can't find that.</body></html>\n\n";
|
||||||
|
|
||||||
#define txt200 \
|
|
||||||
"HTTP/1.0 200 OK\n" \
|
|
||||||
"Connection: close\n" \
|
|
||||||
"Content-Type: %s\n" \
|
|
||||||
"\n"
|
|
||||||
|
|
||||||
static const char *lastError(void)
|
|
||||||
{
|
|
||||||
return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
|
|
||||||
} /* lastError */
|
|
||||||
|
|
||||||
static int writeAll(const char *ipstr, const int sock, void *buf, const size_t len)
|
|
||||||
{
|
|
||||||
if (write(sock, buf, len) != len)
|
|
||||||
{
|
|
||||||
printf("%s: Write error to socket.\n", ipstr);
|
|
||||||
return 0;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
} /* writeAll */
|
|
||||||
|
|
||||||
static int writeString(const char *ipstr, const int sock, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
/* none of this is robust against large strings or HTML escaping. */
|
|
||||||
char buffer[1024];
|
|
||||||
int len;
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = vsnprintf(buffer, sizeof (buffer), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if (len < 0)
|
|
||||||
{
|
|
||||||
printf("uhoh, vsnprintf() failed!\n");
|
|
||||||
return 0;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
return writeAll(ipstr, sock, buffer, len);
|
|
||||||
} /* writeString */
|
|
||||||
|
|
||||||
|
|
||||||
static void feed_file_http(const char *ipstr, int sock, const char *fname)
|
static void feed_file_http(const char *ipstr, int sock, const char *fname)
|
||||||
{
|
{
|
||||||
PHYSFS_File *in = PHYSFS_openRead(fname);
|
PHYSFS_file *in = PHYSFS_openRead(fname);
|
||||||
|
char buffer[1024];
|
||||||
|
printf("%s: requested [%s].\n", ipstr, fname);
|
||||||
if (in == NULL)
|
if (in == NULL)
|
||||||
{
|
{
|
||||||
printf("%s: Can't open [%s]: %s.\n", ipstr, fname, lastError());
|
printf("%s: Can't open [%s]: %s.\n",
|
||||||
writeString(ipstr, sock, txt404, fname);
|
ipstr, fname, PHYSFS_getLastError());
|
||||||
return;
|
write(sock, txt404, strlen(txt404)); /* !!! FIXME: Check retval */
|
||||||
} /* if */
|
} /* if */
|
||||||
|
else
|
||||||
/* !!! FIXME: mimetype */
|
|
||||||
if (writeString(ipstr, sock, txt200, "text/plain; charset=utf-8"))
|
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
PHYSFS_sint64 br = PHYSFS_read(in, buffer, 1, sizeof (buffer));
|
||||||
PHYSFS_sint64 br = PHYSFS_readBytes(in, buffer, sizeof (buffer));
|
|
||||||
if (br == -1)
|
if (br == -1)
|
||||||
{
|
{
|
||||||
printf("%s: Read error: %s.\n", ipstr, lastError());
|
printf("%s: Read error: %s.\n", ipstr, PHYSFS_getLastError());
|
||||||
break;
|
break;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
else if (!writeAll(ipstr, sock, buffer, (size_t) br))
|
write(sock, buffer, (int) br); /* !!! FIXME: CHECK THIS RETVAL! */
|
||||||
{
|
|
||||||
break;
|
|
||||||
} /* else if */
|
|
||||||
} while (!PHYSFS_eof(in));
|
} while (!PHYSFS_eof(in));
|
||||||
} /* if */
|
|
||||||
|
|
||||||
PHYSFS_close(in);
|
PHYSFS_close(in);
|
||||||
|
} /* else */
|
||||||
} /* feed_file_http */
|
} /* feed_file_http */
|
||||||
|
|
||||||
|
|
||||||
static void feed_dirlist_http(const char *ipstr, int sock,
|
|
||||||
const char *dname, char **list)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!writeString(ipstr, sock, txt200, "text/html; charset=utf-8"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
else if (!writeString(ipstr, sock,
|
|
||||||
"<html><head><title>Directory %s</title></head>"
|
|
||||||
"<body><p><h1>Directory %s</h1></p><p><ul>\n",
|
|
||||||
dname, dname))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (strcmp(dname, "/") == 0)
|
|
||||||
dname = "";
|
|
||||||
|
|
||||||
for (i = 0; list[i]; i++)
|
|
||||||
{
|
|
||||||
const char *fname = list[i];
|
|
||||||
if (!writeString(ipstr, sock,
|
|
||||||
"<li><a href='%s/%s'>%s</a></li>\n", dname, fname, fname))
|
|
||||||
break;
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
writeString(ipstr, sock, "</ul></body></html>\n");
|
|
||||||
} /* feed_dirlist_http */
|
|
||||||
|
|
||||||
static void feed_dir_http(const char *ipstr, int sock, const char *dname)
|
|
||||||
{
|
|
||||||
char **list = PHYSFS_enumerateFiles(dname);
|
|
||||||
if (list == NULL)
|
|
||||||
{
|
|
||||||
printf("%s: Can't enumerate directory [%s]: %s.\n",
|
|
||||||
ipstr, dname, lastError());
|
|
||||||
writeString(ipstr, sock, txt404, dname);
|
|
||||||
return;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
feed_dirlist_http(ipstr, sock, dname, list);
|
|
||||||
PHYSFS_freeList(list);
|
|
||||||
} /* feed_dir_http */
|
|
||||||
|
|
||||||
static void feed_http_request(const char *ipstr, int sock, const char *fname)
|
|
||||||
{
|
|
||||||
PHYSFS_Stat statbuf;
|
|
||||||
|
|
||||||
printf("%s: requested [%s].\n", ipstr, fname);
|
|
||||||
|
|
||||||
if (!PHYSFS_stat(fname, &statbuf))
|
|
||||||
{
|
|
||||||
printf("%s: Can't stat [%s]: %s.\n", ipstr, fname, lastError());
|
|
||||||
writeString(ipstr, sock, txt404, fname);
|
|
||||||
return;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
if (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY)
|
|
||||||
feed_dir_http(ipstr, sock, fname);
|
|
||||||
else
|
|
||||||
feed_file_http(ipstr, sock, fname);
|
|
||||||
} /* feed_http_request */
|
|
||||||
|
|
||||||
|
|
||||||
static void *do_http(void *_args)
|
static void *do_http(void *_args)
|
||||||
{
|
{
|
||||||
http_args *args = (http_args *) _args;
|
http_args *args = (http_args *) _args;
|
||||||
|
@ -244,7 +135,7 @@ static void *do_http(void *_args)
|
||||||
ptr = strchr(buffer + 5, ' ');
|
ptr = strchr(buffer + 5, ' ');
|
||||||
if (ptr != NULL)
|
if (ptr != NULL)
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
feed_http_request(ipstr, args->sock, buffer + 4);
|
feed_file_http(ipstr, args->sock, buffer + 4);
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* else */
|
} /* else */
|
||||||
|
|
||||||
|
@ -253,7 +144,7 @@ static void *do_http(void *_args)
|
||||||
close(args->sock);
|
close(args->sock);
|
||||||
free(args->addr);
|
free(args->addr);
|
||||||
free(args);
|
free(args);
|
||||||
return NULL;
|
return(NULL);
|
||||||
} /* do_http */
|
} /* do_http */
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,7 +194,7 @@ static int create_listen_socket(short portnum)
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(portnum);
|
addr.sin_port = htons(portnum);
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
if ((bind(retval, (struct sockaddr *) &addr, (socklen_t) sizeof (addr)) == -1) ||
|
if ((bind(retval, &addr, (socklen_t) sizeof (addr)) == -1) ||
|
||||||
(listen(retval, 5) == -1))
|
(listen(retval, 5) == -1))
|
||||||
{
|
{
|
||||||
close(retval);
|
close(retval);
|
||||||
|
@ -311,7 +202,7 @@ static int create_listen_socket(short portnum)
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
return retval;
|
return(retval);
|
||||||
} /* create_listen_socket */
|
} /* create_listen_socket */
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,7 +219,7 @@ void at_exit_cleanup(void)
|
||||||
close(listensocket);
|
close(listensocket);
|
||||||
|
|
||||||
if (!PHYSFS_deinit())
|
if (!PHYSFS_deinit())
|
||||||
printf("PHYSFS_deinit() failed: %s\n", lastError());
|
printf("PHYSFS_deinit() failed: %s\n", PHYSFS_getLastError());
|
||||||
} /* at_exit_cleanup */
|
} /* at_exit_cleanup */
|
||||||
|
|
||||||
|
|
||||||
|
@ -353,13 +244,13 @@ int main(int argc, char **argv)
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
printf("USAGE: %s <archive1> [archive2 [... archiveN]]\n", argv[0]);
|
printf("USAGE: %s <archive1> [archive2 [... archiveN]]\n", argv[0]);
|
||||||
return 42;
|
return(42);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_init(argv[0]))
|
if (!PHYSFS_init(argv[0]))
|
||||||
{
|
{
|
||||||
printf("PHYSFS_init() failed: %s\n", lastError());
|
printf("PHYSFS_init() failed: %s\n", PHYSFS_getLastError());
|
||||||
return 42;
|
return(42);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
/* normally, this is bad practice, but oh well. */
|
/* normally, this is bad practice, but oh well. */
|
||||||
|
@ -367,7 +258,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (!PHYSFS_mount(argv[i], NULL, 1))
|
if (!PHYSFS_addToSearchPath(argv[i], 1))
|
||||||
printf(" WARNING: failed to add [%s] to search path.\n", argv[i]);
|
printf(" WARNING: failed to add [%s] to search path.\n", argv[i]);
|
||||||
} /* else */
|
} /* else */
|
||||||
|
|
||||||
|
@ -375,7 +266,7 @@ int main(int argc, char **argv)
|
||||||
if (listensocket < 0)
|
if (listensocket < 0)
|
||||||
{
|
{
|
||||||
printf("listen socket failed to create.\n");
|
printf("listen socket failed to create.\n");
|
||||||
return 42;
|
return(42);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
while (1) /* infinite loop for now. */
|
while (1) /* infinite loop for now. */
|
||||||
|
@ -387,13 +278,13 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("accept() failed: %s\n", strerror(errno));
|
printf("accept() failed: %s\n", strerror(errno));
|
||||||
close(listensocket);
|
close(listensocket);
|
||||||
return 42;
|
return(42);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
serve_http_request(s, &addr, len);
|
serve_http_request(s, &addr, len);
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
return 0;
|
return(0);
|
||||||
} /* main */
|
} /* main */
|
||||||
|
|
||||||
/* end of physfshttpd.c ... */
|
/* end of physfshttpd.c ... */
|
||||||
|
|
|
@ -13,10 +13,9 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see LICENSE.txt in the root of the source tree.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* SDL 1.2 falls under the LGPL license. SDL 1.3+ is zlib, like PhysicsFS.
|
* SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
|
||||||
* You can get SDL at https://www.libsdl.org/
|
|
||||||
*
|
*
|
||||||
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
||||||
*/
|
*/
|
||||||
|
@ -24,187 +23,130 @@
|
||||||
#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
|
#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
|
||||||
#include "physfsrwops.h"
|
#include "physfsrwops.h"
|
||||||
|
|
||||||
/* SDL's RWOPS interface changed a little in SDL 2.0... */
|
|
||||||
#if defined(SDL_VERSION_ATLEAST)
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
#define TARGET_SDL2 1
|
|
||||||
#endif
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
|
|
||||||
return (Sint64) PHYSFS_fileLength(handle);
|
|
||||||
} /* physfsrwops_size */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if TARGET_SDL2
|
|
||||||
static Sint64 SDLCALL physfsrwops_seek(struct SDL_RWops *rw, Sint64 offset, int whence)
|
|
||||||
#else
|
|
||||||
static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
|
static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
PHYSFS_sint64 pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
if (whence == RW_SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
pos = (PHYSFS_sint64) offset;
|
|
||||||
|
|
||||||
else if (whence == RW_SEEK_CUR)
|
|
||||||
{
|
{
|
||||||
const PHYSFS_sint64 current = PHYSFS_tell(handle);
|
pos = offset;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
else if (whence == SEEK_CUR)
|
||||||
|
{
|
||||||
|
PHYSFS_sint64 current = PHYSFS_tell(handle);
|
||||||
if (current == -1)
|
if (current == -1)
|
||||||
{
|
{
|
||||||
SDL_SetError("Can't find position in file: %s",
|
SDL_SetError("Can't find position in file: %s",
|
||||||
PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
PHYSFS_getLastError());
|
||||||
return -1;
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
pos = (int) current;
|
||||||
|
if ( ((PHYSFS_sint64) pos) != current )
|
||||||
|
{
|
||||||
|
SDL_SetError("Can't fit current file position in an int!");
|
||||||
|
return(-1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (offset == 0) /* this is a "tell" call. We're done. */
|
if (offset == 0) /* this is a "tell" call. We're done. */
|
||||||
{
|
return(pos);
|
||||||
#if TARGET_SDL2
|
|
||||||
return (Sint64) current;
|
|
||||||
#else
|
|
||||||
return (int) current;
|
|
||||||
#endif
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
pos = current + ((PHYSFS_sint64) offset);
|
pos += offset;
|
||||||
} /* else if */
|
} /* else if */
|
||||||
|
|
||||||
else if (whence == RW_SEEK_END)
|
else if (whence == SEEK_END)
|
||||||
{
|
{
|
||||||
const PHYSFS_sint64 len = PHYSFS_fileLength(handle);
|
PHYSFS_sint64 len = PHYSFS_fileLength(handle);
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
{
|
{
|
||||||
SDL_SetError("Can't find end of file: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
|
||||||
return -1;
|
return(-1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
pos = len + ((PHYSFS_sint64) offset);
|
pos = (int) len;
|
||||||
|
if ( ((PHYSFS_sint64) pos) != len )
|
||||||
|
{
|
||||||
|
SDL_SetError("Can't fit end-of-file position in an int!");
|
||||||
|
return(-1);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
pos += offset;
|
||||||
} /* else if */
|
} /* else if */
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SDL_SetError("Invalid 'whence' parameter.");
|
SDL_SetError("Invalid 'whence' parameter.");
|
||||||
return -1;
|
return(-1);
|
||||||
} /* else */
|
} /* else */
|
||||||
|
|
||||||
if ( pos < 0 )
|
if ( pos < 0 )
|
||||||
{
|
{
|
||||||
SDL_SetError("Attempt to seek past start of file.");
|
SDL_SetError("Attempt to seek past start of file.");
|
||||||
return -1;
|
return(-1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
|
if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
|
||||||
{
|
{
|
||||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
return -1;
|
return(-1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
#if TARGET_SDL2
|
return(pos);
|
||||||
return (Sint64) pos;
|
|
||||||
#else
|
|
||||||
return (int) pos;
|
|
||||||
#endif
|
|
||||||
} /* physfsrwops_seek */
|
} /* physfsrwops_seek */
|
||||||
|
|
||||||
|
|
||||||
#if TARGET_SDL2
|
|
||||||
static size_t SDLCALL physfsrwops_read(struct SDL_RWops *rw, void *ptr,
|
|
||||||
size_t size, size_t maxnum)
|
|
||||||
#else
|
|
||||||
static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
|
static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
const PHYSFS_uint64 readlen = (PHYSFS_uint64) (maxnum * size);
|
PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum);
|
||||||
const PHYSFS_sint64 rc = PHYSFS_readBytes(handle, ptr, readlen);
|
if (rc != maxnum)
|
||||||
if (rc != ((PHYSFS_sint64) readlen))
|
|
||||||
{
|
{
|
||||||
if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
|
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;
|
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
} /* if */
|
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
#if TARGET_SDL2
|
return((int) rc);
|
||||||
return (size_t) rc / size;
|
|
||||||
#else
|
|
||||||
return (int) rc / size;
|
|
||||||
#endif
|
|
||||||
} /* physfsrwops_read */
|
} /* physfsrwops_read */
|
||||||
|
|
||||||
|
|
||||||
#if TARGET_SDL2
|
|
||||||
static size_t SDLCALL physfsrwops_write(struct SDL_RWops *rw, const void *ptr,
|
|
||||||
size_t size, size_t num)
|
|
||||||
#else
|
|
||||||
static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
|
static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
const PHYSFS_uint64 writelen = (PHYSFS_uint64) (num * size);
|
PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num);
|
||||||
const PHYSFS_sint64 rc = PHYSFS_writeBytes(handle, ptr, writelen);
|
if (rc != num)
|
||||||
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((int) rc);
|
||||||
return (size_t) rc;
|
|
||||||
#else
|
|
||||||
return (int) rc;
|
|
||||||
#endif
|
|
||||||
} /* physfsrwops_write */
|
} /* physfsrwops_write */
|
||||||
|
|
||||||
|
|
||||||
static int physfsrwops_close(SDL_RWops *rw)
|
static int physfsrwops_close(SDL_RWops *rw)
|
||||||
{
|
{
|
||||||
PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
|
PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
|
||||||
if (!PHYSFS_close(handle))
|
if (!PHYSFS_close(handle))
|
||||||
{
|
{
|
||||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
return -1;
|
return(-1);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
SDL_FreeRW(rw);
|
SDL_FreeRW(rw);
|
||||||
return 0;
|
return(0);
|
||||||
} /* physfsrwops_close */
|
} /* physfsrwops_close */
|
||||||
|
|
||||||
|
|
||||||
static SDL_RWops *create_rwops(PHYSFS_File *handle)
|
static SDL_RWops *create_rwops(PHYSFS_file *handle)
|
||||||
{
|
{
|
||||||
SDL_RWops *retval = NULL;
|
SDL_RWops *retval = NULL;
|
||||||
|
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retval = SDL_AllocRW();
|
retval = SDL_AllocRW();
|
||||||
if (retval != NULL)
|
if (retval != NULL)
|
||||||
{
|
{
|
||||||
#if TARGET_SDL2
|
|
||||||
retval->size = physfsrwops_size;
|
|
||||||
#endif
|
|
||||||
retval->seek = physfsrwops_seek;
|
retval->seek = physfsrwops_seek;
|
||||||
retval->read = physfsrwops_read;
|
retval->read = physfsrwops_read;
|
||||||
retval->write = physfsrwops_write;
|
retval->write = physfsrwops_write;
|
||||||
|
@ -213,11 +155,11 @@ static SDL_RWops *create_rwops(PHYSFS_File *handle)
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* else */
|
} /* else */
|
||||||
|
|
||||||
return retval;
|
return(retval);
|
||||||
} /* create_rwops */
|
} /* create_rwops */
|
||||||
|
|
||||||
|
|
||||||
SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle)
|
SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle)
|
||||||
{
|
{
|
||||||
SDL_RWops *retval = NULL;
|
SDL_RWops *retval = NULL;
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
|
@ -225,25 +167,25 @@ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle)
|
||||||
else
|
else
|
||||||
retval = create_rwops(handle);
|
retval = create_rwops(handle);
|
||||||
|
|
||||||
return retval;
|
return(retval);
|
||||||
} /* PHYSFSRWOPS_makeRWops */
|
} /* PHYSFSRWOPS_makeRWops */
|
||||||
|
|
||||||
|
|
||||||
SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
|
SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
|
||||||
{
|
{
|
||||||
return create_rwops(PHYSFS_openRead(fname));
|
return(create_rwops(PHYSFS_openRead(fname)));
|
||||||
} /* PHYSFSRWOPS_openRead */
|
} /* PHYSFSRWOPS_openRead */
|
||||||
|
|
||||||
|
|
||||||
SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
|
SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
|
||||||
{
|
{
|
||||||
return create_rwops(PHYSFS_openWrite(fname));
|
return(create_rwops(PHYSFS_openWrite(fname)));
|
||||||
} /* PHYSFSRWOPS_openWrite */
|
} /* PHYSFSRWOPS_openWrite */
|
||||||
|
|
||||||
|
|
||||||
SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
|
SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
|
||||||
{
|
{
|
||||||
return create_rwops(PHYSFS_openAppend(fname));
|
return(create_rwops(PHYSFS_openAppend(fname)));
|
||||||
} /* PHYSFSRWOPS_openAppend */
|
} /* PHYSFSRWOPS_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,9 @@
|
||||||
* NO WARRANTY.
|
* NO WARRANTY.
|
||||||
*
|
*
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
||||||
* Please see LICENSE.txt in the root of the source tree.
|
* Please see LICENSE in the root of the source tree.
|
||||||
*
|
*
|
||||||
* SDL 1.2 falls under the LGPL license. SDL 1.3+ is zlib, like PhysicsFS.
|
* SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
|
||||||
* You can get SDL at https://www.libsdl.org/
|
|
||||||
*
|
*
|
||||||
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +40,7 @@ extern "C" {
|
||||||
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
* of the error can be gleaned from PHYSFS_getLastError().
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
*/
|
*/
|
||||||
PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a platform-independent filename for writing, and make it accessible
|
* Open a platform-independent filename for writing, and make it accessible
|
||||||
|
@ -53,7 +52,7 @@ PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
|
||||||
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
* of the error can be gleaned from PHYSFS_getLastError().
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
*/
|
*/
|
||||||
PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a platform-independent filename for appending, and make it accessible
|
* Open a platform-independent filename for appending, and make it accessible
|
||||||
|
@ -65,7 +64,7 @@ PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
|
||||||
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
* of the error can be gleaned from PHYSFS_getLastError().
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
*/
|
*/
|
||||||
PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a SDL_RWops from an existing PhysicsFS file handle. You should
|
* Make a SDL_RWops from an existing PhysicsFS file handle. You should
|
||||||
|
@ -77,7 +76,7 @@ PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
|
||||||
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
* @return A valid SDL_RWops structure on success, NULL on error. Specifics
|
||||||
* of the error can be gleaned from PHYSFS_getLastError().
|
* of the error can be gleaned from PHYSFS_getLastError().
|
||||||
*/
|
*/
|
||||||
PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle);
|
__EXPORT__ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,181 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "physfs.h"
|
|
||||||
|
|
||||||
|
|
||||||
static int failure = 0;
|
|
||||||
|
|
||||||
static void modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
|
|
||||||
{
|
|
||||||
const char *str = "unknown modtime";
|
|
||||||
if (modtime != -1)
|
|
||||||
{
|
|
||||||
time_t t = (time_t) modtime;
|
|
||||||
str = ctime(&t);
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
strncpy(modstr, str, strsize);
|
|
||||||
modstr[strsize-1] = '\0';
|
|
||||||
strsize = strlen(modstr);
|
|
||||||
while ((modstr[strsize-1] == '\n') || (modstr[strsize-1] == '\r'))
|
|
||||||
modstr[--strsize] = '\0';
|
|
||||||
} /* modTimeToStr */
|
|
||||||
|
|
||||||
|
|
||||||
static void fail(const char *what, const char *why)
|
|
||||||
{
|
|
||||||
if (why == NULL)
|
|
||||||
why = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
|
|
||||||
fprintf(stderr, "%s failed: %s\n", what, why);
|
|
||||||
failure = 1;
|
|
||||||
} /* fail */
|
|
||||||
|
|
||||||
|
|
||||||
static void dumpFile(const char *fname)
|
|
||||||
{
|
|
||||||
const int origfailure = failure;
|
|
||||||
PHYSFS_File *out = NULL;
|
|
||||||
PHYSFS_File *in = NULL;
|
|
||||||
|
|
||||||
failure = 0;
|
|
||||||
|
|
||||||
if ((in = PHYSFS_openRead(fname)) == NULL)
|
|
||||||
fail("\nPHYSFS_openRead", NULL);
|
|
||||||
else if ((out = PHYSFS_openWrite(fname)) == NULL)
|
|
||||||
fail("\nPHYSFS_openWrite", NULL);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char modstr[64];
|
|
||||||
PHYSFS_sint64 size = PHYSFS_fileLength(in);
|
|
||||||
|
|
||||||
printf("(");
|
|
||||||
if (size == -1)
|
|
||||||
printf("?");
|
|
||||||
else
|
|
||||||
printf("%lld", (long long) size);
|
|
||||||
printf(" bytes");
|
|
||||||
|
|
||||||
modTimeToStr(PHYSFS_getLastModTime(fname), modstr, sizeof (modstr));
|
|
||||||
printf(", %s)\n", modstr);
|
|
||||||
|
|
||||||
while ( (!failure) && (!PHYSFS_eof(in)) )
|
|
||||||
{
|
|
||||||
static char buf[64 * 1024];
|
|
||||||
PHYSFS_sint64 br = PHYSFS_read(in, buf, 1, sizeof (buf));
|
|
||||||
if (br == -1)
|
|
||||||
fail("PHYSFS_read", NULL);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PHYSFS_sint64 bw = PHYSFS_write(out, buf, 1, br);
|
|
||||||
if (bw != br)
|
|
||||||
fail("PHYSFS_write", NULL);
|
|
||||||
else
|
|
||||||
size -= bw;
|
|
||||||
} /* else */
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
if ((!failure) && (size != 0))
|
|
||||||
fail("PHYSFS_eof", "BUG! eof != PHYSFS_fileLength bytes!");
|
|
||||||
} /* else */
|
|
||||||
|
|
||||||
if (in != NULL)
|
|
||||||
PHYSFS_close(in);
|
|
||||||
|
|
||||||
if (out != NULL)
|
|
||||||
{
|
|
||||||
if (!PHYSFS_close(out))
|
|
||||||
fail("PHYSFS_close", NULL);
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
if (failure)
|
|
||||||
PHYSFS_delete(fname);
|
|
||||||
else
|
|
||||||
failure = origfailure;
|
|
||||||
} /* dumpFile */
|
|
||||||
|
|
||||||
|
|
||||||
static void unpackCallback(void *_depth, const char *origdir, const char *str)
|
|
||||||
{
|
|
||||||
int depth = *((int *) _depth);
|
|
||||||
const int len = strlen(origdir) + strlen(str) + 2;
|
|
||||||
char *fname = (char *) malloc(len);
|
|
||||||
if (fname == NULL)
|
|
||||||
fail("malloc", "Out of memory!");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (strcmp(origdir, "/") == 0)
|
|
||||||
origdir = "";
|
|
||||||
|
|
||||||
snprintf(fname, len, "%s/%s", origdir, str);
|
|
||||||
|
|
||||||
printf("%s ", fname);
|
|
||||||
if (PHYSFS_isDirectory(fname))
|
|
||||||
{
|
|
||||||
depth++;
|
|
||||||
printf("(directory)\n");
|
|
||||||
if (!PHYSFS_mkdir(fname))
|
|
||||||
fail("PHYSFS_mkdir", NULL);
|
|
||||||
else
|
|
||||||
PHYSFS_enumerateFilesCallback(fname, unpackCallback, &depth);
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
else if (PHYSFS_isSymbolicLink(fname))
|
|
||||||
{
|
|
||||||
printf("(symlink)\n");
|
|
||||||
/* !!! FIXME: ? if (!symlink(fname, */
|
|
||||||
} /* else if */
|
|
||||||
|
|
||||||
else /* ...file. */
|
|
||||||
{
|
|
||||||
dumpFile(fname);
|
|
||||||
} /* else */
|
|
||||||
|
|
||||||
free(fname);
|
|
||||||
} /* else */
|
|
||||||
} /* unpackCallback */
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int zero = 0;
|
|
||||||
|
|
||||||
if (argc != 3)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "USAGE: %s <archive> <unpackDirectory>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
if (!PHYSFS_init(argv[0]))
|
|
||||||
{
|
|
||||||
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_getErrorByCode(PHYSFS_getLastErrorCode()));
|
|
||||||
return 3;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
if (!PHYSFS_mount(argv[1], NULL, 1))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "PHYSFS_mount('%s') failed: %s\n",
|
|
||||||
argv[1], PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
|
||||||
return 4;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
PHYSFS_permitSymbolicLinks(1);
|
|
||||||
PHYSFS_enumerateFilesCallback("/", unpackCallback, &zero);
|
|
||||||
PHYSFS_deinit();
|
|
||||||
if (failure)
|
|
||||||
return 5;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} /* main */
|
|
||||||
|
|
||||||
/* end of physfsunpack.c ... */
|
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* This code shows how to read a zipfile included in an app's binary.
|
|
||||||
*
|
|
||||||
* License: this code is public domain. I make no warranty that it is useful,
|
|
||||||
* correct, harmless, or environmentally safe.
|
|
||||||
*
|
|
||||||
* This particular file may be used however you like, including copying it
|
|
||||||
* verbatim into a closed-source project, exploiting it commercially, and
|
|
||||||
* removing any trace of my name from the source (although I hope you won't
|
|
||||||
* do that). I welcome enhancements and corrections to this file, but I do
|
|
||||||
* not require you to send me patches if you make changes. This code has
|
|
||||||
* NO WARRANTY.
|
|
||||||
*
|
|
||||||
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
|
|
||||||
* Please see LICENSE.txt in the root of the source tree.
|
|
||||||
*
|
|
||||||
* This file was written by Ryan C. Gordon. (icculus@icculus.org).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compile this program and then attach a .zip file to the end of the
|
|
||||||
* compiled binary.
|
|
||||||
*
|
|
||||||
* On Linux, something like this will build the final binary:
|
|
||||||
* gcc -o selfextract.tmp selfextract.c -lphysfs && \
|
|
||||||
* cat selfextract.tmp myzipfile.zip >> selfextract && \
|
|
||||||
* chmod a+x selfextract && \
|
|
||||||
* rm -f selfextract.tmp
|
|
||||||
*
|
|
||||||
* This may not work on all platforms, and it probably only works with
|
|
||||||
* .zip files, since they are designed to be appended to another file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "physfs.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!PHYSFS_init(argv[0]))
|
|
||||||
{
|
|
||||||
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_getErrorByCode(PHYSFS_getLastErrorCode()));
|
|
||||||
printf("This might mean you didn't append a zipfile to the binary.\n");
|
|
||||||
return 42;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
char **files = PHYSFS_enumerateFiles("/");
|
|
||||||
char **i;
|
|
||||||
for (i = files; *i != NULL; i++)
|
|
||||||
{
|
|
||||||
const char *dirorfile = PHYSFS_isDirectory(*i) ? "Directory" : "File";
|
|
||||||
printf(" * %s '%s' is in root of attached data.\n", dirorfile, *i);
|
|
||||||
} /* for */
|
|
||||||
PHYSFS_freeList(files);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} /* main */
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ ! -f "./install_manifest.txt" ]; then
|
|
||||||
echo "ERROR: This needs to be run from your CMake build directory after installing." 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
xargs rm -vf < install_manifest.txt
|
|
||||||
exit 0
|
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
@echo off
|
||||||
|
rem this is a simple batch file to build PhysicsFS on OS/2. You need to have
|
||||||
|
rem the EMX development tools installed for this to work.
|
||||||
|
rem
|
||||||
|
rem This script (and, indeed, our OS/2 support) could use some tweaking.
|
||||||
|
rem Patches go to icculus@icculus.org ...
|
||||||
|
|
||||||
|
set PHYSFSLANG=PHYSFS_LANG_ENGLISH
|
||||||
|
set DEBUGFLAGS=-D_NDEBUG -O2 -s
|
||||||
|
rem set CFLAGS=%DEBUGFLAGS% -Wall -Werror -Zomf -Zmt -Zmtd -I. -Izlib123 -c -D__ST_MT_ERRNO__ -DOS2 -DZ_PREFIX -DPHYSFS_SUPPORTS_ZIP -DPHYSFS_SUPPORTS_GRP -DPHYSFS_SUPPORTS_WAD -DPHYSFS_SUPPORTS_QPAK -DPHYSFS_SUPPORTS_HOG -DPHYSFS_SUPPORTS_MVL -DPHYSFS_LANG=%PHYSFSLANG% -DHAVE_ASSERT_H
|
||||||
|
set CFLAGS=%DEBUGFLAGS% -Wall -Werror -Zomf -Zmt -Zmtd -I. -Izlib123 -c -D__ST_MT_ERRNO__ -DOS2 -DZ_PREFIX -DPHYSFS_SUPPORTS_ZIP -DPHYSFS_SUPPORTS_GRP -DPHYSFS_SUPPORTS_WAD -DPHYSFS_SUPPORTS_QPAK -DPHYSFS_SUPPORTS_HOG -DPHYSFS_SUPPORTS_MVL -DHAVE_ASSERT_H
|
||||||
|
|
||||||
|
rem goto :dolinking
|
||||||
|
|
||||||
|
@echo cleaning up any previous build...
|
||||||
|
@mkdir bin 2>NUL
|
||||||
|
@erase /N bin\*.* 2>NUL
|
||||||
|
|
||||||
|
@echo Building export definitions...
|
||||||
|
@echo ;don't edit this directly! It is rewritten by makeos2.cmd! > bin\test_physfs.def
|
||||||
|
@echo NAME TESTPHYSFS WINDOWCOMPAT >> bin\test_physfs.def
|
||||||
|
@echo DESCRIPTION 'PhysicsFS: http://icculus.org/physfs/' >> bin\test_physfs.def
|
||||||
|
@echo STACKSIZE 0x10000 >> bin\test_physfs.def
|
||||||
|
@echo BASE=0x10000 >> bin\test_physfs.def
|
||||||
|
@echo PROTMODE >> bin\test_physfs.def
|
||||||
|
|
||||||
|
@echo ;don't edit this directly! It is rewritten by makeos2.cmd! > bin\physfs.def
|
||||||
|
@echo LIBRARY 'physfs' INITINSTANCE TERMINSTANCE >> bin\physfs.def
|
||||||
|
@echo STACKSIZE 0x10000 >> bin\physfs.def
|
||||||
|
@echo CODE LOADONCALL >> bin\physfs.def
|
||||||
|
@echo DATA LOADONCALL NONSHARED MULTIPLE >> bin\physfs.def
|
||||||
|
@echo DESCRIPTION 'PhysicsFS: http://icculus.org/physfs/' >> bin\physfs.def
|
||||||
|
@echo EXPORTS >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getLinkedVersion" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_init" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_deinit" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_supportedArchiveTypes" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_freeList" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getLastError" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getDirSeparator" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_permitSymbolicLinks" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getCdRomDirs" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getBaseDir" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getUserDir" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getWriteDir" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_setWriteDir" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_addToSearchPath" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_removeFromSearchPath" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getSearchPath" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_setSaneConfig" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_mkdir" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_delete" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getRealDir" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_enumerateFiles" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_exists" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_isDirectory" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_isSymbolicLink" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_openWrite" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_openAppend" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_openRead" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_close" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_read" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_write" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_eof" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_tell" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_seek" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_fileLength" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapSLE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapULE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapSLE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapULE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapSLE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapULE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapSBE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapUBE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapSBE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapUBE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapSBE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_swapUBE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_getLastModTime" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readSLE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readULE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readSLE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readULE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readSLE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readULE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readSBE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readUBE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readSBE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readUBE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readSBE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_readUBE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeSLE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeULE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeSLE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeULE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeSLE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeULE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeSBE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeUBE16" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeSBE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeUBE32" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeSBE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_writeUBE64" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_setBuffer" >> bin\physfs.def
|
||||||
|
@echo "PHYSFS_flush" >> bin\physfs.def
|
||||||
|
|
||||||
|
@echo Building export library...
|
||||||
|
emximp -o bin/physfs.lib bin/physfs.def
|
||||||
|
|
||||||
|
@echo Compiling PhysicsFS library...
|
||||||
|
@echo on
|
||||||
|
gcc %CFLAGS% -o bin/physfs.obj physfs.c
|
||||||
|
gcc %CFLAGS% -o bin/physfs_byteorder.obj physfs_byteorder.c
|
||||||
|
gcc %CFLAGS% -o bin/os2.obj platform/os2.c
|
||||||
|
gcc %CFLAGS% -o bin/dir.obj archivers/dir.c
|
||||||
|
gcc %CFLAGS% -o bin/grp.obj archivers/grp.c
|
||||||
|
gcc %CFLAGS% -o bin/wad.obj archivers/wad.c
|
||||||
|
gcc %CFLAGS% -o bin/zip.obj archivers/zip.c
|
||||||
|
gcc %CFLAGS% -o bin/qpak.obj archivers/qpak.c
|
||||||
|
gcc %CFLAGS% -o bin/hog.obj archivers/hog.c
|
||||||
|
gcc %CFLAGS% -o bin/mvl.obj archivers/mvl.c
|
||||||
|
gcc %CFLAGS% -o bin/adler32.obj zlib123/adler32.c
|
||||||
|
gcc %CFLAGS% -o bin/compress.obj zlib123/compress.c
|
||||||
|
gcc %CFLAGS% -o bin/crc32.obj zlib123/crc32.c
|
||||||
|
gcc %CFLAGS% -o bin/deflate.obj zlib123/deflate.c
|
||||||
|
gcc %CFLAGS% -o bin/gzio.obj zlib123/gzio.c
|
||||||
|
gcc %CFLAGS% -o bin/infback.obj zlib123/infback.c
|
||||||
|
gcc %CFLAGS% -o bin/inffast.obj zlib123/inffast.c
|
||||||
|
gcc %CFLAGS% -o bin/inflate.obj zlib123/inflate.c
|
||||||
|
gcc %CFLAGS% -o bin/inftrees.obj zlib123/inftrees.c
|
||||||
|
gcc %CFLAGS% -o bin/trees.obj zlib123/trees.c
|
||||||
|
gcc %CFLAGS% -o bin/uncompr.obj zlib123/uncompr.c
|
||||||
|
gcc %CFLAGS% -o bin/zutil.obj zlib123/zutil.c
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
:dolinking
|
||||||
|
@echo Linking PhysicsFS library...
|
||||||
|
gcc %DEBUGFLAGS% -Zdll -Zcrtdll -Zomf -Zmt -Zmtd -o bin/physfs.dll bin/*.obj bin/physfs.def
|
||||||
|
|
||||||
|
rem goto :builddone
|
||||||
|
|
||||||
|
@echo Compiling test program...
|
||||||
|
gcc %CFLAGS% -o bin/test_physfs.obj test/test_physfs.c
|
||||||
|
@echo Linking test program...
|
||||||
|
gcc %DEBUGFLAGS% -Zomf -Zcrtdll -Zmt -Zmtd -o bin/test_physfs.exe bin/test_physfs.obj bin/physfs.lib bin/test_physfs.def
|
||||||
|
|
||||||
|
:builddone
|
||||||
|
|
||||||
|
@echo "All done!"
|
||||||
|
|
||||||
|
rem end of makeos2.cmd ...
|
||||||
|
|
|
@ -0,0 +1,240 @@
|
||||||
|
# Microsoft Developer Studio Project File - Name="physfs" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
|
|
||||||
|
CFG=physfs - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "physfs.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "physfs.mak" CFG="physfs - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "physfs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "physfs - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "physfs - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MDd /W3 /WX /Gm /ZI /Od /I "." /I "zlibwin32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "Z_PREFIX" /D "PHYSFS_EXPORTS" /D "PHYSFS_SUPPORTS_GRP" /D "PHYSFS_SUPPORTS_WAD" /D "PHYSFS_SUPPORTS_ZIP" /D "PHYSFS_SUPPORTS_QPAK" /D "PHYSFS_SUPPORTS_MVL" /D "PHYSFS_SUPPORTS_HOG" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /MTd /W3 /WX /Zi /Od /I "." /I "zlib123" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "Z_PREFIX" /D "PHYSFS_EXPORTS" /D "PHYSFS_SUPPORTS_GRP" /D "PHYSFS_SUPPORTS_WAD" /D "PHYSFS_SUPPORTS_ZIP" /D "PHYSFS_SUPPORTS_QPAK" /D "PHYSFS_SUPPORTS_MVL" /D "PHYSFS_SUPPORTS_HOG" /FR /YX /FD /GZ /c
|
||||||
|
# SUBTRACT CPP /X
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
|
# SUBTRACT BASE LINK32 /incremental:no
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../src/Debug/physfs.dll"
|
||||||
|
# SUBTRACT LINK32 /pdb:none /force
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "physfs - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Ignore_Export_Lib 0
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MD /W3 /WX /O2 /I "." /I "zlibwin32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHYSFS_EXPORTS" /D "PHYSFS_SUPPORTS_GRP" /D "PHYSFS_SUPPORTS_WAD" /D "PHYSFS_SUPPORTS_ZIP" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /WX /O2 /I "." /I "zlib123" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHYSFS_EXPORTS" /D "PHYSFS_SUPPORTS_GRP" /D "PHYSFS_SUPPORTS_WAD" /D "PHYSFS_SUPPORTS_ZIP" /D "PHYSFS_SUPPORTS_QPAK" /D "PHYSFS_SUPPORTS_HOG" /D "PHYSFS_SUPPORTS_MVL" /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 zlibwin32\zlibstat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "physfs - Win32 Debug"
|
||||||
|
# Name "physfs - Win32 Release"
|
||||||
|
# Begin Group "Source Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\adler32.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\compress.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\crc32.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\deflate.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\dir.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\grp.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\hog.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\inffast.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\inflate.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\inftrees.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\mvl.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\physfs.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\physfs_byteorder.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\qpak.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\trees.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\uncompr.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\wad.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\platform\win32.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\archivers\zip.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\zutil.c
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\deflate.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\infblock.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\infcodes.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\inffast.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\inffixed.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\inftrees.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\infutil.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\physfs.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\physfs_internal.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\trees.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\zconf.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\zlib.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\zlib123\zutil.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION 1,0,2,0
|
||||||
|
PRODUCTVERSION 1,0,2,0
|
||||||
|
FILEOS 0x40004
|
||||||
|
FILETYPE 0x2
|
||||||
|
{
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
{
|
||||||
|
BLOCK "040904B0"
|
||||||
|
{
|
||||||
|
VALUE "CompanyName", ""
|
||||||
|
VALUE "FileDescription", "PhysicsFS"
|
||||||
|
VALUE "FileVersion", "1, 0, 2, 0"
|
||||||
|
VALUE "InternalName", "PhysFS"
|
||||||
|
VALUE "LegalCopyright", "Copyright © 2009 Ryan C. Gordon"
|
||||||
|
VALUE "OriginalFilename", "physfs.dll"
|
||||||
|
VALUE "ProductName", "PhysicsFS"
|
||||||
|
VALUE "ProductVersion", "1, 0, 2, 0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
{
|
||||||
|
VALUE "Translation", 0x0409 0x04B0
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
%define version @VERSION@
|
||||||
|
%define release 1
|
||||||
|
%define name physfs
|
||||||
|
%define prefix /usr
|
||||||
|
|
||||||
|
Summary: PhysicsFS file abstraction layer for games
|
||||||
|
Name: %{name}
|
||||||
|
Version: %{version}
|
||||||
|
Release: %{release}
|
||||||
|
Prefix: %{prefix}
|
||||||
|
Copyright: zlib license
|
||||||
|
Group: System Environment/Libraries
|
||||||
|
URL: http://www.icculus/physfs/
|
||||||
|
Source: physfs-%{version}.tar.gz
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}
|
||||||
|
BuildRequires: doxygen, readline-devel, ncurses-devel
|
||||||
|
Requires: readline, ncurses, zlib
|
||||||
|
|
||||||
|
%description
|
||||||
|
PhysicsFS is a library to provide abstract access to various archives.
|
||||||
|
It is intended for use in video games, and the design was somewhat inspired
|
||||||
|
by Quake 3's file subsystem. The programmer defines a "write directory" on
|
||||||
|
the physical filesystem. No file writing done through the PhysicsFS API can
|
||||||
|
leave that write directory, for security. For example, an embedded scripting
|
||||||
|
language cannot write outside of this path if it uses PhysFS for all of its
|
||||||
|
I/O, which means that untrusted scripts can run more safely. Symbolic links
|
||||||
|
can be disabled as well, for added safety. For file reading, the programmer
|
||||||
|
lists directories and archives that form a "search path". Once the search
|
||||||
|
path is defined, it becomes a single, transparent hierarchical filesystem.
|
||||||
|
This makes for easy access to ZIP files in the same way as you access a file
|
||||||
|
directly on the disk, and it makes it easy to ship a new archive that will
|
||||||
|
override a previous archive on a per-file basis. Finally, PhysicsFS gives
|
||||||
|
you platform-abstracted means to determine if CD-ROMs are available, the
|
||||||
|
user's home directory, where in the real filesystem your program is running,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
%package devel
|
||||||
|
Summary: Development headers, libraries, and documentation for PhysicsFS
|
||||||
|
Group: Development/Libraries
|
||||||
|
Requires: %{name} = %{version}
|
||||||
|
|
||||||
|
%description devel
|
||||||
|
PhysicsFS is a library to provide abstract access to various archives.
|
||||||
|
This package contains the development headers, libraries, and documentaion to
|
||||||
|
build programs using PhysicsFS.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup
|
||||||
|
export CFLAGS="${RPM_OPT_FLAGS}" CXXFLAGS="${RPM_OPT_FLAGS}";
|
||||||
|
./configure --prefix=/usr
|
||||||
|
|
||||||
|
%build
|
||||||
|
export CFLAGS="${RPM_OPT_FLAGS}" CXXFLAGS="${RPM_OPT_FLAGS}";
|
||||||
|
make
|
||||||
|
# Make doxygen docs
|
||||||
|
doxygen
|
||||||
|
|
||||||
|
%install
|
||||||
|
[ -d ${RPM_BUILD_ROOT} ] && rm -rf ${RPM_BUILD_ROOT}
|
||||||
|
make DESTDIR=${RPM_BUILD_ROOT} install
|
||||||
|
|
||||||
|
%clean
|
||||||
|
[ -d ${RPM_BUILD_ROOT} ] && rm -rf ${RPM_BUILD_ROOT}
|
||||||
|
|
||||||
|
%post -p /sbin/ldconfig
|
||||||
|
%postun -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root)
|
||||||
|
%doc CHANGELOG CREDITS INSTALL LICENSE TODO zlib_license_change.txt
|
||||||
|
%{_bindir}/test_physfs
|
||||||
|
%{_libdir}/*so.*
|
||||||
|
|
||||||
|
%files devel
|
||||||
|
%defattr(-,root,root)
|
||||||
|
%doc docs/*
|
||||||
|
%{_libdir}/*.so
|
||||||
|
%{_includedir}/physfs.h
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Thu Dec 18 2002 Edward Rudd <eddie@omegaware.com>
|
||||||
|
- added zlib_license_change.txt to documents
|
||||||
|
|
||||||
|
* Wed Jul 10 2002 Edward Rudd <eddie@omegaware.com>
|
||||||
|
- added doxygen to build requirements
|
||||||
|
|
||||||
|
* Wed Jul 10 2002 Edward Rudd <eddie@omegaware.com>
|
||||||
|
- updated to release 0.17
|
||||||
|
|
||||||
|
* Tue May 15 2002 Edward Rudd <eddie@omegaware.com>
|
||||||
|
- updated to latest CVS and modified spec file to use
|
||||||
|
the autoconf/automake support in the latest CVS
|
||||||
|
|
||||||
|
* Tue Apr 30 2002 Edward Rudd <eddie@omegaware.com>
|
||||||
|
- Initial spec file
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue